1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- from flask.sessions import SessionInterface, SessionMixin
- from werkzeug.datastructures import CallbackDict
- from sqlalchemy import Table, Column, String, LargeBinary, DateTime,\
- select, delete, insert, update
- from random import SystemRandom, randrange
- import string
- from datetime import datetime, timedelta
- import cPickle
- random=SystemRandom()
- class SQLSession(CallbackDict, SessionMixin):
- def __init__(self, sid, db, table, new=False, initial=None):
- self.sid=sid
- self.db=db
- self.table=table
- self.modified=False
- self.new=new
- def _on_update(self):
- self.modified=True
- super(SQLSession, self).__init__(initial, _on_update)
- def save(self):
- if self.new:
- self.db.execute(self.table.insert({
- 'session_id': self.sid,
- 'expire': datetime.now()+timedelta(hours=1),
- 'value': cPickle.dumps(dict(self), -1)
- }))
- self.new=False
- else:
- self.db.execute(self.table.update(
- self.table.c.session_id == self.sid,
- {
- 'expire': datetime.now()+timedelta(hours=1),
- 'value': cPickle.dumps(dict(self), -1)
- }
- ))
- class MySessionInterface(SessionInterface):
- def __init__(self, engine, metadata):
- self.engine = engine
- self.table = Table('flask_sessions', metadata,
- Column('session_id', String(32), primary_key=True),
- Column('expire', DateTime, index=True),
- Column('value', LargeBinary, nullable=False)
- )
- def open_session(self, app, request):
- sid = request.cookies.get(app.session_cookie_name)
- if sid:
- res=self.engine.execute(select([self.table.c.value], (self.table.c.session_id == sid) &
- (self.table.c.expire > datetime.now()))).first()
- if res:
- return SQLSession(sid, self.engine, self.table, False, cPickle.loads(res[0]))
- while True:
- sid=''.join(random.choice(string.ascii_letters+string.digits) for i in range(32))
- res=self.engine.execute(select([self.table.c.value], self.table.c.session_id == sid)).first()
- if not res:
- break
- return SQLSession(sid, self.engine, self.table, True)
- def save_session(self, app, session, response):
- if session.modified:
- session.save()
- # remove expired sessions.. or maybe not
- if randrange(20) % 20 == 0:
- self.engine.execute(self.table.delete(self.table.c.expire <= datetime.now()))
- response.set_cookie(app.session_cookie_name, session.sid,
- expires=self.get_expiration_time(app, session),
- domain=self.get_cookie_domain(app),
- path=self.get_cookie_path(app),
- secure=self.get_cookie_secure(app),
- httponly=self.get_cookie_httponly(app))
|