From bca6369b4174ee032cb982ad88dbb7e61b239e74 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Mon, 17 Apr 2006 19:20:14 +0000 Subject: [PATCH] SessionManager and client-server communication implemented git-svn-id: file:///home/www/usr01/svn/gnuviechadmin/gnuviech.info/gnuviechadmin/trunk@185 a67ec6bc-e5d5-0310-a910-815c51eb3124 --- backend/GnuviechAdmin/DomainManager.py | 3 + backend/GnuviechAdmin/ServiceFacade.py | 38 +++++++++--- backend/GnuviechAdmin/SessionManager.py | 78 +++++++++++++++++++------ backend/GnuviechAdmin/Settings.py | 1 - backend/xmlrpcserver.py | 24 +++++--- frontend/common/xmlrpcclient.py | 10 +++- 6 files changed, 118 insertions(+), 36 deletions(-) diff --git a/backend/GnuviechAdmin/DomainManager.py b/backend/GnuviechAdmin/DomainManager.py index 635d557..1885263 100644 --- a/backend/GnuviechAdmin/DomainManager.py +++ b/backend/GnuviechAdmin/DomainManager.py @@ -6,6 +6,9 @@ from SessionManager import Session class DomainManager: + def __init__(self, dbconn): + self._dbconn = dbconn + def listDomains(self, session): if isinstance(session, Session): return 'a,b,c' diff --git a/backend/GnuviechAdmin/ServiceFacade.py b/backend/GnuviechAdmin/ServiceFacade.py index 253d137..5412752 100644 --- a/backend/GnuviechAdmin/ServiceFacade.py +++ b/backend/GnuviechAdmin/ServiceFacade.py @@ -7,13 +7,33 @@ from SessionManager import * from DomainManager import * class ServiceFacade: - def __init__(self): - self.sessionManager = SessionManager() - self.domainManager = DomainManager() """ This class implements the facade to the services provided by the gnuviech admin backend. """ + def __init__(self): + self.sessionManager = SessionManager(None) + self.domainManager = DomainManager(None) + + def _dispatch(self, method, params): + try: + func = getattr(self, method) + except AttributeError: + raise Exception('method "%s" is not supported' % method) + else: + if method != 'login' and method != 'logout': + sessionid = params[0] + try: + session = self.sessionManager.getSession(sessionid) + except InvalidSessionError: + return "" + nparams = [session] + for item in params[1:]: + nparams.append(item) + params = nparams + self.sessionManager.updateSession(sessionid) + return func(*params) + def login(self, login, password): """ Logs in the user specified by the given login and password. @@ -26,12 +46,12 @@ class ServiceFacade: except InvalidLoginError, ile: return 0 - def listdomains(self, sessionid): + def logout(self, sessionid): + self.sessionManager.deleteSession(sessionid) + return 0 + + def listdomains(self, session): """ Lists the domains the given session may see. """ - try: - session = self.sessionManager.getSession(sessionid) - return self.domainManager.listDomains(session) - except InvalidSessionError, ise: - return "" + return self.domainManager.listDomains(session) diff --git a/backend/GnuviechAdmin/SessionManager.py b/backend/GnuviechAdmin/SessionManager.py index 6a4f9c6..3197320 100644 --- a/backend/GnuviechAdmin/SessionManager.py +++ b/backend/GnuviechAdmin/SessionManager.py @@ -1,37 +1,81 @@ -# -# Session manager class for gnuviech-admin tool backend -# (c) 2006 Jan Dittberner -# $Id$ -# +""" +Session manager class for gnuviech-admin tool backend +(c) 2006 Jan Dittberner +$Id$ +""" import Settings -import os +import os, sha, time, logging +from threading import Timer + +SESSIONTIMEOUT=120 # 2 minutes class InvalidLoginError(Exception): + """ + Exception class for invalid logins. + """ pass class InvalidSessionError(Exception): + """ + Exception class for invalid sessions. + """ pass class Session: - def __init__(self, id, login, rights, uid, gid): + def __init__(self, id, login): self.id = id self.login = login - self.right = rights - self.uid = uid - self.gid = gid + self._timeoutTimer = None + + def settimeoutTimer(self, timeoutTimer): + self._timeoutTimer = timeoutTimer + self._timeoutTimer.start() + + def gettimeoutTimer(self): + return self._timeoutTimer class SessionManager: - def _getSessionFile(self, sessionid): - if os.path.exists(Settings.SESSIONDIR) and \ - os.path.isdir(Settings.SESSIONDIR): - return file(os.path.join(SETTINGS.SESSIONDIR, sessionid)) - return None + def __init__(self, dbconn): + self._sessions = {} + self._dbconn = dbconn + self._hashobj = sha.new(str(time.time())) + self.logger = logging.getLogger('SessionManager') + + def listSessions(self): + return self._sessions.keys() def newSession(self, login, password): - raise InvalidLoginError() + self._hashobj.update("%s,%s" % (time.time(), login)) + sessionid = self._hashobj.hexdigest() + self._sessions[sessionid] = Session(sessionid, login) + self.updateSession(sessionid) + return sessionid + def updateSession(self, sessionid): + self.logger.debug("update session %s" % sessionid) + try: + session = self.getSession(sessionid) + except InvalidSessionError, ev: + pass + else: + if session.gettimeoutTimer() is not None: + session.gettimeoutTimer().cancel() + session.settimeoutTimer(Timer(SESSIONTIMEOUT, self.deleteSession, + args=[sessionid])) + def getSession(self, sessionid): + if self._sessions.has_key(sessionid): + return self._sessions[sessionid] raise InvalidSessionError() def deleteSession(self, sessionid): - self._getSessionFile(sessionid) + self.logger.debug("delete session %s" % sessionid) + try: + session = self.getSession(sessionid) + except InvalidSessionError: + print "invalid session" + else: + if session.gettimeoutTimer() is not None: + session.gettimeoutTimer().cancel() + del(self._sessions[sessionid]) + self.logger.debug("%d sessions remaining" % len(self.listSessions())) diff --git a/backend/GnuviechAdmin/Settings.py b/backend/GnuviechAdmin/Settings.py index ae1c32f..f140770 100644 --- a/backend/GnuviechAdmin/Settings.py +++ b/backend/GnuviechAdmin/Settings.py @@ -19,4 +19,3 @@ WEBHOME = ALLPREFIX + '/home/www/' USERPREFIX = 'usr' GNUVIECHADMINDIR = ALLPREFIX + '/var/lib/gnuviechadmin' -SESSIONDIR = GNUVIECHADMINDIR + '/sessions' diff --git a/backend/xmlrpcserver.py b/backend/xmlrpcserver.py index c5a5b5c..edb8b46 100755 --- a/backend/xmlrpcserver.py +++ b/backend/xmlrpcserver.py @@ -6,16 +6,24 @@ # from DocXMLRPCServer import DocXMLRPCServer from GnuviechAdmin import ServiceFacade +import logging def startRPCServer(): - server = DocXMLRPCServer(("localhost", 8080)) - server.register_introspection_functions() - server.register_instance(ServiceFacade()) + address = ('localhost', 8080) + server = DocXMLRPCServer(address) + server.register_introspection_functions() + server.register_instance(ServiceFacade()) - try: - server.serve_forever() - except KeyboardInterrupt: - server.server_close() + try: + server.serve_forever() + except KeyboardInterrupt: + server.server_close() if __name__ == "__main__": - startRPCServer() + logger = logging.getLogger() + hdlr = logging.FileHandler('xmlrpcserver.log') + f = logging.Formatter('%(asctime)s %(levelname)s %(module)s: %(message)s') + hdlr.setFormatter(f) + logger.addHandler(hdlr) + logger.setLevel(logging.DEBUG) + startRPCServer() diff --git a/frontend/common/xmlrpcclient.py b/frontend/common/xmlrpcclient.py index 7c30337..a62d2e9 100755 --- a/frontend/common/xmlrpcclient.py +++ b/frontend/common/xmlrpcclient.py @@ -11,11 +11,19 @@ if __name__ == '__main__': logger = logging.getLogger() logging.basicConfig() + sessionid = None try: sessionid = server.login('jan', 'heyyou97') if sessionid: - server.listDomains(sessionid) + print "Session %s" % sessionid + print server.listdomains(sessionid) + server.logout(sessionid) else: print "login failed" except Exception, v: logger.exception(v) + if sessionid is not None: + try: + server.logout(sessionid) + except Exception, vn: + logger.exception(vn)