parameciofm/paramecio/citoplasma/sessions.py
Antonio de la Rosa 28172e86d7 Fix in sqlalchemy
2018-04-18 02:33:27 +02:00

242 lines
5.9 KiB
Python

#!/usr/bin/env python3
from paramecio.citoplasma.keyutils import create_key_encrypt, create_key_encrypt_256, create_key
from oslo_concurrency import lockutils
try:
from settings import config
except:
class config:
cookie_name='paramecio.session'
key_encrypt=create_key_encrypt_256(30)
session_opts={'session.data_dir': 'sessions', 'session.type': 'file', 'session.path': 'paramecio'}
from itsdangerous import JSONWebSignatureSerializer
from bottle import request, response
import os
import json
import fcntl
import errno
import time
import shutil
import uuid
#from diskcache import Cache
#from dogpile.cache import make_region
# Cookie session
# This save the session in a cookie for maximum performance. In next version i can use memcached or something for session
# In next versions have two secret_keys for more security.
class ParamecioSession:
def __init__(self, session_dict):
self.session=session_dict
def get(self, name, default_value):
if not name in self.session:
self.session[name]=default_value
return self.session[name]
def __getitem__(self, key):
return self.session[key]
def __setitem__(self, key, value):
self.session[key]=value
def __delitem__(self, key):
if key!='token':
del self.session[key]
def __contains__(self, key):
if key in self.session:
return True
else:
return False
def __iter__(self):
return self.session
def __str__(self):
return self.session.__str__()
def keys(self):
return self.session.keys()
def remove(self):
response.delete_cookie(config.cookie_name, path="/")
def delete(self):
self.remove()
def save(self):
# Here get the function for load session
save_session(self.session['token'], self.session)
def reset(self):
token=self.session['token']
self.session={'token': token}
self.save()
def get_session():
s={}
try:
if request.environ:
if not 'session' in request.environ:
cookie=None
if request.cookies.get(config.cookie_name):
cookie=request.get_cookie(config.cookie_name)
if not cookie:
if hasattr(request, 'app'):
s=generate_session()
else:
# Here get the function for load session
s=load_session(cookie)
request.environ['session']=s
else:
s=request.environ['session']
except RuntimeError:
pass
return ParamecioSession(s)
if config.session_opts['session.type']=='mysql':
pass
elif config.session_opts['session.type']=='redis':
import redis
def load_session(token):
s={}
r=redis.StrictRedis(host=config.session_opts['session.host'], port=config.session_opts['session.port'], db=config.session_opts['session.db'])
value=r.get(token)
if not value:
s={'token': token}
else:
try:
s=json.loads(value.decode('utf-8'))
except:
s={'token': token}
return s
def save_session(token, session):
r=redis.StrictRedis(host=config.session_opts['session.host'], port=config.session_opts['session.port'], db=config.session_opts['session.db'])
r.set(token, json.dumps(session))
def after_session():
pass
else:
def generate_session(session={}):
#secret=URLSafeSerializer(config.key_encrypt)
#session=secret.dumps(session)
token=create_key(30).replace('/', '#')
s={'token': token}
response.set_cookie(config.cookie_name, token, path=config.session_opts['session.path'])
request.environ['session']=s
file_session=config.session_opts['session.data_dir']+'/'+token+'_session'
save_session(token, s, True)
request.environ['session']=s
return s
def regenerate_session():
token=create_key(30).replace('/', '#')
s={'token': token}
response.set_cookie(config.cookie_name, token, path=config.session_opts['session.path'])
file_session=config.session_opts['session.data_dir']+'/'+token+'_session'
save_session(token, s, True)
request.environ['session']=s
return ParamecioSession(s)
def load_session(token):
file_session=config.session_opts['session.data_dir']+'/'+token+'_session'
if os.path.isfile(file_session):
with open(file_session) as f:
try:
s=json.loads(f.read())
os.utime(file_session)
except:
s={'token': token}
else:
return generate_session({'token': token})
return s
@lockutils.synchronized('not_thread_safe')
def save_session(token, session, create_file=False):
file_session=config.session_opts['session.data_dir']+'/'+token+'_session'
# Check if exists lock
if os.path.isfile(file_session) or create_file:
with open(file_session, 'w') as f:
#try:
json_session=json.dumps(session)
f.write(json_session)