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:
parent
f0f1ed9a83
commit
611b01fd0e
4 changed files with 48 additions and 33 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue