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]
ServerPort = %(port)s + 4
[AuthenticationServer]
ServerPort = %(port)s + 5
#authentication# [AuthenticationServer]
#authentication# ServerPort = %(port)s + 5
[AuthenticationLoginPasswordServer]
ServerPort = %(port)s + 6
#authentication# [AuthenticationLoginPasswordServer]
#authentication# ServerPort = %(port)s + 6
#authentication# [AuthenticationLdapServer]
#authentication# ServerPort = %(port)s + 7
@ -137,8 +137,8 @@ ServerPort = %(port)s + 27
[PeopleServer]
ServerPort = %(port)s + 30
[PreferencesServer]
ServerPort = %(port)s + 31
#obsolete# [PreferencesServer]
#obsolete# ServerPort = %(port)s + 31
[RubricsServer]
ServerPort = %(port)s + 32
@ -164,3 +164,17 @@ ServerPort = %(port)s + 38
[VotesServer]
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,
objectId = None,
positionalArguments = None,
preferences = None,
readLanguages = None,
req = req,
sectionLevel = 1,
@ -262,6 +261,7 @@ class Application(applications.Application):
templatesDirectoryPath = None,
templateFileName = None,
templatePrefix = None,
user = None,
userId = '',
userToken = '',
virtualHost = None,
@ -420,7 +420,7 @@ class Application(applications.Application):
except ImportError:
raise apache.SERVER_RETURN, apache.HTTP_NOT_IMPLEMENTED
try:
xmlPost = xml.dom.minidom.parseString(xmlPost)
xmlPost = xml.dom.minidom.parseString(xmlPostRaw)
except: # TODO: tighter check
if context.getVar('debug'):
raise
@ -429,16 +429,26 @@ class Application(applications.Application):
context.setVar('xmlPostRaw', xmlPostRaw)
class FakeFieldStorage:
list = []
fieldStorage = FakeFieldStorage
def keys(self):
return []
fieldStorage = FakeFieldStorage()
fields = {}
for field in fieldStorage.list:
if field.name is not None and not fields.has_key(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])
# This code is commented, because it doesn't work when a field has
# several occurences using the same key. In this case, the key is
# listed several times in fieldStorage.list, but
# fieldStorage[field.name] is already a complete list.
## for field in fieldStorage.list:
## if field.name is not None and not fields.has_key(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 = []
for fieldName, fieldValue in fields.items():
@ -508,21 +518,24 @@ class Application(applications.Application):
context.setVar('sessionTokenInCookie', sessionTokenInCookie)
userToken = ''
userId = None
user = None
if session and session.has_key('userToken') and session['userToken']:
userToken = session['userToken']
context.setVar('userToken', userToken)
userId = getProxyForServerRole('authentication').getUserId()
userId = getWebForServerRole('identities').getUserId()
if userId:
userToken = session['userToken']
else:
userToken = None
try:
user = getWeb(userId).getObject(userId)
except faults.MissingItem:
pass
if user is None:
userToken = ''
userId = None
del session['userToken']
if session.has_key('userId'):
del session['userId']
session['isDirty'] = 1
context.setVar('userId', userId)
context.setVar('userToken', userToken)
context.setVar('userId', userId)
context.setVar('user', user)
if not userToken and req.headers_in.has_key('Authorization'):
authorization = req.headers_in['Authorization']
@ -531,26 +544,15 @@ class Application(applications.Application):
raise apache.SERVER_RETURN, apache.HTTP_NOT_ACCEPTABLE
# 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.
languages = []
if session and session.has_key('lang'):
languages = [session['lang']]
elif preferences is not None and preferences.language \
and preferences.language != 'None':
languages = [preferences.language]
elif req.headers_in.has_key('Accept-Language'):
elif user is not None:
userLanguage = user.getLanguage()
if userLanguage is not None:
languages = [userLanguage]
if not languages and req.headers_in.has_key('Accept-Language'):
try:
languages = req.headers_in['Accept-Language']
languages = languages.split(',')
@ -559,7 +561,7 @@ class Application(applications.Application):
return HTTP_BAD_REQUEST
translationsProxy = getProxyForServerRole('translations')
languages = [language == 'C' and 'en' or language
for language in languages]
for language in languages]
try:
possibleLanguages = translationsProxy.getPossibleLanguages()
except (faults.UnknownServerId, faults.UnknownDispatcherInId):

