Fusion de la branche glasnost-lasso avec le tronc.

Upgrade en reprenant les informations des anciens serveurs
d'authentification. Cela devrait permettre de se logguer (un peu testé),
mais cela ne marche pas encore pour les anciens votes par exemple.

Amélioration du mécanisme d'upgrade : les fonctions d'upgrade peuvent être
maintenant aussi mises ailleurs que dans les serveurs.

N'enregistre plus les données salies lorsqu'un serveur s'appelle directement
(afin d'éviter une boucle sans fin).
This commit is contained in:
eraviart 2003-12-22 15:55:46 +00:00
parent 8224db135a
commit a6962d4a5a
75 changed files with 4107 additions and 817 deletions

View File

@ -59,11 +59,11 @@ ServerPort = %(port)s + 3
[AtomsServer] [AtomsServer]
ServerPort = %(port)s + 4 ServerPort = %(port)s + 4
[AuthenticationServer] #authentication# [AuthenticationServer]
ServerPort = %(port)s + 5 #authentication# ServerPort = %(port)s + 5
[AuthenticationLoginPasswordServer] #authentication# [AuthenticationLoginPasswordServer]
ServerPort = %(port)s + 6 #authentication# ServerPort = %(port)s + 6
#authentication# [AuthenticationLdapServer] #authentication# [AuthenticationLdapServer]
#authentication# ServerPort = %(port)s + 7 #authentication# ServerPort = %(port)s + 7
@ -137,8 +137,8 @@ ServerPort = %(port)s + 27
[PeopleServer] [PeopleServer]
ServerPort = %(port)s + 30 ServerPort = %(port)s + 30
[PreferencesServer] #obsolete# [PreferencesServer]
ServerPort = %(port)s + 31 #obsolete# ServerPort = %(port)s + 31
[RubricsServer] [RubricsServer]
ServerPort = %(port)s + 32 ServerPort = %(port)s + 32
@ -164,3 +164,17 @@ ServerPort = %(port)s + 38
[VotesServer] [VotesServer]
ServerPort = %(port)s + 39 ServerPort = %(port)s + 39
[PasswordAccountsServer]
ServerPort = %(port)s + 40
[IdentitiesServer]
ServerPort = %(port)s + 41
[ProvidersServer]
ServerPort = %(port)s + 42
[AssertionsServer]
ServerPort = %(port)s + 44
[X509AccountsServer]
ServerPort = %(port)s + 45

View File

@ -249,7 +249,6 @@ class Application(applications.Application):
languageSetInUrl = 0, languageSetInUrl = 0,
objectId = None, objectId = None,
positionalArguments = None, positionalArguments = None,
preferences = None,
readLanguages = None, readLanguages = None,
req = req, req = req,
sectionLevel = 1, sectionLevel = 1,
@ -262,6 +261,7 @@ class Application(applications.Application):
templatesDirectoryPath = None, templatesDirectoryPath = None,
templateFileName = None, templateFileName = None,
templatePrefix = None, templatePrefix = None,
user = None,
userId = '', userId = '',
userToken = '', userToken = '',
virtualHost = None, virtualHost = None,
@ -420,7 +420,7 @@ class Application(applications.Application):
except ImportError: except ImportError:
raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
try: try:
xmlPost = xml.dom.minidom.parseString(xmlPost) xmlPost = xml.dom.minidom.parseString(xmlPostRaw)
except: # TODO: tighter check except: # TODO: tighter check
if context.getVar('debug'): if context.getVar('debug'):
raise raise
@ -429,16 +429,26 @@ class Application(applications.Application):
context.setVar('xmlPostRaw', xmlPostRaw) context.setVar('xmlPostRaw', xmlPostRaw)
class FakeFieldStorage: class FakeFieldStorage:
list = [] list = []
fieldStorage = FakeFieldStorage
def keys(self):
return []
fieldStorage = FakeFieldStorage()
fields = {} fields = {}
for field in fieldStorage.list: # This code is commented, because it doesn't work when a field has
if field.name is not None and not fields.has_key(field.name): # several occurences using the same key. In this case, the key is
fields[field.name] = fieldStorage[field.name] # listed several times in fieldStorage.list, but
elif field.name is not None: # fieldStorage[field.name] is already a complete list.
if not type(fields[field.name]) is type([]): ## for field in fieldStorage.list:
fields[field.name] = [ fields[field.name] ] ## if field.name is not None and not fields.has_key(field.name):
fields[field.name].append(fieldStorage[field.name]) ## fields[field.name] = fieldStorage[field.name]
## elif field.name is not None:
## if not type(fields[field.name]) is type([]):
## fields[field.name] = [ fields[field.name] ]
## fields[field.name].append(fieldStorage[field.name])
for key in fieldStorage.keys():
if key is not None:
fields[key] = fieldStorage[key]
fieldNamesToDelete = [] fieldNamesToDelete = []
for fieldName, fieldValue in fields.items(): for fieldName, fieldValue in fields.items():
@ -508,21 +518,24 @@ class Application(applications.Application):
context.setVar('sessionTokenInCookie', sessionTokenInCookie) context.setVar('sessionTokenInCookie', sessionTokenInCookie)
userToken = '' userToken = ''
userId = None userId = None
user = None
if session and session.has_key('userToken') and session['userToken']: if session and session.has_key('userToken') and session['userToken']:
userToken = session['userToken'] userToken = session['userToken']
context.setVar('userToken', userToken) context.setVar('userToken', userToken)
userId = getProxyForServerRole('authentication').getUserId() userId = getWebForServerRole('identities').getUserId()
if userId: if userId:
userToken = session['userToken'] try:
else: user = getWeb(userId).getObject(userId)
userToken = None except faults.MissingItem:
pass
if user is None:
userToken = ''
userId = None userId = None
del session['userToken'] del session['userToken']
if session.has_key('userId'):
del session['userId']
session['isDirty'] = 1 session['isDirty'] = 1
context.setVar('userId', userId)
context.setVar('userToken', userToken) context.setVar('userToken', userToken)
context.setVar('userId', userId)
context.setVar('user', user)
if not userToken and req.headers_in.has_key('Authorization'): if not userToken and req.headers_in.has_key('Authorization'):
authorization = req.headers_in['Authorization'] authorization = req.headers_in['Authorization']
@ -531,26 +544,15 @@ class Application(applications.Application):
raise apache.SERVER_RETURN, apache.HTTP_NOT_ACCEPTABLE raise apache.SERVER_RETURN, apache.HTTP_NOT_ACCEPTABLE
# TODO: http auth # TODO: http auth
# Handle preferences
preferences = None
if userToken:
try:
preferences = getWebForServerRole(
'preferences').getPreference()
except faults.UnknownServerId:
pass
else:
context.setVar('preferences', preferences)
# Handle languages. # Handle languages.
languages = [] languages = []
if session and session.has_key('lang'): if session and session.has_key('lang'):
languages = [session['lang']] languages = [session['lang']]
elif preferences is not None and preferences.language \ elif user is not None:
and preferences.language != 'None': userLanguage = user.getLanguage()
languages = [preferences.language] if userLanguage is not None:
elif req.headers_in.has_key('Accept-Language'): languages = [userLanguage]
if not languages and req.headers_in.has_key('Accept-Language'):
try: try:
languages = req.headers_in['Accept-Language'] languages = req.headers_in['Accept-Language']
languages = languages.split(',') languages = languages.split(',')
@ -559,7 +561,7 @@ class Application(applications.Application):
return HTTP_BAD_REQUEST return HTTP_BAD_REQUEST
translationsProxy = getProxyForServerRole('translations') translationsProxy = getProxyForServerRole('translations')
languages = [language == 'C' and 'en' or language languages = [language == 'C' and 'en' or language
for language in languages] for language in languages]
try: try:
possibleLanguages = translationsProxy.getPossibleLanguages() possibleLanguages = translationsProxy.getPossibleLanguages()
except (faults.UnknownServerId, faults.UnknownDispatcherInId): except (faults.UnknownServerId, faults.UnknownDispatcherInId):

View File

@ -62,13 +62,13 @@ def index():
## pass ## pass
## else: ## else:
## if virtualHostsCount <= 1: ## if virtualHostsCount <= 1:
## peopleWeb = getWebForServerRole('people') ## identitiesWeb = getWebForServerRole('identities')
## try: ## try:
## peopleCount = peopleWeb.getObjectsCount() ## identitiesCount = identitiesWeb.getObjectsCount()
## except faults.UserAccessDenied: ## except faults.UserAccessDenied:
## pass ## pass
## else: ## else:
## if peopleCount == 0: ## if identitiesCount == 0:
## pageNamesWeb = getWebForServerRole('pagenames') ## pageNamesWeb = getWebForServerRole('pagenames')
## newVirtualHostWizardId = pageNamesWeb.getIdByName( ## newVirtualHostWizardId = pageNamesWeb.getIdByName(
## 'newVirtualHost') ## 'newVirtualHost')

View File

@ -43,23 +43,3 @@
__doc__ = """Glasnost Login Python Web Page""" __doc__ = """Glasnost Login Python Web Page"""
__version__ = '$Revision$'[11:-2] __version__ = '$Revision$'[11:-2]
from glasnost.web.tools import *
def index(access = ''):
authAdmin = getWebForServerRole('authentication').getAdmin()
for authMethod in authAdmin.authenticationMethods or ['login-password']:
authWeb = getWebForServerRole('authentication-%s' % authMethod)
if authWeb:
break
return authWeb.login(access)
def logout():
authWeb = getWebForServerRole('authentication')
return authWeb.logout()

View File

@ -44,6 +44,7 @@ __doc__ = """Glasnost Sessions Page"""
__version__ = '$Revision$'[11:-2] __version__ = '$Revision$'[11:-2]
import time import time
import glasnost.common.context as context import glasnost.common.context as context
@ -53,9 +54,10 @@ import glasnost.common.xhtmlgenerator as X
import glasnost.web.calendaring import glasnost.web.calendaring
from glasnost.web.tools import * from glasnost.web.tools import *
def index(): def index():
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
if not peopleProxy.isAdmin(): if not identitiesProxy.isAdmin():
return accessForbidden() return accessForbidden()
sessionsProxy = getProxyForServerRole('sessions') sessionsProxy = getProxyForServerRole('sessions')
history = sessionsProxy.getHistory() history = sessionsProxy.getHistory()
@ -76,18 +78,16 @@ def index():
history.sort(lambda x,y: -cmp(x['startTime'], y['startTime'])) history.sort(lambda x,y: -cmp(x['startTime'], y['startTime']))
for session in [x for x in history if x.has_key('expirationTime')]: for session in [x for x in history if x.has_key('expirationTime')]:
tr = X.tr() tr = X.tr()
tr += X.td( time.strftime('%Y-%m-%d %H:%M', tr += X.td(time.strftime('%Y-%m-%d %H:%M',
time.localtime(session['startTime']))) time.localtime(session['startTime'])))
tr += X.td( time.strftime('%Y-%m-%d %H:%M', tr += X.td(time.strftime('%Y-%m-%d %H:%M',
time.localtime(session['expirationTime']))) time.localtime(session['expirationTime'])))
try: user = context.getVar('user')
if session['userId'] == 0: if user is None:
raise faults.MissingItem('')
person = peopleProxy.getObject(session['userId'])
tr += X.td( person.getLabel() )
except faults.MissingItem:
tr += X.td() tr += X.td()
tr += X.td( session['ipAddress'] ) else:
tr += X.td(user.getLabel())
tr += X.td(session['ipAddress'])
tbody += tr tbody += tr
layout += X.h3(_('Previous Sessions')) layout += X.h3(_('Previous Sessions'))
@ -105,25 +105,23 @@ def index():
table += tbody table += tbody
for session in [x for x in history if x.has_key('endTime')]: for session in [x for x in history if x.has_key('endTime')]:
tr = X.tr() tr = X.tr()
tr += X.td( time.strftime('%Y-%m-%d %H:%M', tr += X.td(time.strftime('%Y-%m-%d %H:%M',
time.localtime(session['startTime']))) time.localtime(session['startTime'])))
tr += X.td( time.strftime('%Y-%m-%d %H:%M', tr += X.td(time.strftime('%Y-%m-%d %H:%M',
time.localtime(session['endTime']))) time.localtime(session['endTime'])))
try: user = context.getVar('user')
if session['userId'] == 0: if user is None:
raise faults.MissingItem('')
person = peopleProxy.getObject(session['userId'])
tr += X.td( person.getLabel() )
except faults.MissingItem:
tr += X.td() tr += X.td()
tr += X.td( session['ipAddress'] ) else:
tr += X.td(user.getLabel())
tr += X.td(session['ipAddress'])
tbody += tr tbody += tr
return writePageLayout(layout, _('Sessions History')) return writePageLayout(layout, _('Sessions History'))
def month(year = '', month = ''): def month(year = '', month = ''):
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
if not peopleProxy.isAdmin(): if not identitiesProxy.isAdmin():
return accessForbidden() return accessForbidden()
if not year or not month: if not year or not month:
@ -137,8 +135,8 @@ def month(year = '', month = ''):
if nextMonth == 13: if nextMonth == 13:
nextMonth, nextYear = 1, nextYear + 1 nextMonth, nextYear = 1, nextYear + 1
timeStart = time.mktime( [year, month, 1] + [0]*6 ) timeStart = time.mktime([year, month, 1] + [0] * 6)
timeEnd = time.mktime( [nextYear, nextMonth, 1] + [0]*6 ) timeEnd = time.mktime([nextYear, nextMonth, 1] + [0] * 6)
sessionsProxy = getProxyForServerRole('sessions') sessionsProxy = getProxyForServerRole('sessions')
history = sessionsProxy.getHistory() history = sessionsProxy.getHistory()
@ -160,7 +158,7 @@ def month(year = '', month = ''):
sessions = [] sessions = []
for date, number in sessionsDict.items(): for date, number in sessionsDict.items():
s = SessionStat() s = SessionStat()
s.date = time.mktime( [int(x) for x in date.split('-')] + 6*[0]) s.date = time.mktime([int(x) for x in date.split('-')] + 6 * [0])
s.number = number s.number = number
if number: if number:
sessions.append(s) sessions.append(s)

View File

@ -2,12 +2,11 @@
<glasnost> <glasnost>
<_description>Basic Functionalities</_description> <_description>Basic Functionalities</_description>
<roles> <roles>
<role>authentication</role> <role>identities</role>
<role>authentication-login-password</role>
<role>groups</role> <role>groups</role>
<role>pagenames</role> <role>pagenames</role>
<role>passwordaccounts</role>
<role>people</role> <role>people</role>
<role>preferences</role>
<role>sessions</role> <role>sessions</role>
<role>virtualhosts</role> <role>virtualhosts</role>
</roles> </roles>

View File

@ -86,50 +86,6 @@ class Appointment(ObjectServerMixin, AppointmentCommon):
register(Appointment) register(Appointment)
def vCalDateToTime(s):
if len(s) == 8:
return time.mktime(time.strptime(s, '%Y%m%d'))
if len(s) == 15:
return time.mktime(time.strptime(s, '%Y%m%dT%H%M%S'))
return None
def domToObject(domDocument):
# FIXME: the document could have several VEVENT
nodes = domDocument._get_childNodes()[1]._get_childNodes()[-1]._get_childNodes()
attrs = [(x._get_nodeName(),
x._get_childNodes()[0]._get_nodeValue()) for x in nodes]
# yep, I hope it will work. Incredible.
# TODO: something smarter
# attrs now is a list of pairs (key, value)
# ex: [('UID', 'glasnost://projects.entrouvert.be.lan/appointments/1'),
# ('SUMMARY', 'rdv avec Olivier Lattignies et Etienne Saliez'),
# ('URL', 'http://projects.entrouvert.be.lan/appointments/1'),
# ('REVISION', '0'),
# ('DTSTART', '20030210'),
# ('DTEND', '20030210T235900')]
d = {}
for k,v in attrs:
d[k] = unicode(v.encode('latin-1'), 'utf-8').encode('latin-1')
appointment = Appointment()
if d['UID'].startswith('glasnost://'):
appointment.id = d['UID']
appointment.title = d['SUMMARY']
if d.has_key('SEQUENCE'):
appointment.version = d['SEQUENCE']
if d.has_key('DTSTART'):
t = vCalDateToTime(d['DTSTART'])
if t:
appointment.start = t
if d.has_key('DTEND'):
t = vCalDateToTime(d['DTEND'])
if t:
appointment.end = t
if d.has_key('DESCRIPTION'):
s = d['DESCRIPTION']
s = s.replace('\\n', '\n')
appointment.body = s
return appointment
class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer): class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
useAdminWritersSet = 1 useAdminWritersSet = 1
@ -150,15 +106,15 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
if not participantIds or participantIds == ['']: if not participantIds or participantIds == ['']:
participantIds = [] participantIds = []
authenticationProxy = getProxyForServerRole('authentication') identitiesProxy = getProxyForServerRole('identities')
result = [] result = []
for objectId, object in virtualServer.objects.items(): for objectId, object in virtualServer.objects.items():
if not (isAdmin if not (isAdmin
or authenticationProxy.setContainsUser(object.readersSet) or identitiesProxy.setContainsUser(object.readersSet)
or (object.participantsSet or (object.participantsSet
and getProxyForServerRole('authentication' and identitiesProxy.setContainsUser(
).setContainsUser(object.participantsSet))): object.participantsSet))):
continue continue
if participantIds and not self.isAskedParticipant( if participantIds and not self.isAskedParticipant(
@ -220,8 +176,8 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
def sendNotification(self, virtualServerId, appointment, subject, body): def sendNotification(self, virtualServerId, appointment, subject, body):
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
mailFrom = virtualServer.adminEmailAddress mailFrom = virtualServer.adminEmailAddress
people = getSetContainedIds(appointment.participantsSet) personIds = getSetContainedIds(appointment.participantsSet)
for personId in people: for personId in personIds:
person = getProxyForServerRole('people').getObject(personId) person = getProxyForServerRole('people').getObject(personId)
if person.email: if person.email:
mailTo = person.email mailTo = person.email
@ -279,6 +235,52 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
appointmentsServer = AppointmentsServer() appointmentsServer = AppointmentsServer()
def domToObject(domDocument):
# FIXME: the document could have several VEVENT
nodes = domDocument._get_childNodes()[1]._get_childNodes()[-1]._get_childNodes()
attrs = [(x._get_nodeName(),
x._get_childNodes()[0]._get_nodeValue()) for x in nodes]
# yep, I hope it will work. Incredible.
# TODO: something smarter
# attrs now is a list of pairs (key, value)
# ex: [('UID', 'glasnost://projects.entrouvert.be.lan/appointments/1'),
# ('SUMMARY', 'rdv avec Olivier Lattignies et Etienne Saliez'),
# ('URL', 'http://projects.entrouvert.be.lan/appointments/1'),
# ('REVISION', '0'),
# ('DTSTART', '20030210'),
# ('DTEND', '20030210T235900')]
d = {}
for k,v in attrs:
d[k] = unicode(v.encode('latin-1'), 'utf-8').encode('latin-1')
appointment = Appointment()
if d['UID'].startswith('glasnost://'):
appointment.id = d['UID']
appointment.title = d['SUMMARY']
if d.has_key('SEQUENCE'):
appointment.version = d['SEQUENCE']
if d.has_key('DTSTART'):
t = vCalDateToTime(d['DTSTART'])
if t:
appointment.start = t
if d.has_key('DTEND'):
t = vCalDateToTime(d['DTEND'])
if t:
appointment.end = t
if d.has_key('DESCRIPTION'):
s = d['DESCRIPTION']
s = s.replace('\\n', '\n')
appointment.body = s
return appointment
def vCalDateToTime(s):
if len(s) == 8:
return time.mktime(time.strptime(s, '%Y%m%d'))
if len(s) == 15:
return time.mktime(time.strptime(s, '%Y%m%dT%H%M%S'))
return None
if __name__ == "__main__": if __name__ == "__main__":
appointmentsServer.launch(applicationName, applicationRole) appointmentsServer.launch(applicationName, applicationRole)

View File

@ -133,7 +133,7 @@ class Article(ObjectServerMixin, ArticleCommon):
if self.editionTime: if self.editionTime:
del self.editionTime del self.editionTime
else: else:
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
if userId: if userId:
self.lastEditorId = userId self.lastEditorId = userId
self.editionTime = time.time() self.editionTime = time.time()
@ -203,9 +203,9 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
object = commonTools.importThing(objectImport) object = commonTools.importThing(objectImport)
if not self.canAddObject()or ( if not self.canAddObject()or (
not self.isAdmin() and not ( not self.isAdmin() and not (
getProxyForServerRole('authentication').setContainsUser( getProxyForServerRole('identities').setContainsUser(
self.getAdminCore().writersSet) self.getAdminCore().writersSet)
and getProxyForServerRole('authentication').setContainsUser( and getProxyForServerRole('identities').setContainsUser(
object.writersSet))): object.writersSet))):
if not object.canBeCreatedByClient(): if not object.canBeCreatedByClient():
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
@ -213,7 +213,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
object.setAutomaticalSlots() object.setAutomaticalSlots()
virtualServer.objects[object.id] = object virtualServer.objects[object.id] = object
if object.body is not None: if object.body is not None:
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
if userId: if userId:
object.lastEditorId = userId object.lastEditorId = userId
object.editionTime = object.modificationTime object.editionTime = object.modificationTime
@ -315,12 +315,14 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
possibleAuthorIds = 'everybody' possibleAuthorIds = 'everybody'
try: try:
possibleReaderIds = getSetContainedIds( possibleReaderIds = getSetContainedIds(
possibleReadersSet, ['people'], raiseWhenUncountable = 1) possibleReadersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
possibleReaderIds = 'everybody' possibleReaderIds = 'everybody'
try: try:
possibleWriterIds = getSetContainedIds( possibleWriterIds = getSetContainedIds(
possibleWritersSet, ['people'], raiseWhenUncountable = 1) possibleWritersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
possibleWriterIds = 'everybody' possibleWriterIds = 'everybody'
objectIds = virtualServer.objects.keys() objectIds = virtualServer.objects.keys()
@ -333,7 +335,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
for objectId in objectIds: for objectId in objectIds:
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
if not isAdmin and not getProxyForServerRole( if not isAdmin and not getProxyForServerRole(
'authentication').setContainsUser(object.readersSet): 'identities').setContainsUser(object.readersSet):
continue continue
if not self.getLastObjectIds_filter( if not self.getLastObjectIds_filter(
possibleAuthorIds, 1, object.authorsSet): possibleAuthorIds, 1, object.authorsSet):
@ -495,7 +497,7 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
multiCall = MultiCall() multiCall = MultiCall()
for objectId, object in virtualServer.objects.items(): for objectId, object in virtualServer.objects.items():
if not isAdmin \ if not isAdmin \
and not getProxyForServerRole('authentication' and not getProxyForServerRole('identities'
).setContainsUser(object.readersSet): ).setContainsUser(object.readersSet):
continue continue
if 'body' in scope: if 'body' in scope:

View File

@ -0,0 +1,142 @@
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Assertions Server"""
__version__ = '$Revision$'[11:-2]
import md5
import sys
import time
import whrandom
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
import glasnost
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.server.ObjectsServer as objects
applicationName = 'AssertionsServer'
applicationRole = 'assertions'
dispatcher = None
expirationTime = 1 * 60
class AssertionsVirtualServer(objects.VirtualServer):
assertions = None
assertionExpirationTimes = None
def init(self):
objects.VirtualServer.init(self)
self.assertions = {}
self.assertionExpirationTimes = {}
class AssertionsServer(objects.Server):
VirtualServer = AssertionsVirtualServer
def addAssertion(self, assertion):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
virtualServer.lock.acquire()
while 1:
digest = md5.new(assertion)
randomSalt = str(self.randomGenerator.uniform(0.1, 1))[2:]
digest.update(randomSalt)
artifact = digest.hexdigest()
if not virtualServer.assertions.has_key(artifact):
break
virtualServer.assertions[artifact] = assertion
virtualServer.assertionExpirationTimes[artifact] \
= time.time() + expirationTime
virtualServer.lock.release()
virtualServer.markCoreAsDirty()
return artifact
def convertVirtualServersIds(self, sourceDispatcherId,
destinationDispatcherId):
# Erase the assertions when converting ids.
return 0
def getAssertion(self, artifact):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
# Remove expired assertions.
currentTime = time.time()
for artifact2 in virtualServer.assertions.keys():
if currentTime > virtualServer.assertionExpirationTimes[artifact2]:
del virtualServer.assertions[artifact2]
del virtualServer.assertionExpirationTimes[artifact2]
if not virtualServer.assertions.has_key(artifact):
raise faults.WrongArtifact(artifact)
assertion = virtualServer.assertions[artifact]
del virtualServer.assertions[artifact]
del virtualServer.assertionExpirationTimes[artifact]
virtualServer.markCoreAsDirty()
return assertion
def init(self):
self.randomGenerator = whrandom.whrandom()
objects.Server.init(self)
def registerPublicMethods(self):
objects.Server.registerPublicMethods(self)
self.registerPublicMethod('addAssertion')
self.registerPublicMethod('getAssertion')
assertionsServer = AssertionsServer()
if __name__ == "__main__":
assertionsServer.launch(applicationName, applicationRole)

View File

@ -456,7 +456,7 @@ class AuthenticationLoginPasswordServer(
AuthenticationMethodServer.registerPublicMethods(self) AuthenticationMethodServer.registerPublicMethods(self)
self.registerPublicMethod('emailPassword') self.registerPublicMethod('emailPassword')
def upgrade_0001_0022(self, virtualServer): def upgradeVirtualServer_0001_0022(self, virtualServer):
if not hasattr(virtualServer, 'authentications'): if not hasattr(virtualServer, 'authentications'):
return return
if not virtualServer.authentications: if not virtualServer.authentications:

View File

@ -77,7 +77,8 @@ applicationRole = 'authentication'
dispatcher = None dispatcher = None
# Don't forget to also change the value in SessionsServer.py. # Don't forget to also change the value in SessionsServer.py.
expirationTime = 120 expirationTime = 120 * 60
class AdminAuthentication(AdminServerMixin, AdminAuthenticationCommon): class AdminAuthentication(AdminServerMixin, AdminAuthenticationCommon):
pass pass

View File

@ -136,9 +136,10 @@ class BallotsServer(Server):
def abstainForVote(self, electionId): def abstainForVote(self, electionId):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
try: try:
previousVoteToken = peopleProxy.getElectionVoteToken(electionId) previousVoteToken = identitiesProxy.getElectionVoteToken(
electionId)
except faults.MissingItem: except faults.MissingItem:
previousVoteToken = '' previousVoteToken = ''
if previousVoteToken \ if previousVoteToken \
@ -149,7 +150,7 @@ class BallotsServer(Server):
del virtualServer.electionIds[previousVote.electionToken] del virtualServer.electionIds[previousVote.electionToken]
del virtualServer.voterIds[previousVote.voterToken] del virtualServer.voterIds[previousVote.voterToken]
del virtualServer.voteIds[previousVote.token] del virtualServer.voteIds[previousVote.token]
peopleProxy.abstainForVote(electionId) identitiesProxy.abstainForVote(electionId)
getProxyForServerRole('elections').abstainForVote( getProxyForServerRole('elections').abstainForVote(
electionId, previousVoteToken) electionId, previousVoteToken)
votesProxy.deleteObject(voteId) votesProxy.deleteObject(voteId)
@ -159,7 +160,7 @@ class BallotsServer(Server):
def canGetVoteVoterId(self, voteId): def canGetVoteVoterId(self, voteId):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
vote = getProxyForServerRole('votes').getObject(voteId) vote = getProxyForServerRole('votes').getObject(voteId)
if not virtualServer.voterIds.has_key(vote.voterToken): if not virtualServer.voterIds.has_key(vote.voterToken):
return 0 return 0
@ -188,7 +189,7 @@ class BallotsServer(Server):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
votesExport = [] votesExport = []
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
votesProxy = getProxyForServerRole('votes') votesProxy = getProxyForServerRole('votes')
for voteToken in voteTokens: for voteToken in voteTokens:
if virtualServer.voteIds.has_key(voteToken): if virtualServer.voteIds.has_key(voteToken):
@ -198,7 +199,7 @@ class BallotsServer(Server):
if virtualServer.voterIds.has_key(vote.voterToken): if virtualServer.voterIds.has_key(vote.voterToken):
voterId = virtualServer.voterIds[vote.voterToken] voterId = virtualServer.voterIds[vote.voterToken]
if voterId in electionVoterIds \ if voterId in electionVoterIds \
and peopleProxy.hasObject(voterId): and identitiesProxy.hasObject(voterId):
votesExport.append(vote.exportToXmlRpc()) votesExport.append(vote.exportToXmlRpc())
return votesExport return votesExport
@ -207,7 +208,7 @@ class BallotsServer(Server):
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
electionVoterIds = weightingsById.keys() electionVoterIds = weightingsById.keys()
weightings = {} weightings = {}
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
votesProxy = getProxyForServerRole('votes') votesProxy = getProxyForServerRole('votes')
for voteToken in voteTokens: for voteToken in voteTokens:
if virtualServer.voteIds.has_key(voteToken): if virtualServer.voteIds.has_key(voteToken):
@ -217,7 +218,7 @@ class BallotsServer(Server):
if virtualServer.voterIds.has_key(vote.voterToken): if virtualServer.voterIds.has_key(vote.voterToken):
voterId = virtualServer.voterIds[vote.voterToken] voterId = virtualServer.voterIds[vote.voterToken]
if voterId in electionVoterIds \ if voterId in electionVoterIds \
and peopleProxy.hasObject(voterId): and identitiesProxy.hasObject(voterId):
weightings[vote.voterToken] = weightingsById[ weightings[vote.voterToken] = weightingsById[
voterId] voterId]
return weightings return weightings
@ -225,7 +226,7 @@ class BallotsServer(Server):
def getVote(self, voteId): def getVote(self, voteId):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
vote = getProxyForServerRole('votes').getObject(voteId) vote = getProxyForServerRole('votes').getObject(voteId)
if not virtualServer.voterIds.has_key(vote.voterToken): if not virtualServer.voterIds.has_key(vote.voterToken):
raise faults.UnknownVoterToken(vote.voterToken) raise faults.UnknownVoterToken(vote.voterToken)
@ -253,7 +254,7 @@ class BallotsServer(Server):
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
if voteToken == 'secret': if voteToken == 'secret':
return 'secret' return 'secret'
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
if not virtualServer.voteIds.has_key(voteToken): if not virtualServer.voteIds.has_key(voteToken):
raise faults.UnknownVoteToken(voteToken) raise faults.UnknownVoteToken(voteToken)
voteId = virtualServer.voteIds[voteToken] voteId = virtualServer.voteIds[voteToken]
@ -281,7 +282,7 @@ class BallotsServer(Server):
def getVotesFromTokens(self, voteTokens): def getVotesFromTokens(self, voteTokens):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
votesExport = {} votesExport = {}
electionsProxy = getProxyForServerRole('elections') electionsProxy = getProxyForServerRole('elections')
votesProxy = getProxyForServerRole('votes') votesProxy = getProxyForServerRole('votes')
@ -317,7 +318,7 @@ class BallotsServer(Server):
def getVoteVoterId(self, voteId): def getVoteVoterId(self, voteId):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
vote = getProxyForServerRole('votes').getObject(voteId) vote = getProxyForServerRole('votes').getObject(voteId)
if not virtualServer.voterIds.has_key(vote.voterToken): if not virtualServer.voterIds.has_key(vote.voterToken):
raise faults.UnknownVoterToken(vote.voterToken) raise faults.UnknownVoterToken(vote.voterToken)
@ -346,7 +347,7 @@ class BallotsServer(Server):
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
if voteToken == 'secret': if voteToken == 'secret':
return 'secret' return 'secret'
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
if not virtualServer.voteIds.has_key(voteToken): if not virtualServer.voteIds.has_key(voteToken):
raise faults.UnknownVoteToken(voteToken) raise faults.UnknownVoteToken(voteToken)
voteId = virtualServer.voteIds[voteToken] voteId = virtualServer.voteIds[voteToken]
@ -414,9 +415,10 @@ class BallotsServer(Server):
def vote(self, electionId, voteImport): def vote(self, electionId, voteImport):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
try: try:
previousVoteToken = peopleProxy.getElectionVoteToken(electionId) previousVoteToken = identitiesProxy.getElectionVoteToken(
electionId)
except faults.MissingItem: except faults.MissingItem:
previousVoteToken = '' previousVoteToken = ''
@ -461,12 +463,12 @@ class BallotsServer(Server):
voteId = getProxyForServerRole('votes').addObject( voteId = getProxyForServerRole('votes').addObject(
vote, serverId = commonTools.extractServerId(electionId)) vote, serverId = commonTools.extractServerId(electionId))
getProxyForServerRole('people').vote(electionId, voteToken) getProxyForServerRole('identities').vote(electionId, voteToken)
getProxyForServerRole('elections').vote( getProxyForServerRole('elections').vote(
electionId, voteToken, previousVoteToken) electionId, voteToken, previousVoteToken)
virtualServer.electionIds[electionToken] = electionId virtualServer.electionIds[electionToken] = electionId
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
virtualServer.voterIds[voterToken] = userId virtualServer.voterIds[voterToken] = userId
virtualServer.voteIds[voteToken] = voteId virtualServer.voteIds[voteToken] = voteId

View File

@ -89,7 +89,7 @@ class Comment(ObjectServerMixin, CommentCommon):
def setAutomaticalSlots(self, parentSlot = None): def setAutomaticalSlots(self, parentSlot = None):
ObjectServerMixin.setAutomaticalSlots(self, parentSlot = parentSlot) ObjectServerMixin.setAutomaticalSlots(self, parentSlot = parentSlot)
self.authorId = getProxyForServerRole('authentication').getUserId() self.authorId = getProxyForServerRole('identities').getUserId()
self.creationTime = time.time() self.creationTime = time.time()
register(Comment) register(Comment)

View File

@ -374,9 +374,9 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
# User must be an admin or (a writer and a writer of this object)) # User must be an admin or (a writer and a writer of this object))
if not self.isAdmin() and not ( if not self.isAdmin() and not (
self.useAdminWritersSet self.useAdminWritersSet
and getProxyForServerRole('authentication').setContainsUser( and getProxyForServerRole('identities').setContainsUser(
self.getAdminCore().writersSet) and ( self.getAdminCore().writersSet) and (
getProxyForServerRole('authentication').setContainsUser( getProxyForServerRole('identities').setContainsUser(
object.writersSet))) \ object.writersSet))) \
or object.state != 'draft': or object.state != 'draft':
if not object.canBeCreatedByClient(): if not object.canBeCreatedByClient():
@ -397,7 +397,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
return 0 return 0
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
isAdmin = self.isAdmin() isAdmin = self.isAdmin()
if not isAdmin and not getProxyForServerRole('authentication' if not isAdmin and not getProxyForServerRole('identities'
).setContainsUser(object.writersSet): ).setContainsUser(object.writersSet):
return 0 return 0
if not isAdmin and object.state != 'draft': if not isAdmin and object.state != 'draft':
@ -413,7 +413,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
if not object.canBeModified(): if not object.canBeModified():
return 0 return 0
isAdmin = self.isAdmin() isAdmin = self.isAdmin()
if not isAdmin and not getProxyForServerRole('authentication' if not isAdmin and not getProxyForServerRole('identities'
).setContainsUser(object.writersSet): ).setContainsUser(object.writersSet):
return 0 return 0
if not isAdmin and object.state != 'draft': if not isAdmin and object.state != 'draft':
@ -455,12 +455,14 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
possibleAuthorIds = 'everybody' possibleAuthorIds = 'everybody'
try: try:
possibleReaderIds = getSetContainedIds( possibleReaderIds = getSetContainedIds(
possibleReadersSet, ['people'], raiseWhenUncountable = 1) possibleReadersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
possibleReaderIds = 'everybody' possibleReaderIds = 'everybody'
try: try:
possibleWriterIds = getSetContainedIds( possibleWriterIds = getSetContainedIds(
possibleWritersSet, ['people'], raiseWhenUncountable = 1) possibleWritersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
possibleWriterIds = 'everybody' possibleWriterIds = 'everybody'
objectIds = virtualServer.objects.keys() objectIds = virtualServer.objects.keys()
@ -475,7 +477,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
if possibleStates and not object.state in possibleStates: if possibleStates and not object.state in possibleStates:
continue continue
if not isAdmin and not getProxyForServerRole( if not isAdmin and not getProxyForServerRole(
'authentication').setContainsUser(object.readersSet): 'identities').setContainsUser(object.readersSet):
continue continue
if not self.getLastObjectIds_filter( if not self.getLastObjectIds_filter(
possibleAuthorIds, 1, object.authorsSet): possibleAuthorIds, 1, object.authorsSet):
@ -504,7 +506,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
for objectId in objectIds: for objectId in objectIds:
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
if not self.isAdmin() \ if not self.isAdmin() \
and not getProxyForServerRole('authentication' and not getProxyForServerRole('identities'
).setContainsUser(object.readersSet): ).setContainsUser(object.readersSet):
continue continue
if possibleStates and not object.state in possibleStates: if possibleStates and not object.state in possibleStates:
@ -540,7 +542,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
if not self.canModifyObject(object.id) or not ( if not self.canModifyObject(object.id) or not (
self.isAdmin() self.isAdmin()
or not objectChanges.hasSlotName('writersSet') or not objectChanges.hasSlotName('writersSet')
or getProxyForServerRole('authentication' or getProxyForServerRole('identities'
).setContainsUser( ).setContainsUser(
objectChanges.getSlot('writersSet').getValue())): objectChanges.getSlot('writersSet').getValue())):
if not object.canBeModifiedByClient(): if not object.canBeModifiedByClient():
@ -619,7 +621,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
fromAddress = virtualServer.adminEmailAddress fromAddress = virtualServer.adminEmailAddress
abstentionnistsCount = 0 abstentionnistsCount = 0
for voterId in object.getVoterIds(virtualServerId): for voterId in object.getVoterIds(virtualServerId):
voter = getProxyForServerRole('people').getObject(voterId) voter = getProxyForServerRole('identities').getObject(voterId)
if voter.voteTokens is not None \ if voter.voteTokens is not None \
and voter.voteTokens.has_key(objectId): and voter.voteTokens.has_key(objectId):
continue continue

View File

@ -122,8 +122,8 @@ class GroupsServer(commonGroups.GroupsCommonMixin, objects.ObjectsServer):
if not self.isAdmin(): if not self.isAdmin():
clientToken = context.getVar('clientToken') clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken) clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId) clientRole = commonTools.extractRole(clientId)
if clientRole != 'people': if clientRole != 'identities':
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
if not isinstance(object, GroupUnion): if not isinstance(object, GroupUnion):
@ -155,8 +155,8 @@ class GroupsServer(commonGroups.GroupsCommonMixin, objects.ObjectsServer):
if not self.isAdmin(): if not self.isAdmin():
clientToken = context.getVar('clientToken') clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken) clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId) clientRole = commonTools.extractRole(clientId)
if clientRole != 'people': if clientRole != 'identities':
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
if not isinstance(object, GroupUnion): if not isinstance(object, GroupUnion):

View File

@ -0,0 +1,411 @@
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Identities Server"""
__version__ = '$Revision$'[11:-2]
import md5
import sys
import time
import whrandom
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
import glasnost
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.IdentitiesCommon as commonIdentities
import glasnost.common.tools_new as commonTools
import glasnost.server.ObjectsServer as objects
import glasnost.server.things as things
from glasnost.proxy.CacheProxy import invalidateValue
from glasnost.proxy.DispatcherProxy import getApplicationId
from glasnost.proxy.GroupsProxy import setContains
from glasnost.proxy.tools import getProxy
applicationName = 'IdentitiesServer'
applicationRole = 'identities'
dispatcher = None
# Don't forget to also change the value in SessionsServer.py.
expirationTime = 120 * 60
# FIXME: those classes are necessary to upgrade data from
# PeopleServer.pickle & PreferencesServer.pickle; they should be removed as
# soon as it is no longer necessary to access these files.
class AdminPeople: pass
class PeopleVirtualServer: pass
class Person: pass
class PreferencesVirtualServer: pass
class AdminIdentities(objects.AdminServerMixin,
commonIdentities.AdminIdentities):
pass
objects.register(AdminIdentities)
class Identification(things.ThingMixin, commonIdentities.Identification):
pass
things.register(Identification)
class Identity(objects.ObjectServerMixin, commonIdentities.Identity):
def abstainForVote(self, electionId):
if self.voteTokens is not None and self.voteTokens.has_key(electionId):
del self.voteTokens[electionId]
if len(self.voteTokens) == 0:
del self.voteTokens
def exportToXmlRpc(self, requiredSlotNames = None, parentSlot = None):
identityExport = commonIdentities.Identity.exportToXmlRpc(
self, requiredSlotNames = requiredSlotNames,
parentSlot = parentSlot)
userId = self.getServer().getUserId()
if self.id != userId and identityExport.has_key('voteTokens'):
if not userId:
del identityExport['voteTokens']
else:
voteTokens = identityExport['voteTokens'].copy()
for electionId, voteToken in voteTokens.items():
electionsProxy = getProxy(electionId)
if not electionsProxy.hasObject(electionId):
del voteTokens[electionId]
else:
electionBallotKind = electionsProxy.getBallotKind(
electionId)
if electionBallotKind == 'secret' \
or electionBallotKind == 'voterChoice' \
and getProxyForServerRole(
'ballots').isVoteSecret(voteToken):
voteTokens[electionId] = 'secret'
if len(voteTokens) == 0:
del identityExport['voteTokens']
else:
identityExport['voteTokens'] = voteTokens
return identityExport
def vote(self, electionId, voteToken):
if self.voteTokens is None:
self.voteTokens = {}
self.voteTokens[electionId] = voteToken
objects.register(Identity)
class IdentitiesVirtualServer(objects.ObjectsVirtualServer):
idsByToken = None
tokenExpirationTimes = None
def convertIds(self, sourceDispatcherId, destinationDispatcherId):
objects.ObjectsVirtualServer.convertIds(
self, sourceDispatcherId, destinationDispatcherId)
for token, expiration in self.tokenExpirationTimes.items():
newToken = token.replace(sourceDispatcherId,
destinationDispatcherId)
if newToken != token:
del self.tokenExpirationTimes[token]
self.tokenExpirationTimes[newToken] = expiration
for token, id in self.idsByToken.items():
newToken = token.replace(sourceDispatcherId,
destinationDispatcherId)
if newToken != token:
del self.idsByToken[token]
token = newToken
self.idsByToken[token] = id
newId = id.replace(sourceDispatcherId, destinationDispatcherId)
if newId != id:
self.idsByToken[token] = newId
def getObjectToken(self, object):
self.removeExpiredTokens()
self.lock.acquire()
for token, id in self.idsByToken.items():
if id == object.id:
objectToken = token
self.tokenExpirationTimes[token] = time.time() + expirationTime
break
else:
server = context.getVar('server')
while 1:
randomSalt = str(server.randomGenerator.uniform(0.1, 1))[2:]
digest = md5.new(randomSalt)
localToken = digest.hexdigest()
objectToken = '%s/%s' % (self.virtualServerId, localToken)
if not self.idsByToken.has_key(objectToken):
break
self.idsByToken[objectToken] = object.id
self.tokenExpirationTimes[objectToken] = time.time() \
+ expirationTime
self.lock.release()
self.markCoreAsDirty()
return objectToken
def init(self):
objects.ObjectsVirtualServer.init(self)
self.idsByToken = {}
self.tokenExpirationTimes = {}
def removeExpiredTokens(self):
currentTime = time.time()
removed = 0
self.lock.acquire()
for token in self.tokenExpirationTimes.keys():
if currentTime > self.tokenExpirationTimes[token]:
removed = 1
del self.idsByToken[token]
del self.tokenExpirationTimes[token]
self.lock.release()
if removed:
self.markCoreAsDirty()
class IdentitiesServer(commonIdentities.IdentitiesCommonMixin,
objects.ObjectsServer):
VirtualServer = IdentitiesVirtualServer
def abstainForVote(self, electionId):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
voterId = self.getUserId()
object = virtualServer.loadObjectCore(voterId)
object.abstainForVote(electionId)
virtualServer.markObjectAsDirty(object)
invalidateValue(object.id)
def checkIdentityLocalNameIdentifier(
self, peerHostName, localNameIdentifier):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
for object in virtualServer.objects.values():
if object.identityIdentifications is not None:
for identityIdentification in object.identityIdentifications:
if identityIdentification.peerHostName == peerHostName \
and identityIdentification.localNameIdentifier \
== localNameIdentifier:
return virtualServer.getObjectToken(object)
raise faults.WrongNameIdentifier(localNameIdentifier)
def checkIdentityPeerNameIdentifier(
self, peerHostName, peerNameIdentifier):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
for object in virtualServer.objects.values():
if object.identityIdentifications is not None:
for identityIdentification in object.identityIdentifications:
if identityIdentification.peerHostName == peerHostName \
and identityIdentification.peerNameIdentifier \
== peerNameIdentifier:
return virtualServer.getObjectToken(object)
raise faults.WrongNameIdentifier(peerNameIdentifier)
def deleteUserToken(self):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
userToken = context.getVar('userToken')
if virtualServer.idsByToken.has_key(userToken):
del virtualServer.idsByToken[userToken]
del virtualServer.tokenExpirationTimes[userToken]
def fillEmptyVirtualServer(self, virtualServer):
objects.ObjectsServer.fillEmptyVirtualServer(self, virtualServer)
# Upgrade to version 0001_0028.
import cPickle
import os
peoplePickleFilePath = os.path.join(virtualServer.dataDirectoryPath,
'PeopleServer.pickle')
if os.access(peoplePickleFilePath, os.F_OK):
print 'Importing PeopleServer data for %s.' \
% virtualServer.virtualServerId
peopleRcFile = open(peoplePickleFilePath, 'rb')
peopleVersion = self.readFileVersion(peopleRcFile)
peopleVirtualServer = cPickle.load(peopleRcFile)
peopleRcFile.close()
preferencesPickleFilePath = os.path.join(
virtualServer.dataDirectoryPath,
'PreferencesServer.pickle')
hasPreferences = 0
if os.access(peoplePickleFilePath, os.F_OK):
hasPreferences = 1
print 'Importing PreferencesServer data for %s.' \
% virtualServer.virtualServerId
preferencesRcFile = open(preferencesPickleFilePath, 'rb')
preferencesVersion = self.readFileVersion(preferencesRcFile)
preferencesVirtualServer = cPickle.load(preferencesRcFile)
preferencesRcFile.close()
personIds = peopleVirtualServer.objects.keys()
personIds.sort() # PasswordAccountsServer uses the same order.
for personId in personIds:
person = peopleVirtualServer.objects[personId]
identity = Identity()
identity.personId = personId
if hasattr(person, 'voteTokens'):
identity.voteTokens = person.voteTokens
if hasPreferences \
and preferencesVirtualServer.objects.has_key(personId):
preference = preferencesVirtualServer.objects[personId]
if preference.has_key('objectsMemory'):
identity.objectsMemory = preference['objectsMemory']
if preference.has_key('spellcheckEntries'):
identity.objectsMemory = preference[
'spellcheckEntries']
identity.setAutomaticalSlots()
virtualServer.objects[identity.id] = identity
identity.saveNonCore()
identity.releaseNonCore()
virtualServer.markObjectAsDirty(identity)
virtualServer.markCoreAsDirty()
def getElectionVoteToken(self, electionId):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientRole = commonTools.extractRole(clientId)
if clientRole != 'ballots':
raise faults.UserAccessDenied()
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
voterId = self.getUserId()
object = virtualServer.loadObjectCore(voterId)
if object.voteTokens is None \
or not object.voteTokens.has_key(electionId):
raise faults.MissingItem(electionId)
return object.voteTokens[electionId]
def getUserId(self):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
userToken = context.getVar('userToken')
virtualServer.removeExpiredTokens()
if not virtualServer.idsByToken.has_key(userToken):
return ''
virtualServer.tokenExpirationTimes[userToken] = time.time() \
+ expirationTime
virtualServer.markCoreAsDirty()
return virtualServer.idsByToken[userToken]
def getUserToken(self, id):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientRole = commonTools.extractRole(clientId)
if not clientRole in ['passwordaccounts', 'x509accounts']:
raise faults.ApplicationAccessDenied(clientId)
object = virtualServer.loadObjectCore(id)
return virtualServer.getObjectToken(object)
def init(self):
self.randomGenerator = whrandom.whrandom()
objects.ObjectsServer.init(self)
def registerPublicMethods(self):
objects.ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('abstainForVote')
self.registerPublicMethod('checkIdentityLocalNameIdentifier')
self.registerPublicMethod('checkIdentityPeerNameIdentifier')
self.registerPublicMethod('deleteUserToken')
self.registerPublicMethod('getElectionVoteToken')
self.registerPublicMethod('getUserId')
self.registerPublicMethod('getUserToken')
self.registerPublicMethod('rememberId')
self.registerPublicMethod('setContainsUser')
self.registerPublicMethod('vote')
def rememberId(self, id):
virtualServerId = context.getVar('applicationId')
if virtualServerId == 'glasnost://system/identities':
return
virtualServer = self.getVirtualServer(virtualServerId)
userId = self.getUserId()
serverRole = commonTools.extractRole(id)
object = virtualServer.loadObjectCore(userId)
if object.objectsMemory is None:
object.objectsMemory = {}
objectsMemory = object.objectsMemory
if objectsMemory.has_key(serverRole):
serverMemory = objectsMemory[serverRole]
else:
serverMemory = None
if serverMemory is None:
serverMemory = objectsMemory[serverRole] = []
if id in serverMemory:
serverMemory.remove(id)
serverMemory.insert(0, id)
if len(serverMemory) > 10:
del serverMemory[10:]
virtualServer.markObjectAsDirty(object)
invalidateValue(object.id)
def setContainsUser(self, set):
return setContains(set, self.getUserId())
def vote(self, electionId, voteToken):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
voterId = self.getUserId()
object = virtualServer.loadObjectCore(voterId)
object.vote(electionId, voteToken)
virtualServer.markObjectAsDirty(object)
invalidateValue(object.id)
identitiesServer = IdentitiesServer()
if __name__ == "__main__":
identitiesServer.launch(applicationName, applicationRole)

View File

@ -0,0 +1,232 @@
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Password Accounts Server"""
__version__ = '$Revision$'[11:-2]
import copy
import sys
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
import glasnost
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.PasswordAccountsCommon as commonPasswordAccounts
from glasnost.common.tools import iso8859_15
import glasnost.common.tools_new as commonTools
import glasnost.server.ObjectsServer as objects
from glasnost.proxy.tools import getProxy
applicationName = 'PasswordAccountsServer'
applicationRole = 'passwordaccounts'
dispatcher = None
# FIXME: those classes are necessary to upgrade data from
# AuthenticationLoginPasswordServer.pickle; they should be removed as
# soon as it is no longer necessary to access this file.
class AccountLoginPassword: pass
class AdminAuthenticationLoginPassword: pass
class AuthenticationLoginPasswordVirtualServer: pass
class AdminPasswordAccounts(objects.AdminServerMixin,
commonPasswordAccounts.AdminPasswordAccounts):
def checkModifyIsPossible(self, changes, givenSlotNames = None):
# This change is irreversible.
if self.storePasswordsInClearText == 0 \
and changes.storePasswordsInClearText == 1:
raise faults.UnableToChangePasswordStorage()
objects.AdminServerMixin.checkModifyIsPossible(
self, changes, givenSlotNames = givenSlotNames)
objects.register(AdminPasswordAccounts)
class PasswordAccount(objects.ObjectServerMixin,
commonPasswordAccounts.PasswordAccount):
def checkModifyIsPossible(self, changes, givenSlotNames = None):
objects.ObjectServerMixin.checkModifyIsPossible(
self, changes, givenSlotNames = givenSlotNames)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getServer().getVirtualServer(virtualServerId)
if (not givenSlotNames or 'login' in givenSlotNames) \
and changes.login != self.login and changes.login is not None:
if virtualServer.objectsByLogin.has_key(changes.login) \
and changes.id != virtualServer.objectsByLogin[
changes.login].id:
raise faults.DuplicateLogin(changes.login)
def clear(self):
objectsByLogin = self.getServer().virtualServer.objectsByLogin
if objectsByLogin.has_key(self.login):
del objectsByLogin[self.login]
def modify(self, changes, givenSlotNames = None):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getServer().getVirtualServer(virtualServerId)
login = self.login
if not virtualServer.admin.userCanChoosePassword:
self.password_kind = copy.copy(self.password_kind)
self.password_kind.hasToModify = 0
objects.ObjectServerMixin.modify(
self, changes, givenSlotNames = givenSlotNames)
if not virtualServer.admin.userCanChoosePassword:
del self.password_kind
if self.login != login:
if login is not None:
del virtualServer.objectsByLogin[login]
if self.login is not None:
virtualServer.objectsByLogin[self.login] = self
objects.register(PasswordAccount)
class PasswordAccountsVirtualServer(objects.ObjectsVirtualServer):
objectsByLogin = None
def init(self):
objects.ObjectsVirtualServer.init(self)
self.objectsByLogin = {}
class PasswordAccountsServer(
commonPasswordAccounts.PasswordAccountsCommonMixin,
objects.ObjectsServer):
VirtualServer = PasswordAccountsVirtualServer
def addObjectXmlRpc(self, objectImport):
objectId = objects.ObjectsServer.addObjectXmlRpc(self, objectImport)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(objectId)
if virtualServer.objectsByLogin.has_key(object.login):
# Login already used.
del virtualServer.objects[objectId]
virtualServer.markObjectAsDeleted(objectId)
virtualServer.markCoreAsDirty()
raise faults.DuplicateLogin(object.login)
virtualServer.objectsByLogin[object.login] = object
virtualServer.markCoreAsDirty()
return objectId
def checkObjectAuthenticationXmlRpc(self, loginImport, passwordImport):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
login = iso8859_15(loginImport)
password = iso8859_15(passwordImport)
if not virtualServer.objectsByLogin.has_key(login):
raise faults.WrongLogin(login)
object = virtualServer.objectsByLogin[login]
if object.password and password != object.password:
raise faults.WrongPassword(password)
identitiesProxy = getProxy(object.identityId)
return identitiesProxy.getUserToken(object.identityId)
def fillEmptyVirtualServer(self, virtualServer):
objects.ObjectsServer.fillEmptyVirtualServer(self, virtualServer)
# Upgrade to version 0001_0028.
import cPickle
import os
authenticationPickleFilePath = os.path.join(
virtualServer.dataDirectoryPath,
'AuthenticationLoginPasswordServer.pickle')
if os.access(authenticationPickleFilePath, os.F_OK):
print 'Importing AuthenticationLoginPasswordServer data for %s.' \
% virtualServer.virtualServerId
authenticationRcFile = open(authenticationPickleFilePath, 'rb')
authenticationVersion = self.readFileVersion(authenticationRcFile)
authenticationVirtualServer = cPickle.load(authenticationRcFile)
authenticationRcFile.close()
admin = virtualServer.admin
authenticationAdmin = authenticationVirtualServer.admin
if hasattr(authenticationAdmin, 'stockPasswordsInClearText'):
admin.storePasswordsInClearText \
= authenticationAdmin.stockPasswordsInClearText
if hasattr(authenticationAdmin, 'userCanChoosePassword'):
admin.userCanChoosePassword \
= authenticationAdmin.userCanChoosePassword
virtualServer.markAdminAsDirty(virtualServer.admin)
personIds = authenticationVirtualServer.authentications.keys()
personIds.sort() # IdentitiesServer uses the same order.
for personId in personIds:
authentication = authenticationVirtualServer.authentications[
personId]
passwordAccount = PasswordAccount()
passwordAccount.login = authentication.login
passwordAccount.password = authentication.password
passwordAccount.setAutomaticalSlots()
passwordAccount.identityId = '%s/%s' % (
commonTools.makeApplicationId(passwordAccount.id,
'identities'),
commonTools.extractLocalId(passwordAccount.id))
virtualServer.objects[passwordAccount.id] = passwordAccount
virtualServer.objectsByLogin[
passwordAccount.login] = passwordAccount
passwordAccount.saveNonCore()
passwordAccount.releaseNonCore()
virtualServer.markObjectAsDirty(passwordAccount)
virtualServer.markCoreAsDirty()
def registerPublicMethods(self):
objects.ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('checkObjectAuthentication',
self.checkObjectAuthenticationXmlRpc)
passwordAccountsServer = PasswordAccountsServer()
if __name__ == "__main__":
passwordAccountsServer.launch(applicationName, applicationRole)

View File

@ -85,22 +85,6 @@ register(AdminPeople)
class Person(ObjectServerMixin, PersonCommon): class Person(ObjectServerMixin, PersonCommon):
def abstainForVote(self, electionId):
"""Drop the person election token.
Keyword arguments:
==================
*electionId*:
The Id of the election to abstain.
"""
if self.voteTokens is not None and self.voteTokens.has_key(electionId):
del self.voteTokens[electionId]
if len(self.voteTokens) == 0:
del self.voteTokens
def checkAddIsPossible(self): def checkAddIsPossible(self):
ObjectServerMixin.checkAddIsPossible(self) ObjectServerMixin.checkAddIsPossible(self)
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
@ -146,49 +130,6 @@ class Person(ObjectServerMixin, PersonCommon):
if person.fingerprint == changes.fingerprint \ if person.fingerprint == changes.fingerprint \
and person.id != changes.id: and person.id != changes.id:
raise faults.DuplicateFingerprint(changes.fingerprint) raise faults.DuplicateFingerprint(changes.fingerprint)
def exportToXmlRpc(self, requiredSlotNames = None, parentSlot = None):
personExport = PersonCommon.exportToXmlRpc(
self, requiredSlotNames = requiredSlotNames,
parentSlot = parentSlot)
userId = getProxyForServerRole('authentication').getUserId()
if self.id != userId and not self.getServer().isAdmin():
#if personExport.has_key('email') and not userId:
# del personExport['email']
if personExport.has_key('voteTokens'):
if not userId:
del personExport['voteTokens']
else:
voteTokens = personExport['voteTokens'].copy()
for electionId, voteToken in voteTokens.items():
if not getProxyForServerRole('elections').hasObject(
electionId):
del voteTokens[electionId]
else:
electionBallotKind = getProxyForServerRole(
'elections').getBallotKind(electionId)
if electionBallotKind == 'secret' \
or electionBallotKind == 'voterChoice' \
and getProxyForServerRole(
'ballots').isVoteSecret(voteToken):
voteTokens[electionId] = 'secret'
if len(voteTokens) == 0:
del personExport['voteTokens']
else:
personExport['voteTokens'] = voteTokens
return personExport
def modify(self, changes, givenSlotNames = None):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getServer().getVirtualServer(virtualServerId)
ObjectServerMixin.modify(
self, changes, givenSlotNames = givenSlotNames)
def vote(self, electionId, voteToken):
if self.voteTokens is None:
self.voteTokens = {}
self.voteTokens[electionId] = voteToken
register(Person) register(Person)
@ -234,36 +175,6 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
VirtualServer = PeopleVirtualServer VirtualServer = PeopleVirtualServer
def abstainForVote(self, electionId):
"""Abstain voting on an election.
Keyword argument:
=================
*electionId*:
The Id of the election to abstain.
Return 0 everytime.
Exceptions:
===========
*faults.MissingItem*:
The specified election does not exist on the specified server.
*AttributeError*:
No authentication proxy found.
"""
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
voterId = getProxyForServerRole('authentication').getUserId()
object = virtualServer.loadObjectCore(voterId)
object.abstainForVote(electionId)
virtualServer.markObjectAsDirty(object)
invalidateValue(object.id)
def addObjectXmlRpc(self, objectImport): def addObjectXmlRpc(self, objectImport):
"""Create a new person on the server. """Create a new person on the server.
@ -334,7 +245,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
return 0 return 0
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
return self.isAdmin() \ return self.isAdmin() \
or getProxyForServerRole('authentication').setContainsUser( or getProxyForServerRole('identities').setContainsUser(
[object.id]) [object.id])
def canGetObject(self, objectId): def canGetObject(self, objectId):
@ -344,7 +255,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
if not virtualServer.canLoadObjectCore(objectId): if not virtualServer.canLoadObjectCore(objectId):
return 0 return 0
return getProxyForServerRole('authentication').setContainsUser( return getProxyForServerRole('identities').setContainsUser(
[objectId]) [objectId])
@ -355,7 +266,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
return 0 return 0
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
return self.isAdmin() \ return self.isAdmin() \
or getProxyForServerRole('authentication').setContainsUser( or getProxyForServerRole('identities').setContainsUser(
[object.id]) [object.id])
def deleteObject(self, objectId): def deleteObject(self, objectId):
@ -409,21 +320,6 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
if object.containsText(text): if object.containsText(text):
foundIds.append(objectId) foundIds.append(objectId)
return foundIds return foundIds
def getElectionVoteToken(self, electionId):
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientRole = commonTools.extractRole(clientId)
if clientRole != 'ballots':
raise faults.UserAccessDenied()
voterId = getProxyForServerRole('authentication').getUserId()
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(voterId)
if object.voteTokens is None \
or not object.voteTokens.has_key(electionId):
raise faults.MissingItem(electionId)
return object.voteTokens[electionId]
def getObjectStringFromDigestXmlRpc(self, objectId, path, digest): def getObjectStringFromDigestXmlRpc(self, objectId, path, digest):
"""Retrieve a string in the specified object from its MD5 digest. """Retrieve a string in the specified object from its MD5 digest.
@ -474,7 +370,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
result = getStringFromDigest(object.getLabel(), digest) result = getStringFromDigest(object.getLabel(), digest)
else: else:
if not self.isAdmin() and not getProxyForServerRole( if not self.isAdmin() and not getProxyForServerRole(
'authentication').setContainsUser([objectId]): 'identities').setContainsUser([objectId]):
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
result = getStringFromDigest( result = getStringFromDigest(
eval(path, {'self': object}), digest) eval(path, {'self': object}), digest)
@ -530,7 +426,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
if not object.canBeModified(): if not object.canBeModified():
raise faults.ReadOnlyObject() raise faults.ReadOnlyObject()
if not self.isAdmin() and not getProxyForServerRole( if not self.isAdmin() and not getProxyForServerRole(
'authentication').setContainsUser([object.id]): 'identities').setContainsUser([object.id]):
if not object.canBeModifiedByClient(): if not object.canBeModifiedByClient():
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
object.checkModifyIsPossible(objectChanges) object.checkModifyIsPossible(objectChanges)
@ -554,10 +450,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
"""Register the people server XML RPs.""" """Register the people server XML RPs."""
ObjectsServer.registerPublicMethods(self) ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('abstainForVote')
self.registerPublicMethod('findObjectIds', self.findObjectIdsXmlRpc) self.registerPublicMethod('findObjectIds', self.findObjectIdsXmlRpc)
self.registerPublicMethod('getElectionVoteToken')
self.registerPublicMethod('vote')
def repairVirtualServer(self, virtualServer, version): def repairVirtualServer(self, virtualServer, version):
"""Handle a descendant compatibily with older server datas. """Handle a descendant compatibily with older server datas.
@ -622,8 +515,8 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
if changed: if changed:
virtualServer.markAllAsDirtyFIXME() virtualServer.markAllAsDirtyFIXME()
def upgrade_0001_0019(self, virtualServer): def upgradeVirtualServer_0001_0019(self, virtualServer):
ObjectsServer.upgrade_0001_0019(self, virtualServer) ObjectsServer.upgradeVirtualServer_0001_0019(self, virtualServer)
# Fill empty writersSet slots in admin. # Fill empty writersSet slots in admin.
admin = virtualServer.admin admin = virtualServer.admin
@ -631,38 +524,6 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
admin.writersSet = [system.generalPublicId] admin.writersSet = [system.generalPublicId]
virtualServer.markAdminAsDirty(admin) virtualServer.markAdminAsDirty(admin)
def vote(self, electionId, voteToken):
"""Vote to an election.
Keyword arguments:
==================
*electionId*:
The ID of the election to vote.
*voteToken*:
The vote token associated to the vote.
Exceptions:
===========
*faults.MissingItem*:
The specified election was not found.
*KeyError*:
The virtual server ID does not correspond to a instanciated virtual
server.
"""
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
voterId = getProxyForServerRole('authentication').getUserId()
object = virtualServer.loadObjectCore(voterId)
object.vote(electionId, voteToken)
virtualServer.markObjectAsDirty(object)
invalidateValue(object.id)
peopleServer = PeopleServer() peopleServer = PeopleServer()

View File

@ -104,7 +104,7 @@ class PreferencesServer(Server):
def deleteObject(self): def deleteObject(self):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
virtualServer.lock.acquire() virtualServer.lock.acquire()
if virtualServer.objects.has_key(userId): if virtualServer.objects.has_key(userId):
del virtualServer.objects[userId] del virtualServer.objects[userId]
@ -113,7 +113,7 @@ class PreferencesServer(Server):
#invalidateValue(no id!) #invalidateValue(no id!)
def getObject(self): def getObject(self):
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
return self.getObjectByUserId(userId) return self.getObjectByUserId(userId)
def getObjectByUserId(self, userId): def getObjectByUserId(self, userId):
@ -136,47 +136,9 @@ class PreferencesServer(Server):
self.registerPublicMethod('deleteObject') self.registerPublicMethod('deleteObject')
self.registerPublicMethod('getObject') self.registerPublicMethod('getObject')
self.registerPublicMethod('getObjectByUserId') self.registerPublicMethod('getObjectByUserId')
self.registerPublicMethod('rememberId')
self.registerPublicMethod('setObject') self.registerPublicMethod('setObject')
self.registerPublicMethod('setObjectForUserId') self.registerPublicMethod('setObjectForUserId')
def rememberId(self, id):
virtualServerId = context.getVar('applicationId')
if virtualServerId == 'glasnost://system/preferences':
return
virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId()
if virtualServer.objects.has_key(userId):
preference = virtualServer.objects[userId]
else:
preference = {
'__thingCategory__': 'object',
'__thingName__': 'preferences.Preference',
'version': 0,
}
serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(id)
if preference.has_key('objectsMemory'):
objectsMemory = preference['objectsMemory']
else:
objectsMemory = None
if objectsMemory is None:
objectsMemory = preference['objectsMemory'] = {}
if objectsMemory.has_key(serverRole):
serverMemory = objectsMemory[serverRole]
else:
serverMemory = None
if serverMemory is None:
serverMemory = objectsMemory[serverRole] = []
if id in serverMemory:
serverMemory.remove(id)
serverMemory.insert(0, id)
if len(serverMemory) > 10:
serverMemory[10:] = []
virtualServer.objects[userId] = preference
virtualServer.markCoreAsDirty()
#invalidateValue(no id!)
def repairVirtualServer(self, virtualServer, version): def repairVirtualServer(self, virtualServer, version):
changed = 0 changed = 0
if version < 2006: if version < 2006:
@ -229,7 +191,7 @@ class PreferencesServer(Server):
def setObject(self, objectChanges): def setObject(self, objectChanges):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
version = 0 version = 0
object = None object = None
if virtualServer.objects.has_key(userId): if virtualServer.objects.has_key(userId):
@ -253,8 +215,8 @@ class PreferencesServer(Server):
def setObjectForUserId(self, userId, objectChanges): def setObjectForUserId(self, userId, objectChanges):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
userTokenId = getProxyForServerRole('authentication').getUserId() userTokenId = identitiesProxy.getUserId()
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
version = 0 version = 0
object = None object = None
@ -263,7 +225,7 @@ class PreferencesServer(Server):
if object.has_key('version'): if object.has_key('version'):
version = object['version'] version = object['version']
isAdmin = peopleProxy.isAdmin(serverId = virtualServerId) isAdmin = identitiesProxy.isAdmin(serverId = virtualServerId)
if not (isAdmin or userTokenId == userId): if not (isAdmin or userTokenId == userId):
raise faults.UserAccessDenied() raise faults.UserAccessDenied()

View File

@ -0,0 +1,116 @@
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Providers Server"""
__version__ = '$Revision$'[11:-2]
import sys
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
import glasnost
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.ProvidersCommon as commonProviders
import glasnost.server.ObjectsServer as objects
applicationName = 'ProvidersServer'
applicationRole = 'providers'
dispatcher = None
class AdminProviders(objects.AdminServerMixin, commonProviders.AdminProviders):
pass
objects.register(AdminProviders)
class IdentityProvider(objects.ObjectServerMixin,
commonProviders.IdentityProvider):
pass
objects.register(IdentityProvider)
class ServiceProvider(objects.ObjectServerMixin,
commonProviders.ServiceProvider):
pass
objects.register(ServiceProvider)
class ProvidersServer(commonProviders.ProvidersCommonMixin,
objects.ObjectsServer):
def getRemoteIdentityProviderId(self):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
admin = virtualServer.admin
if admin.remoteIdentityProviderId is None:
raise faults.MissingItem('Remote Identity Provider')
return admin.remoteIdentityProviderId
def getServiceProviderId(self, providerId):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
for objectId, objectCore in virtualServer.objects.items():
if isinstance(objectCore, ServiceProvider) \
and objectCore.providerId == providerId \
and (self.canGetObject(objectId)
or objectCore.canBeGottenByClient()):
return objectId
raise faults.MissingItem('Service Provider "%s"' % providerId)
def registerPublicMethods(self):
objects.ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('getRemoteIdentityProviderId')
self.registerPublicMethod('getServiceProviderId')
providersServer = ProvidersServer()
if __name__ == "__main__":
providersServer.launch(applicationName, applicationRole)

View File

@ -66,8 +66,8 @@ applicationName = 'SessionsServer'
applicationRole = 'sessions' applicationRole = 'sessions'
dispatcher = None dispatcher = None
# Don't forget to also change the value in AuthenticationServer.py. # Don't forget to also change the value in IdentitiesServer.py.
expirationTime = 120 expirationTime = 120 * 60
class SessionsVirtualServer(VirtualServer): class SessionsVirtualServer(VirtualServer):
@ -150,8 +150,8 @@ class SessionsServer(Server):
def getHistory(self): def getHistory(self):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
peopleProxy = getProxyForServerRole('people') identitiesProxy = getProxyForServerRole('identities')
if not peopleProxy.isAdmin( if not identitiesProxy.isAdmin(
serverId = commonTools.extractServerId(virtualServerId)): serverId = commonTools.extractServerId(virtualServerId)):
raise faults.UserAccessDenied() raise faults.UserAccessDenied()

View File

@ -315,7 +315,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
else: else:
translatorsSet = None translatorsSet = None
result = self.isAdmin() \ result = self.isAdmin() \
or getProxyForServerRole('authentication').setContainsUser( or getProxyForServerRole('identities').setContainsUser(
translatorsSet) translatorsSet)
return result return result
@ -325,9 +325,9 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
if not virtualServer.admin.translatorsSets.has_key(localizationKey): if not virtualServer.admin.translatorsSets.has_key(localizationKey):
return 0 return 0
translatorsSet = virtualServer.admin.translatorsSets[localizationKey] translatorsSet = virtualServer.admin.translatorsSets[localizationKey]
authenticationProxy = getProxyForServerRole('authentication') identitiesProxy = getProxyForServerRole('identities')
return self.isAdmin() or \ return self.isAdmin() or \
authenticationProxy.setContainsUser(translatorsSet) identitiesProxy.setContainsUser(translatorsSet)
def getLanguagesForObjectId(self, objectId): def getLanguagesForObjectId(self, objectId):
#languages = self.getPossibleLanguages() #languages = self.getPossibleLanguages()
@ -365,7 +365,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
else: else:
translatorsSet = None translatorsSet = None
if not self.isAdmin() \ if not self.isAdmin() \
and not getProxyForServerRole('authentication' and not getProxyForServerRole('identities'
).setContainsUser(translatorsSet): ).setContainsUser(translatorsSet):
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
digestsAndLabels = [] digestsAndLabels = []
@ -398,7 +398,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
else: else:
translatorsSet = None translatorsSet = None
if not self.isAdmin() \ if not self.isAdmin() \
and not getProxyForServerRole('authentication' and not getProxyForServerRole('identities'
).setContainsUser(translatorsSet): ).setContainsUser(translatorsSet):
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
destinationLanguage = localizationKey[2:] destinationLanguage = localizationKey[2:]
@ -721,7 +721,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
localizationKeys = [] localizationKeys = []
for localizationKey, translatorsSet in \ for localizationKey, translatorsSet in \
virtualServer.admin.translatorsSets.items(): virtualServer.admin.translatorsSets.items():
if getProxyForServerRole('authentication').setContainsUser( if getProxyForServerRole('identities').setContainsUser(
translatorsSet): translatorsSet):
localizationKeys.append(localizationKey) localizationKeys.append(localizationKey)
return localizationKeys return localizationKeys
@ -759,7 +759,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
else: else:
translatorsSet = None translatorsSet = None
if not self.isAdmin() \ if not self.isAdmin() \
and not getProxyForServerRole('authentication' and not getProxyForServerRole('identities'
).setContainsUser(translatorsSet): ).setContainsUser(translatorsSet):
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
assert translation.sourceLanguage == localization.sourceLanguage assert translation.sourceLanguage == localization.sourceLanguage
@ -772,7 +772,7 @@ class TranslationsServer(TranslationsCommonMixin, AdministrableServerMixin,
translation.setDestinationString( translation.setDestinationString(
localization.destinationLanguage, localization.isTranslatable, localization.destinationLanguage, localization.isTranslatable,
localization.destinationString, localization.isFuzzy) localization.destinationString, localization.isFuzzy)
userId = getProxyForServerRole('authentication').getUserId() userId = getProxyForServerRole('identities').getUserId()
translation.addTranslator(localization.destinationLanguage, userId) translation.addTranslator(localization.destinationLanguage, userId)
if not translation.destinationStrings and not translation.sources: if not translation.destinationStrings and not translation.sources:
del virtualServer.translations[sign] del virtualServer.translations[sign]

View File

@ -236,9 +236,9 @@ class UploadFilesServer(UploadFilesCommonMixin, ObjectsServer):
if mimeType[0] is not None: if mimeType[0] is not None:
object.dataType = mimeType[0] object.dataType = mimeType[0]
if not self.isAdmin() and not ( if not self.isAdmin() and not (
getProxyForServerRole('authentication').setContainsUser( getProxyForServerRole('identities').setContainsUser(
self.getAdminCore().writersSet) self.getAdminCore().writersSet)
and getProxyForServerRole('authentication').setContainsUser( and getProxyForServerRole('identities').setContainsUser(
object.writersSet)): object.writersSet)):
if not object.canBeCreatedByClient(): if not object.canBeCreatedByClient():
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
@ -401,7 +401,7 @@ class UploadFilesServer(UploadFilesCommonMixin, ObjectsServer):
if not self.canModifyObject(object.id) or not ( if not self.canModifyObject(object.id) or not (
self.isAdmin() self.isAdmin()
or not objectChanges.hasSlotName('writersSet') or not objectChanges.hasSlotName('writersSet')
or getProxyForServerRole('authentication' or getProxyForServerRole('identities'
).setContainsUser( ).setContainsUser(
objectChanges.getSlot('writersSet').getValue())): objectChanges.getSlot('writersSet').getValue())):
if not object.canBeModifiedByClient(): if not object.canBeModifiedByClient():

View File

@ -526,7 +526,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
except IOError: except IOError:
pass pass
def upgrade_0001_0025(self, virtualServer): def upgradeVirtualServer_0001_0025(self, virtualServer):
# Repair dissociated objects and objectsByHostName # Repair dissociated objects and objectsByHostName
virtualServer.objectsByHostName = {} virtualServer.objectsByHostName = {}
for object in virtualServer.objects.values(): for object in virtualServer.objects.values():
@ -534,7 +534,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.objectsByHostName[object.hostName] = object virtualServer.objectsByHostName[object.hostName] = object
virtualServer.markCoreAsDirty() virtualServer.markCoreAsDirty()
def upgrade_0001_0027(self, virtualServer): def upgradeVirtualServer_0001_0027(self, virtualServer):
for object in virtualServer.objects.values(): for object in virtualServer.objects.values():
object.profiles = ['basic', 'cms', 'vote', 'translations'] object.profiles = ['basic', 'cms', 'vote', 'translations']
virtualServer.markCoreAsDirty() virtualServer.markCoreAsDirty()

View File

@ -0,0 +1,161 @@
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@entrouvert.com>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost X509account Accounts Server"""
__version__ = '$Revision$'[11:-2]
import copy
import sys
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
import glasnost
import glasnost.common.context as context
import glasnost.common.faults as faults
from glasnost.common.tools import iso8859_15
import glasnost.common.tools_new as commonTool
import glasnost.common.X509AccountsCommon as commonX509Accounts
import glasnost.server.ObjectsServer as objects
from glasnost.proxy.tools import getProxy
applicationName = 'X509AccountsServer'
applicationRole = 'x509accounts'
dispatcher = None
class AdminX509Accounts(objects.AdminServerMixin,
commonX509Accounts.AdminX509Accounts):
pass
objects.register(AdminX509Accounts)
class X509Account(objects.ObjectServerMixin,
commonX509Accounts.X509Account):
def checkModifyIsPossible(self, changes, givenSlotNames = None):
objects.ObjectServerMixin.checkModifyIsPossible(
self, changes, givenSlotNames = givenSlotNames)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getServer().getVirtualServer(virtualServerId)
if (not givenSlotNames or 'serial' in givenSlotNames) \
and changes.serial != self.serial \
and changes.serial is not None:
if virtualServer.objectsBySerial.has_key(changes.serial) \
and changes.id != virtualServer.objectsBySerial[
changes.serial].id:
raise faults.DuplicateSerial(changes.serial)
def clear(self):
objectsBySerial = self.getServer().virtualServer.objectsBySerial
if objectsBySerial.has_key(self.serial):
del objectsBySerial[self.serial]
def modify(self, changes, givenSlotNames = None):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getServer().getVirtualServer(virtualServerId)
serial = self.serial
objects.ObjectServerMixin.modify(
self, changes, givenSlotNames = givenSlotNames)
if self.serial != serial:
if serial is not None:
del virtualServer.objectsBySerial[serial]
if self.serial is not None:
virtualServer.objectsBySerial[self.serial] = self
objects.register(X509Account)
class X509AccountsVirtualServer(objects.ObjectsVirtualServer):
objectsBySerial = None
def init(self):
objects.ObjectsVirtualServer.init(self)
self.objectsBySerial = {}
class X509AccountsServer(
commonX509Accounts.X509AccountsCommonMixin,
objects.ObjectsServer):
VirtualServer = X509AccountsVirtualServer
def addObjectXmlRpc(self, objectImport):
objectId = objects.ObjectsServer.addObjectXmlRpc(self, objectImport)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(objectId)
if virtualServer.objectsBySerial.has_key(object.serial):
# Serial already used.
del virtualServer.objects[objectId]
virtualServer.markObjectAsDeleted(objectId)
virtualServer.markCoreAsDirty()
raise faults.DuplicateSerial(object.serial)
virtualServer.objectsBySerial[object.serial] = object
virtualServer.markCoreAsDirty()
return objectId
def checkObjectAuthenticationXmlRpc(self, serial):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
if not virtualServer.objectsBySerial.has_key(serial):
raise faults.WrongX509Serial(serial)
object = virtualServer.objectsBySerial[serial]
identitiesProxy = getProxy(object.identityId)
return identitiesProxy.getUserToken(object.identityId)
def registerPublicMethods(self):
objects.ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('checkObjectAuthentication',
self.checkObjectAuthenticationXmlRpc)
x509AccountsServer = X509AccountsServer()
if __name__ == "__main__":
x509AccountsServer.launch(applicationName, applicationRole)

View File

@ -95,7 +95,7 @@ class ArticleCommon(ObjectCommon):
lastEditorId = None lastEditorId = None
lastEditorId_kind_importExport = 'from-server-only' lastEditorId_kind_importExport = 'from-server-only'
lastEditorId_kind_serverRoles = ['people'] lastEditorId_kind_serverRoles = ['identities']
lastEditorId_kindName = 'Id' lastEditorId_kindName = 'Id'
modificationTime = None modificationTime = None

View File

@ -183,7 +183,7 @@ class CardCommon(ObjectCommon):
try: try:
proxyGroups.getSetContainedIds( proxyGroups.getSetContainedIds(
self.getSlot('readersSet').getValue(), self.getSlot('readersSet').getValue(),
serverRoles = ['people'], serverRoles = ['identities'],
raiseWhenUncountable = 1) raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
# Even non identified users can read the object. We can cache # Even non identified users can read the object. We can cache
@ -364,6 +364,11 @@ class CardCommon(ObjectCommon):
return property.kind return property.kind
return None return None
def getEmail(self):
if not self.hasSlotName('email'):
return None
return self.getSlot('email')
# This method has ben commented, because it doesn't work when a property name # This method has ben commented, because it doesn't work when a property name
# has changed: self.values may contain an item whose name doesn't correspond to # has changed: self.values may contain an item whose name doesn't correspond to
# a property anymore. # a property anymore.
@ -374,6 +379,11 @@ class CardCommon(ObjectCommon):
## return slotNames ## return slotNames
## return slotNames + self.values.keys() ## return slotNames + self.values.keys()
def getFingerprint(self):
if not self.hasSlotName('fingerprint'):
return None
return self.getSlot('fingerprint')
def getImportSlotNames(self, parentSlot = None): def getImportSlotNames(self, parentSlot = None):
names = ObjectCommon.getImportSlotNames(self, parentSlot = parentSlot) names = ObjectCommon.getImportSlotNames(self, parentSlot = parentSlot)
names = names[:] names = names[:]
@ -416,9 +426,15 @@ class CardCommon(ObjectCommon):
return 'Card number %s' % commonTools.extractLocalId(self.id) return 'Card number %s' % commonTools.extractLocalId(self.id)
def getLabelLanguage(self): def getLabelLanguage(self):
if hasattr(self, 'language') and self.language: language = self.getLanguage()
return self.language if language is None:
return '' language = ''
return language
def getLanguage(self):
if not self.hasSlotName('language'):
return None
return self.getSlot('language')
def getMode(self, modeName, parentSlot = None): def getMode(self, modeName, parentSlot = None):
if modeName == 'edit': if modeName == 'edit':
@ -561,6 +577,14 @@ class CardCommon(ObjectCommon):
return ObjectCommon.importFromXmlRpc( return ObjectCommon.importFromXmlRpc(
self, dataImport, parentSlot = parentSlot) self, dataImport, parentSlot = parentSlot)
def mustCryptEmails(self):
if not self.hasSlotName('cryptEmails'):
return 0
if self.getSlot('cryptEmails'):
return 1
else:
return 0
def setDirectPropertyValue(self, propertyName, value): def setDirectPropertyValue(self, propertyName, value):
if self.values is None: if self.values is None:
self.values = {} self.values = {}

View File

@ -205,7 +205,7 @@ class AbstractElectionCommon(ObjectCommon):
def getVoterIds(self, virtualServerId = None): def getVoterIds(self, virtualServerId = None):
from glasnost.proxy.GroupsProxy import getSetContainedIds from glasnost.proxy.GroupsProxy import getSetContainedIds
return getSetContainedIds(self.votersSet, ['people']) return getSetContainedIds(self.votersSet, ['identities'])
def newVote(self): def newVote(self):
from glasnost.proxy.VotesProxy import votesProxy from glasnost.proxy.VotesProxy import votesProxy

View File

@ -58,7 +58,7 @@ class GradeCommon(ObjectCommon):
marks_kindName = 'Marks' marks_kindName = 'Marks'
membersSet = None membersSet = None
membersSet_kind_itemKind_value_serverRoles = ['people'] membersSet_kind_itemKind_value_serverRoles = ['identities']
membersSet_kind_itemKind_valueName = 'Id' membersSet_kind_itemKind_valueName = 'Id'
membersSet_kind_minCount = 1 membersSet_kind_minCount = 1
membersSet_kindName = 'Sequence' membersSet_kindName = 'Sequence'

View File

@ -127,8 +127,7 @@ class GroupAbstract(objects.ObjectCommon):
if groupId == system.generalPublicId: if groupId == system.generalPublicId:
if results.has_key(groupId): if results.has_key(groupId):
return results[groupId] return results[groupId]
if not serverRoles or 'people' in serverRoles or \ if not serverRoles or 'identities' in serverRoles:
'ldappeople' in serverRoles:
smallAndLarge = 'uncountable', 'uncountable' smallAndLarge = 'uncountable', 'uncountable'
else: else:
smallAndLarge = [], [] smallAndLarge = [], []
@ -154,9 +153,8 @@ class GroupAbstract(objects.ObjectCommon):
if groupId == system.generalPublicId: if groupId == system.generalPublicId:
if results.has_key(groupId): if results.has_key(groupId):
return results[groupId] return results[groupId]
result = not objectId or \ result = not objectId \
commonTools.extractRole(objectId) in \ or commonTools.extractRole(objectId) == 'identities'
('people', 'ldappeople')
results[groupId] = result results[groupId] = result
return result return result
else: else:

View File

@ -0,0 +1,188 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Identities Common Models"""
__version__ = '$Revision$'[11:-2]
import faults
import ObjectsCommon as objects
import things
import tools_new as commonTools
class AdminIdentities(objects.AdminCommon):
serverRole = 'identities'
class Identification(things.BaseThing):
localNameIdentifier = None
class localNameIdentifier_kindClass:
_kindName = 'String' # FIXME: NameIdentifier or Token or...
# isRequired = 1 FIXME removed for CVQ demo only. Uncomment ASAP.
peerHostName = None
class peerHostName_kindClass:
_kindName = 'String' # FIXME.
# isRequired = 1 FIXME removed for CVQ demo only. Uncomment ASAP.
peerNameIdentifier = None
class peerNameIdentifier_kindClass:
_kindName = 'String' # FIXME: NameIdentifier or Token or...
# isRequired = 1 FIXME removed for CVQ demo only. Uncomment ASAP.
things.register(Identification)
class Identity(objects.ObjectCommon):
identityIdentifications = None
class identityIdentifications_kindClass:
_kindName = 'Sequence'
label = N_('Identity Providers Identifications')
class itemKind_valueClass:
_kindName = 'Thing'
valueThingCategory = 'other'
valueThingName = 'Identification'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
language_kindName = None
objectsMemory = None
class objectsMemory_kindClass:
_kindName = 'Memory'
importExport = 'from-server-only'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
personId = None
class personId_kindClass:
_kindName = 'Id'
# isRequired = 1 FIXME: uncomment later
label = N_('Person')
serverRoles = ['people']
serverRole = 'identities'
serviceIdentifications = None
class serviceIdentifications_kindClass:
_kindName = 'Sequence'
label = N_('Service Providers Identifications')
class itemKind_valueClass:
_kindName = 'Thing'
valueThingCategory = 'other'
valueThingName = 'Identification'
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
spellcheckEntries = 1
class spellcheckEntries_kindClass:
_kindName = 'Boolean'
balloonHelp = N_('Should Glasnost spellcheck your texts?')
isRequired = 1
label = N_('Spellcheck Entries')
voteTokens = None
class voteTokens_kindClass:
_kindName = 'Mapping'
importExport = 'from-server-only'
class keyKind_valueClass:
_kindName = 'Id'
serverRoles = ['elections']
stateInEditMode = 'hidden'
stateInViewMode = 'hidden'
class valueKind_valueClass:
_kindName = 'Token'
def getEmail(self):
person = self.getPerson()
if person is None:
return None
return person.getEmail()
def getFingerprint(self):
person = self.getPerson()
if person is None:
return None
return person.getFingerprint()
def getLabel(self):
person = self.getPerson()
if person is None:
return '#%s' % commonTools.extractLocalId(self.id)
return person.getLabel()
def getLanguage(self):
person = self.getPerson()
if person is None:
return None
return person.getLanguage()
def getPerson(self):
if self.personId is not None:
from glasnost.proxy.tools import getProxy
peopleWeb = getProxy(self.personId)
if peopleWeb is None:
return None
try:
return peopleWeb.getObject(self.personId)
except faults.MissingItem:
pass
return None
def mustCryptEmails(self):
person = self.getPerson()
if person is None:
return 0
return person.mustCryptEmails()
class IdentitiesCommonMixin(objects.ObjectsCommonMixin):
adminClassName = 'AdminIdentities'
newObjectNameCapitalized = N_('New Identity')
objectClassName = 'Identity'
objectName = N_('identity')
objectNameCapitalized = N_('Identity')
objectsName = N_('identities')
objectsNameCapitalized = N_('Identities')
serverRole = 'identities'

View File

@ -80,7 +80,7 @@ class ObjectCommon(things.BaseThing):
import glasnost.proxy.GroupsProxy as proxyGroups import glasnost.proxy.GroupsProxy as proxyGroups
try: try:
proxyGroups.getSetContainedIds( proxyGroups.getSetContainedIds(
self.readersSet, serverRoles = ['people'], self.readersSet, serverRoles = ['identities'],
raiseWhenUncountable = 1) raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
# Even non identified users can read the object. We can cache # Even non identified users can read the object. We can cache

View File

@ -0,0 +1,136 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Password Accounts Common Models"""
__version__ = '$Revision$'[11:-2]
import ObjectsCommon as objects
class AdminPasswordAccounts(objects.AdminCommon):
serverRole = 'passwordaccounts'
storePasswordsInClearText = 1
class storePasswordsInClearText_kindClass:
_kindName = 'Boolean'
isRequired = 1
label = N_('Password Type')
labels = {
'0': N_('Clear Text'),
'1': N_('Crypted'),
}
userCanChoosePassword = 0
class userCanChoosePassword_kindClass:
_kindName = 'Boolean'
balloonHelp = N_(
'Specifies whether users are allowed to choose '
'their passwords (instead of autogenerating one for them).')
isRequired = 1
label = N_('Password')
labels = {
'0': N_('Automatically Generated'),
'1': N_('User Choice'),
}
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = objects.AdminCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['userCanChoosePassword', 'storePasswordsInClearText']
return slotNames
class PasswordAccount(objects.ObjectCommon):
language_kindName = None
login = None
class login_kindClass:
_kindName = 'String'
balloonHelp = N_('Enter the username you use on this site.')
isRequired = 1
isTranslatable = 0
label = N_('Username')
textMaxLength = 40
widget_size = 15
password = None
class password_kindClass:
_kindName = 'Password'
balloonHelp = N_('Enter your secret password.')
isRequired = 1
label = N_('Password')
textMaxLength = 15
widget_size = 15
identityId = None
class identityId_kindClass:
_kindName = 'Id'
isRequired = 1
label = N_('Identity')
serverRoles = ['identities']
serverRole = 'passwordaccounts'
def getLabel(self):
label = self.login
if label is None:
return ''
return label
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = objects.ObjectCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['login', 'password', 'identityId']
return slotNames
class PasswordAccountsCommonMixin(objects.ObjectsCommonMixin):
adminClassName = 'AdminPasswordAccounts'
newObjectNameCapitalized = N_('New Password Account')
objectClassName = 'PasswordAccount'
objectName = N_('password account')
objectNameCapitalized = N_('Password Account')
objectsName = N_('password accounts')
objectsNameCapitalized = N_('Password Accounts')
serverRole = 'passwordaccounts'

View File

@ -74,6 +74,17 @@ class PersonCommon(ObjectCommon):
creationTime = None creationTime = None
creationTime_kindName = 'CreationTime' creationTime_kindName = 'CreationTime'
cryptEmails = 0
class cryptEmails_kindClass:
_kindName = 'Boolean'
balloonHelp = N_('Should Glasnost encrypt your emails?')
isRequired = 1
label = N_('Crypt Emails')
labels = {
'0': N_('Never'),
'1': N_('When Possible'),
}
email = None email = None
email_kind_balloonHelp = N_('Enter the e-mail address.') email_kind_balloonHelp = N_('Enter the e-mail address.')
email_kind_isRequired = 1 email_kind_isRequired = 1
@ -92,8 +103,6 @@ class PersonCommon(ObjectCommon):
firstName_kind_isRequired = 1 firstName_kind_isRequired = 1
firstName_kindName = 'String' firstName_kindName = 'String'
language_kindName = None
lastName = None lastName = None
lastName_kind_balloonHelp = N_('Enter the last name.') lastName_kind_balloonHelp = N_('Enter the last name.')
lastName_kind_isTranslatable = 0 lastName_kind_isTranslatable = 0
@ -110,13 +119,6 @@ class PersonCommon(ObjectCommon):
serverRole = 'people' serverRole = 'people'
voteTokens = None
voteTokens_kind_importExport = 'from-server-only'
voteTokens_kind_keyKind_valueName = 'Id'
voteTokens_kind_keyKind_value_serverRoles = ['elections']
voteTokens_kind_valueKind_valueName = 'Token'
voteTokens_kindName = 'Mapping'
def canCache(self): def canCache(self):
return 0 return 0
@ -157,6 +159,12 @@ class PersonCommon(ObjectCommon):
return 1 return 1
return 0 return 0
def getEmail(self):
return self.email
def getFingerprint(self):
return self.fingerprint
def getFullName(self): def getFullName(self):
"""Return the full person name string. """Return the full person name string.
@ -180,14 +188,6 @@ class PersonCommon(ObjectCommon):
return self.email return self.email
return label return label
def getLabelLanguage(self):
"""Return an empty string."""
return ''
def getLanguage(self):
"""Return an empty string."""
return ''
def getOrderedLayoutSlotNames(self, parentSlot = None): def getOrderedLayoutSlotNames(self, parentSlot = None):
"""Return the layout slots names sequences. """Return the layout slots names sequences.
@ -227,6 +227,9 @@ class PersonCommon(ObjectCommon):
sortString += ' ' + self.firstName sortString += ' ' + self.firstName
return sortString return sortString
def mustCryptEmails(self):
return self.cryptEmails
class PeopleCommonMixin(ObjectsCommonMixin): class PeopleCommonMixin(ObjectsCommonMixin):

View File

@ -92,10 +92,6 @@ class PreferenceCommon(ObjectCommon):
'sv', 'sv',
] ]
objectsMemory = None
objectsMemory_kind_importExport = 'from-server-only'
objectsMemory_kindName = 'Memory'
serverRole = 'preferences' serverRole = 'preferences'
spellcheckEntries = 0 spellcheckEntries = 0
@ -107,7 +103,7 @@ class PreferenceCommon(ObjectCommon):
def getOrderedLayoutSlotNames(self, parentSlot = None): def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = ObjectCommon.getOrderedLayoutSlotNames( slotNames = ObjectCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot) self, parentSlot = parentSlot)
slotNames += ['currency', 'cryptEmails', 'spellcheckEntries', 'objectsMemory'] slotNames += ['currency', 'cryptEmails', 'spellcheckEntries']
return slotNames return slotNames

View File

@ -0,0 +1,180 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Providers Common Models"""
__version__ = '$Revision$'[11:-2]
import ObjectsCommon as objects
class AdminProviders(objects.AdminCommon):
remoteIdentityProviderId = None
class remoteIdentityProviderId_kindClass:
_kindName = 'Id'
label = N_('Remote Identity Provider')
serverRoles = ['providers']
# FIXME: To do: Restrict to identity providers ids. Don't accept
# service providers ids.
serverRole = 'providers'
class ProviderAbstract(objects.ObjectCommon):
# The URL to which the provider redirects at the end of user-agent-based
# Federation Termination Notification Protocol profiles.
federationTerminationServiceReturnUrl = None
class federationTerminationServiceReturnUrl_kindClass:
_kindName = 'String' # FIXME: url
# The URL Used for user-agent-based Federation Termination Notification
# Protocol profiles.
federationTerminationServiceUrl = None
class federationTerminationServiceUrl_kindClass:
_kindName = 'String' # FIXME: url
# The providerID of the entity.
# Example http://serviceprovider.com
providerId = None
class providerId_kindClass:
_kindName = 'String' # FIXME: uri
isRequired = 1
# The provider s redirecting URL for use after HTTP name registration has
# taken place.
registerNameIdentifierServiceReturnUrl = None
class registerNameIdentifierServiceReturnUrl_kindClass:
_kindName = 'String' # FIXME: uri
# The URL used for user-agent-based Register Name Identifier Protocol
# profiles.
registerNameIdentifierServiceUrl = None
class registerNameIdentifierServiceUrl_kindClass:
_kindName = 'String' # FIXME: uri
# The provider's preferred Register Name Identifier Protocol profile,
# which should be used by other providers when registering a new
# identifier. Each element MUST contain a valid Register Name Identifier
# Protocol profile identification URI. The absence of this element SHALL
# mean that the provider does not support any profile of the Register Name
#Identifier Protocol.
registerNameIdentifierProtocolProfiles = None
class registerNameIdentifierProtocolProfiles_kindClass:
_kindName = 'Sequence'
class itemKind_valueClass:
_kindName = 'String' # FIXME: uri
serverRole = 'providers'
# The Single Logout Protocol profiles supported by the provider. Each
# element MUST contain a valid Single Logout Protocol profile
# identification URI. The absence of this element SHALL mean that the
# provider does not support any profile of the Single Logout Protocol.
singleLogoutProtocolProfiles = None
class singleLogoutProtocolProfiles_kindClass:
_kindName = 'Sequence'
class itemKind_valueClass:
_kindName = 'String' # FIXME: uri
# The URL to which the provider redirects at the end of user-agent-based
# Single Logout Protocol profiles.
singleLogoutServiceReturnUrl = None
class singleLogoutServiceReturnUrl_kindClass:
_kindName = 'String' # FIXME: url
# The URL Used for user-agent-based Single Logout Protocol profiles.
singleLogoutServiceUrl = None
class singleLogoutServiceUrl_kindClass:
_kindName = 'String' # FIXME: url
# The provider SOAP endpoint URI.
soapEndpoint = None
class soapEndpoint_kindClass:
_kindName = 'String' # FIXME: uri
isRequired = 1
def getLabel(self):
label = self.providerId
if label is None:
return ''
return label
class IdentityProvider(ProviderAbstract):
# The Single Sign-On Protocol profiles supported by the provider. Each
# element MUST contain a valid Single Sign-On Protocol profile
# identification URI.
singleSignOnProtocolProfiles = None
class singleSignOnProtocolProfiles_kindClass:
_kindName = 'Sequence'
class itemKind_valueClass:
_kindName = 'String' # FIXME: uri
# The identity provider's URL for accepting authentication requests for the
# Single Sign-On and Federation Protocol.
singleSignOnServiceUrl = None
class singleSignOnServiceUrl_kindClass:
_kindName = 'String'
isRequired = 1
class ServiceProvider(ProviderAbstract):
# URI of the SP for receiving Authentication Assertions from an
# authenticating party.
# FIXME: Liberty Alliance allows several AssertionConsumerServiceURLs.
assertionConsumerServiceUrl = None
class assertionConsumerServiceUrl_kindClass:
_kindName = 'String'
isRequired = 1
class ProvidersCommonMixin(objects.ObjectsCommonMixin):
adminClassName = 'AdminProviders'
newObjectNameCapitalized = N_('New Provider')
objectClassName = 'IdentityProvider'
objectName = N_('provider')
objectNameCapitalized = N_('Provider')
objectsName = N_('providers')
objectsNameCapitalized = N_('Providers')
serverRole = 'providers'

View File

@ -201,7 +201,9 @@ class VirtualHostCommon(ObjectCommon):
widgetName = 'MultiCheck' widgetName = 'MultiCheck'
readersSet = None readersSet = None
# FIXME: Which of the following lines is correct?
readersSet_defaultValue = [system.generalPublicId] readersSet_defaultValue = [system.generalPublicId]
# readersSet_kind_itemKind_value_defaultValue = system.generalPublicId
readersSet_kindName = 'ReadersSet' readersSet_kindName = 'ReadersSet'
serverRole = 'virtualhosts' serverRole = 'virtualhosts'

View File

@ -77,7 +77,7 @@ class AbstractVoteCommon(ObjectCommon):
token_kindName = 'Token' token_kindName = 'Token'
voterId_kind_importExport = 'private' voterId_kind_importExport = 'private'
voterId_kind_serverRoles = ['people'] voterId_kind_serverRoles = ['identities']
voterId_kindName = 'Id' voterId_kindName = 'Id'
voterToken = None voterToken = None

View File

@ -0,0 +1,99 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@entrouvert.com>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost X509 Accounts Common Models"""
__version__ = '$Revision$'[11:-2]
import ObjectsCommon as objects
class AdminX509Accounts(objects.AdminCommon):
serverRole = 'x509accounts'
class X509Account(objects.ObjectCommon):
language_kindName = None
serial = None
class serial_kindClass:
_kindName = 'String'
balloonHelp = N_('Enter the serial you use on this site.')
isRequired = 1
isTranslatable = 0
label = N_('Serial')
textMaxLength = 40
widget_size = 15
identityId = None
class identityId_kindClass:
_kindName = 'Id'
isRequired = 1
label = N_('Identity')
serverRoles = ['identities']
serverRole = 'x509accounts'
def getLabel(self):
label = self.serial
if label is None:
return ''
return label
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = objects.ObjectCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['serial', 'identityId']
return slotNames
class X509AccountsCommonMixin(objects.ObjectsCommonMixin):
adminClassName = 'AdminX509Accounts'
newObjectNameCapitalized = N_('New X509v3 Account')
objectClassName = 'X509Account'
objectName = N_('X509v3 account')
objectNameCapitalized = N_('X509v3 Account')
objectsName = N_('X509v3 accounts')
objectsNameCapitalized = N_('X509v3 Accounts')
serverRole = 'x509accounts'

View File

@ -479,8 +479,16 @@ class httpUrl(urlCommon):
relativeUrl = urllib.quote(self.getPath(**keywords)) relativeUrl = urllib.quote(self.getPath(**keywords))
if self.parameters: if self.parameters:
relativeUrl = '%s;%s' % (relativeUrl, self.parameters) relativeUrl = '%s;%s' % (relativeUrl, self.parameters)
query = '&'.join([ '%s=%s' % (name, urllib.quote(str(value))) expandedArguments = []
for name, value in self.getArguments()]) for name, value in self.getArguments():
if type(value) in [types.ListType, types.TupleType]:
for item in value:
expandedArguments.append(
'%s=%s' % (name, urllib.quote(str(item))))
else:
expandedArguments.append(
'%s=%s' % (name, urllib.quote(str(value))))
query = '&'.join(expandedArguments)
if self.query and query: if self.query and query:
query = '%s&%s' % (self.query, query) query = '%s&%s' % (self.query, query)
elif self.query: elif self.query:

View File

@ -4,7 +4,7 @@
# Glasnost # Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com> # By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com> # Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org> # Nicolas Clapiès <nclapies@entrouvert.com>
# Pierre-Antoine Dejace <padejace@entrouvert.be> # Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com> # Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com> # Florent Monnier <monnier@codelutin.com>
@ -94,6 +94,10 @@ faultCodeValueTooBig = 41
faultCodeValueTooSmall = 42 faultCodeValueTooSmall = 42
faultCodeRoleNotInProfiles = 43 faultCodeRoleNotInProfiles = 43
faultCodeUnknownObjectVersion = 44 faultCodeUnknownObjectVersion = 44
faultCodeWrongArtifact = 45
faultCodeUnableToChangePasswordStorage = 46
faultCodeWrongNameIdentifier = 47
faultCodeWrongX509Serial = 48
faultCodeUnknownVoteToken = 1000 faultCodeUnknownVoteToken = 1000
faultCodeUnknownVoterToken = 1001 faultCodeUnknownVoterToken = 1001
@ -448,6 +452,35 @@ class UnknownCommandAction(BaseFault):
return 'Unknown command action: "%s"' % action return 'Unknown command action: "%s"' % action
class WrongArtifact(BaseFault):
faultCode = faultCodeWrongArtifact
def makeFaultString(self, artifact):
return 'Unknown artifact = %s' % artifact
class UnableToChangePasswordStorage(BaseFault):
faultCode = faultCodeUnableToChangePasswordStorage
def makeFaultString(self):
return 'Unable to change password storage'
class WrongNameIdentifier(BaseFault):
faultCode = faultCodeWrongNameIdentifier
def makeFaultString(self, nameIdentifier):
return 'Unknown name identifier = %s' % nameIdentifier
class WrongX509Serial(BaseFault):
faultCode = faultCodeWrongX509Serial
uiFaultString = N_('Wrong value!')
def makeFaultString(self, serial):
return 'Unknown serial = "%s"' % serial
# Vote # Vote

View File

@ -784,6 +784,24 @@ class BaseKind(things.BaseThing):
defaultValue = self.getDefaultValue(slot) defaultValue = self.getDefaultValue(slot)
if defaultValue is not None: if defaultValue is not None:
slot.setValue(defaultValue) slot.setValue(defaultValue)
def upgradeModel(self, slot, model, toVersion):
changed = 0
# Call upgradeModel_xxx methods.
classes = commonTools.getC3ClassLinearization(self.__class__)
upgradeMethodNames = []
for class_ in classes:
for attributeName in class_.__dict__.keys():
if attributeName.startswith('upgradeModel_'):
if not attributeName in upgradeMethodNames:
upgradeMethodNames.append(attributeName)
upgradeMethodNames.sort()
for upgradeMethodName in upgradeMethodNames:
if upgradeMethodName[len('upgradeModel_'):] <= toVersion:
continue
modelChanged, model = getattr(self, upgradeMethodName)(slot, model)
changed = changed or modelChanged
return changed, model
register(BaseKind) register(BaseKind)
@ -922,6 +940,19 @@ class AbstractSequence(BaseKind):
itemKind = itemSlot.getKind() itemKind = itemSlot.getKind()
itemKind.setToDefaultValue(slot) itemKind.setToDefaultValue(slot)
def upgradeModel(self, slot, model, toVersion):
changed, model = BaseKind.upgradeModel(self, slot, model, toVersion)
# Upgrade each item.
if model is not None:
for i, item in enumerate(model):
itemSlot = self.getItemSlot(slot, i)
itemChanged, item = itemSlot.getKind().upgradeModel(
itemSlot, item, toVersion)
if itemChanged:
changed = 1
model[i] = item
return changed, model
class Alias(BaseKind): class Alias(BaseKind):
defaultValue_kindName = 'Alias' defaultValue_kindName = 'Alias'
@ -1633,6 +1664,19 @@ class Id(BaseKind):
if toVersion == 4000: if toVersion == 4000:
return repairId(value) return repairId(value)
return None return None
def upgradeModel_0001_0028(self, slot, model):
"""Convert user ids from "people" to "identities"."""
changed = 0
if self.serverRoles is not None and 'identities' in serverRoles \
and not 'people' in serverRoles \
and commonTools.extractRole(model) == 'people':
changed = 1
model = '%s/%s' % (
commonTools.makeApplicationId(model, 'identities'),
commonTools.extractLocalId(model))
return changed, model
register(Id) register(Id)
@ -2136,6 +2180,28 @@ class Mapping(BaseKind):
if changed: if changed:
return value return value
return None return None
def upgradeModel(self, slot, model, toVersion):
changed, model = BaseKind.upgradeModel(self, slot, model, toVersion)
# Upgrade each key and value.
if model is not None:
# The .keys() below is required, even for Python >= 2.3, because
# the for loop modifies the dict, while iterating inside.
for keyIndex, key in enumerate(model.keys()):
keySlot = self.getItemKeySlot(slot, keyIndex)
keyChanged, upgradedKey = keySlot.getKind().upgradeModel(
keySlot, key, toVersion)
if keyChanged:
changed = 1
model[upgradedKey] = model.pop(key)
for key, value in model.items():
valueSlot = self.getItemValueSlot(slot, key)
valueChanged, value = valueSlot.getKind().upgradeModel(
valueSlot, value, toVersion)
if valueChanged:
changed = 1
model[key] = value
return changed, model
register(Mapping) register(Mapping)
@ -2722,7 +2788,7 @@ class UsersSet(Sequence):
itemKind_kind_stateInViewMode = 'hidden' itemKind_kind_stateInViewMode = 'hidden'
itemKind_value_permanentIds = [system.generalPublicId, itemKind_value_permanentIds = [system.generalPublicId,
system.loggedUsersGroupId] system.loggedUsersGroupId]
itemKind_value_serverRoles = ['groups', 'people', 'ldappeople'] itemKind_value_serverRoles = ['groups', 'identities']
itemKind_valueName = 'Id' itemKind_valueName = 'Id'
label = N_('Users') label = N_('Users')
@ -2734,14 +2800,18 @@ class UsersSet(Sequence):
thingPublicName = N_('Users') thingPublicName = N_('Users')
def getDefaultValue(self, slot): def getDefaultValue(self, slot):
return [context.getVar('userId')] userId = context.getVar('userId')
if userId:
return [userId]
else:
return None
register(UsersSet) register(UsersSet)
class AuthorsSet(UsersSet): class AuthorsSet(UsersSet):
balloonHelp = N_('Choose the author(s) for this object.') balloonHelp = N_('Choose the author(s) for this object.')
containerNames = ['Any', 'Sequence', 'UsersSet'] containerNames = ['Any', 'Sequence']
defaultValue_kindName = 'AuthorsSet' defaultValue_kindName = 'AuthorsSet'
@ -2750,10 +2820,18 @@ class AuthorsSet(UsersSet):
# FIXME: that's useless since the user may "visit" the group and it will # FIXME: that's useless since the user may "visit" the group and it will
# be shown nevertheless # be shown nevertheless
itemKind_value_permanentIds = None itemKind_value_permanentIds = None
itemKind_value_serverRoles = ['groups', 'people']
label = N_('Authors') label = N_('Authors')
thingPublicName = N_('Authors') thingPublicName = N_('Authors')
def getDefaultValue(self, slot):
user = context.getVar('user')
if user is not None and user.personId is not None:
return [user.personId]
else:
return None
register(AuthorsSet) register(AuthorsSet)
@ -2837,7 +2915,7 @@ register(Properties)
class ReadersSet(UsersSet): class ReadersSet(UsersSet):
balloonHelp = N_( balloonHelp = N_(
'Select the people and groups who are allowed to read the item.') 'Select the identities and groups who are allowed to read the item.')
containerNames = ['Any', 'Sequence', 'UsersSet'] containerNames = ['Any', 'Sequence', 'UsersSet']
@ -3326,7 +3404,12 @@ class Thing(Choice):
else: else:
BaseKind.setToDefaultValue(self, slot) BaseKind.setToDefaultValue(self, slot)
def upgradeModel(self, slot, model, toVersion):
changed, model = BaseKind.upgradeModel(self, slot, model, toVersion)
if model is not None:
if model.upgrade(toVersion, parentSlot = slot):
changed = 1
return changed, model
register(Thing) register(Thing)
@ -3531,7 +3614,7 @@ register(TranslatorsSets)
class WritersSet(UsersSet): class WritersSet(UsersSet):
balloonHelp = N_( balloonHelp = N_(
'Select the people and groups who are allowed to modify the item.') 'Select the identities and groups who are allowed to modify the item.')
containerNames = ['Any', 'Sequence', 'UsersSet'] containerNames = ['Any', 'Sequence', 'UsersSet']

View File

@ -181,7 +181,7 @@ class BaseSlot:
def getObject(self): def getObject(self):
if self.container is not None and \ if self.container is not None and \
self.container.thingCategory in ('object', 'authentication'): self.container.thingCategory == 'object':
return self.container return self.container
elif self.parent is not None: elif self.parent is not None:
return self.parent.getObject() return self.parent.getObject()
@ -190,7 +190,7 @@ class BaseSlot:
def getObjectSlot(self): def getObjectSlot(self):
if self.container is not None and \ if self.container is not None and \
self.container.thingCategory in ('object', 'authentication'): self.container.thingCategory == 'object':
return self.parent return self.parent
elif self.parent is not None: elif self.parent is not None:
return self.parent.getObjectSlot() return self.parent.getObjectSlot()

View File

@ -549,3 +549,35 @@ class BaseThing:
def saveNonCore(self, objectDirectoryPath, parentSlot = None): def saveNonCore(self, objectDirectoryPath, parentSlot = None):
pass pass
def upgrade(self, toVersion, parentSlot = None):
changed = 0
# Call object upgrade_xxx methods.
classes = commonTools.getC3ClassLinearization(self.__class__)
upgradeMethodNames = []
for class_ in classes:
for attributeName in class_.__dict__.keys():
if attributeName.startswith('upgrade_'):
if not attributeName in upgradeMethodNames:
upgradeMethodNames.append(attributeName)
upgradeMethodNames.sort()
for upgradeMethodName in upgradeMethodNames:
if upgradeMethodName[len('upgrade_'):] <= toVersion:
continue
changed = getattr(self, upgradeMethodName)(
parentSlot = parentSlot) or changed
# Upgrade each object slot.
slotNames = self.getSlotNames(parentSlot = parentSlot)
for slotName, value in self.__dict__.items():
if not slotName in slotNames:
continue
slot = self.getSlot(slotName, parentSlot = parentSlot)
valueChanged, value = slot.getKind().upgradeModel(
slot, value, toVersion)
if valueChanged:
changed = 1
slot.setValue(value)
return changed

View File

@ -67,7 +67,6 @@ except ImportError:
import faults import faults
import context import context
import tools_new as commonTools import tools_new as commonTools
is8bit = re.compile("[\x80-\xff]").search is8bit = re.compile("[\x80-\xff]").search
@ -273,9 +272,7 @@ def sendMail(mailFrom, mailTo, mailSubject, mailMessage, mailPerson = None,
The message string to send. The message string to send.
*mailPerson*: *mailPerson*:
If the Person object has GPG abilities, the Person object has to be The recipient's person or identity.
gived in order to test if the mail have to be crypted.
Default: None.
*moreHearders*: *moreHearders*:
If other hearders have to be included in the mail, this dictionnary If other hearders have to be included in the mail, this dictionnary
@ -306,16 +303,13 @@ def sendMail(mailFrom, mailTo, mailSubject, mailMessage, mailPerson = None,
mailMessage = "\n" + mailMessage mailMessage = "\n" + mailMessage
gpgEncrypted = 0 gpgEncrypted = 0
if mailPerson: if mailIdentity:
from glasnost.proxy.tools import getProxyForServerRole cryptEmails = mailPerson.mustCryptEmails()
preferencesProxy = getProxyForServerRole('preferences')
cryptEmails = preferencesProxy.getPreferenceByUserId(
mailPerson.id).cryptEmails
if cryptEmails: if cryptEmails:
try: try:
from gpg import Gpg from gpg import Gpg
gpg = Gpg(email = mailPerson.email, gpg = Gpg(email = mailPerson.getEmail(),
fingerprint = mailPerson.fingerprint) fingerprint = mailPerson.getFingerprint())
gpg.deleteKey() gpg.deleteKey()
gpg.addKey() gpg.addKey()
mailMessage = gpg.encrypt(mailMessage) mailMessage = gpg.encrypt(mailMessage)

View File

@ -302,9 +302,9 @@ class menuIds:
objectIds = acceptedObjectIds objectIds = acceptedObjectIds
self.menus[role] = getObjectLabelsTranslated( self.menus[role] = getObjectLabelsTranslated(
objectIds, context.getVar('readLanguages')) objectIds, context.getVar('readLanguages'))
preferences = context.getVar('preferences') user = context.getVar('user')
if preferences: if user:
objectsMemory = preferences.objectsMemory objectsMemory = user.objectsMemory
if objectsMemory is not None: if objectsMemory is not None:
for role in self.roles: for role in self.roles:
if not objectsMemory.has_key(role): if not objectsMemory.has_key(role):

View File

@ -0,0 +1,66 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Identities Gtk"""
__version__ = '$Revision$'[11:-2]
import glasnost.proxy.IdentitiesProxy as proxyIdentities
import ObjectsGtk as objects
import things
class Identification(things.ThingMixin, proxyIdentities.Identification):
pass
things.register(Identification)
class Identity(objects.ObjectGtkMixin, proxyIdentities.Identity):
pass
objects.register(Identity)
class IdentitiesGtk(objects.ObjectsGtkMixin, proxyIdentities.IdentitiesProxy):
pass

View File

@ -0,0 +1,62 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Password Accounts Gtk"""
__version__ = '$Revision$'[11:-2]
import glasnost.proxy.PasswordAccountsProxy as proxyPasswordAccounts
import ObjectsGtk as objects
class PasswordAccount(objects.ObjectGtkMixin,
proxyPasswordAccounts.PasswordAccount):
pass
objects.register(PasswordAccount)
class PasswordAccountsGtk(objects.ObjectsGtkMixin,
proxyPasswordAccounts.PasswordAccountsProxy):
pass

View File

@ -0,0 +1,67 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Providers Gtk"""
__version__ = '$Revision$'[11:-2]
import glasnost.proxy.ProvidersProxy as proxyProviders
import ObjectsGtk as objects
class IdentityProvider(objects.ObjectGtkMixin,
proxyProviders.IdentityProvider):
pass
objects.register(IdentityProvider)
class ServiceProvider(objects.ObjectGtkMixin,
proxyProviders.ServiceProvider):
pass
objects.register(ServiceProvider)
class ProvidersGtk(objects.ObjectsGtkMixin, proxyProviders.ProvidersProxy):
pass

View File

@ -0,0 +1,72 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Assertions Proxy"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
from DispatcherProxy import callServer, getApplicationToken
import ObjectsProxy as objects
class AssertionsProxy(objects.Proxy):
serverRole = 'assertions'
def addAssertion(self, assertion, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'addAssertion',
[serverId, getApplicationToken(), userToken, assertion])
def getAssertion(self, artifact, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getAssertion',
[serverId, getApplicationToken(), userToken, artifact])

View File

@ -0,0 +1,169 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Identities Proxy"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
import glasnost.common.IdentitiesCommon as commonIdentities
import glasnost.common.tools_new as commonTools
from DispatcherProxy import callServer, getApplicationToken
import ObjectsProxy as objects
import things
class AdminIdentities(objects.AdminMixin, commonIdentities.AdminIdentities):
pass
objects.register(AdminIdentities)
class Identification(things.ThingMixin, commonIdentities.Identification):
pass
things.register(Identification)
class Identity(objects.ObjectProxyMixin, commonIdentities.Identity):
pass
objects.register(Identity)
class IdentitiesProxy(commonIdentities.IdentitiesCommonMixin,
objects.ObjectsProxy):
def abstainForVote(self, electionId):
userToken = context.getVar('userToken', default = '')
serverId = self.computeServerIdFromUserToken(userToken)
callServer(
serverId,
'abstainForVote',
[serverId, getApplicationToken(), userToken, electionId])
def checkIdentityLocalNameIdentifier(
self, peerHostName, localNameIdentifier, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'checkIdentityLocalNameIdentifier',
[serverId, getApplicationToken(), userToken, peerHostName,
localNameIdentifier])
def checkIdentityPeerNameIdentifier(
self, peerHostName, peerNameIdentifier, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'checkIdentityPeerNameIdentifier',
[serverId, getApplicationToken(), userToken, peerHostName,
peerNameIdentifier])
def computeServerIdFromUserToken(self, userToken):
return commonTools.makeApplicationId(userToken, self.serverRole)
def deleteUserToken(self):
userToken = context.getVar('userToken', default = '')
if not userToken:
return
serverId = self.computeServerIdFromUserToken(userToken)
callServer(
serverId,
'deleteUserToken',
[serverId, getApplicationToken(), userToken])
def getElectionVoteToken(self, electionId):
userToken = context.getVar('userToken', default = '')
serverId = self.computeServerIdFromUserToken(userToken)
return callServer(
serverId,
'getElectionVoteToken',
[serverId, getApplicationToken(), userToken, electionId])
def getUserId(self):
userToken = context.getVar('userToken', default = '')
if not userToken:
return ''
serverId = self.computeServerIdFromUserToken(userToken)
return callServer(
serverId,
'getUserId',
[serverId, getApplicationToken(), userToken])
def getUserToken(self, id):
userToken = ''
serverId = commonTools.extractServerId(id)
return callServer(
serverId,
'getUserToken',
[serverId, getApplicationToken(), userToken, id])
def rememberId(self, id, serverId = None):
userToken = context.getVar('userToken', default = '')
if not userToken:
return
serverId = self.computeServerIdFromUserToken(userToken)
callServer(
serverId,
'rememberId',
[serverId, getApplicationToken(), userToken, id])
def setContainsUser(self, set, serverId = None):
userToken = context.getVar('userToken', default = '')
if set is None:
return 0
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'setContainsUser',
[serverId, getApplicationToken(), userToken, set])
def vote(self, electionId, voteToken):
userToken = context.getVar('userToken', default = '')
serverId = self.computeServerIdFromUserToken(userToken)
callServer(
serverId,
'vote',
[serverId, getApplicationToken(), userToken, electionId,
voteToken])

View File

@ -0,0 +1,86 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Password Accounts Proxy"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
import glasnost.common.PasswordAccountsCommon as commonPasswordAccounts
from DispatcherProxy import callServer, getApplicationToken
import ObjectsProxy as objects
from tools import utf8
class AdminPasswordAccounts(objects.AdminMixin,
commonPasswordAccounts.AdminPasswordAccounts):
pass
objects.register(AdminPasswordAccounts)
class PasswordAccount(objects.ObjectProxyMixin,
commonPasswordAccounts.PasswordAccount):
pass
objects.register(PasswordAccount)
class PasswordAccountsProxy(commonPasswordAccounts.PasswordAccountsCommonMixin,
objects.ObjectsProxy):
def checkObjectAuthentication(self, login, password, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
if login is None:
loginExport = ''
else:
loginExport = utf8(login)
if password is None:
passwordExport = ''
else:
passwordExport = utf8(password)
return callServer(
serverId,
'checkObjectAuthentication',
[serverId, getApplicationToken(), userToken, loginExport,
passwordExport])

View File

@ -81,135 +81,8 @@ register(Person)
class PeopleProxy(PeopleCommonMixin, ObjectsProxy): class PeopleProxy(PeopleCommonMixin, ObjectsProxy):
"""Proxy of the People server.
This class is used in order to communicate with the server.
Attributes:
==========
*adminClassName*:
The Administrator wrapper people class name.
*newObjectNameCapitalized*:
The gettext string illustrating a new user.
*objectClassName*:
The normal people wrapper class name.
*objectName*:
The gettext string of the people object name.
*objectNameCapitalized*:
The gettext string of the people object name, capitalzed.
*objectsName*:
The gettext string of the collection of people objects.
*objectsNameCapitalized*:
The gettext string of the collection of people objects, capitalized.
*serverRole*:
The name of the server.
"""
def abstainForVote(self, electionId):
"""Abstain voting on an election.
Keyword arguments:
==================
*virtualServerId*:
The virtual server ID string where are the elections.
*clientToken*:
The client application token.
*userToken*:
The user token.
*electionId*:
The Id of the election to abstain.
Return 0 everytime.
Exceptions:
===========
*faults.MissingItem*:
The specified election does not exist on the specified server.
*AttributeError*:
No authentication proxy found.
"""
userToken = context.getVar('userToken', default = '')
serverId = self.computeServerIdFromUserToken(userToken)
callServer(
serverId,
'abstainForVote',
[serverId, getApplicationToken(), userToken, electionId])
def computeServerIdFromUserToken(self, userToken):
"""Return the user's server ID string from his token.
Keyword argument:
=================
*userToken*:
The well formed user token.
*Exception*:
============
*Exception*:
The *userToken* is malformed.
The string has no fields separated by ':'.
"""
return 'glasnost://%s/%s' % (
extractApplicationHostNameAndPort(userToken),
self.serverRole)
def findObjectIds(self, text, serverId = None): def findObjectIds(self, text, serverId = None):
"""Find person objects ID corresponding to a specified string. """Find people IDs corresponding to a specified string."""
Keyword arguments:
==================
*text*:
The text that must be in the person object (conforming to the
object containstext method).
*serverId*:
The server ID (default: None).
Return values:
==============
*The corresponding objects IDs sequence*
Exceptions:
===========
*KeyError*:
The virtual server ID does not correspond to a instanciated virtual
server.
*AssertionError*:
The given server ID doesn't begin by 'glasnost://'.
*Standard Exception*:
The server ID folowing the protocol specifier is not valid.
*Exception*('Missing context'):
The context does not contain information about the dispatcher Id.
"""
userToken = context.getVar('userToken', default = '') userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
@ -220,46 +93,3 @@ class PeopleProxy(PeopleCommonMixin, ObjectsProxy):
'findObjectIds', 'findObjectIds',
[serverId, getApplicationToken(), userToken, utf8(text)]) [serverId, getApplicationToken(), userToken, utf8(text)])
def getElectionVoteToken(self, electionId):
userToken = context.getVar('userToken', default = '')
serverId = self.computeServerIdFromUserToken(userToken)
return callServer(
serverId,
'getElectionVoteToken',
[serverId, getApplicationToken(), userToken, electionId])
def vote(self, electionId, voteToken):
"""Vote to an election.
Keyword arguments:
==================
*electionId*:
The ID of the election to vote.
*voteToken*:
The vote token associated to the vote.
*Return 0.*
===========
Exceptions:
===========
*faults.MissingItem*:
The specified election was not found.
*KeyError*:
The virtual server ID does not correspond to a instanciated virtual
server.
"""
userToken = context.getVar('userToken', default = '')
serverId = self.computeServerIdFromUserToken(userToken)
callServer(
serverId,
'vote',
[serverId, getApplicationToken(), userToken, electionId,
voteToken])

View File

@ -84,14 +84,6 @@ class PreferencesProxy(PreferencesCommonMixin, Proxy):
'getObjectByUserId', 'getObjectByUserId',
[serverId, getApplicationToken(), userToken, userId]) [serverId, getApplicationToken(), userToken, userId])
return commonTools.importThing(objectImport) return commonTools.importThing(objectImport)
def rememberId(self, id, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
callServer(
serverId,
'rememberId',
[serverId, getApplicationToken(), userToken, id])
def setPreference(self, object, serverId = None): def setPreference(self, object, serverId = None):
userToken = context.getVar('userToken', default = '') userToken = context.getVar('userToken', default = '')

View File

@ -0,0 +1,88 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Providers Proxy"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
import glasnost.common.ProvidersCommon as commonProviders
from DispatcherProxy import callServer, getApplicationToken
import ObjectsProxy as objects
class AdminProviders(objects.AdminMixin, commonProviders.AdminProviders):
pass
objects.register(AdminProviders)
class IdentityProvider(objects.ObjectProxyMixin,
commonProviders.IdentityProvider):
pass
objects.register(IdentityProvider)
class ServiceProvider(objects.ObjectProxyMixin,
commonProviders.ServiceProvider):
pass
objects.register(ServiceProvider)
class ProvidersProxy(commonProviders.ProvidersCommonMixin,
objects.ObjectsProxy):
def getRemoteIdentityProviderId(self, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getRemoteIdentityProviderId',
[serverId, getApplicationToken(), userToken])
def getServiceProviderId(self, providerId, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getServiceProviderId',
[serverId, getApplicationToken(), userToken, providerId])

View File

@ -55,7 +55,7 @@ class SessionsProxy(Proxy):
serverRole = 'sessions' serverRole = 'sessions'
def addTemporaryData(self, data, serverId = None): def addTemporaryData(self, data, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
sessionToken = context.getVar('sessionToken') sessionToken = context.getVar('sessionToken')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
return callServer( return callServer(
@ -65,7 +65,7 @@ class SessionsProxy(Proxy):
sessionToken, data]) sessionToken, data])
def delTemporaryData(self, dataToken, serverId = None): def delTemporaryData(self, dataToken, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
sessionToken = context.getVar('sessionToken') sessionToken = context.getVar('sessionToken')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
callServer( callServer(
@ -75,7 +75,7 @@ class SessionsProxy(Proxy):
sessionToken, dataToken]) sessionToken, dataToken])
def getTemporaryData(self, dataToken, serverId = None): def getTemporaryData(self, dataToken, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
sessionToken = context.getVar('sessionToken') sessionToken = context.getVar('sessionToken')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
return callServer( return callServer(
@ -85,7 +85,7 @@ class SessionsProxy(Proxy):
sessionToken, dataToken]) sessionToken, dataToken])
def deleteSession(self, objectToken, serverId = None): def deleteSession(self, objectToken, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
callServer( callServer(
serverId, serverId,
@ -93,7 +93,7 @@ class SessionsProxy(Proxy):
[serverId, getApplicationToken(), userToken, objectToken]) [serverId, getApplicationToken(), userToken, objectToken])
def getHistory(self, serverId = None): def getHistory(self, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
return callServer( return callServer(
serverId, serverId,
@ -101,7 +101,7 @@ class SessionsProxy(Proxy):
[serverId, getApplicationToken(), userToken]) [serverId, getApplicationToken(), userToken])
def getSession(self, objectToken, ipAddress, serverId = None): def getSession(self, objectToken, ipAddress, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
object = callServer( object = callServer(
serverId, serverId,
@ -111,7 +111,7 @@ class SessionsProxy(Proxy):
return object return object
def newSession(self, ipAddress, serverId = None): def newSession(self, ipAddress, serverId = None):
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
return callServer( return callServer(
serverId, serverId,
@ -130,7 +130,7 @@ class SessionsProxy(Proxy):
if not object.has_key('isDirty'): if not object.has_key('isDirty'):
return return
del object['isDirty'] del object['isDirty']
userToken = context.getVar('userToken') userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId) serverId = self.getServerId(serverId = serverId)
object['version'] = callServer( object['version'] = callServer(
serverId, serverId,

View File

@ -0,0 +1,75 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@entrouvert.com
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost X509 Accounts Proxy"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
import glasnost.common.X509AccountsCommon as commonX509Accounts
from DispatcherProxy import callServer, getApplicationToken
import ObjectsProxy as objects
class AdminX509Accounts(objects.AdminMixin,
commonX509Accounts.AdminX509Accounts):
pass
objects.register(AdminX509Accounts)
class X509Account(objects.ObjectProxyMixin, commonX509Accounts.X509Account):
pass
objects.register(X509Account)
class X509AccountsProxy(commonX509Accounts.X509AccountsCommonMixin,
objects.ObjectsProxy):
def checkObjectAuthentication(self, serial, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'checkObjectAuthentication',
[serverId, getApplicationToken(), userToken, serial])

View File

@ -726,12 +726,12 @@ class ObjectsVirtualServer(AdministrableVirtualServer):
return return
object = self.loadObjectCore(objectId) object = self.loadObjectCore(objectId)
object.acquireNonCore() object.acquireNonCore()
data = {
'time': time.time(),
'userId': getProxyForServerRole('authentication').getUserId(),
'object': object
}
try: try:
data = {
'time': time.time(),
'userId': getProxyForServerRole('identities').getUserId(),
'object': object,
}
if not os.access(self.dataDirectoryPath, os.F_OK): if not os.access(self.dataDirectoryPath, os.F_OK):
os.mkdir(self.dataDirectoryPath) os.mkdir(self.dataDirectoryPath)
os.chmod(self.dataDirectoryPath, 0750) os.chmod(self.dataDirectoryPath, 0750)
@ -837,8 +837,11 @@ class Server(things.BaseThing, applications.Application):
return return
if self.hasMultipleVirtualServers: if self.hasMultipleVirtualServers:
self.virtualServers[newVirtualServerId] = self.loadVirtualServer( newVirtualServer = self.initVirtualServer(newVirtualServerId)
newVirtualServerId) self.virtualServers[newVirtualServerId] = newVirtualServer
newVirtualServer = self.loadVirtualServer(newVirtualServer)
self.virtualServers[newVirtualServerId] = newVirtualServer
context.push( context.push(
applicationId = newVirtualServerId, applicationId = newVirtualServerId,
) )
@ -860,12 +863,13 @@ class Server(things.BaseThing, applications.Application):
upgradeMethodNames = [] upgradeMethodNames = []
for class_ in classes: for class_ in classes:
for attributeName in class_.__dict__.keys(): for attributeName in class_.__dict__.keys():
if attributeName.startswith('upgrade_'): if attributeName.startswith('upgradeVirtualServer_'):
if not attributeName in upgradeMethodNames: if not attributeName in upgradeMethodNames:
upgradeMethodNames.append(attributeName) upgradeMethodNames.append(attributeName)
upgradeMethodNames.sort() upgradeMethodNames.sort()
if len(upgradeMethodNames) > 0: if len(upgradeMethodNames) > 0:
lastMethodVersionNumber = upgradeMethodNames[-1][len('upgrade_'):] lastMethodVersionNumber = upgradeMethodNames[-1][
len('upgradeVirtualServer_'):]
if lastMethodVersionNumber > glasnost.fileVersionNumber: if lastMethodVersionNumber > glasnost.fileVersionNumber:
raise Exception( raise Exception(
'The constant fileVersionNumber in shared/__init__' 'The constant fileVersionNumber in shared/__init__'
@ -922,6 +926,9 @@ class Server(things.BaseThing, applications.Application):
virtualServer.exportNonCore(exportDirectoryPath) virtualServer.exportNonCore(exportDirectoryPath)
return None return None
def fillEmptyVirtualServer(self, virtualServer):
pass
def getVirtualServer(self, virtualServerId): def getVirtualServer(self, virtualServerId):
"""Return the Virtal server instance. """Return the Virtal server instance.
@ -1116,7 +1123,9 @@ class Server(things.BaseThing, applications.Application):
elif os.access(pickleFilePath, os.F_OK): elif os.access(pickleFilePath, os.F_OK):
import cPickle as glasnostPickle import cPickle as glasnostPickle
rcFile = open(pickleFilePath, 'rb') rcFile = open(pickleFilePath, 'rb')
if rcFile is not None: if rcFile is None:
self.fillEmptyVirtualServer(virtualServer)
else:
fcntl.lockf(rcFile, fcntl.LOCK_SH) fcntl.lockf(rcFile, fcntl.LOCK_SH)
version = self.readFileVersion(rcFile) version = self.readFileVersion(rcFile)
#print 'file:', rcFile #print 'file:', rcFile
@ -1146,6 +1155,20 @@ class Server(things.BaseThing, applications.Application):
originalContext.setVar('server', self) originalContext.setVar('server', self)
originalContext.setVar('serverRole', self.applicationRole) originalContext.setVar('serverRole', self.applicationRole)
def initVirtualServer(self, virtualServerId):
assert virtualServerId is not None
dispatcherId = commonTools.extractDispatcherId(virtualServerId)
context.push(
applicationId = virtualServerId,
dispatcherId = dispatcherId,
)
try:
virtualServer = self.VirtualServer()
virtualServer.init()
finally:
context.pull()
return virtualServer
def launch(self, applicationName, applicationRole): def launch(self, applicationName, applicationRole):
self.applicationName = applicationName self.applicationName = applicationName
self.applicationRole = applicationRole self.applicationRole = applicationRole
@ -1173,11 +1196,14 @@ class Server(things.BaseThing, applications.Application):
if dispatcherId is not None: if dispatcherId is not None:
virtualServerId = commonTools.makeApplicationId( virtualServerId = commonTools.makeApplicationId(
dispatcherId, self.applicationRole) dispatcherId, self.applicationRole)
self.virtualServers[virtualServerId] = self.loadVirtualServer( virtualServer = self.initVirtualServer(virtualServerId)
virtualServerId) self.virtualServers[virtualServerId] = virtualServer
virtualServer = self.loadVirtualServer(virtualServer)
self.virtualServers[virtualServerId] = virtualServer
else: else:
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
self.virtualServer = self.loadVirtualServer(virtualServerId) self.virtualServer = self.initVirtualServer(virtualServerId)
self.virtualServer = self.loadVirtualServer(self.virtualServer)
def loadConfigOptions(self): def loadConfigOptions(self):
applications.Application.loadConfigOptions(self) applications.Application.loadConfigOptions(self)
@ -1202,20 +1228,15 @@ class Server(things.BaseThing, applications.Application):
self.dataDirectoryPath = commonTools.getConfig( self.dataDirectoryPath = commonTools.getConfig(
'Misc', 'DataDirectoryPath') 'Misc', 'DataDirectoryPath')
def loadVirtualServer(self, virtualServerId): def loadVirtualServer(self, virtualServer):
assert virtualServerId is not None
dispatcherId = commonTools.extractDispatcherId(virtualServerId)
context.push( context.push(
applicationId = virtualServerId, applicationId = virtualServer.virtualServerId,
dispatcherId = dispatcherId, dispatcherId = commonTools.extractDispatcherId(
emptyVirtualServer = None, virtualServer.virtualServerId),
emptyVirtualServer = virtualServer,
) )
try: if self.useDataFile:
virtualServer = self.VirtualServer() try:
virtualServer.init()
context.setVar('emptyVirtualServer', virtualServer)
if self.useDataFile:
pickleFilePath = os.path.join( pickleFilePath = os.path.join(
virtualServer.dataDirectoryPath, virtualServer.dataDirectoryPath,
self.applicationName + '.pickle') self.applicationName + '.pickle')
@ -1230,7 +1251,9 @@ class Server(things.BaseThing, applications.Application):
elif os.access(pickleFilePath, os.F_OK): elif os.access(pickleFilePath, os.F_OK):
import cPickle as glasnostPickle import cPickle as glasnostPickle
rcFile = open(pickleFilePath, 'rb') rcFile = open(pickleFilePath, 'rb')
if rcFile is not None: if rcFile is None:
self.fillEmptyVirtualServer(virtualServer)
else:
fcntl.lockf(rcFile, fcntl.LOCK_SH) fcntl.lockf(rcFile, fcntl.LOCK_SH)
version = self.readFileVersion(rcFile) version = self.readFileVersion(rcFile)
print 'file:', rcFile print 'file:', rcFile
@ -1247,11 +1270,11 @@ class Server(things.BaseThing, applications.Application):
virtualServer.initFromOldData(data) virtualServer.initFromOldData(data)
virtualServer.isReadOnly = isReadOnly virtualServer.isReadOnly = isReadOnly
self.upgradeVirtualServer(virtualServer, version) self.upgradeVirtualServer(virtualServer, version)
finally: finally:
context.pull() context.pull()
return virtualServer return virtualServer
def publicMethodWrapper(self, method, arguments): def publicMethodWrapper(self, method, arguments, isDirectCall = 0):
"""The standard wrapper for public methods. """The standard wrapper for public methods.
Most Glasnost public methods use the same 3 parameters: Most Glasnost public methods use the same 3 parameters:
@ -1271,13 +1294,14 @@ class Server(things.BaseThing, applications.Application):
return apply(method, arguments) return apply(method, arguments)
finally: finally:
# Save all dirty data. # Save all dirty data.
virtualServerId = context.getVar('applicationId') if not isDirectCall:
try: virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) try:
except faults.UnknownServerId: virtualServer = self.getVirtualServer(virtualServerId)
pass except faults.UnknownServerId:
else: pass
virtualServer.savePendingRequests() else:
virtualServer.savePendingRequests()
self.pullContext() self.pullContext()
@ -1390,8 +1414,10 @@ class Server(things.BaseThing, applications.Application):
self.hostName, self.port, virtualServerId) self.hostName, self.port, virtualServerId)
except faults.RoleNotInProfiles: except faults.RoleNotInProfiles:
continue continue
self.virtualServers[virtualServerId] = self.loadVirtualServer( virtualServer = self.initVirtualServer(virtualServerId)
virtualServerId) self.virtualServers[virtualServerId] = virtualServer
virtualServer = self.loadVirtualServer(virtualServer)
self.virtualServers[virtualServerId] = virtualServer
context.push( context.push(
applicationId = virtualServerId, applicationId = virtualServerId,
) )
@ -1491,12 +1517,13 @@ class Server(things.BaseThing, applications.Application):
upgradeMethodNames = [] upgradeMethodNames = []
for class_ in classes: for class_ in classes:
for attributeName in class_.__dict__.keys(): for attributeName in class_.__dict__.keys():
if attributeName.startswith('upgrade_'): if attributeName.startswith('upgradeVirtualServer_'):
if not attributeName in upgradeMethodNames: if not attributeName in upgradeMethodNames:
upgradeMethodNames.append(attributeName) upgradeMethodNames.append(attributeName)
upgradeMethodNames.sort() upgradeMethodNames.sort()
for upgradeMethodName in upgradeMethodNames: for upgradeMethodName in upgradeMethodNames:
if upgradeMethodName[len('upgrade_'):] <= fileVersionNumber: if upgradeMethodName[len('upgradeVirtualServer_'):] \
<= fileVersionNumber:
continue continue
getattr(self, upgradeMethodName)(virtualServer) getattr(self, upgradeMethodName)(virtualServer)
virtualServer.savePendingRequests() virtualServer.savePendingRequests()
@ -1606,7 +1633,7 @@ class AdministrableServerMixin:
admin = virtualServer.admin admin = virtualServer.admin
if context.getVar('isAdmin') is not None: if context.getVar('isAdmin') is not None:
return context.getVar('isAdmin') return context.getVar('isAdmin')
result = getProxyForServerRole('authentication').setContainsUser( result = getProxyForServerRole('identities').setContainsUser(
admin.adminsSet) admin.adminsSet)
context.setVar('isAdmin', result) context.setVar('isAdmin', result)
return result return result
@ -1710,20 +1737,24 @@ class AdministrableServerMixin:
virtualServer.markAdminAsDirty(admin) virtualServer.markAdminAsDirty(admin)
invalidateValue('admin_%s' % self.serverRole) invalidateValue('admin_%s' % self.serverRole)
def upgrade_0001_0019(self, virtualServer): def upgradeVirtualServer_0001_0019(self, virtualServer):
# Fill empty adminsSet slots in admin. # Fill empty adminsSet slots in admin.
admin = virtualServer.admin admin = virtualServer.admin
if admin.hasSlotName('adminsSet') and not admin.adminsSet: if admin.hasSlotName('adminsSet') and not admin.adminsSet:
admin.adminsSet = [system.generalPublicId] admin.adminsSet = [system.generalPublicId]
virtualServer.markAdminAsDirty(admin) virtualServer.markAdminAsDirty(admin)
def upgrade_0001_0020(self, virtualServer): def upgradeVirtualServer_0001_0020(self, virtualServer):
# Fill empty readersSet slots in admin. # Fill empty readersSet slots in admin.
admin = virtualServer.admin admin = virtualServer.admin
if admin.hasSlotName('readersSet') and not admin.readersSet: if admin.hasSlotName('readersSet') and not admin.readersSet:
admin.readersSet = [system.generalPublicId] admin.readersSet = [system.generalPublicId]
virtualServer.markAdminAsDirty(admin) virtualServer.markAdminAsDirty(admin)
def upgradeVirtualServer_0001_0028(self, virtualServer):
# Convert user ids from "people" to "identities".
if virtualServer.admin.upgrade('0001_0028'):
virtualServer.markAdminAsDirty(admin)
class ObjectsServer(AdministrableServerMixin, Server): class ObjectsServer(AdministrableServerMixin, Server):
@ -1797,7 +1828,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
if not self.isAdmin() and not (self.canAddObject() and ( if not self.isAdmin() and not (self.canAddObject() and (
not object.hasSlotName('writersSet') not object.hasSlotName('writersSet')
or getProxyForServerRole('authentication' or getProxyForServerRole('identities'
).setContainsUser(object.getSlot('writersSet' ).setContainsUser(object.getSlot('writersSet'
).getValue()))): ).getValue()))):
if not object.canBeCreatedByClient(): if not object.canBeCreatedByClient():
@ -1823,7 +1854,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
admin = self.getAdminCore() admin = self.getAdminCore()
except faults.UserAccessDenied: except faults.UserAccessDenied:
return 0 return 0
return getProxyForServerRole('authentication').setContainsUser( return getProxyForServerRole('identities').setContainsUser(
admin.writersSet) admin.writersSet)
def canDeleteObject(self, objectId): def canDeleteObject(self, objectId):
@ -1836,7 +1867,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)
return self.isAdmin() or ( return self.isAdmin() or (
object.hasSlotName('writersSet') object.hasSlotName('writersSet')
and getProxyForServerRole('authentication').setContainsUser( and getProxyForServerRole('identities').setContainsUser(
object.getSlot('writersSet').getValue())) object.getSlot('writersSet').getValue()))
def canGetObject(self, objectId): def canGetObject(self, objectId):
@ -1856,7 +1887,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
pass pass
if object.hasSlotName('readersSet'): if object.hasSlotName('readersSet'):
readersSet = object.getSlot('readersSet').getValue() readersSet = object.getSlot('readersSet').getValue()
return getProxyForServerRole('authentication').setContainsUser( return getProxyForServerRole('identities').setContainsUser(
readersSet) readersSet)
else: else:
if not self.useAdminReadersSet: if not self.useAdminReadersSet:
@ -1865,7 +1896,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
admin = self.getAdminCore() admin = self.getAdminCore()
except faults.UserAccessDenied: except faults.UserAccessDenied:
return 0 return 0
return getProxyForServerRole('authentication').setContainsUser( return getProxyForServerRole('identities').setContainsUser(
admin.readersSet) admin.readersSet)
def canGetObjects(self): def canGetObjects(self):
@ -1879,7 +1910,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
admin = self.getAdminCore() admin = self.getAdminCore()
except faults.UserAccessDenied: except faults.UserAccessDenied:
return 0 return 0
if getProxyForServerRole('authentication').setContainsUser( if getProxyForServerRole('identities').setContainsUser(
admin.readersSet): admin.readersSet):
return 1 return 1
return 0 return 0
@ -1896,7 +1927,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
return 0 return 0
return self.isAdmin() or ( return self.isAdmin() or (
object.hasSlotName('writersSet') object.hasSlotName('writersSet')
and getProxyForServerRole('authentication').setContainsUser( and getProxyForServerRole('identities').setContainsUser(
object.getSlot('writersSet').getValue())) object.getSlot('writersSet').getValue()))
def canUseObject(self, objectId): def canUseObject(self, objectId):
@ -1922,7 +1953,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
if object.hasSlotName('usersSet'): if object.hasSlotName('usersSet'):
usersSet = object.getSlot('usersSet').getValue() usersSet = object.getSlot('usersSet').getValue()
return not usersSet or getProxyForServerRole( return not usersSet or getProxyForServerRole(
'authentication').setContainsUser(usersSet) 'identities').setContainsUser(usersSet)
else: else:
return 1 return 1
@ -2073,12 +2104,14 @@ class ObjectsServer(AdministrableServerMixin, Server):
isAdmin = self.isAdmin() isAdmin = self.isAdmin()
try: try:
possibleReaderIds = getSetContainedIds( possibleReaderIds = getSetContainedIds(
possibleReadersSet, ['people'], raiseWhenUncountable = 1) possibleReadersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
possibleReaderIds = 'everybody' possibleReaderIds = 'everybody'
try: try:
possibleWriterIds = getSetContainedIds( possibleWriterIds = getSetContainedIds(
possibleWritersSet, ['people'], raiseWhenUncountable = 1) possibleWritersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup: except faults.UncountableGroup:
possibleWriterIds = 'everybody' possibleWriterIds = 'everybody'
objectIds = virtualServer.objects.keys() objectIds = virtualServer.objects.keys()
@ -2099,7 +2132,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
hasReadersSet = 0 hasReadersSet = 0
readersSet = None readersSet = None
if not isAdmin and hasReadersSet and not getProxyForServerRole( if not isAdmin and hasReadersSet and not getProxyForServerRole(
'authentication').setContainsUser(readersSet): 'identities').setContainsUser(readersSet):
continue continue
if not self.getLastObjectIds_filter( if not self.getLastObjectIds_filter(
possibleReaderIds, hasReadersSet, readersSet): possibleReaderIds, hasReadersSet, readersSet):
@ -2124,7 +2157,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
if hasSet: if hasSet:
try: try:
ids = getSetContainedIds( ids = getSetContainedIds(
set, ['people'], raiseWhenUncountable = 1) set, ['identities'], raiseWhenUncountable = 1)
except faults.IllegalRecursiveGroup: except faults.IllegalRecursiveGroup:
# There is an error in the group. For security reasons, return # There is an error in the group. For security reasons, return
# false. # false.
@ -2507,7 +2540,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
if not self.canModifyObject(object.id) or not ( if not self.canModifyObject(object.id) or not (
self.isAdmin() self.isAdmin()
or not objectChanges.hasSlotName('writersSet') or not objectChanges.hasSlotName('writersSet')
or getProxyForServerRole('authentication').setContainsUser( or getProxyForServerRole('identities').setContainsUser(
objectChanges.getSlot('writersSet').getValue())): objectChanges.getSlot('writersSet').getValue())):
if not object.canBeModifiedByClient(): if not object.canBeModifiedByClient():
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
@ -2585,7 +2618,7 @@ class ObjectsServer(AdministrableServerMixin, Server):
if not self.canModifyObject(object.id) or not ( if not self.canModifyObject(object.id) or not (
self.isAdmin() self.isAdmin()
or not objectChanges.hasSlotName('writersSet') or not objectChanges.hasSlotName('writersSet')
or getProxyForServerRole('authentication').setContainsUser( or getProxyForServerRole('identities').setContainsUser(
objectChanges.getSlot('writersSet').getValue())): objectChanges.getSlot('writersSet').getValue())):
if not object.canBeModifiedByClient(): if not object.canBeModifiedByClient():
raise faults.UserAccessDenied() raise faults.UserAccessDenied()
@ -2980,8 +3013,9 @@ class ObjectsServer(AdministrableServerMixin, Server):
self.rpcServer.remove_subscription( self.rpcServer.remove_subscription(
when, virtualServerId, method, clientId, callBackName) when, virtualServerId, method, clientId, callBackName)
def upgrade_0001_0019(self, virtualServer): def upgradeVirtualServer_0001_0019(self, virtualServer):
AdministrableServerMixin.upgrade_0001_0019(self, virtualServer) AdministrableServerMixin.upgradeVirtualServer_0001_0019(
self, virtualServer)
# In each object, fill the readersSet slot when it exists and is empty. # In each object, fill the readersSet slot when it exists and is empty.
for id, object in virtualServer.objects.items(): for id, object in virtualServer.objects.items():
@ -2989,3 +3023,12 @@ class ObjectsServer(AdministrableServerMixin, Server):
object.readersSet = [system.generalPublicId] object.readersSet = [system.generalPublicId]
virtualServer.markObjectAsDirty(object) virtualServer.markObjectAsDirty(object)
def upgradeVirtualServer_0001_0028(self, virtualServer):
AdministrableServerMixin.upgradeVirtualServer_0001_0028(
self, virtualServer)
# Convert user ids from "people" to "identities".
for object in virtualServer.objects.values():
if object.upgrade('0001_0028'):
virtualServer.markObjectAsDirty(object)

View File

@ -290,7 +290,7 @@ class ServerMixin:
context.initFromOther(self.baseContext) context.initFromOther(self.baseContext)
currentContext = context.get() currentContext = context.get()
if useWrapper and self._wrapper is not None: if useWrapper and self._wrapper is not None:
result = self._wrapper(method, params) result = self._wrapper(method, params, isDirectCall)
else: else:
result = apply(method, params) result = apply(method, params)
if not isDirectCall: if not isDirectCall:

View File

@ -89,6 +89,7 @@ class AccountLoginPassword(BaseObjectWebMixin, AccountLoginPassword):
return slotNames return slotNames
register(AccountLoginPassword) register(AccountLoginPassword)
class ChangingPassword(BaseObjectWebMixin, ObjectCommon): class ChangingPassword(BaseObjectWebMixin, ObjectCommon):
id_kindName = None id_kindName = None
language_kindName = None language_kindName = None
@ -493,7 +494,6 @@ correctly configured.\
return writePageLayout(layout, _('Login')) return writePageLayout(layout, _('Login'))
finally: finally:
context.pull(_level = 'index') context.pull(_level = 'index')
login.isPublicForWeb = 1
def loginSubmit(self, **keywords): def loginSubmit(self, **keywords):
if keywords is None: if keywords is None:
@ -541,6 +541,7 @@ correctly configured.\
authObject = self.newAuthenticationObject() authObject = self.newAuthenticationObject()
return self.newAccountObject(userCardObject, authObject) return self.newAccountObject(userCardObject, authObject)
newAccount.isPublicForWeb = 1
def newAccountObject(self, userCardObject, authObject): def newAccountObject(self, userCardObject, authObject):
userCardSlot = slots.Root(userCardObject, name = 'userCard') userCardSlot = slots.Root(userCardObject, name = 'userCard')
@ -573,7 +574,6 @@ correctly configured.\
return writePageLayout(layout, _('New Account')) return writePageLayout(layout, _('New Account'))
finally: finally:
context.pull(_level = 'index') context.pull(_level = 'index')
newAccount.isPublicForWeb = 1
def newAccountSubmit(self, **keywords): def newAccountSubmit(self, **keywords):
if keywords is None: if keywords is None:

View File

@ -506,8 +506,8 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
if not object.hasMode(modeName): if not object.hasMode(modeName):
return pageNotFound() return pageNotFound()
mode = object.getMode(modeName) mode = object.getMode(modeName)
authenticationProxy = getProxyForServerRole('authentication') identitiesProxy = getProxyForServerRole('identities')
if not authenticationProxy.setContainsUser( if not identitiesProxy.setContainsUser(
mode.getModelUsersSet(object)): mode.getModelUsersSet(object)):
return accessForbidden() return accessForbidden()
@ -675,8 +675,8 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
object.prototypeIds = [prototypeId] object.prototypeIds = [prototypeId]
object.__class__ = CardForUse # Important. object.__class__ = CardForUse # Important.
mode = object.getMode(modeName) mode = object.getMode(modeName)
authenticationProxy = getProxyForServerRole('authentication') identitiesProxy = getProxyForServerRole('identities')
if not authenticationProxy.setContainsUser( if not identitiesProxy.setContainsUser(
mode.getModelUsersSet(object)): mode.getModelUsersSet(object)):
return accessForbidden() return accessForbidden()

View File

@ -269,13 +269,12 @@ class ElectionMixin(ObjectWebMixin):
def getVotesLayout(self): def getVotesLayout(self):
ballotsWeb = getWebForServerRole('ballots') ballotsWeb = getWebForServerRole('ballots')
gradesWeb = getWebForServerRole('grades') gradesWeb = getWebForServerRole('grades')
peopleWeb = getWebForServerRole('people')
layout = X.array() layout = X.array()
userVoteToken = None userVoteToken = None
userId = context.getVar('userId', default = '') userId = context.getVar('userId')
if userId: user = context.getVar('user')
user = peopleWeb.getObject(userId) if user is not None:
if user.voteTokens is not None \ if user.voteTokens is not None \
and user.voteTokens.has_key(self.id): and user.voteTokens.has_key(self.id):
userVoteToken = user.voteTokens[self.id] userVoteToken = user.voteTokens[self.id]
@ -727,15 +726,15 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
layout += ObjectsWebMixin.getViewOtherActionButtonsBarLayout( layout += ObjectsWebMixin.getViewOtherActionButtonsBarLayout(
self, object, fields) self, object, fields)
if object.state == 'running' \ if object.state == 'running' \
and getProxyForServerRole('authentication').setContainsUser( and getProxyForServerRole('identities').setContainsUser(
object.votersSet): object.votersSet):
layout += X.buttonStandalone( layout += X.buttonStandalone(
'vote', 'vote',
X.roleUrl('votes', 'edit').add('electionId', object.id)) X.roleUrl('votes', 'edit').add('electionId', object.id))
authenticationProxy = getProxyForServerRole('authentication') identitiesProxy = getProxyForServerRole('identities')
if object.state == 'running' and \ if object.state == 'running' and \
(isAdmin or \ (isAdmin or \
authenticationProxy.setContainsUser(object.writersSet)): identitiesProxy.setContainsUser(object.writersSet)):
layout += X.buttonStandalone( layout += X.buttonStandalone(
'pester-abstentionnists', 'pester-abstentionnists',
X.idUrl(object.id, 'confirmPesterAbstentionnists')) X.idUrl(object.id, 'confirmPesterAbstentionnists'))
@ -821,7 +820,7 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
if not self.canGetObjects(): if not self.canGetObjects():
return accessForbidden() return accessForbidden()
isAdmin = self.isAdmin() isAdmin = self.isAdmin()
userId = context.getVar('userId', default = '') userId = context.getVar('userId')
if userId: if userId:
userSet = [userId] userSet = [userId]
else: else:

721
shared/web/IdentitiesWeb.py Normal file
View File

@ -0,0 +1,721 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Identities Web"""
__version__ = '$Revision$'[11:-2]
import httplib
import md5
from OpenSSL import SSL
import socket
import urlparse
import whrandom
from xml.dom.minidom import parseString
import lasso.Protocols.SingleSignOnAndFederation as sso
from lasso.Schemas.SchemaDom import importFromNode
import lasso.Soap
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.slots as slots
import glasnost.common.xhtmlgenerator as X
import glasnost.proxy.IdentitiesProxy as proxyIdentities
from glasnost.proxy.tools import getProxyForServerRole
import ObjectsWeb as objects
import things
from tools import OK, accessForbidden, getWeb, getWebForServerRole, redirect, writePageLayout
class AdminIdentities(objects.AdminMixin, proxyIdentities.AdminIdentities):
pass
objects.register(AdminIdentities)
class HTTPSConnection(httplib.HTTPConnection):
certificateFile = None
default_port = httplib.HTTPS_PORT
peerCaCertificateFile = None
privateKeyFile = None
def __init__(self, host, port = None, privateKeyFile = None,
certificateFile = None, peerCaCertificateFile = None,
strict = None):
httplib.HTTPConnection.__init__(self, host, port, strict)
self.privateKeyFile = privateKeyFile
self.certificateFile = certificateFile
self.peerCaCertificateFile = peerCaCertificateFile
def connect(self):
"Connect to a host on a given (SSL) port."
context = SSL.Context(SSL.SSLv23_METHOD)
# Demand a certificate.
context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
self.verifyCallback)
context.use_privatekey_file(self.privateKeyFile)
context.use_certificate_file(self.certificateFile)
context.load_verify_locations(self.peerCaCertificateFile)
# Strange hack, that is derivated from httplib.HTTPSConnection, but
# that I (Emmanuel) don't really understand...
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sslSocket = SSL.Connection(context, sock)
sslSocket.connect((self.host, self.port))
self.sock = httplib.FakeSocket(sslSocket, sslSocket)
def verifyCallback(self, connection, x509Object, errorNumber, errorDepth,
returnCode):
# FIXME: What should be done?
return returnCode
class Identification(things.ThingMixin, proxyIdentities.Identification):
pass
things.register(Identification)
class Identity(objects.ObjectWebMixin, proxyIdentities.Identity):
pass
objects.register(Identity)
class IdentitiesWeb(objects.ObjectsWebMixin, proxyIdentities.IdentitiesProxy):
def createSessionIfNeeded(self, nextUri):
"""Create a session, if it doesn't exist yet.
Return either None (if the session already existed or has been created
immediately) or a redirect page which must be returned to the user
agent, in order to create the session.
"""
session = context.getVar('session')
if session is None:
req = context.getVar('req')
sessionsProxy = getProxyForServerRole('sessions')
virtualHost = context.getVar('virtualHost')
try:
session = sessionsProxy.newSession(
req.connection.remote_ip,
serverId = virtualHost.defaultDispatcherId)
except: # Do a tighter check?
if context.getVar('debug'):
raise
return failure(_('Failed to initialize a session.'),
X.roleUrl('login'))
sessionToken = session['sessionToken']
context.setVar('sessionToken', sessionToken)
context.setVar('session', session)
canUseCookie = context.getVar('canUseCookie', default = 0)
if canUseCookie:
url = X.roleUrl('define', action = 'testCookie')
url.add('nextUri', nextUri)
url.add('sessionToken', sessionToken)
context.setVar('canUseCookie', 0)
url = url.getAsUrl()
context.setVar('canUseCookie', 1)
return redirect(url)
return None
def getViewAboveButtonsBarLayout(self, object, fields):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
layout = X.array()
layout += objects.ObjectsWebMixin.getViewAboveButtonsBarLayout(
self, object, fields)
def getVotesSectionLayout(person, votes, elections, intertitle):
layout = None
if len(elections) > 0:
layout = X.array( X.h3()(intertitle) )
layout += X.br()
table = X.table()
layout += table
for election in elections:
if not person.id in election.getVoterIds():
continue
tr = X.tr(X.th(scope = 'row')(
X.a(href = X.idUrl(election.id))(
election.getLabelTranslated(
context.getVar('readLanguages')))))
table += tr
if not votes.has_key(election.id):
tr += X.td(_('Abstention'))
else:
vote = votes[election.id]
if vote == 'secret':
tr += X.td(_('Secret Ballot'))
else:
tr += X.td(X.a(href = X.idUrl(vote.id))(
X.asIs(vote.getLabelLine(election))))
return layout
userId = context.getVar('userId')
knownRoles = context.getVar('knownRoles')
if userId and 'ballots' in knownRoles and 'elections' in knownRoles:
# Only an identified user can see someone's votes.
votes = ballotsWeb.getVotesFromTokens(object.voteTokens)
try:
lastElections = electionsWeb.getLastObjectsWithVoter(
50, object.id, ['running'])
except faults.UserAccessDenied:
lastElections = []
layout += getVotesSectionLayout(
object, votes, lastElections,
_("""The votes for the elections in progress"""))
try:
lastElections = electionsWeb.getLastObjectsWithVoter(
10, object.id, ['closed'])
except faults.UserAccessDenied:
lastElections = []
layout += getVotesSectionLayout(
object, votes, lastElections,
_("""The votes for the closed elections"""))
return layout
def login(self): # FIXME: Rename to signOn or authentication or ..., because some authentication methods require no password?
identityProviderId = None
providersWeb = getWebForServerRole('providers')
if providersWeb is not None:
try:
identityProviderId = providersWeb.getRemoteIdentityProviderId()
except faults.MissingItem:
pass
if identityProviderId is None:
# Don't use Liberty Alliance protocol to authenticate user.
return self.loginLocal(context.getVar('nextUri'))
identityProvider = providersWeb.getObject(identityProviderId)
singleSignOnServiceUrl = identityProvider.singleSignOnServiceUrl
loginUrl = sso.getIdentityProviderAuthenticationUrl(
authenticationMethods = ['softwarePki', 'password'],
profile = 'artifact', # FIXME: or 'post'.
relayState = context.getVar('nextUri'), # FIXME: To encrypt.
serviceProviderId = context.getVar('httpHostName'),
singleSignOnServiceUrl = singleSignOnServiceUrl)
return redirect(loginUrl)
login.isPublicForWeb = 1
def loginLibertyAlliance(self, **authenticationRequestKeywords):
"""Liberty Alliance Identity Provider Login Method."""
nextUri = X.actionUrl('loginLibertyAlliance')
for key, value in authenticationRequestKeywords.items():
nextUri.add(key, value)
redirectPage = self.createSessionIfNeeded(nextUri)
if redirectPage is not None:
return redirectPage
session = context.getVar('session')
session['authenticationRequestKeywords'] \
= authenticationRequestKeywords
session['isDirty'] = 1
authenticationRequest = sso.buildAuthenticationRequestFromKeywords(
authenticationRequestKeywords)
authenticationMethods = authenticationRequest.getAuthenticationMethods(
)
isPassive, forceAuthentication = sso.processAuthenticationRequest(
authenticationRequest)
userId = context.getVar('userId')
if isPassive:
if not userId:
url = sso.getServiceProviderAssertionArtifactHandlerUrl(
serviceProvider.assertionConsumerServiceUrl, # FIXME
sso.buildStatus('noPassive'))
return redirect(url)
return self.loginSucceeded2(session['authenticationMethod'],
authenticationRequest)
elif forceAuthentication or not userId:
accountsServerRoles = {
'password': 'passwordaccounts',
'softwarePki': 'x509accounts',
}
accountsWeb = getWebForServerRole(
accountsServerRoles[authenticationMethods[0]]) # FIXME
return accountsWeb.login()
else:
return self.loginSucceeded2(session['authenticationMethod'],
authenticationRequest)
loginLibertyAlliance.isPublicForWeb = 1
def loginLocal(self, afterLoginUri = ''):
"""Non Liberty Alliance local login."""
nextUri = X.actionUrl('loginLocal')
nextUri.add('afterLoginUri', afterLoginUri)
redirectPage = self.createSessionIfNeeded(nextUri)
if redirectPage is not None:
return redirectPage
session = context.getVar('session')
session['afterLoginUri'] = afterLoginUri
session['isDirty'] = 1
authenticationMethods = ['password', 'softwarePki'] # FIXME
accountsServerRoles = {
'password': 'passwordaccounts',
'softwarePki': 'x509accounts',
}
accountsWeb = getWebForServerRole(
accountsServerRoles[authenticationMethods[0]]) # FIXME
return accountsWeb.login()
loginLocal.isPublicForWeb = 1
def loginSucceeded(self, userToken, authenticationMethod):
"""Liberty Alliance Identity Provider Login Succeeded Method."""
session = context.getVar('session')
session['authenticationMethod'] = authenticationMethod
context.setVar('userToken', userToken)
userId = self.getUserId()
user = None
if userId:
try:
user = self.getObject(userId)
except faults.MissingItem:
pass
if user is None:
userToken = ''
userId = None
if session.has_key('userToken'):
del session['userToken']
else:
session['userToken'] = userToken
session['isDirty'] = 1
context.setVar('userToken', userToken)
context.setVar('userId', userId)
context.setVar('user', user)
if not session.has_key('authenticationRequestKeywords'):
# Non Liberty Alliance local login.
if session.has_key('afterLoginUri') and session['afterLoginUri']:
nextUri = session['afterLoginUri']
canUseCookie = context.getVar('canUseCookie', default = 0)
if not canUseCookie:
sessionToken = context.getVar('sessionToken')
nextUri = appendToUri(nextUri,
'sessionToken=' + sessionToken)
else:
nextUri = X.rootUrl()
return redirect(nextUri)
# Liberty Alliance login.
authenticationRequestKeywords \
= session['authenticationRequestKeywords']
authenticationRequest = sso.buildAuthenticationRequestFromKeywords(
authenticationRequestKeywords)
return self.loginSucceeded2(authenticationMethod,
authenticationRequest)
def loginSucceeded2(self, authenticationMethod, authenticationRequest):
user = context.getVar('user')
serviceProviderHostName = authenticationRequest.getProviderID()
providersWeb = getWebForServerRole('providers')
serviceProviderId = providersWeb.getServiceProviderId(
serviceProviderHostName)
serviceProvider = providersWeb.getObject(serviceProviderId)
serviceIdentification = None
if user.serviceIdentifications is not None:
for serviceIdentification in user.serviceIdentifications:
if serviceIdentification.peerHostName \
== serviceProviderHostName:
break
if serviceIdentification is None:
serviceIdentification = Identification()
serviceIdentification.peerHostName = serviceProviderHostName
digest = md5.new(serviceIdentification.peerHostName)
randomGenerator = whrandom.whrandom()
randomSalt = str(randomGenerator.uniform(0.1, 1))[2:]
digest.update(randomSalt)
serviceIdentification.localNameIdentifier = digest.hexdigest()
if user.serviceIdentifications is None:
user.serviceIdentifications = []
user.serviceIdentifications.append(serviceIdentification)
self.modifyPartialObject(user, ['serviceIdentifications'])
peerNameIdentifier = serviceIdentification.peerNameIdentifier
if not peerNameIdentifier:
peerNameIdentifier = serviceIdentification.localNameIdentifier
nameIdentifierPolicy = authenticationRequest.getNameIDPolicy()
assertion = sso.buildAuthenticationAssertion(
authnRequest = authenticationRequest,
issuer = context.getVar('httpHostName'),
authenticationMethod = authenticationMethod,
nameIdentifier = peerNameIdentifier,
nameIdentifierFormat = 'federated', # FIXME
idpNameIdentifier = serviceIdentification.localNameIdentifier,
idpNameIdentifierFormat = 'federated', # FIXME
)
profile = authenticationRequest.getProtocolProfile()
if profile == 'artifact':
assertionsProxy = getProxyForServerRole('assertions')
artifact = assertionsProxy.addAssertion(assertion.exportToString())
url = sso.getServiceProviderAssertionArtifactHandlerUrl(
serviceProvider.assertionConsumerServiceUrl, # FIXME
artifact,
authenticationRequest.getRelayState())
return redirect(url)
else: # profile == 'post'
authenticationResponse \
= sso.buildAuthenticationResponseFromAuthnRequest(
providerId = context.getVar('httpHostName'),
statusCode = 'success', # FIXME
assertion = assertion,
authnRequest = authenticationRequest)
authenticationResponseEmbedded \
= authenticationResponse.exportToEmbeddedUrl()
context.push(_level = 'loginSucceeded', layoutMode = 'edit')
try:
layout = X.array()
submitUrl = serviceProvider.assertionConsumerServiceUrl # FIXME
form = X.form(action = submitUrl,
enctype = 'multipart/form-data', method = 'post')
layout += form
form += X.input(name = 'LARES', type = 'hidden',
value = authenticationResponseEmbedded)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
buttonsBar += X.buttonInForm('ok', 'okButton')
return writePageLayout(layout, _('Authentication Succeeded'))
finally:
context.pull(_level = 'loginSucceeded')
def logout(self):
self.deleteUserToken()
session = context.getVar('session')
if session is not None:
# Don't delete the session, just remove userToken from it.
context.setVar('userId', None)
context.setVar('user', None)
if session.has_key('userToken'):
del session['userToken']
session['isDirty'] = 1
context.setVar('userToken', '')
# if not context.getVar('sessionTokenInCookie', default = 0):
# # The sessionToken was not stored in a cookie, so don't try to
# # use
# # the cookie when loging out.
# context.setVar('canUseCookie', 0)
nextUri = context.getVar('nextUri') or ''
if not nextUri:
nextUri = '/'
else:
nextUri = cleanUpUri(nextUri, ['sessionToken'])
canUseCookie = context.getVar('canUseCookie', default = 0)
if not canUseCookie:
nextUri = appendToUri(nextUri,
'sessionToken=' + context.getVar('sessionToken'))
return redirect(nextUri)
logout.isPublicForWeb = 1
def newPerson(self):
peopleWeb = getWebForServerRole('people')
if not peopleWeb.canAddObject():
return accessForbidden()
person = peopleWeb.newObject()
return self.newPersonObject(person)
def newPersonObject(self, object):
context.push(_level = 'newPersonObject', layoutMode = 'edit')
try:
layout = X.array()
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.actionUrl('newPersonSubmit'),
enctype = 'multipart/form-data', method = 'post')
layout += form
if context.getVar('nextUri'):
form += X.input(name = 'nextUri', type = 'hidden',
value = context.getVar('nextUri'))
slot = slots.Root(object)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, fields = None)
form += X.div(_class = 'buttons-bar')(
X.span(_class = 'action-buttons-bar')(
X.buttonInForm('create', 'createButton')))
return writePageLayout(layout, _('New Account'))
finally:
context.pull(_level = 'newPersonObject')
def newPersonSubmit(self, **keywords):
if keywords is None:
keywords = {}
peopleWeb = getWebForServerRole('people')
person = peopleWeb.newObject(keywords)
person.submitFields(keywords)
if context.getVar('again'):
return self.newPersonObject(person)
try:
result = peopleWeb.submitAddObject(person)
except:
if context.getVar('debug'):
raise
return accessForbidden() # TODO: return failure ?
if result:
return result
user = context.getVar('user')
if user is not None:
user.personId = person.id
self.modifyPartialObject(user, ['personId'])
if context.getVar('nextUri'):
return redirect(context.getVar('nextUri'))
return redirect(X.idUrl(person.id))
newPersonSubmit.isPublicForWeb = 1
def processAuthenticationResponse(self, **keywords):
# Create the service provider side session.
nextUri = X.actionUrl('processAuthenticationResponse')
for key, value in keywords.items():
nextUri.add(key, value)
redirectPage = self.createSessionIfNeeded(nextUri)
if redirectPage is not None:
return redirectPage
if keywords.has_key('LARES'):
# POST
authenticationResponseEmbedded = keywords['LARES']
# Remove base64 url encoding.
import lasso.Schemas.Schema as schema
authenticationResponseEmbeddedDecoded = schema.decodeEmbeddedUrl(
authenticationResponseEmbedded)
authenticationResponseKeywords = {}
for segment in authenticationResponseEmbeddedDecoded.split('&'):
key, value = segment.split('=')
authenticationResponseKeywords[key] = value
response = sso.buildAuthenticationResponseFromKeywords(
authenticationResponseKeywords)
relayState = response.getRelayState() # FIXME: Uncrypt relayState.
identityProviderHostName = response.getProviderID()
elif keywords.has_key('samlp:AssertionArtifact'):
# Artifact.
if keywords.has_key('RelayState'):
# FIXME: Uncrypt relayState.
relayState = keywords['RelayState']
del keywords['RelayState']
else:
relayState = None
providersWeb = getWebForServerRole('providers')
# FIXME: Don't use getRemoteIdentityProviderId(). Use instead, the
# IdentityProviderSuccintID which is encoded into the artifact.
identityProviderId = providersWeb.getRemoteIdentityProviderId()
identityProvider = providersWeb.getObject(identityProviderId)
identityProviderHostName = identityProvider.providerId
idpParsedSoapEndpoint = urlparse.urlparse(
identityProvider.soapEndpoint)
idpAddressingScheme, idpHostName, idpPath \
= idpParsedSoapEndpoint[:3]
assertionArtifact = sso.buildAssertionArtifactFromKeywords(
keywords)
request = sso.buildRequest(assertionArtifact)
requestSoapMessage = lasso.Soap.buildMessage(
request.exportToString())
headers = {'Content-type': 'text/xml'}
if idpAddressingScheme == 'https':
# Use HTTPS protocol.
# FIXME: Use PEM stored in glasnost attributes.
shortHostName = context.getVar('httpHostName').split('.')[0]
connection = HTTPSConnection(
idpHostName,
privateKeyFile = '/home/manou/ssl-certificates/servers/%s/%s_private_key_uncrypted.pem' % (shortHostName, shortHostName),
certificateFile = '/home/manou/ssl-certificates/servers/%s/%s_entrouvert.crt' % (shortHostName, shortHostName),
peerCaCertificateFile = '/home/manou/ssl-certificates/certification-authorities/entrouvert_and_vandoeuvre-les-nancy_ca.crt')
else:
# Use HTTP protocol.
connection = httplib.HTTPConnection(idpHostName)
connection.request(
'POST',
idpPath,
requestSoapMessage,
headers)
responseSoapMessageFile = connection.getresponse()
responseSoapMessage = responseSoapMessageFile.read()
try:
responseXml = lasso.Soap.extractFromMessage(
responseSoapMessage)
except: # FIXME
raise responseSoapMessage
responseDom = parseString(responseXml)
response = importFromNode(responseDom, 1)
else:
# FIXME: Is this needed? Can idp directly return a status?
response = buildStatusFromKeywords(keywords)
statusCode = response.getStatusCode()
if statusCode != 'success':
layout = X.array()
layout += X.p(_class = 'alert')(
_('Liberty Alliance authentication assertion request'
' failed (reason = %s)') % statusCode)
return writePageLayout(layout, _('Failure'), canCache = 0)
assertion = response.getAssertion()
idpNameIdentifier = assertion.getIDPProvidedNameIdentifier()
nameIdentifier = assertion.getNameIdentifier()
if nameIdentifier and nameIdentifier != idpNameIdentifier:
try:
userToken = self.checkIdentityLocalNameIdentifier(
identityProviderHostName, nameIdentifier)
except faults.WrongNameIdentifier:
userToken = None
else:
try:
userToken = self.checkIdentityPeerNameIdentifier(
identityProviderHostName, idpNameIdentifier)
except faults.WrongNameIdentifier:
userToken = None
nextUri = relayState
if nextUri:
canUseCookie = context.getVar('canUseCookie', default = 0)
if not canUseCookie:
sessionToken = context.getVar('sessionToken')
nextUri = appendToUri(nextUri,
'sessionToken=' + sessionToken)
else:
nextUri = X.rootUrl()
session = context.getVar('session')
session['authenticationMethod'] = assertion.getAuthenticationMethod()
session['isDirty'] = 1
if userToken is None:
user = Identity()
user.language = context.getVar('readLanguages')[0]
identification = Identification()
if nameIdentifier and nameIdentifier != idpNameIdentifier:
identification.localNameIdentifier = nameIdentifier
identification.peerHostName = identityProviderHostName
identification.peerNameIdentifier = idpNameIdentifier
user.identityIdentifications = [identification]
userId = self.addObject(user)
if nameIdentifier and nameIdentifier != idpNameIdentifier:
userToken = self.checkIdentityLocalNameIdentifier(
identityProviderHostName, nameIdentifier)
else:
userToken = self.checkIdentityPeerNameIdentifier(
identityProviderHostName, idpNameIdentifier)
session['userToken'] = userToken
context.setVar('userToken', userToken)
context.setVar('userId', userId)
context.setVar('user', user)
context.push(_level = 'processAuthenticationResponse',
nextUri = nextUri)
try:
return self.newPerson()
finally:
context.pull(_level = 'processAuthenticationResponse')
context.setVar('userToken', userToken)
userId = self.getUserId()
user = None
if userId:
try:
user = self.getObject(userId)
except faults.MissingItem:
pass
if user is None:
userToken = ''
userId = None
if session.has_key('userToken'):
del session['userToken']
else:
session['userToken'] = userToken
session['isDirty'] = 1
context.setVar('userToken', userToken)
context.setVar('userId', userId)
context.setVar('user', user)
return redirect(nextUri)
processAuthenticationResponse.isPublicForWeb = 1
def processSoapRequest(self):
"""Liberty Alliance Identity Provider SOAP Request Processing Method.
"""
requestSoapMessage = context.getVar('xmlPostRaw') # FIXME: Use xmlPost.
requestXml = lasso.Soap.extractFromMessage(requestSoapMessage)
requestDom = parseString(requestXml)
request = importFromNode(requestDom, 1)
artifact = request.samlp_AssertionArtifact[0].PCDATA
assertionsProxy = getProxyForServerRole('assertions')
try:
assertionXml = assertionsProxy.getAssertion(artifact)
except faults.WrongArtifact:
# FIXME: Is it the proper way ton signal an error?
# I believe the good solution is to call buildResponse without any
# assertion => buildStatus should be modified.
response = sso.buildStatus('requestDenied') # FIXME
except:
# FIXME: Is it the proper way ton signal an error?
# I believe the good solution is to call buildResponse without any
# assertion => buildStatus should be modified.
response = sso.buildStatus('requestDenied') # FIXME
else:
assertionDom = parseString(assertionXml)
assertion = importFromNode(assertionDom, 1)
response = sso.buildResponse('success', assertion)
responseSoapMessage = lasso.Soap.buildMessage(
response.exportToString())
req = context.getVar('req')
req.content_type = 'text/xml'
req.send_http_header()
req.write(responseSoapMessage)
return OK
processSoapRequest.isPublicForWeb = 1

View File

@ -904,7 +904,6 @@ class ObjectsWebMixin(AdministrableWebMixin):
if context.getVar('debug'): if context.getVar('debug'):
raise raise
return accessForbidden() # TODO: return failure ? return accessForbidden() # TODO: return failure ?
if result: if result:
return result return result

View File

@ -0,0 +1,191 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Password Accounts Web"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.ObjectsCommon as commonObjects
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
import glasnost.proxy.PasswordAccountsProxy as proxyPasswordAccounts
import ObjectsWeb as objects
from tools import accessForbidden, getWebForServerRole, writePageLayout
class AdminPasswordAccounts(objects.AdminMixin,
proxyPasswordAccounts.AdminPasswordAccounts):
pass
objects.register(AdminPasswordAccounts)
class Login(objects.ObjectWebMixin, commonObjects.ObjectCommon):
id_kindName = None
language_kindName = None
login = None
class login_kindClass:
_kindName = 'String'
balloonHelp = N_('Enter the username you use on this site.')
isRequired = 1
isTranslatable = 0
label = N_('Username')
textMaxLength = 40
widget_size = 15
password = None
class password_kindClass:
_kindName = 'Password'
balloonHelp = N_('Enter your secret password.')
isRequired = 1
label = N_('Password')
textMaxLength = 15
widget_size = 15
class PasswordAccount(objects.ObjectWebMixin,
proxyPasswordAccounts.PasswordAccount):
## skipPassword = 1
## def getEditLayoutSlotNames(self, fields, parentSlot = None):
## slotNames = objects.ObjectWebMixin.getEditLayoutSlotNames(self,
## fields, parentSlot = parentSlot)
## if self.skipPassword:
## slotNames.remove('password')
## return slotNames
pass
objects.register(PasswordAccount)
class PasswordAccountsWeb(objects.ObjectsWebMixin,
proxyPasswordAccounts.PasswordAccountsProxy):
def login(self):
object = Login()
return self.loginObject(object)
login.isPublicForWeb = 1
def loginObject(self, object):
req = context.getVar('req')
req.headers_out['Cache-Control'] = 'no-cache, must-revalidate'
## object.skipPassword = 0
context.push(_level = 'loginObject', layoutMode = 'edit')
try:
layout = X.array()
if context.getVar('error'):
layout += object.getErrorLayout()
# The instruction submitUrl = X.actionUrl('loginSubmit')
# doesn't work because the login method can be called from
# IdentitiesWeb.
submitUrl = X.roleUrl(self.serverRole, action = 'loginSubmit')
if context.getVar('virtualHost').useHTTPS:
hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'),
context.getVar('httpPort'))
submitUrl = 'https://%s%s' % (hostNameAndPort, submitUrl)
form = X.form(action = submitUrl, enctype = 'multipart/form-data',
method = 'post')
layout += form
if context.getVar('nextUri'):
form += X.div(X.input(name = 'nextUri', type = 'hidden',
value = context.getVar('nextUri')))
form += object.getEditLayout(fields = None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
buttonsBar += X.buttonInForm('login', 'loginButton')
## if 1: # TODO: check if emailPassword is available
## buttonsBar += X.buttonInForm(
## 'send-password-by-email', 'sendButton')
return writePageLayout(layout, _('Login'))
finally:
context.pull(_level = 'loginObject')
def loginSubmit(self, **keywords):
if keywords is None:
keywords = {}
## sendPasswordByEmail = isButtonSelected('sendButton', keywords)
object = Login()
object.submitFields(keywords)
if context.getVar('again'):
return self.loginObject(object)
## if sendPasswordByEmail:
## try:
## self.emailPassword(object)
## except:
## return failure(_('An error occured while sending the password.'),
## X.rootUrl())
## return success(_('The password has been sent successfully.'), X.rootUrl())
try:
userToken = self.checkObjectAuthentication(
object.login, object.password)
except faults.WrongLogin, fault:
context.getVar('error', 1)
object.setError('self.login', fault)
return self.loginObject(object)
except faults.WrongPassword, fault:
context.getVar('error', 1)
object.setError('self.password', fault)
return self.loginObject(object)
except:
if context.getVar('debug'):
raise
return accessForbidden()
identitiesWeb = getWebForServerRole('identities')
return identitiesWeb.loginSucceeded(userToken, 'password')
loginSubmit.isPublicForWeb = 1

View File

@ -92,9 +92,6 @@ class Person(ObjectWebMixin, Person):
nickname_kind_widget_size = 40 nickname_kind_widget_size = 40
nickname_kind_widgetName = 'InputText' nickname_kind_widgetName = 'InputText'
voteTokens_kind_stateInEditMode = 'hidden'
voteTokens_kind_stateInViewMode = 'hidden'
def getEditLayout(self, fields, parentSlot = None): def getEditLayout(self, fields, parentSlot = None):
if context.getVar('userId') != self.id: if context.getVar('userId') != self.id:
return ObjectWebMixin.getEditLayout(self, fields, parentSlot) return ObjectWebMixin.getEditLayout(self, fields, parentSlot)
@ -147,7 +144,6 @@ register(Person)
class PeopleWeb(ObjectsWebMixin, PeopleProxy): class PeopleWeb(ObjectsWebMixin, PeopleProxy):
def getObject_handleResult(self, lazyObject): def getObject_handleResult(self, lazyObject):
object = PeopleProxy.getObject_handleResult(self, lazyObject) object = PeopleProxy.getObject_handleResult(self, lazyObject)
groupsProxy = getProxyForServerRole('groups') groupsProxy = getProxyForServerRole('groups')
@ -165,65 +161,6 @@ class PeopleWeb(ObjectsWebMixin, PeopleProxy):
cmp(labels[id1], labels[id2])) cmp(labels[id1], labels[id2]))
return ids return ids
def getViewAboveButtonsBarLayout(self, object, fields):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
layout = X.array()
layout += ObjectsWebMixin.getViewAboveButtonsBarLayout(
self, object, fields)
def getVotesSectionLayout(person, votes, elections, intertitle):
layout = None
if len(elections) > 0:
layout = X.array( X.h3()(intertitle) )
layout += X.br()
table = X.table()
layout += table
for election in elections:
if not person.id in election.getVoterIds():
continue
tr = X.tr(X.th(scope = 'row')(
X.a(href = X.idUrl(election.id))(
election.getLabelTranslated(
context.getVar('readLanguages')))))
table += tr
if not votes.has_key(election.id):
tr += X.td(_('Abstention'))
else:
vote = votes[election.id]
if vote == 'secret':
tr += X.td(_('Secret Ballot'))
else:
tr += X.td(X.a(href = X.idUrl(vote.id))(
X.asIs(vote.getLabelLine(election))))
return layout
userId = context.getVar('userId', default = '')
knownRoles = context.getVar('knownRoles')
if userId and 'ballots' in knownRoles and 'elections' in knownRoles:
# Only an identified user can see someone's votes.
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
votes = ballotsWeb.getVotesFromTokens(object.voteTokens)
try:
lastElections = electionsWeb.getLastObjectsWithVoter(
50, object.id, ['running'])
except faults.UserAccessDenied:
lastElections = []
layout += getVotesSectionLayout(
object, votes, lastElections,
_("""The votes for the elections in progress"""))
try:
lastElections = electionsWeb.getLastObjectsWithVoter(
10, object.id, ['closed'])
except faults.UserAccessDenied:
lastElections = []
layout += getVotesSectionLayout(
object, votes, lastElections,
_("""The votes for the closed elections"""))
return layout
def submitAddObject(self, object): def submitAddObject(self, object):
error = 0 error = 0
try: try:
@ -282,8 +219,8 @@ class PeopleWeb(ObjectsWebMixin, PeopleProxy):
layout = X.array() layout = X.array()
layout += X.asIs(_("""<p> layout += X.asIs(_("""<p>
Note that user accounts should now be created from the Note that user accounts should now be created from the
<a href="%s">authentication page</a>. <a href="%s">identities page</a>.
</p>""") % X.roleUrl('authentication')) </p>""") % X.roleUrl('identities'))
ids = self.getSortedIds(partialObjects) ids = self.getSortedIds(partialObjects)
layout += self.getObjectsLayout(partialObjects, ids, []) layout += self.getObjectsLayout(partialObjects, ids, [])
layout += self.getViewAllButtonsBarLayout() layout += self.getViewAllButtonsBarLayout()

View File

@ -79,9 +79,6 @@ class Preference(ObjectWebMixin, Preference):
currency_kind_widget_labels = accounting.currencyLabels currency_kind_widget_labels = accounting.currencyLabels
currency_kind_widgetName = 'Select' currency_kind_widgetName = 'Select'
objectsMemory_kind_stateInEditMode = 'hidden'
objectsMemory_kind_stateInViewMode = 'hidden'
spellcheckEntries_kind_defaultValue = 1 spellcheckEntries_kind_defaultValue = 1
spellcheckEntries_kind_widget_fieldLabel = N_('Spellcheck Entries') spellcheckEntries_kind_widget_fieldLabel = N_('Spellcheck Entries')
spellcheckEntries_kind_widget_labels = { spellcheckEntries_kind_widget_labels = {

109
shared/web/ProvidersWeb.py Normal file
View File

@ -0,0 +1,109 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost Providers Web"""
__version__ = '$Revision$'[11:-2]
import glasnost.common.tools_new as commonTools
import glasnost.proxy.ProvidersProxy as proxyProviders
import ObjectsWeb as objects
class AdminProviders(objects.AdminMixin, proxyProviders.AdminProviders):
pass
objects.register(AdminProviders)
class ProviderMixin(objects.ObjectWebMixin):
className = None
class className_kindClass:
_kindName = 'Choice'
defaultValue = 'IdentityProvider'
importExport = 'private'
isRequired = 1
isRequiredInEditMode = 1
values = [
'IdentityProvider',
'ServiceProvider',
]
widget_apply = 1
widget_fieldLabel = N_('Type')
widget_labels = {
'IdentityProvider': N_('Identity Provider'),
'ServiceProvider': N_('Service Provider'),
}
class IdentityProvider(ProviderMixin, proxyProviders.IdentityProvider):
pass
objects.register(IdentityProvider)
class ServiceProvider(ProviderMixin, proxyProviders.ServiceProvider):
pass
objects.register(ServiceProvider)
class ProvidersWeb(objects.ObjectsWebMixin, proxyProviders.ProvidersProxy):
def getObject_handleResult(self, lazyObject):
object = proxyProviders.ProvidersProxy.getObject_handleResult(
self, lazyObject)
object.className = object.__class__.__name__
return object
def newObject(self, fields = None):
provider = IdentityProvider() # Fake provider to get className.
if not fields:
provider.className = 'IdentityProvider'
return provider
classNameSlot = provider.getSlot('className')
className = classNameSlot.getWidget().submit(classNameSlot, fields)
if not className:
className = 'IdentityProvider'
provider = commonTools.newThing('object', 'providers.%s' % className)
provider.className = className
return provider

View File

@ -369,7 +369,7 @@ class VoteMixin(ObjectWebMixin):
voterId_kind_hasToSubmitField = 0 voterId_kind_hasToSubmitField = 0
voterId_kind_stateInEditMode = 'read-only' voterId_kind_stateInEditMode = 'read-only'
voterId_kindName = 'Id' voterId_kindName = 'Id'
voterId_kind_serverRoles = ['people'] voterId_kind_serverRoles = ['identities']
voterId_kind_widget_fieldLabel = N_('Voter') voterId_kind_widget_fieldLabel = N_('Voter')
voterId_kind_widgetName = 'SelectId' voterId_kind_widgetName = 'SelectId'
@ -694,7 +694,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
def edit(self, id = '', electionId = ''): def edit(self, id = '', electionId = ''):
ballotsWeb = getWebForServerRole('ballots') ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections') electionsWeb = getWebForServerRole('elections')
peopleWeb = getWebForServerRole('people') identitiesWeb = getWebForServerRole('identities')
userId = context.getVar('userId', default = '') userId = context.getVar('userId', default = '')
userToken = context.getVar('userToken', default = '') userToken = context.getVar('userToken', default = '')
if not userToken: if not userToken:
@ -721,7 +721,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
return accessForbidden() return accessForbidden()
election = electionsWeb.getObject(electionId) election = electionsWeb.getObject(electionId)
rememberObject(electionId) rememberObject(electionId)
voter = peopleWeb.getObject(userId) voter = identitiesWeb.getObject(userId)
if voter.voteTokens is not None \ if voter.voteTokens is not None \
and voter.voteTokens.has_key(electionId): and voter.voteTokens.has_key(electionId):
voteToken = voter.voteTokens[electionId] voteToken = voter.voteTokens[electionId]
@ -826,7 +826,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
def view(self, id = '', electionId = '', voterId = ''): def view(self, id = '', electionId = '', voterId = ''):
ballotsWeb = getWebForServerRole('ballots') ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections') electionsWeb = getWebForServerRole('elections')
peopleWeb = getWebForServerRole('people') identitiesWeb = getWebForServerRole('identities')
userId = context.getVar('userId', default = '') userId = context.getVar('userId', default = '')
if id: if id:
vote = ballotsWeb.getVote(id) vote = ballotsWeb.getVote(id)
@ -851,15 +851,15 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
or not electionsWeb.hasObject(electionId): or not electionsWeb.hasObject(electionId):
return pageNotFound() return pageNotFound()
if not voterId \ if not voterId \
or not peopleWeb.hasObject(voterId): or not identitiesWeb.hasObject(voterId):
return pageNotFound() return pageNotFound()
if not electionsWeb.canGetObject(electionId): if not electionsWeb.canGetObject(electionId):
return accessForbidden() return accessForbidden()
if not peopleWeb.canGetObject(voterId): if not identitiesWeb.canGetObject(voterId):
return accessForbidden() return accessForbidden()
election = electionsWeb.getObject(electionId) election = electionsWeb.getObject(electionId)
rememberObject(electionId) rememberObject(electionId)
voter = peopleWeb.getObject(voterId) voter = identitiesWeb.getObject(voterId)
if voter.voteTokens is not None \ if voter.voteTokens is not None \
and voter.voteTokens.has_key(electionId): and voter.voteTokens.has_key(electionId):
voteToken = voter.voteTokens[electionId] voteToken = voter.voteTokens[electionId]

View File

@ -0,0 +1,125 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@entrouvert.com>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
__doc__ = """Glasnost X509 Accounts Web"""
__version__ = '$Revision$'[11:-2]
import os
from mod_python import apache
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.ObjectsCommon as commonObjects
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
import glasnost.proxy.X509AccountsProxy as proxyX509Accounts
import ObjectsWeb as objects
from tools import accessForbidden, getWebForServerRole, writePageLayout
class AdminX509Accounts(objects.AdminMixin,
proxyX509Accounts.AdminX509Accounts):
pass
objects.register(AdminX509Accounts)
class X509Account(objects.ObjectWebMixin,
proxyX509Accounts.X509Account):
pass
objects.register(X509Account)
class X509AccountsWeb(objects.ObjectsWebMixin,
proxyX509Accounts.X509AccountsProxy):
def returnToRetryPage(self, stringError):
req = context.getVar('req')
req.headers_out['Cache-Control'] = 'no-cache, must-revalidate'
context.push(_level = 'returnToRetryPage', layoutMode = 'edit')
try:
context.push(_level = 'login', layoutMode = 'edit')
layout = X.array()
submitUrl = X.roleUrl(self.serverRole, action = 'login')
form = X.form(action = submitUrl,
enctype = 'multipart/form-data',
method = 'post')
layout += form
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
buttonsBar += X.buttonInForm('retry', 'retryButton')
return writePageLayout(layout, _(stringError))
finally:
context.pull(_level = 'returnToRetryPage')
def login(self):
serial = None
req = context.getVar('req')
env = apache.build_cgi_env(req)
try:
sslClientVerify = env['SSL_CLIENT_VERIFY']
except KeyError:
return self.returnToRetryPage(_('SSL not activated'))
if sslClientVerify != 'SUCCESS':
return self.returnToRetryPage(_(
'Client certificate verification error'))
else:
serial = env['SSL_CLIENT_M_SERIAL']
try:
userToken = self.checkObjectAuthentication(serial)
except faults.WrongX509Serial:
return self.returnToRetryPage(_(
'Unknown certificate serial number = %s' % serial))
except:
if context.getVar('debug'):
raise
return accessForbidden()
identitiesWeb = getWebForServerRole('identities')
return identitiesWeb.loginSucceeded(userToken, 'softwarePki')
login.isPublicForWeb = 1

View File

@ -151,8 +151,8 @@ def accessForbidden(dontAskForLogin = 0):
cleanedUpUri = cleanUpUnparsedUri([], 'http') cleanedUpUri = cleanUpUnparsedUri([], 'http')
cleanedUpUri = cleanedUpUri.replace('/people/submit', '/').replace( cleanedUpUri = cleanedUpUri.replace('/people/submit', '/').replace(
'/index.py', '/') '/index.py', '/')
loginUrl = X.roleUrl('login').add('nextUri', cleanedUpUri).add( loginUrl = X.roleUrl('identities', action = 'login').add(
'access', 'forbidden') 'nextUri', cleanedUpUri).add('access', 'forbidden')
hostNameAndPort = commonTools.makeHttpHostNameAndPort( hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'), context.getVar('httpHostName'),
context.getVar('httpPort')) context.getVar('httpPort'))
@ -364,10 +364,8 @@ def redirectPermanently(url):
def rememberObject(id): def rememberObject(id):
preferencesWeb = getWebForServerRole('preferences') identitiesWeb = getWebForServerRole('identities')
if not preferencesWeb: identitiesWeb.rememberId(id)
return
preferencesWeb.rememberId(id)
def repairMimeType(fieldValue, fileName): def repairMimeType(fieldValue, fileName):
@ -582,7 +580,8 @@ def getTemplateVars():
cleanedUpUri = cleanUpUnparsedUri([]) cleanedUpUri = cleanUpUnparsedUri([])
cleanedUpUri = cleanedUpUri.replace('/people/submit', '/').replace( cleanedUpUri = cleanedUpUri.replace('/people/submit', '/').replace(
'/index.py', '/') '/index.py', '/')
loginUrl = X.roleUrl('login').add('nextUri', cleanedUpUri) loginUrl = X.roleUrl('identities', action = 'login').add(
'nextUri', cleanedUpUri)
hostNameAndPort = commonTools.makeHttpHostNameAndPort( hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'), context.getVar('httpHostName'),
context.getVar('httpPort')) context.getVar('httpPort'))
@ -592,7 +591,7 @@ def getTemplateVars():
'nameAndQuery': loginUrl, 'nameAndQuery': loginUrl,
} }
logoutUrl = X.roleUrl('authentication', 'logout') logoutUrl = X.roleUrl('identities', action = 'logout')
httpScriptDirectoryPath = context.getVar('httpScriptDirectoryPath') httpScriptDirectoryPath = context.getVar('httpScriptDirectoryPath')
@ -600,15 +599,15 @@ def getTemplateVars():
aboutUrl = X.roleUrl('about').getAsUrl() aboutUrl = X.roleUrl('about').getAsUrl()
logoutButton = X.buttonStandalone('logout', logoutUrl).getAsXml() logoutButton = X.buttonStandalone('logout', logoutUrl).getAsXml()
prefsButton = X.buttonStandalone('prefs', X.roleUrl('preferences') if userId:
).getAsXml() prefsButton = X.buttonStandalone('prefs', X.idUrl(userId)).getAsXml()
prefsUrl = X.roleUrl('preferences').getAsUrl() prefsUrl = X.idUrl(userId).getAsUrl()
loginButton = X.buttonStandalone('login', loginUrl).getAsXml() loginButton = X.buttonStandalone('login', loginUrl).getAsXml()
# FIXME: should take the favourite authentication method # FIXME: should take the favourite identities method
newAccountUrl = X.roleUrl('authentication-login-password', 'newAccount') newAccountUrl = X.roleUrl('identities', action = 'newAccount')
newAccountButton = X.buttonStandalone( newAccountButton = X.buttonStandalone(
'new-account', newAccountUrl).getAsXml() 'new-account', newAccountUrl).getAsXml()
newAccountUrl = newAccountUrl.getAsUrl() newAccountUrl = newAccountUrl.getAsUrl()

View File

@ -1514,8 +1514,9 @@ class SelectId(WidgetMixin, proxyWidgets.SelectId):
layout += X.menuIds( layout += X.menuIds(
serverRoles, attributes = selectAttributes, serverRoles, attributes = selectAttributes,
fieldValue = fieldValue, fullRoles = showFullList, menus = menus, fieldValue = fieldValue, fullRoles = showFullList,
noneLabel = self.noneLabel, permanentIds = kind.permanentIds) menus = menus, noneLabel = self.noneLabel,
permanentIds = kind.permanentIds)
if showOthersButton: if showOthersButton:
roles = [] roles = []
for role in serverRoles: for role in serverRoles:
@ -1690,12 +1691,12 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
formattedText = parsers.makeHtmlFromUnformattedText( formattedText = parsers.makeHtmlFromUnformattedText(
fieldValue) fieldValue)
formattedText = replaceSpecialTags(formattedText) formattedText = replaceSpecialTags(formattedText)
preferences = context.getVar('preferences') user = context.getVar('user')
if (not preferences or preferences.spellcheckEntries) and \ if user is not None and user.spellcheckEntries \
slot.getObject().hasSlotName('language'): and slot.getObject().hasSlotName('language'):
languageSlot = slot.getObject().getSlot('language') languageSlot = slot.getObject().getSlot('language')
formattedText = spellcheck(formattedText, formattedText = spellcheck(formattedText,
languageSlot.getValue()) languageSlot.getValue())
if formattedText: if formattedText:
layout += X.div(_class = 'preview')(X.asIs(formattedText)) layout += X.div(_class = 'preview')(X.asIs(formattedText))

View File

@ -69,7 +69,7 @@ class BuildCase01_generalPublicGroup(unittest.TestCase):
"""Build the general public group.""" """Build the general public group."""
group = groups.GroupAll() group = groups.GroupAll()
group.acceptedRoles = ['people', 'ldappeople'] group.acceptedRoles = ['identities']
group.language = 'en' group.language = 'en'
group.name = N_('General Public') group.name = N_('General Public')
## group.itemIds = [system.generalPublicId] ## group.itemIds = [system.generalPublicId]
@ -82,7 +82,7 @@ class BuildCase01_generalPublicGroup(unittest.TestCase):
"""Build the logged users group.""" """Build the logged users group."""
group = groups.GroupRole() group = groups.GroupRole()
group.acceptedRoles = [ 'people', 'ldappeople' ] group.acceptedRoles = ['identities']
group.language = 'en' group.language = 'en'
group.name = N_('Logged Users') group.name = N_('Logged Users')
groupId = groupsProxy.addObject(group) groupId = groupsProxy.addObject(group)

View File

@ -1,5 +1,4 @@
<script metal:define-macro="formScript" <script metal:define-macro="formScript" type="text/javascript">
tal:condition="user" type="text/javascript">
function selectOthers(tdHere, url) function selectOthers(tdHere, url)
{ {
var selectBox = tdHere.getElementsByTagName('select')[0]; var selectBox = tdHere.getElementsByTagName('select')[0];

View File

@ -48,7 +48,7 @@ class AllGroupsTestCase(GroupsTestCase):
set = [system.generalPublicId] set = [system.generalPublicId]
self.failUnlessRaises( self.failUnlessRaises(
faults.UncountableGroup, Groups.getSetContainedIds, faults.UncountableGroup, Groups.getSetContainedIds,
set, ['people'], raiseWhenUncountable = 1) set, ['identities'], raiseWhenUncountable = 1)
class UnionGroupsTestCase(GroupsTestCase): class UnionGroupsTestCase(GroupsTestCase):