Browse Source

Created a FileSystemSessionStore class

Roland Haroutiounian 8 years ago
parent
commit
c73e782003

+ 116
- 0
plugins/filesystem_session/filesystem_session_store.py View File

1
+# -*- coding: utf-8 -*-
2
+
3
+import os
4
+import pickle
5
+import uuid
6
+
7
+from lodel.auth.exceptions import AuthenticationError
8
+from lodel.settings import Settings
9
+from lodel.utils.datetime import get_utc_timestamp
10
+
11
+
12
+class FileSystemSessionStore:
13
+
14
+    ## @brief instanciates a FileSystemSessionStore
15
+    # @param base_directory str : path to the base directory containing the session files (default: session.directory param of the settings)
16
+    # @param file_name_template str : template for the session files name (default : session.file_template param of the settings)
17
+    # @param expiration_limit int : duration of a session validity without any action made (defaut : session.expiration param of the settings)
18
+    def __init__(self, base_directory=Settings.session.directory, file_name_template=Settings.session.file_template, expiration_limit=Settings.session.expiration):
19
+        self.expiration_limit = expiration_limit
20
+        self.base_directory = base_directory
21
+        self.file_name_template = file_name_template
22
+
23
+    # === CRUD === #
24
+
25
+    ## @brief creates a new session and returns its id
26
+    # @param content dict : session content
27
+    # @return str
28
+    def create_new_session(self, content={}):
29
+        sid = FileSystemSessionStore.generate_new_sid()
30
+        session_file_path = self.get_session_file_path(sid)
31
+        session = content
32
+        self.save_session(sid, session)
33
+        return sid
34
+
35
+    ## @brief delete a session
36
+    # @param sid str : id of the session to be deleted
37
+    def delete_session(self, sid):
38
+        if self.is_session_existing(sid):
39
+            os.unlink(self.get_session_file_path(sid))
40
+        else:
41
+            raise AuthenticationError("No session file found for the sid %s" % sid)
42
+
43
+    ## @brief gets a session's content
44
+    # @param sid str : id of the session to read
45
+    def get_session(self, sid):
46
+        if self.is_session_existing(sid):
47
+            if not self.has_session_expired(sid):
48
+                session = self.get_session(sid)
49
+            else:
50
+                self.delete_session(sid)
51
+                session = {}
52
+        else:
53
+            raise AuthenticationError("No session file found for the sid %s" % sid)
54
+
55
+        return session
56
+
57
+    ## @brief updates a session's content
58
+    # @param sid str : session's id
59
+    # @param content dict : items to update with their new value
60
+    def update_session(self, sid, content):
61
+        session = self.get_session(sid)
62
+        for key, value in content.items():
63
+            if key != 'sid':
64
+                session[key] = value
65
+        self.save_session(sid, session)
66
+
67
+    ## @brief lists all the session files paths
68
+    # @return list
69
+    def list_all_sessions(self):
70
+        session_files_directory = os.path.abspath(self.base_directory)
71
+        session_files_list = [os.path.join(session_files_directory, file_object) for file_object in os.listdir(session_files_directory) if os.path.isfile(os.path.join(session_files_directory, file_object))]
72
+        return session_files_list
73
+
74
+    def clean(self):
75
+        files_list = self.list_all_sessions()
76
+        now_timestamp = get_utc_timestamp()
77
+        for session_file in files_list:
78
+            if self.has_session_file_expired(session_file):
79
+                os.unlink(session_file)
80
+
81
+    # === UTILS === #
82
+    @classmethod
83
+    def generate_new_sid(cls):
84
+        return uuid.uuid1()
85
+
86
+    ## @brief returns the file path for a given session id
87
+    # @param sid str : session id
88
+    # @return str
89
+    def get_session_file_path(self, sid):
90
+        return os.path.join(self.base_directory, self.file_name_template) % sid
91
+
92
+    ## @brief saves a session to a file
93
+    # @param sid str : session id
94
+    # @param session dict : content to be saved
95
+    def save_session(self, sid, session):
96
+        session_file_path = self.get_session_file_path(sid)
97
+        pickle.dump(session, open(session_file_path, "wb"))
98
+
99
+    ## @brief checks if a session exists
100
+    # @param sid str : session id
101
+    # @return bool
102
+    def is_session_existing(self, sid):
103
+        session_file = self.get_session_file_path(sid)
104
+        return os.path.is_file(session_file)
105
+
106
+    ## @brief checks if a session has expired
107
+    # @param sid str: session id
108
+    # @return bool
109
+    def has_session_expired(self, sid):
110
+        session_file = self.get_session_file_path(sid)
111
+        return self.has_session_file_expired(session_file)
112
+
113
+    def has_session_file_expired(self, session_file):
114
+        expiration_timestamp = os.stat(session_file).st_mtime + self.expiration_limit
115
+        now_timestamp = get_utc_timestamp()
116
+        return now_timestamp > expiration_timestamp

+ 16
- 88
plugins/filesystem_session/main.py View File

1
 # -*- coding: utf-8 -*-
1
 # -*- coding: utf-8 -*-
2
 
2
 
3
-import os
4
-import pickle
5
-import uuid
6
-
7
 from lodel.auth.exceptions import AuthenticationError
3
 from lodel.auth.exceptions import AuthenticationError
8
 from lodel.plugin import LodelHook
4
 from lodel.plugin import LodelHook