View File

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

View File

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

View File

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

View File

@ -86,50 +86,6 @@ class Appointment(ObjectServerMixin, AppointmentCommon):
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):
useAdminWritersSet = 1
@ -150,15 +106,15 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
if not participantIds or participantIds == ['']:
participantIds = []
authenticationProxy = getProxyForServerRole('authentication')
identitiesProxy = getProxyForServerRole('identities')
result = []
for objectId, object in virtualServer.objects.items():
if not (isAdmin
or authenticationProxy.setContainsUser(object.readersSet)
or identitiesProxy.setContainsUser(object.readersSet)
or (object.participantsSet
and getProxyForServerRole('authentication'
).setContainsUser(object.participantsSet))):
and identitiesProxy.setContainsUser(
object.participantsSet))):
continue
if participantIds and not self.isAskedParticipant(
@ -220,8 +176,8 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
def sendNotification(self, virtualServerId, appointment, subject, body):
virtualServer = self.getVirtualServer(virtualServerId)
mailFrom = virtualServer.adminEmailAddress
people = getSetContainedIds(appointment.participantsSet)
for personId in people:
personIds = getSetContainedIds(appointment.participantsSet)
for personId in personIds:
person = getProxyForServerRole('people').getObject(personId)
if person.email:
mailTo = person.email
@ -279,6 +235,52 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
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__":
appointmentsServer.launch(applicationName, applicationRole)

View File

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

View File

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

View File

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

View File

@ -89,7 +89,7 @@ class Comment(ObjectServerMixin, CommentCommon):
def setAutomaticalSlots(self, parentSlot = None):
ObjectServerMixin.setAutomaticalSlots(self, parentSlot = parentSlot)
self.authorId = getProxyForServerRole('authentication').getUserId()
self.authorId = getProxyForServerRole('identities').getUserId()
self.creationTime = time.time()
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))
if not self.isAdmin() and not (
self.useAdminWritersSet
and getProxyForServerRole('authentication').setContainsUser(
and getProxyForServerRole('identities').setContainsUser(
self.getAdminCore().writersSet) and (
getProxyForServerRole('authentication').setContainsUser(
getProxyForServerRole('identities').setContainsUser(
object.writersSet))) \
or object.state != 'draft':
if not object.canBeCreatedByClient():
@ -397,7 +397,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
return 0
object = virtualServer.loadObjectCore(objectId)
isAdmin = self.isAdmin()
if not isAdmin and not getProxyForServerRole('authentication'
if not isAdmin and not getProxyForServerRole('identities'
).setContainsUser(object.writersSet):
return 0
if not isAdmin and object.state != 'draft':
@ -413,7 +413,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
if not object.canBeModified():
return 0
isAdmin = self.isAdmin()
if not isAdmin and not getProxyForServerRole('authentication'
if not isAdmin and not getProxyForServerRole('identities'
).setContainsUser(object.writersSet):
return 0
if not isAdmin and object.state != 'draft':
@ -455,12 +455,14 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
possibleAuthorIds = 'everybody'
try:
possibleReaderIds = getSetContainedIds(
possibleReadersSet, ['people'], raiseWhenUncountable = 1)
possibleReadersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup:
possibleReaderIds = 'everybody'
try:
possibleWriterIds = getSetContainedIds(
possibleWritersSet, ['people'], raiseWhenUncountable = 1)
possibleWritersSet, ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup:
possibleWriterIds = 'everybody'
objectIds = virtualServer.objects.keys()
@ -475,7 +477,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
if possibleStates and not object.state in possibleStates:
continue
if not isAdmin and not getProxyForServerRole(
'authentication').setContainsUser(object.readersSet):
'identities').setContainsUser(object.readersSet):
continue
if not self.getLastObjectIds_filter(
possibleAuthorIds, 1, object.authorsSet):
@ -504,7 +506,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
for objectId in objectIds:
object = virtualServer.loadObjectCore(objectId)
if not self.isAdmin() \
and not getProxyForServerRole('authentication'
and not getProxyForServerRole('identities'
).setContainsUser(object.readersSet):
continue
if possibleStates and not object.state in possibleStates:
@ -540,7 +542,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
if not self.canModifyObject(object.id) or not (
self.isAdmin()
or not objectChanges.hasSlotName('writersSet')
or getProxyForServerRole('authentication'
or getProxyForServerRole('identities'
).setContainsUser(
objectChanges.getSlot('writersSet').getValue())):
if not object.canBeModifiedByClient():
@ -619,7 +621,7 @@ class ElectionsServer(ElectionsCommonMixin, ObjectsServer):
fromAddress = virtualServer.adminEmailAddress
abstentionnistsCount = 0
for voterId in object.getVoterIds(virtualServerId):
voter = getProxyForServerRole('people').getObject(voterId)
voter = getProxyForServerRole('identities').getObject(voterId)
if voter.voteTokens is not None \
and voter.voteTokens.has_key(objectId):
continue

View File

@ -122,8 +122,8 @@ class GroupsServer(commonGroups.GroupsCommonMixin, objects.ObjectsServer):
if not self.isAdmin():
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
if clientRole != 'people':
clientRole = commonTools.extractRole(clientId)
if clientRole != 'identities':
raise faults.UserAccessDenied()
object = virtualServer.loadObjectCore(objectId)
if not isinstance(object, GroupUnion):
@ -155,8 +155,8 @@ class GroupsServer(commonGroups.GroupsCommonMixin, objects.ObjectsServer):
if not self.isAdmin():
clientToken = context.getVar('clientToken')
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole, mu = commonTools.splitId(clientId)
if clientRole != 'people':
clientRole = commonTools.extractRole(clientId)
if clientRole != 'identities':
raise faults.UserAccessDenied()
object = virtualServer.loadObjectCore(objectId)
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):
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):
ObjectServerMixin.checkAddIsPossible(self)
virtualServerId = context.getVar('applicationId')
@ -146,49 +130,6 @@ class Person(ObjectServerMixin, PersonCommon):
if person.fingerprint == changes.fingerprint \
and person.id != changes.id:
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)
@ -234,36 +175,6 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
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):
"""Create a new person on the server.
@ -334,7 +245,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
return 0
object = virtualServer.loadObjectCore(objectId)
return self.isAdmin() \
or getProxyForServerRole('authentication').setContainsUser(
or getProxyForServerRole('identities').setContainsUser(
[object.id])
def canGetObject(self, objectId):
@ -344,7 +255,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
virtualServer = self.getVirtualServer(virtualServerId)
if not virtualServer.canLoadObjectCore(objectId):
return 0
return getProxyForServerRole('authentication').setContainsUser(
return getProxyForServerRole('identities').setContainsUser(
[objectId])
@ -355,7 +266,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
return 0
object = virtualServer.loadObjectCore(objectId)
return self.isAdmin() \
or getProxyForServerRole('authentication').setContainsUser(
or getProxyForServerRole('identities').setContainsUser(
[object.id])
def deleteObject(self, objectId):
@ -409,21 +320,6 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
if object.containsText(text):
foundIds.append(objectId)
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):
"""Retrieve a string in the specified object from its MD5 digest.
@ -474,7 +370,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
result = getStringFromDigest(object.getLabel(), digest)
else:
if not self.isAdmin() and not getProxyForServerRole(
'authentication').setContainsUser([objectId]):
'identities').setContainsUser([objectId]):
raise faults.UserAccessDenied()
result = getStringFromDigest(
eval(path, {'self': object}), digest)
@ -530,7 +426,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
if not object.canBeModified():
raise faults.ReadOnlyObject()
if not self.isAdmin() and not getProxyForServerRole(
'authentication').setContainsUser([object.id]):
'identities').setContainsUser([object.id]):
if not object.canBeModifiedByClient():
raise faults.UserAccessDenied()
object.checkModifyIsPossible(objectChanges)
@ -554,10 +450,7 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
"""Register the people server XML RPs."""
ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('abstainForVote')
self.registerPublicMethod('findObjectIds', self.findObjectIdsXmlRpc)
self.registerPublicMethod('getElectionVoteToken')
self.registerPublicMethod('vote')
def repairVirtualServer(self, virtualServer, version):
"""Handle a descendant compatibily with older server datas.
@ -622,8 +515,8 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
if changed:
virtualServer.markAllAsDirtyFIXME()
def upgrade_0001_0019(self, virtualServer):
ObjectsServer.upgrade_0001_0019(self, virtualServer)
def upgradeVirtualServer_0001_0019(self, virtualServer):
ObjectsServer.upgradeVirtualServer_0001_0019(self, virtualServer)
# Fill empty writersSet slots in admin.
admin = virtualServer.admin
@ -631,38 +524,6 @@ class PeopleServer(PeopleCommonMixin, ObjectsServer):
admin.writersSet = [system.generalPublicId]
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()

View File

@ -104,7 +104,7 @@ class PreferencesServer(Server):
def deleteObject(self):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId()
userId = getProxyForServerRole('identities').getUserId()
virtualServer.lock.acquire()
if virtualServer.objects.has_key(userId):
del virtualServer.objects[userId]
@ -113,7 +113,7 @@ class PreferencesServer(Server):
#invalidateValue(no id!)
def getObject(self):
userId = getProxyForServerRole('authentication').getUserId()
userId = getProxyForServerRole('identities').getUserId()
return self.getObjectByUserId(userId)
def getObjectByUserId(self, userId):
@ -136,47 +136,9 @@ class PreferencesServer(Server):
self.registerPublicMethod('deleteObject')
self.registerPublicMethod('getObject')
self.registerPublicMethod('getObjectByUserId')
self.registerPublicMethod('rememberId')
self.registerPublicMethod('setObject')
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):
changed = 0
if version < 2006:
@ -229,7 +191,7 @@ class PreferencesServer(Server):
def setObject(self, objectChanges):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
userId = getProxyForServerRole('authentication').getUserId()
userId = getProxyForServerRole('identities').getUserId()
version = 0
object = None
if virtualServer.objects.has_key(userId):
@ -253,8 +215,8 @@ class PreferencesServer(Server):
def setObjectForUserId(self, userId, objectChanges):
virtualServerId = context.getVar('applicationId')
peopleProxy = getProxyForServerRole('people')
userTokenId = getProxyForServerRole('authentication').getUserId()
identitiesProxy = getProxyForServerRole('identities')
userTokenId = identitiesProxy.getUserId()
virtualServer = self.getVirtualServer(virtualServerId)
version = 0
object = None
@ -263,7 +225,7 @@ class PreferencesServer(Server):
if object.has_key('version'):
version = object['version']
isAdmin = peopleProxy.isAdmin(serverId = virtualServerId)
isAdmin = identitiesProxy.isAdmin(serverId = virtualServerId)
if not (isAdmin or userTokenId == userId):
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'
dispatcher = None
# Don't forget to also change the value in AuthenticationServer.py.
expirationTime = 120
# Don't forget to also change the value in IdentitiesServer.py.
expirationTime = 120 * 60
class SessionsVirtualServer(VirtualServer):
@ -150,8 +150,8 @@ class SessionsServer(Server):
def getHistory(self):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
peopleProxy = getProxyForServerRole('people')
if not peopleProxy.isAdmin(
identitiesProxy = getProxyForServerRole('identities')
if not identitiesProxy.isAdmin(
serverId = commonTools.extractServerId(virtualServerId)):
raise faults.UserAccessDenied()

View File

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

View File

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

View File

@ -526,7 +526,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
except IOError:
pass
def upgrade_0001_0025(self, virtualServer):
def upgradeVirtualServer_0001_0025(self, virtualServer):
# Repair dissociated objects and objectsByHostName
virtualServer.objectsByHostName = {}
for object in virtualServer.objects.values():
@ -534,7 +534,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.objectsByHostName[object.hostName] = object
virtualServer.markCoreAsDirty()
def upgrade_0001_0027(self, virtualServer):
def upgradeVirtualServer_0001_0027(self, virtualServer):
for object in virtualServer.objects.values():
object.profiles = ['basic', 'cms', 'vote', 'translations']
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_kind_importExport = 'from-server-only'
lastEditorId_kind_serverRoles = ['people']
lastEditorId_kind_serverRoles = ['identities']
lastEditorId_kindName = 'Id'
modificationTime = None

View File

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

View File

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

View File

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

View File

@ -127,8 +127,7 @@ class GroupAbstract(objects.ObjectCommon):
if groupId == system.generalPublicId:
if results.has_key(groupId):
return results[groupId]
if not serverRoles or 'people' in serverRoles or \
'ldappeople' in serverRoles:
if not serverRoles or 'identities' in serverRoles:
smallAndLarge = 'uncountable', 'uncountable'
else:
smallAndLarge = [], []
@ -154,9 +153,8 @@ class GroupAbstract(objects.ObjectCommon):
if groupId == system.generalPublicId:
if results.has_key(groupId):
return results[groupId]
result = not objectId or \
commonTools.extractRole(objectId) in \
('people', 'ldappeople')
result = not objectId \
or commonTools.extractRole(objectId) == 'identities'
results[groupId] = result
return result
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
try:
proxyGroups.getSetContainedIds(
self.readersSet, serverRoles = ['people'],
self.readersSet, serverRoles = ['identities'],
raiseWhenUncountable = 1)
except faults.UncountableGroup:
# 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_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_kind_balloonHelp = N_('Enter the e-mail address.')
email_kind_isRequired = 1
@ -92,8 +103,6 @@ class PersonCommon(ObjectCommon):
firstName_kind_isRequired = 1
firstName_kindName = 'String'
language_kindName = None
lastName = None
lastName_kind_balloonHelp = N_('Enter the last name.')
lastName_kind_isTranslatable = 0
@ -110,13 +119,6 @@ class PersonCommon(ObjectCommon):
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):
return 0
@ -157,6 +159,12 @@ class PersonCommon(ObjectCommon):
return 1
return 0
def getEmail(self):
return self.email
def getFingerprint(self):
return self.fingerprint
def getFullName(self):
"""Return the full person name string.
@ -180,14 +188,6 @@ class PersonCommon(ObjectCommon):
return self.email
return label
def getLabelLanguage(self):
"""Return an empty string."""
return ''
def getLanguage(self):
"""Return an empty string."""
return ''
def getOrderedLayoutSlotNames(self, parentSlot = None):
"""Return the layout slots names sequences.
@ -227,6 +227,9 @@ class PersonCommon(ObjectCommon):
sortString += ' ' + self.firstName
return sortString
def mustCryptEmails(self):
return self.cryptEmails
class PeopleCommonMixin(ObjectsCommonMixin):

View File

@ -92,10 +92,6 @@ class PreferenceCommon(ObjectCommon):
'sv',
]
objectsMemory = None
objectsMemory_kind_importExport = 'from-server-only'
objectsMemory_kindName = 'Memory'
serverRole = 'preferences'
spellcheckEntries = 0
@ -107,7 +103,7 @@ class PreferenceCommon(ObjectCommon):
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = ObjectCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['currency', 'cryptEmails', 'spellcheckEntries', 'objectsMemory']
slotNames += ['currency', 'cryptEmails', 'spellcheckEntries']
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'
readersSet = None
# FIXME: Which of the following lines is correct?
readersSet_defaultValue = [system.generalPublicId]
# readersSet_kind_itemKind_value_defaultValue = system.generalPublicId
readersSet_kindName = 'ReadersSet'
serverRole = 'virtualhosts'

View File

@ -77,7 +77,7 @@ class AbstractVoteCommon(ObjectCommon):
token_kindName = 'Token'
voterId_kind_importExport = 'private'
voterId_kind_serverRoles = ['people']
voterId_kind_serverRoles = ['identities']
voterId_kindName = 'Id'
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))
if self.parameters:
relativeUrl = '%s;%s' % (relativeUrl, self.parameters)
query = '&'.join([ '%s=%s' % (name, urllib.quote(str(value)))
for name, value in self.getArguments()])
expandedArguments = []
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:
query = '%s&%s' % (self.query, query)
elif self.query:

View File

@ -4,7 +4,7 @@
# Glasnost
# By: Odile Bénassy <obenassy@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>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
@ -94,6 +94,10 @@ faultCodeValueTooBig = 41
faultCodeValueTooSmall = 42
faultCodeRoleNotInProfiles = 43
faultCodeUnknownObjectVersion = 44
faultCodeWrongArtifact = 45
faultCodeUnableToChangePasswordStorage = 46
faultCodeWrongNameIdentifier = 47
faultCodeWrongX509Serial = 48
faultCodeUnknownVoteToken = 1000
faultCodeUnknownVoterToken = 1001
@ -448,6 +452,35 @@ class UnknownCommandAction(BaseFault):
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

View File

@ -784,6 +784,24 @@ class BaseKind(things.BaseThing):
defaultValue = self.getDefaultValue(slot)
if defaultValue is not None:
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)
@ -922,6 +940,19 @@ class AbstractSequence(BaseKind):
itemKind = itemSlot.getKind()
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):
defaultValue_kindName = 'Alias'
@ -1633,6 +1664,19 @@ class Id(BaseKind):
if toVersion == 4000:
return repairId(value)
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)
@ -2136,6 +2180,28 @@ class Mapping(BaseKind):
if changed:
return value
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)
@ -2722,7 +2788,7 @@ class UsersSet(Sequence):
itemKind_kind_stateInViewMode = 'hidden'
itemKind_value_permanentIds = [system.generalPublicId,
system.loggedUsersGroupId]
itemKind_value_serverRoles = ['groups', 'people', 'ldappeople']
itemKind_value_serverRoles = ['groups', 'identities']
itemKind_valueName = 'Id'
label = N_('Users')
@ -2734,14 +2800,18 @@ class UsersSet(Sequence):
thingPublicName = N_('Users')
def getDefaultValue(self, slot):
return [context.getVar('userId')]
userId = context.getVar('userId')
if userId:
return [userId]
else:
return None
register(UsersSet)
class AuthorsSet(UsersSet):
balloonHelp = N_('Choose the author(s) for this object.')
containerNames = ['Any', 'Sequence', 'UsersSet']
containerNames = ['Any', 'Sequence']
defaultValue_kindName = 'AuthorsSet'
@ -2750,10 +2820,18 @@ class AuthorsSet(UsersSet):
# FIXME: that's useless since the user may "visit" the group and it will
# be shown nevertheless
itemKind_value_permanentIds = None
itemKind_value_serverRoles = ['groups', 'people']
label = 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)
@ -2837,7 +2915,7 @@ register(Properties)
class ReadersSet(UsersSet):
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']
@ -3326,7 +3404,12 @@ class Thing(Choice):
else:
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)
@ -3531,7 +3614,7 @@ register(TranslatorsSets)
class WritersSet(UsersSet):
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']

View File

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

View File

@ -549,3 +549,35 @@ class BaseThing:
def saveNonCore(self, objectDirectoryPath, parentSlot = None):
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 context
import tools_new as commonTools
is8bit = re.compile("[\x80-\xff]").search
@ -273,9 +272,7 @@ def sendMail(mailFrom, mailTo, mailSubject, mailMessage, mailPerson = None,
The message string to send.
*mailPerson*:
If the Person object has GPG abilities, the Person object has to be
gived in order to test if the mail have to be crypted.
Default: None.
The recipient's person or identity.
*moreHearders*:
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
gpgEncrypted = 0
if mailPerson:
from glasnost.proxy.tools import getProxyForServerRole
preferencesProxy = getProxyForServerRole('preferences')
cryptEmails = preferencesProxy.getPreferenceByUserId(
mailPerson.id).cryptEmails
if mailIdentity:
cryptEmails = mailPerson.mustCryptEmails()
if cryptEmails:
try:
from gpg import Gpg
gpg = Gpg(email = mailPerson.email,
fingerprint = mailPerson.fingerprint)
gpg = Gpg(email = mailPerson.getEmail(),
fingerprint = mailPerson.getFingerprint())
gpg.deleteKey()
gpg.addKey()
mailMessage = gpg.encrypt(mailMessage)

View File

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

View File

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

View File

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

View File

@ -269,13 +269,12 @@ class ElectionMixin(ObjectWebMixin):
def getVotesLayout(self):
ballotsWeb = getWebForServerRole('ballots')
gradesWeb = getWebForServerRole('grades')
peopleWeb = getWebForServerRole('people')
layout = X.array()
userVoteToken = None
userId = context.getVar('userId', default = '')
if userId:
user = peopleWeb.getObject(userId)
userId = context.getVar('userId')
user = context.getVar('user')
if user is not None:
if user.voteTokens is not None \
and user.voteTokens.has_key(self.id):
userVoteToken = user.voteTokens[self.id]
@ -727,15 +726,15 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
layout += ObjectsWebMixin.getViewOtherActionButtonsBarLayout(
self, object, fields)
if object.state == 'running' \
and getProxyForServerRole('authentication').setContainsUser(
and getProxyForServerRole('identities').setContainsUser(
object.votersSet):
layout += X.buttonStandalone(
'vote',
X.roleUrl('votes', 'edit').add('electionId', object.id))
authenticationProxy = getProxyForServerRole('authentication')
identitiesProxy = getProxyForServerRole('identities')
if object.state == 'running' and \
(isAdmin or \
authenticationProxy.setContainsUser(object.writersSet)):
identitiesProxy.setContainsUser(object.writersSet)):
layout += X.buttonStandalone(
'pester-abstentionnists',
X.idUrl(object.id, 'confirmPesterAbstentionnists'))
@ -821,7 +820,7 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
if not self.canGetObjects():
return accessForbidden()
isAdmin = self.isAdmin()
userId = context.getVar('userId', default = '')
userId = context.getVar('userId')
if userId:
userSet = [userId]
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'):
raise
return accessForbidden() # TODO: return failure ?
if 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_widgetName = 'InputText'
voteTokens_kind_stateInEditMode = 'hidden'
voteTokens_kind_stateInViewMode = 'hidden'
def getEditLayout(self, fields, parentSlot = None):
if context.getVar('userId') != self.id:
return ObjectWebMixin.getEditLayout(self, fields, parentSlot)
@ -147,7 +144,6 @@ register(Person)
class PeopleWeb(ObjectsWebMixin, PeopleProxy):
def getObject_handleResult(self, lazyObject):
object = PeopleProxy.getObject_handleResult(self, lazyObject)
groupsProxy = getProxyForServerRole('groups')
@ -165,65 +161,6 @@ class PeopleWeb(ObjectsWebMixin, PeopleProxy):
cmp(labels[id1], labels[id2]))
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):
error = 0
try:
@ -282,8 +219,8 @@ class PeopleWeb(ObjectsWebMixin, PeopleProxy):
layout = X.array()
layout += X.asIs(_("""<p>
Note that user accounts should now be created from the
<a href="%s">authentication page</a>.
</p>""") % X.roleUrl('authentication'))
<a href="%s">identities page</a>.
</p>""") % X.roleUrl('identities'))
ids = self.getSortedIds(partialObjects)
layout += self.getObjectsLayout(partialObjects, ids, [])
layout += self.getViewAllButtonsBarLayout()

