nouveau fichier: session.py
modifié: superTornado.py
This commit is contained in:
parent
8f8ca84f42
commit
da61cbe690
147
session.py
Normal file
147
session.py
Normal file
@ -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
|
@ -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")
|
||||
|
Reference in New Issue
Block a user