9
-from lodel.settings import Settings
10
-from lodel.utils.datetime import get_utc_timestamp
11
-
12
-SESSION_FILES_BASE_DIR = Settings.sessions.directory
13
-SESSION_FILES_TEMPLATE = Settings.sessions.file_template
14
-SESSION_EXPIRATION_LIMIT = Settings.sessions.expiration
15
-
16
-
17
-## @brief generates a new session id
18
-def generate_new_sid():
19
-    return uuid.uuid1()
20
-
21
-
22
-## @brief gets the session file path, given a session id
23
-# @param sid str : session id
24
-# @return str
25
-def get_session_file_path(sid):
26
-    return os.path.join(SESSION_FILES_BASE_DIR, SESSION_FILES_TEMPLATE) % sid
27
-
28
-
29
-## @brief saves the session content to a session file
30
-# @param sid str: session id
31
-# @param session dict : session content to be saved
32
-def save_session(sid, session):
33
-    session_file_path = get_session_file_path(sid)
34
-    pickle.dump(session, open(session_file_path, "wb"))
35
 
5
 
6
+from .filesystem_session_store import FileSystemSessionStore
36
 
7
 
37
-## @brief checks if a session file has expired
38
-# @param sid str : session id
39
-# @return bool
40
-def is_session_expired(sid):
41
-    session_file = get_session_file_path(sid)
42
-    if not os.path.isfile(session_file):
43
-        raise AuthenticationError("No session file found for the sid : %s" % sid)
44
-
45
-    expiration_timestamp = os.stat(session_file).st_mtime + SESSION_EXPIRATION_LIMIT
46
-    now_timestamp = get_utc_timestamp()
47
-    return now_timestamp >= expiration_timestamp
48
-
49
-
50
-## @brief reads a session content
51
-# @param sid str: session id
52
-# @return dict
53
-def get_session_content(sid):
54
-    session_file_path = get_session_file_path(sid)
55
-    return pickle.load(open(session_file_path), 'rb')
8
+session_store = FileSystemSessionStore()
56
 
9
 
57
 
10
 
58
 ## @brief starts a new session and returns its sid
11
 ## @brief starts a new session and returns its sid
61
 # @return str
14
 # @return str
62
 @LodelHook('session_start')
15
 @LodelHook('session_start')
63
 def start_session(caller, payload):
16
 def start_session(caller, payload):
64
-    sid = generate_new_sid()
65
-    session_file = get_session_file_path(sid)
66
-    session = dict()
67
-    for key, value in payload.items():
68
-        session[key] = value
69
-    save_session(sid, session)
70
-    return sid
17
+    return session_store.create_new_session(payload)
71
 
18
 
72
-## @brief stops a session
19
+
20
+## @brief destroys a session
73
 # @param caller *
21
 # @param caller *
74
 # @param sid str : session id
22
 # @param sid str : session id
75
 @LodelHook('session_destroy')
23
 @LodelHook('session_destroy')
76
 def stop_session(caller, sid):
24
 def stop_session(caller, sid):
77
-    session_file_path = get_session_file_path(sid)
78
-    if os.path.isfile(session_file_path):
79
-        os.unlink(session_file_path)
80
-    else:
81
-        raise AuthenticationError("No session file found for the sid %s" % sid)
25
+    session_store.delete_session(sid)
82
 
26
 
83
 
27
 
84
 ## @brief reads a session content
28
 ## @brief reads a session content
85
 # @param caller *
29
 # @param caller *
86
 # @param sid str: session id
30
 # @param sid str: session id
31
+# @return dict
87
 @LodelHook('session_load')
32
 @LodelHook('session_load')
88
 def read_session(caller, sid):
33
 def read_session(caller, sid):
89
-    session_file = get_session_file_path(sid)
90
-    if os.path.isfile(session_file):
91
-        if not is_session_expired(sid):
92
-            session = get_session_content(sid)
93
-        else:
94
-            LodelHook.call_hook('session_stop', __file__, sid)
95
-            session = {}
96
-    else:
97
-        raise AuthenticationError("No session file found for the sid %s" % sid)
98
-    return session
34
+    return session_store.get_session(sid)
99
 
35
 
100
 
36
 
101
-## @brief deletes all old session files (expired ones)
37
+## @brief destroys all the old sessions (expired ones)
102
 # @param caller *
38
 # @param caller *
103
 @LodelHook('session_clean')
39
 @LodelHook('session_clean')
104
 def clean_sessions(caller):
40
 def clean_sessions(caller):
105
-    session_files_path = os.path.abspath(SESSION_FILES_BASE_DIR)
106
-    session_files = [os.path.join(session_files_path, file_object) for file_object in os.listdir(session_files_path) if os.path.isfile(os.path.join(session_files_path, file_object))]
107
-    now_timestamp = get_utc_timestamp()
108
-    for session_file in session_files:
109
-        last_modified = os.stat(session_file).st_mtime
110
-        expiration_timestamp = last_modified + SESSION_EXPIRATION_LIMIT
111
-        if now_timestamp > expiration_timestamp:
112
-            os.unlink(session_file)
41
+    session_store.clean()
42
+
113
 
43
 
114
-## @brief updates the content session
44
+## @brief updates the content of the session
115
 # @param caller *
45
 # @param caller *
116
-# @param payload dict: datas to insert/update in the session
46
+# @param payload dict : datas to insert/update in the session
117
 @LodelHook('update_session')
47
 @LodelHook('update_session')
118
 def update_session_content(caller, payload):
48
 def update_session_content(caller, payload):
119
     if 'sid' in payload:
49
     if 'sid' in payload:
120
         sid = payload['sid']
50
         sid = payload['sid']
121
-        session = LodelHook.call_hook('session_load', __file__, sid)
122
-        for key, value in payload.items():
123
-            session[key] = value
124
-        save_session(sid, session)
51
+        del payload['sid']
52
+        session_store.update_session(sid, payload)
125
     else:
53
     else:
126
-        raise AuthenticationError("Missing session id in the request")
54
+        raise AuthenticationError("Session Update: Missing sid (session id) in the given payload argument")

Loading…
Cancel
Save