View File

@ -79,9 +79,6 @@ class Preference(ObjectWebMixin, Preference):
currency_kind_widget_labels = accounting.currencyLabels
currency_kind_widgetName = 'Select'
objectsMemory_kind_stateInEditMode = 'hidden'
objectsMemory_kind_stateInViewMode = 'hidden'
spellcheckEntries_kind_defaultValue = 1
spellcheckEntries_kind_widget_fieldLabel = N_('Spellcheck Entries')
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_stateInEditMode = 'read-only'
voterId_kindName = 'Id'
voterId_kind_serverRoles = ['people']
voterId_kind_serverRoles = ['identities']
voterId_kind_widget_fieldLabel = N_('Voter')
voterId_kind_widgetName = 'SelectId'
@ -694,7 +694,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
def edit(self, id = '', electionId = ''):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
peopleWeb = getWebForServerRole('people')
identitiesWeb = getWebForServerRole('identities')
userId = context.getVar('userId', default = '')
userToken = context.getVar('userToken', default = '')
if not userToken:
@ -721,7 +721,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
return accessForbidden()
election = electionsWeb.getObject(electionId)
rememberObject(electionId)
voter = peopleWeb.getObject(userId)
voter = identitiesWeb.getObject(userId)
if voter.voteTokens is not None \
and voter.voteTokens.has_key(electionId):
voteToken = voter.voteTokens[electionId]
@ -826,7 +826,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
def view(self, id = '', electionId = '', voterId = ''):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
peopleWeb = getWebForServerRole('people')
identitiesWeb = getWebForServerRole('identities')
userId = context.getVar('userId', default = '')
if id:
vote = ballotsWeb.getVote(id)
@ -851,15 +851,15 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
or not electionsWeb.hasObject(electionId):
return pageNotFound()
if not voterId \
or not peopleWeb.hasObject(voterId):
or not identitiesWeb.hasObject(voterId):
return pageNotFound()
if not electionsWeb.canGetObject(electionId):
return accessForbidden()
if not peopleWeb.canGetObject(voterId):
if not identitiesWeb.canGetObject(voterId):
return accessForbidden()
election = electionsWeb.getObject(electionId)
rememberObject(electionId)
voter = peopleWeb.getObject(voterId)
voter = identitiesWeb.getObject(voterId)
if voter.voteTokens is not None \
and voter.voteTokens.has_key(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 = cleanedUpUri.replace('/people/submit', '/').replace(
'/index.py', '/')
loginUrl = X.roleUrl('login').add('nextUri', cleanedUpUri).add(
'access', 'forbidden')
loginUrl = X.roleUrl('identities', action = 'login').add(
'nextUri', cleanedUpUri).add('access', 'forbidden')
hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'),
context.getVar('httpPort'))
@ -364,10 +364,8 @@ def redirectPermanently(url):
def rememberObject(id):
preferencesWeb = getWebForServerRole('preferences')
if not preferencesWeb:
return
preferencesWeb.rememberId(id)
identitiesWeb = getWebForServerRole('identities')
identitiesWeb.rememberId(id)
def repairMimeType(fieldValue, fileName):
@ -582,7 +580,8 @@ def getTemplateVars():
cleanedUpUri = cleanUpUnparsedUri([])
cleanedUpUri = cleanedUpUri.replace('/people/submit', '/').replace(
'/index.py', '/')
loginUrl = X.roleUrl('login').add('nextUri', cleanedUpUri)
loginUrl = X.roleUrl('identities', action = 'login').add(
'nextUri', cleanedUpUri)
hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'),
context.getVar('httpPort'))
@ -592,7 +591,7 @@ def getTemplateVars():
'nameAndQuery': loginUrl,
}
logoutUrl = X.roleUrl('authentication', 'logout')
logoutUrl = X.roleUrl('identities', action = 'logout')
httpScriptDirectoryPath = context.getVar('httpScriptDirectoryPath')
@ -600,15 +599,15 @@ def getTemplateVars():
aboutUrl = X.roleUrl('about').getAsUrl()
logoutButton = X.buttonStandalone('logout', logoutUrl).getAsXml()
prefsButton = X.buttonStandalone('prefs', X.roleUrl('preferences')
).getAsXml()
prefsUrl = X.roleUrl('preferences').getAsUrl()
if userId:
prefsButton = X.buttonStandalone('prefs', X.idUrl(userId)).getAsXml()
prefsUrl = X.idUrl(userId).getAsUrl()
loginButton = X.buttonStandalone('login', loginUrl).getAsXml()
# FIXME: should take the favourite authentication method
newAccountUrl = X.roleUrl('authentication-login-password', 'newAccount')
# FIXME: should take the favourite identities method
newAccountUrl = X.roleUrl('identities', action = 'newAccount')
newAccountButton = X.buttonStandalone(
'new-account', newAccountUrl).getAsXml()
newAccountUrl = newAccountUrl.getAsUrl()

