ソースを参照

Changed the filesystem_session handler and added new commands to the sessionhandler (to add, del and read values from the session)

Roland Haroutiounian 7年前
コミット
bda7779166

+ 4
- 1
lodel/plugin/sessionhandler.py ファイルの表示

@@ -14,7 +14,10 @@ class SessionPluginWrapper(MetaPlugType):
14 14
         'start': 'start_session',
15 15
         'destroy': 'destroy_session', 
16 16
         'restore': 'restore_session',
17
-        'save': 'save_session'}
17
+        'save': 'save_session',
18
+        'set': 'set_session_value',
19
+        'get': 'get_session_value',
20
+        'del': 'del_session_value'}
18 21
 
19 22
     def __init__(self, name, bases, attrs):
20 23
         super().__init__(name, bases, attrs)

+ 20
- 0
plugins/filesystem_session/filesystem_session.py ファイルの表示

@@ -0,0 +1,20 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+
4
+class FileSystemSession(dict):
5
+
6
+    def __init__(self, token):
7
+        self.__token = token
8
+        self.__path = None
9
+
10
+    @property
11
+    def token(self):
12
+        return self.__token
13
+
14
+    @property
15
+    def path(self):
16
+        return self.__path
17
+
18
+    @path.setter
19
+    def path(self, path):
20
+        self.__path = path

+ 82
- 78
plugins/filesystem_session/main.py ファイルの表示

@@ -1,7 +1,5 @@
1 1
 # -*- coding: utf-8 -*-
2
-
3 2
 import binascii
4
-import copy
5 3
 import datetime
6 4
 import os
7 5
 import pickle
@@ -9,128 +7,134 @@ import re
9 7
 import time
10 8
 
11 9
 from lodel import logger
12
-from lodel.settings import Settings
13 10
 from lodel.auth.exceptions import ClientAuthenticationFailure
11
+from lodel.settings import Settings
14 12
 
15 13
 from .filesystem_session import FileSystemSession
16 14
 
17
-## @brief lists the active sessions in a dict
18
-# Its keys are the session tokens and its values are the file paths of session 
19
-# files.
20 15
 __sessions = dict()
21 16
 
22
-# ====== UTILS ====== # 
23 17
 
24
-## @brief Generates a session token
18
+## @brief generates a new session token
25 19
 # @return str
