From da61cbe6906c4e82c4990357b0183db326a10980 Mon Sep 17 00:00:00 2001 From: sidya82 Date: Thu, 27 Feb 2014 22:34:28 +0100 Subject: [PATCH] =?UTF-8?q?=09nouveau=20fichier:=20session.py=20=09modifi?= =?UTF-8?q?=C3=A9:=20=20=20=20=20=20=20=20=20superTornado.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- session.py | 147 ++++++++++++++++++++++++++++++++++++++++++++++++ superTornado.py | 13 ++++- 2 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 session.py diff --git a/session.py b/session.py new file mode 100644 index 0000000..4c8c4ee --- /dev/null +++ b/session.py @@ -0,0 +1,147 @@ + +""" + +Usage: +In your application script, + settings["session_secret"] = 'some secret password!!' + settings["session_dir"] = 'sessions' # the directory to store sessions in + application.session_manager = session.TornadoSessionManager(settings["session_secret"], settings["session_dir"]) + +In your RequestHandler (probably in __init__), + self.session = session.TornadoSession(self.application.session_manager, self) + +After that, you can use it like this (in get(), post(), etc): + self.session['blah'] = 1234 + self.save() + blah = self.session['blah'] + + etc. + + +the basic session mechanism is this: +* take some data, pickle it, store it somewhere. +* assign an id to it. run that id through a HMAC (NOT just a hash function) to prevent tampering. +* put the id and HMAC output in a cookie. +* when you get a request, load the id, verify the HMAC. if it matches, load the data from wherever you put it and depickle it. + + +""" + +import pickle +import os.path +import hmac +import hashlib +import uuid + +class Session(dict): + """ A Session is basically a dict with a session_id and an hmac_digest string to verify access rights """ + def __init__(self, session_id, hmac_digest): + self.session_id = session_id + self.hmac_digest = hmac_digest + + +class SessionManager(object): + """ SessionManager handles the cookie and file read/writes for a Session """ + def __init__(self, secret, session_dir = ''): + self.secret = secret + + # figure out where to store the session file + if session_dir == '': + session_dir = os.path.join(os.path.dirname(__file__), 'sessions') + self.session_dir = session_dir + + + def _read(self, session_id): + session_path = self._get_session_path(session_id) + try : + data = pickle.load(open(session_path)) + if type(data) == type({}): + return data + else: + return {} + except IOError: + return {} + + def get(self, session_id = None, hmac_digest = None): + # set up the session state (create it from scratch, or from parameters + if session_id == None: + session_should_exist = False + session_id = self._generate_uid() + hmac_digest = self._get_hmac_digest(session_id) + else: + session_should_exist = True + session_id = session_id + hmac_digest = hmac_digest # keyed-Hash Message Authentication Code + + # make sure the HMAC digest we generate matches the given one, to validate + expected_hmac_digest = self._get_hmac_digest(session_id) + if hmac_digest != expected_hmac_digest: + raise InvalidSessionException() + + # create the session object + session = Session(session_id, hmac_digest) + + # read the session file, if this is a pre-existing session + if session_should_exist: + data = self._read(session_id) + for i, j in data.iteritems(): + session[i] = j + + return session + + def _get_session_path(self, session_id): + return os.path.join(self.session_dir, 'SESSION' + str(session_id)) + + def set(self, session): + session_path = self._get_session_path(session.session_id) + session_file = open(session_path, 'wb') + pickle.dump(dict(session.items()), session_file) + session_file.close() + + def _get_hmac_digest(self, session_id): + return hmac.new(session_id, self.secret, hashlib.sha1).hexdigest() + + def _generate_uid(self): + base = hashlib.md5( self.secret + str(uuid.uuid4()) ) + return base.hexdigest() + +class TornadoSessionManager(SessionManager): + """ A TornadoSessionManager is a SessionManager that is specifically for use in Tornado, using Tornado's cookies """ + + def get(self, requestHandler = None): + if requestHandler == None: + return super(TornadoSessionManager, self).get() + else: + session_id = requestHandler.get_secure_cookie("session_id") + hmac_digest = requestHandler.get_secure_cookie("hmac_digest") + return super(TornadoSessionManager, self).get(session_id, hmac_digest) + + + def set(self, requestHandler, session): + requestHandler.set_secure_cookie("session_id", session.session_id) + requestHandler.set_secure_cookie("hmac_digest", session.hmac_digest) + return super(TornadoSessionManager, self).set(session) + +class TornadoSession(Session): + """ A TornadoSession is a Session object for use in Tornado """ + def __init__(self, tornado_session_manager, request_handler): + self.session_manager = tornado_session_manager + self.request_handler = request_handler + # get the session object's data and transfer it to this session item + try: + plain_session = tornado_session_manager.get(request_handler) + except InvalidSessionException: + plain_session = tornado_session_manager.get() + + for i, j in plain_session.iteritems(): + self[i] = j + self.session_id = plain_session.session_id + self.hmac_digest = plain_session.hmac_digest + + + + def save(self): + self.session_manager.set(self.request_handler, self) + +class InvalidSessionException(Exception): + pass diff --git a/superTornado.py b/superTornado.py index 6d54aee..ad32f1d 100644 --- a/superTornado.py +++ b/superTornado.py @@ -2,16 +2,22 @@ import tornado.ioloop import tornado.web import tornado.httpserver import tornado.websocket + from tornado.ioloop import PeriodicCallback - +from session import * from loadConf import * from login import * confAveug = False ficLog = Login() +settings["session_secret"] = 'some secret password!!' +settings["session_dir"] = 'sessions' # the directory to store sessions in +application.session_manager = session.TornadoSessionManager(settings["session_secret"], settings["session_dir"]) class MainHandler(tornado.web.RequestHandler): + def __init__ (self) : + self.session = session.TornadoSession(self.application.session_manager, self) def get(self): self.render("index.html") def post(self): @@ -30,7 +36,10 @@ class MainHandler(tornado.web.RequestHandler): print '->Send visual alarm authorized user' print 'maison.request("GET", "micom/lamp.php?room=salon1&order=1")' print "->Send to client authorized user access" - self.write("Authorized user access") + self.session['blah'] = 1234 + self.save() + blah = self.session['blah'] + self.write(blah) else: ficLog.enregDansLog(iden,"Unauthorized user connection","IP TO DO")