View File

@ -1514,8 +1514,9 @@ class SelectId(WidgetMixin, proxyWidgets.SelectId):
layout += X.menuIds(
serverRoles, attributes = selectAttributes,
fieldValue = fieldValue, fullRoles = showFullList, menus = menus,
noneLabel = self.noneLabel, permanentIds = kind.permanentIds)
fieldValue = fieldValue, fullRoles = showFullList,
menus = menus, noneLabel = self.noneLabel,
permanentIds = kind.permanentIds)
if showOthersButton:
roles = []
for role in serverRoles:
@ -1690,12 +1691,12 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
formattedText = parsers.makeHtmlFromUnformattedText(
fieldValue)
formattedText = replaceSpecialTags(formattedText)
preferences = context.getVar('preferences')
if (not preferences or preferences.spellcheckEntries) and \
slot.getObject().hasSlotName('language'):
user = context.getVar('user')
if user is not None and user.spellcheckEntries \
and slot.getObject().hasSlotName('language'):
languageSlot = slot.getObject().getSlot('language')
formattedText = spellcheck(formattedText,
languageSlot.getValue())
languageSlot.getValue())
if 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."""
group = groups.GroupAll()
group.acceptedRoles = ['people', 'ldappeople']
group.acceptedRoles = ['identities']
group.language = 'en'
group.name = N_('General Public')
## group.itemIds = [system.generalPublicId]
@ -82,7 +82,7 @@ class BuildCase01_generalPublicGroup(unittest.TestCase):
"""Build the logged users group."""
group = groups.GroupRole()
group.acceptedRoles = [ 'people', 'ldappeople' ]
group.acceptedRoles = ['identities']
group.language = 'en'
group.name = N_('Logged Users')
groupId = groupsProxy.addObject(group)

View File

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

View File

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