from types import StringTypes import random import base64 import time from PLC.Faults import * from PLC.Parameter import Parameter from PLC.Debug import profile from PLC.Storage.AlchemyObject import AlchemyObj from PLC.Persons import Person, Persons from PLC.Nodes import Node, Nodes class Session(AlchemyObj): """ Representation of a row in the sessions table. To use, instantiate with a dict of values. """ tablename = 'sessions' join_tables = ['person_session', 'node_session'] fields = { 'session_id': Parameter(str, "Session key", primary_key=True), 'person_id': Parameter(int, "Account identifier, if applicable"), 'node_id': Parameter(int, "Node identifier, if applicable"), 'expires': Parameter(int, "Date and time when session expires, in seconds since UNIX epoch"), } def validate_expires(self, expires): if expires < time.time(): raise PLCInvalidArgument, "Expiration date must be in the future" return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(expires)) #add_person = Row.add_object(Person, 'person_session') def sync(self, commit = True, insert = None, validate=True): AlchemyObj.sync(commit=commit, validate=validate) if not self.has_key('session_id'): # Before a new session is added, delete expired sessions expired = Sessions(self.api, expires = -int(time.time())) for session in expired: session.delete(commit) # Generate 32 random bytes bytes = random.sample(xrange(0, 256), 32) # Base64 encode their string representation self['session_id'] = base64.b64encode("".join(map(chr, bytes))) # Force insert AlchemyObj.insert(self, dict(self)) class Sessions(list): """ Representation of row(s) from the session table in the database. """ def __init__(self, api, session_filter = None, expires = int(time.time())): if session_filter is not None: sessions = Session().select() if isinstance(session_filter, (list, tuple, set)): # Separate the list into integers and strings ints = filter(lambda x: isinstance(x, (int, long)), session_filter) strs = filter(lambda x: isinstance(x, StringTypes), session_filter) session_filter = {'person_id': ints, 'session_id': strs} sessions = Session().select(filter=session_filter) elif isinstance(session_filter, dict): sessions = Session().select(filter=session_filter) elif isinstance(session_filter, (int, long)): sessions = Session().select(filter={'person_id': session_filter}) elif isinstance(session_filter, StringTypes): sessions = Session().select(filter={'session_id': session_filter}) else: raise PLCInvalidArgument, "Wrong session filter"%session_filter if expires is not None: if expires >= 0: sql += " AND expires > %(expires)d" else: expires = -expires sql += " AND expires < %(expires)d" self.extend(sessions)