This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
glasnost/servers/IdentitiesServer/IdentitiesServer.py

412 lines
17 KiB
Python
Executable File

#!/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)