Browse Source

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
Yann Weber 8 years ago
parent
commit
611b01fd0e
4 changed files with 48 additions and 33 deletions
  1. 23
    8
      lodel/auth/client.py
  2. 1
    1
      plugins/ram_sessions/__init__.py
  3. 10
    12
      plugins/ram_sessions/main.py
  4. 14
    12
      plugins/webui/run.py

+ 23
- 8
lodel/auth/client.py View File

@@ -8,6 +8,7 @@ from lodel.settings import Settings
8 8
 from lodel import logger
9 9
 from lodel.plugin.hooks import LodelHook
10 10
 from lodel.plugin import SessionHandlerPlugin as SessionHandler
11
+from .exceptions import *
11 12
 
12 13
 ##@brief Class designed to handle sessions and its datas
13 14
 class LodelSession(object):
@@ -61,6 +62,7 @@ exists ! (exactly %d)" % refcount)
61 62
             raise ClientAuthenticationError("Trying to restore a session, but \
62 63
 a session is allready started !!!")
63 64
         self.__datas = SessionHandler.restore(token)
65
+        self.__token = token
64 66
         return self.datas
65 67
 
66 68
     ##@brief Save the current session state
@@ -68,7 +70,7 @@ a session is allready started !!!")
68 70
         if not self.started:
69 71
             raise ClientAuthenticationError(
70 72
                 "Trying to save a non started session")
71
-        SessionHandler.save(self.__token)
73
+        SessionHandler.save(self.__token, self.__datas)
72 74
     
73 75
     ##@brief Destroy a session
74 76
     def destroy(self):
@@ -185,6 +187,9 @@ class Client(object, metaclass = ClientMetaclass):
185 187
         self.__session = LodelSession(session_token)
186 188
         logger.debug("New client : %s" % self)
187 189
     
190
+    def __del__(self):
191
+        del(self.__session)
192
+
188 193
     ##@brief Try to authenticate a user with a login and a password
189 194
     #@param login str : provided login
190 195
     #@param password str : provided password (hash)
@@ -227,27 +232,37 @@ class Client(object, metaclass = ClientMetaclass):
227 232
     #@throw ClientAuthenticationFailure if token is not valid or not
228 233
     #existing
229 234
     @classmethod
230
-    def restore_session(self, token):
235
+    def restore_session(cls, token):
231 236
         cls._assert_instance()
232
-        return self.__session.restore(token)
237
+        return Client._instance.__session.restore(token)
233 238
     
234 239
     ##@brief Return the current session token or None
235 240
     #@return A session token or None
236 241
     @classmethod
237 242
     def session_token(cls):
238 243
         cls._assert_instance()
239
-        return cls._instance.__session.retrieve_token()
244
+        return Client._instance.__session.retrieve_token()
240 245
 
241 246
     @classmethod
242 247
     def session(cls):
243 248
         cls._assert_instance()
244
-        return cls._instance.__session
245
-
249
+        return Client._instance.__session
250
+    
251
+    ##@brief Delete current session
246 252
     @classmethod
247 253
     def destroy(cls):
248 254
         cls._assert_instance()
249
-        cls._instance.__session.destroy()
250
-
255
+        Client._instance.__session.destroy()
256
+    
257
+    ##@brief Delete current client and save its session
258
+    @classmethod
259
+    def clean(cls):
260
+        if Client._instance.__session.started:
261
+            Client._instance.__session.save()
262
+        if Client._instance is not None:
263
+            del(Client._instance)
264
+        Client._instance = None
265
+    
251 266
     ##@brief Test wether a client is anonymous or logged in
252 267
     #@return True if client is anonymous
253 268
     @classmethod

+ 1
- 1
plugins/ram_sessions/__init__.py View File

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

+ 10
- 12
plugins/ram_sessions/main.py View File

@@ -1,6 +1,7 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 import os
3 3
 import copy
4
+import binascii
4 5
 
5 6
 from lodel import logger
6 7
 from lodel.settings import Settings
@@ -8,20 +9,26 @@ from lodel.auth.exceptions import *
8 9
 
9 10
 __sessions = dict()
10 11
 
12
+def __generate_token():
13
+    return binascii.hexlify(os.urandom(Settings.sessions.tokensize//2))
14
+
11 15
 def _check_token(token):
12
-    if len(token) != Settings.sessions.token_size:
16
+    if len(token) != Settings.sessions.tokensize:
13 17
         raise ClientAuthenticationFailure("Malformed session token")
14 18
     if token not in __sessions:
15 19
         raise ClientAuthenticationFailure("No session with this token")
16 20
 
17 21
 def start_session():
18
-    token = os.urandom(Settings.sessions.token_size)
22
+    token = __generate_token()
19 23
     __sessions[token] = dict()
24
+    _check_token(token)
25
+    logger.debug("New session created")
20 26
     return token
21 27
 
22 28
 def destroy_session(token):
23 29
     _check_token(token)
24 30
     del(__sessions[token])
31
+    logger.debug("Session %s destroyed" % token)
25 32
 
26 33
 def restore_session(token):
27 34
     _check_token(token)
@@ -31,14 +38,5 @@ def restore_session(token):
31 38
 def save_session(token, datas):
32 39
     _check_token(token)
33 40
     __sessions[token] = copy.copy(datas)
34
-
35
-
36
-def get_value(token, name):
37
-    _check_token(token)
38
-    return __sessions[token][name]
39
-
40
-def del_value(token, name):
41
-    _check_token(token)
42
-    if name in __sessions[token]:
43
-        del(__sessions[token][name])
41
+    logger.debug("Session saved")
44 42
 

+ 14
- 12
plugins/webui/run.py View File

@@ -26,13 +26,16 @@ session_store = FilesystemSessionStore(path=SESSION_FILES_BASE_DIR, filename_tem
26 26
 
27 27
 COOKIE_SESSION_ID = 'toktoken'
28 28
 COOKIE_SESSION_HASH = 'nekotkot'
29
-COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
29
+#COOKIE_SESSION_HASH_SALT = [ os.urandom(32) for _ in range(2) ] #Before and after salt (maybe useless)
30
+COOKIE_SESSION_HASH_SALT = ['salt1', 'salt2']
30 31
 COOKIE_SESSION_HASH_ALGO = hashlib.sha512
31 32
 
32 33
 ##@brief Return a salted hash of a cookie
33 34
 def cookie_hash(token):
35
+    token = str(token)
36
+    return COOKIE_SESSION_HASH_ALGO(token.encode()).hexdigest()
34 37
     return COOKIE_SESSION_HASH_ALGO(
35
-        COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).hexdigest()
38
+        (COOKIE_SESSION_HASH_SALT[0]+token+COOKIE_SESSION_HASH_SALT[1]).encode()).hexdigest()
36 39
     
37 40
 
38 41
 ##@brief Load cookie from request
@@ -41,9 +44,9 @@ def cookie_hash(token):
41 44
 #@return None or a session token
42 45
 def load_cookie(request):
43 46
     token = request.cookies.get(COOKIE_SESSION_ID)
44
-    if token is None and token != '':
47
+    token=token.encode()
48
+    if token is None or len(token) == 0:
45 49
         return None
46
-    token = bytes(token, 'utf-8')
47 50
     hashtok = request.cookies.get(COOKIE_SESSION_HASH)
48 51
     if hashtok is None:
49 52
         raise ClientAuthenticationFailure(
@@ -103,11 +106,12 @@ def application(env, start_response):
103 106
         #to log messages with client infos
104 107
         client = WebUiClient(env['REMOTE_ADDR'], env['HTTP_USER_AGENT'], None)
105 108
         session_token = load_cookie(request)
106
-
107 109
         if session_token is not None:
108
-            WebClient.restore_session(token)
110
+            WebUiClient.restore_session(session_token)
111
+            #next line is for testing purpose
112
+            print("ACCESS DATAS : ", WebUiClient['last_request'])
109 113
         session_token = None
110
-        #test
114
+        #next line is for testing purpose
111 115
         WebUiClient['last_request'] = time.time()
112 116
         try:
113 117
             controller = get_controller(request)
@@ -124,18 +128,16 @@ def application(env, start_response):
124 128
         if session_token is not None:
125 129
             save_cookie(response,session_token)
126 130
         session_token = None
127
-            
128
-
129 131
     except (ClientError, ClientAuthenticationError):
130
-        response = HttpException(400).render(request)
132
+        response = HttpException(200).render(request)
131 133
         empty_cookie(response)
132 134
     except ClientAuthenticationFailure:
133
-        response = HttpException(401).render(request)
135
+        response = HttpException(200).render(request)
134 136
         empty_cookie(response)
135 137
     except Exception as e:
136 138
         raise e
137 139
 
138 140
     res = response(env, start_response)
139 141
 
140
-    WebUiClient.destroy()
142
+    WebUiClient.clean()
141 143
     return res

Loading…
Cancel
Save