import time
import uuid
import threading
class Session:
def __init__(self, manager, user_id):
self.manager = manager
self.server = manager.server
self.id = uuid.uuid4().hex
self.user_id = user_id
self.maxtime = self.server.config['session']['time']
self.touch()
def touch(self):
self.time = time.monotonic()
def expired(self):
return self.time + self.maxtime < time.monotonic()
class SessionManager:
COOKIE='session'
def __init__(self, server):
self.server = server
self.lock = threading.Lock()
self.sessions = dict()
self.timer = threading.Timer(server.config['session']['time']*0.1, self.remove_expired)
self.timer.start()
def remove_expired(self):
with self.lock:
remove = list()
for id, session in self.sessions.items():
if session.expired():
remove.append(id)
for id in remove:
del self.sessions[id]
def delete_by_user_id(self, user_id):
assert(type(user_id) is int)
with self.lock:
remove = list()
for id, session in self.sessions.items():
if session.user_id == user_id:
remove.append(id)
for id in remove:
del self.sessions[id]
def add_cookie_header(self, request):
remove = list()
j = 0
for i in request.answer.headers:
if i[0] == 'Set-Cookie':
remove.insert(0, j)
j += 1
for i in remove:
del request.answer.headers[i]
value = None
if request.session:
path = self.server.config['urlprefix'] + '/'
value = '%s=%s; Path=%s; Max-Age=%d; Secure' \
% (self.COOKIE, request.session.id, path, request.session.maxtime)
else:
value = '%s=; Expires=Thu, 01 Jan 1970 00:00:00 GMT' \
% (self.COOKIE)
request.answer.headers.append( ('Set-Cookie', value) )
def create_session(self, request, user_id):
assert(type(user_id) is int)
assert(user_id)
with self.lock:
session = Session(self, user_id)
self.sessions[session.id] = session
request.session = session
self.add_cookie_header(request)
def attach_session(self, request):
request.session = None
# parse cookie
id = None
for i in request.cookie.split(';'):
j = i.split('=')
if len(j) == 2:
if j[0].strip() == self.COOKIE:
if not id is None: # double cookie equals no cookie
id = None
break
id = j[1].strip()
if id:
with self.lock:
session = self.sessions.get(id)
if session:
if session.expired():
del self.sessions[id]
else:
session.touch()
request.session = session
if request.session or request.cookie: # need we add new or delete existant cookie
self.add_cookie_header(request)
def close_session(self, request):
if request.session:
with self.lock:
if request.session.id in self.sessions:
del self.sessions[request.session.id]
request.session = None
if request.cookie:
self.add_cookie_header(request)