1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2025-10-30 02:59:03 +01:00

Bugfixes on ram_session on sessions and on cookies

- webui fix in cookies handling
- ram_session fix in token generation (return an str : hex representation of os.urandom(n))
- more fixes in Client session handling
This commit is contained in:
Yann 2016-08-25 10:17:08 +02:00
commit 611b01fd0e
4 changed files with 48 additions and 33 deletions

View file

@ -8,6 +8,7 @@ from lodel.settings import Settings
from lodel import logger
from lodel.plugin.hooks import LodelHook
from lodel.plugin import SessionHandlerPlugin as SessionHandler
from .exceptions import *
##@brief Class designed to handle sessions and its datas
class LodelSession(object):
@ -61,6 +62,7 @@ exists ! (exactly %d)" % refcount)
raise ClientAuthenticationError("Trying to restore a session, but \
a session is allready started !!!")
self.__datas = SessionHandler.restore(token)
self.__token = token
return self.datas
##@brief Save the current session state
@ -68,7 +70,7 @@ a session is allready started !!!")
if not self.started:
raise ClientAuthenticationError(
"Trying to save a non started session")
SessionHandler.save(self.__token)
SessionHandler.save(self.__token, self.__datas)
##@brief Destroy a session
def destroy(self):
@ -185,6 +187,9 @@ class Client(object, metaclass = ClientMetaclass):
self.__session = LodelSession(session_token)
logger.debug("New client : %s" % self)
def __del__(self):
del(self.__session)
##@brief Try to authenticate a user with a login and a password
#@param login str : provided login
#@param password str : provided password (hash)
@ -227,27 +232,37 @@ class Client(object, metaclass = ClientMetaclass):
#@throw ClientAuthenticationFailure if token is not valid or not
#existing
@classmethod
def restore_session(self, token):
def restore_session(cls, token):
cls._assert_instance()
return self.__session.restore(token)
return Client._instance.__session.restore(token)
##@brief Return the current session token or None
#@return A session token or None
@classmethod
def session_token(cls):
cls._assert_instance()
return cls._instance.__session.retrieve_token()
return Client._instance.__session.retrieve_token()
@classmethod
def session(cls):
cls._assert_instance()
return cls._instance.__session
return Client._instance.__session
##@brief Delete current session
@classmethod
def destroy(cls):
cls._assert_instance()
cls._instance.__session.destroy()
Client._instance.__session.destroy()
##@brief Delete current client and save its session
@classmethod
def clean(cls):
if Client._instance.__session.started:
Client._instance.__session.save()
if Client._instance is not None:
del(Client._instance)
Client._instance = None
##@brief Test wether a client is anonymous or logged in
#@return True if client is anonymous
@classmethod

View file

@ -10,6 +10,6 @@ __fullname__ = "RAM Session Store Plugin"
CONFSPEC = {
'lodel2.sessions':{
'expiration': (900, SettingValidator('int')),
'token_size': (512, SettingValidator('int')),
'tokensize': (512, SettingValidator('int')),
}
}

View file

@ -1,6 +1,7 @@
#-*- coding: utf-8 -*-
import os
import copy
import binascii
from lodel import logger
from lodel.settings import Settings
@ -8,20 +9,26 @@ from lodel.auth.exceptions import *
__sessions = dict()
def __generate_token():
return binascii.hexlify(os.urandom(Settings.sessions.tokensize//2))
def _check_token(token):
if len(token) != Settings.sessions.token_size:
if len(token) != Settings.sessions.tokensize:
raise ClientAuthenticationFailure("Malformed session token")
if token not in __sessions:
raise ClientAuthenticationFailure("No session with this token")
def start_session():
token = os.urandom(Settings.sessions.token_size)
token = __generate_token()
__sessions[token] = dict()
_check_token(token)
logger.debug("New session created")
return token
def destroy_session(token):
_check_token(token)
del(__sessions[token])
logger.debug("Session %s destroyed" % token)
def restore_session(token):
_check_token(token)
@ -31,14 +38,5 @@ def restore_session(token):
def save_session(token, datas):
_check_token(token)
__sessions[token] = copy.copy(datas)
def get_value(token, name):
_check_token(token)
return __sessions[token][name]
def del_value(token, name):
_check_token(token)
if name in __sessions[token]:
del(__sessions[token][name])
logger.debug("Session saved")

View file

@ -26,13 +26,16 @@ session_store = FilesystemSessionStore(path=SESSION_FILES_BASE_DIR, filename_tem
COOKIE_SESSION_ID = 'toktoken'
COOKIE_SESSION_HASH = 'nekotkot'
COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
#COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
COOKIE_SESSION_HASH_SALT = ['salt1', 'salt2']
COOKIE_SESSION_HASH_ALGO = hashlib.sha512
##@brief Return a salted hash of a cookie
def cookie_hash(token):
token = str(token)
return COOKIE_SESSION_HASH_ALGO(token.encode()).hexdigest()
return COOKIE_SESSION_HASH_ALGO(
COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).hexdigest()
(COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).encode()).hexdigest()
##@brief Load cookie from request
@ -41,9 +44,9 @@ def cookie_hash(token):
#@return None or a session token
def load_cookie(request):
token = request.cookies.get(COOKIE_SESSION_ID)
if token is None and token != '':
token=token.encode()
if token is None or len(token) == 0:
return None
token = bytes(token, 'utf-8')
hashtok = request.cookies.get(COOKIE_SESSION_HASH)
if hashtok is None:
raise ClientAuthenticationFailure(
@ -103,11 +106,12 @@ def application(env, start_response):
#to log messages with client infos
client = WebUiClient(env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], None)
session_token = load_cookie(request)
if session_token is not None:
WebClient.restore_session(token)
WebUiClient.restore_session(session_token)
#next line is for testing purpose
print("ACCESS DATAS : ", WebUiClient['last_request'])
session_token = None
#test
#next line is for testing purpose
WebUiClient['last_request'] = time.time()
try:
controller = get_controller(request)
@ -124,18 +128,16 @@ def application(env, start_response):
if session_token is not None:
save_cookie(response,session_token)
session_token = None
except (ClientError, ClientAuthenticationError):
response = HttpException(400).render(request)
response = HttpException(200).render(request)
empty_cookie(response)
except ClientAuthenticationFailure:
response = HttpException(401).render(request)
response = HttpException(200).render(request)
empty_cookie(response)
except Exception as e:
raise e
res = response(env, start_response)
WebUiClient.destroy()
WebUiClient.clean()
return res