26
-def __generate_token():
27
-    new_token = binascii.hexlify(os.urandom(Settings.sessions.tokensize//2))
28
-    if new_token in __sessions.keys():
29
-        new_token = __generate_token()
30
-    return new_token
20
+def generate_token():
21
+    token = binascii.hexlify(os.urandom(Settings.sessions.tokensize//2))
22
+    if token in __sessions.keys():
23
+        token = generate_token()
24
+    return token
25
+
31 26
 
32
-## @brief Checks if a token is valid and matchs with a registered session
27
+## @brief checks the validity of a given session token
33 28
 # @param token str
34 29
 # @raise ClientAuthenticationFailure for invalid or not found session token
35
-def _check_token(token):
36
-    # Bad length
30
+def check_token(token):
37 31
     if len(token) != Settings.sessions.tokensize:
38
-        raise ClientAuthenticationFailure("Malformed session token")
39
-    # Not found
40
-    if token not in __sessions:
41
-        raise ClientAuthenticationFailure("No session found with this token")
32
+        raise ClientAuthenticationFailure("Invalid token string")
33
+    if token not in __sessions.keys():
34
+        raise ClientAuthenticationFailure("No session found for this token")
42 35
 
43 36
 
44
-## @brief Lists all the session files' paths
45
-# @return list
46
-def _list_all_sessions():
47
-    session_files_directory = os.abspath(Settings.sessions.directory)
48
-    return [file_path for file_path in os.listdir(session_files_directory) if os.path.isfile(os.path.join(session_files_directory, file_path))]
37
+def generate_file_path(token):
38
+    return os.abspath(os.path.join(Settings.sessions.directory, Settings.sessions.file_template) % token)
49 39
 
50 40
 
51
-## @brief Returns the token from a session file's name
52
-# @param filename str
53
-# @return str
54
-def _get_token_from_session_filename(filename):
55
-    token_regex = re.compile(Settings.sessions.file_template % '(?P<token>.*)')
56
-    token_searching_result = token_regex.match(filename)
57
-    if token_searching_result is not None:
58
-        return token_searching_result.groupdict()['token']
41
+def get_token_from_filepath(filepath):
42
+    token_regex = re.compile(os.abspath(os.path.join(Settings.sessions.directory, Settings.sessions.file_template % '(?P<token>.*)')))
43
+    token_search_result = token_regex.match(filepath)
44
+    if token_search_result is not None:
45
+        return token_search_result.groupdict()['token']
59 46
     return None
60 47
 
61 48
 
62
-## @brief Returns the session's last modification timestamp
49
+## @brief returns the session's last modification timestamp
63 50
 # @param token str
64 51
 # @return float
65
-def _get_session_last_modified(token):
66
-    if token in __sessions.keys():
52
+# @raise ValueError if the given token doesn't match with an existing session
53
+def get_session_last_modified(token):
54
+    if token in __sessions[token]:
67 55
         return os.stat(__sessions[token]).st_mtime
68 56
     else:
69 57
         raise ValueError("The given token %s doesn't match with an existing session")
70 58
 
71
-# ====== SESSION MANAGEMENT ====== #
72
-## @brief Registers the session in the active sessions' list
73
-# @param session LodelSession
74
-def _register_session(token):
75
-    __sessions[token] = os.path.join(Settings.sessions.directory, Settings.sessions.file_template % token)
76
-    
77
-    
78
-## @brief Session store's garbage collector
79
-def gc():
80
-    # unregistered files in the session directory
81
-    sessions_dir_files = _list_all_sessions()
82
-    for sessions_dir_file in sessions_dir_files:
83
-        token = _get_token_from_session_filename(sessions_dir_file)
84
-        if token is None or token not in __sessions.keys():
85
-            os.unlink(sessions_dir_file)
86
-    
87
-    # expired registered sessions
88
-    for token in __sessions.keys():
89
-        if os.path.isfile(__sessions[token]):
90
-            now_timestamp = time.mktime(datetime.datetime.now().timetuple())
91
-            if now_timestamp - _get_session_last_modified(token) > Settings.sessions.expiration:
92
-                destroy_session(token)
93 59
 
94
-
95
-## @brief starts a new session and returns its token
60
+## @brief returns the token of a new session
96 61
 # @return str
97 62
 def start_session():
98
-    new_token = __generate_token()
99
-    new_session = FileSystemSession(new_token)
100
-    new_session.save()
101
-    _register_session(new_token)
102
-    _check_token(new_token)
63
+    session = FileSystemSession(generate_token())
64
+    session.path = generate_file_path()
65
+    with open(session.path, 'wb') as session_file:
66
+        pickle.dump(session, session_file)
67
+    __sessions[session.token] = session.path
103 68
     logger.debug("New session created")
104
-    return new_token
69
+    return session.token
105 70
 
106 71
 
107
-## @brief destroys a session defined by its token
72
+## @brief destroys a session given its token
108 73
 # @param token str
109 74
 def destroy_session(token):
110
-    _check_token(token)
75
+    check_token(token)
111 76
     if os.path.isfile(__sessions[token]):
112 77
         os.unlink(__sessions[token])
78
+        logger.debug("Session file for %s destroyed" % token)
113 79
     del(__sessions[token])
114
-    logger.debug("Session %s destroyed" % token)
80
+    logger.debug("Session %s unregistered" % token)
115 81
 
116 82
 
117
-## @brief restores a session's content
118
-# @param token str
119
-# @return FileSystemSession
120 83
 def restore_session(token):
121
-    _check_token(token)
84
+    check_token(token)
122 85
     logger.debug("Restoring session : %s" % token)
123 86
     if os.path.isfile(__sessions[token]):
124 87
         with open(__sessions[token], 'rb') as session_file:
125 88
             session = pickle.load(session_file)
126 89
         return session
127
-    return None
90
+    else:
91
+        raise FileNotFoundError("Session file not foudn for the token %s" % token)
128 92
 
129 93
 
130
-def save_session(token, datas=None):
131
-    _check_token(token)
132
-    session = restore_session(token)
133
-    session.datas = copy.copy(datas)
94
+def save_session(token, datas):
95
+    session = datas
96
+    if not isinstance(datas, FileSystemSession):
97
+        session = FileSystemSession(token)
98
+        session.path = generate_file_path(token)
99
+        session.update(datas)
100
+
134 101
     with open(__sessions[token], 'wb') as session_file:
135 102
         pickle.dump(session, session_file)
103
+
104
+    if token not in __sessions.keys():
105
+        __sessions[token] = session.path
106
+
136 107
     logger.debug("Session %s saved" % token)
108
+
109
+
110
+def gc():
111
+    # Unregistered files in the session directory
112
+    session_files_directory = os.abspath(Settings.sessions.directory)
113
+    for session_file_path in [file_path for file_path in os.listdir(session_files_directory) if os.path.isfile(os.path.join(session_files_directory, file_path))]:
114
+        token = get_token_from_filepath(session_file_path)
115
+        if token is None or token not in __sessions.keys():
116
+            os.unlink(session_file_path)
117
+
118
+    # Expired registered sessions
119
+    for token in __sessions.keys():
120
+        if os.path.isfile(__sessions[token]):
121
+            now_timestamp = time.mktime(datetime.datetime.now().timetuple())
122
+            if now_timestamp - get_session_last_modified(token) > Settings.sessions.expiration:
123
+                destroy_session(token)
124
+
125
+
126
+def set_value(token, key, value):
127
+    session = restore_session(token)
128
+    session[key] = value
129
+    save_session(token, session)
130
+
131
+
132
+def get_value(token, key):
133
+    session = restore_session(token)
134
+    return session[key]
135
+
136
+
137
+def del_value(token, key):
138
+    session = restore_session(token)
139
+    if key in session:
140
+        del(session[key])

読み込み中…
キャンセル
保存