|
@@ -12,113 +12,6 @@ from lodel.plugin import SessionHandlerPlugin as SessionHandler
|
12
|
12
|
from .exceptions import *
|
13
|
13
|
from ..leapi.query import LeGetQuery
|
14
|
14
|
|
15
|
|
-##@brief Class designed to handle sessions and its datas
|
16
|
|
-class LodelSession(object):
|
17
|
|
-
|
18
|
|
- ##@brief Try to restore or to create a session
|
19
|
|
- #@param token None | mixed : If None no session will be loaded nor created
|
20
|
|
- #restore an existing session
|
21
|
|
- #@throw ClientAuthenticationFailure if a session restore fails
|
22
|
|
- def __init__(self, token = None):
|
23
|
|
- ##@brief Stores the session token
|
24
|
|
- self.__token = token
|
25
|
|
- ##@brief Stores the session datas
|
26
|
|
- self.__datas = dict()
|
27
|
|
- if token is not None:
|
28
|
|
- self.restore(token)
|
29
|
|
-
|
30
|
|
- ##@brief A token reference checker to ensure token deletion at the end of
|
31
|
|
- #a session
|
32
|
|
- #@warning Cause maybe a performance issue !
|
33
|
|
- def __token_checker(self):
|
34
|
|
- refcount = sys.getrefcount(self.__token)
|
35
|
|
- if self.__token is not None and refcount > 1:
|
36
|
|
- warnings.warn("More than one reference to the session token \
|
37
|
|
-exists ! (exactly %d)" % refcount)
|
38
|
|
-
|
39
|
|
- ##@brief Property. Equals True if a session is started else False
|
40
|
|
- @property
|
41
|
|
- def started(self):
|
42
|
|
- res = self.__token is not None
|
43
|
|
- if res:
|
44
|
|
- self.__token_checker()
|
45
|
|
- return res
|
46
|
|
-
|
47
|
|
- ##@brief Property that ensure ro acces to sessions datas
|
48
|
|
- @property
|
49
|
|
- def datas(self):
|
50
|
|
- return copy.copy(self.__datas)
|
51
|
|
-
|
52
|
|
- ##@brief Return the session token
|
53
|
|
- def retrieve_token(self):
|
54
|
|
- # DO NOT COPY THE TOKEN TO ENSURE THAT NOT MORE THAN ONE REFERENCE TO
|
55
|
|
- # IT EXISTS
|
56
|
|
- return self.__token
|
57
|
|
-
|
58
|
|
- ##@brief Late restore of a session
|
59
|
|
- #@param token mixed : the session token
|
60
|
|
- #@throw ClientAuthenticationError if a session was allready started
|
61
|
|
- #@throw ClientAuthenticationFailure if no session exists with this token
|
62
|
|
- def restore(self, token):
|
63
|
|
- if self.started:
|
64
|
|
- raise ClientAuthenticationError("Trying to restore a session, but \
|
65
|
|
-a session is allready started !!!")
|
66
|
|
- self.__datas = SessionHandler.restore(token)
|
67
|
|
- self.__token = token
|
68
|
|
- return self.datas
|
69
|
|
-
|
70
|
|
- ##@brief Save the current session state
|
71
|
|
- def save(self):
|
72
|
|
- if not self.started:
|
73
|
|
- raise ClientAuthenticationError(
|
74
|
|
- "Trying to save a non started session")
|
75
|
|
- SessionHandler.save(self.__token, self.__datas)
|
76
|
|
-
|
77
|
|
- ##@brief Destroy a session
|
78
|
|
- def destroy(self):
|
79
|
|
- if not self.started:
|
80
|
|
- logger.debug("Destroying a session that is not started")
|
81
|
|
- else:
|
82
|
|
- SessionHandler.destroy(self.__token)
|
83
|
|
- self.__token = None
|
84
|
|
- self.__datas = dict()
|
85
|
|
-
|
86
|
|
- ##@brief Destructor
|
87
|
|
- def __del__(self):
|
88
|
|
- del(self.__token)
|
89
|
|
- del(self.__datas)
|
90
|
|
-
|
91
|
|
- ##@brief Implements setter for dict access to instance
|
92
|
|
- #@todo Custom exception throwing
|
93
|
|
- def __setitem__(self, key, value):
|
94
|
|
- self.__init_session() #Start the sesssion
|
95
|
|
- self.__datas[key] = value
|
96
|
|
-
|
97
|
|
- ##@brief Implements destructor for dict access to instance
|
98
|
|
- #@todo Custom exception throwing
|
99
|
|
- def __delitem__(self, key):
|
100
|
|
- if not self.started:
|
101
|
|
- raise ClientAuthenticationError(
|
102
|
|
- "Data read access to a non started session is not possible")
|
103
|
|
- del(self.__datas[key])
|
104
|
|
-
|
105
|
|
- ##@brief Implements getter for dict acces to instance
|
106
|
|
- #@todo Custom exception throwing
|
107
|
|
- def __getitem__(self, key):
|
108
|
|
- if not self.started:
|
109
|
|
- raise ClientAuthenticationError(
|
110
|
|
- "Data read access to a non started session is not possible")
|
111
|
|
- return self.__datas[key]
|
112
|
|
-
|
113
|
|
- ##@brief Start a new session
|
114
|
|
- #@note start a new session only if no session started yet
|
115
|
|
- def __init_session(self):
|
116
|
|
- if self.__token is not None:
|
117
|
|
- return
|
118
|
|
- self.__token = SessionHandler.start()
|
119
|
|
-
|
120
|
|
-
|
121
|
|
-
|
122
|
15
|
##@brief Client metaclass designed to implements container accessor on
|
123
|
16
|
#Client Class
|
124
|
17
|
#
|
|
@@ -129,13 +22,16 @@ class ClientMetaclass(type):
|
129
|
22
|
return super(ClientMetaclass, self).__init__(name, bases, attrs)
|
130
|
23
|
|
131
|
24
|
def __getitem__(self, key):
|
132
|
|
- return self.session()[key]
|
|
25
|
+ return self.datas()[key]
|
133
|
26
|
|
134
|
27
|
def __delitem__(self, key):
|
135
|
|
- del(self.session()[key])
|
|
28
|
+ del(self.datas()[key])
|
136
|
29
|
|
137
|
30
|
def __setitem__(self, key, value):
|
138
|
|
- self.session()[key] = value
|
|
31
|
+ if self.get_session_token() is None:
|
|
32
|
+ self.set_session_token(SessionHandler.start())
|
|
33
|
+ datas = self.datas()
|
|
34
|
+ datas[key] = value
|
139
|
35
|
|
140
|
36
|
def __str__(self):
|
141
|
37
|
return str(self._instance)
|
|
@@ -169,6 +65,7 @@ class Client(object, metaclass = ClientMetaclass):
|
169
|
65
|
##@brief Constructor
|
170
|
66
|
#@param session_token mixed : Session token provided by client to interface
|
171
|
67
|
def __init__(self,session_token = None):
|
|
68
|
+ logger.debug(session_token)
|
172
|
69
|
if self.__class__ == Client:
|
173
|
70
|
raise NotImplementedError("Abstract class")
|
174
|
71
|
logger.debug("New instance of Client child class %s" %
|
|
@@ -186,12 +83,36 @@ class Client(object, metaclass = ClientMetaclass):
|
186
|
83
|
##@brief Stores the session handler
|
187
|
84
|
Client._instance = self
|
188
|
85
|
##@brief Stores LodelSession instance
|
189
|
|
- self.__session = LodelSession(session_token)
|
|
86
|
+
|
|
87
|
+ self.__datas = dict()
|
|
88
|
+ if session_token is not None:
|
|
89
|
+ self.__datas = SessionHandler.restore(session_token)
|
|
90
|
+ self.__session_token = session_token
|
|
91
|
+
|
190
|
92
|
logger.debug("New client : %s" % self)
|
191
|
93
|
|
192
|
94
|
def __del__(self):
|
193
|
|
- del(self.__session)
|
|
95
|
+ del(self.__session_token)
|
|
96
|
+ del(self.__datas)
|
194
|
97
|
|
|
98
|
+ @classmethod
|
|
99
|
+ def datas(cls):
|
|
100
|
+ return cls._instance.__datas
|
|
101
|
+
|
|
102
|
+ @classmethod
|
|
103
|
+ def user(cls):
|
|
104
|
+ if '__auth_user_infos' in cls._instance.__datas:
|
|
105
|
+ return cls._instance.__datas['__auth_user_infos']
|
|
106
|
+ else:
|
|
107
|
+ return None
|
|
108
|
+ @classmethod
|
|
109
|
+ def get_session_token(cls):
|
|
110
|
+ return cls._instance.__session_token
|
|
111
|
+
|
|
112
|
+ @classmethod
|
|
113
|
+ def set_session_token(cls, value):
|
|
114
|
+ cls._instance.__session_token = value
|
|
115
|
+
|
195
|
116
|
##@brief Try to authenticate a user with a login and a password
|
196
|
117
|
#@param login str : provided login
|
197
|
118
|
#@param password str : provided password (hash)
|
|
@@ -236,31 +157,34 @@ class Client(object, metaclass = ClientMetaclass):
|
236
|
157
|
@classmethod
|
237
|
158
|
def restore_session(cls, token):
|
238
|
159
|
cls._assert_instance()
|
239
|
|
- return Client._instance.__session.restore(token)
|
|
160
|
+ if cls._instance.__session_token is not None:
|
|
161
|
+ raise ClientAuthenticationError("Trying to restore a session, but \
|
|
162
|
+a session is allready started !!!")
|
|
163
|
+ cls._instance.__datas = SessionHandler.restore(token)
|
|
164
|
+ cls._instance.__session_token = token
|
|
165
|
+ return copy.copy(cls._instance.datas)
|
240
|
166
|
|
241
|
167
|
##@brief Return the current session token or None
|
242
|
168
|
#@return A session token or None
|
243
|
169
|
@classmethod
|
244
|
170
|
def session_token(cls):
|
245
|
171
|
cls._assert_instance()
|
246
|
|
- return Client._instance.__session.retrieve_token()
|
|
172
|
+ return cls._instance.__session_token
|
247
|
173
|
|
248
|
|
- @classmethod
|
249
|
|
- def session(cls):
|
250
|
|
- cls._assert_instance()
|
251
|
|
- return Client._instance.__session
|
252
|
|
-
|
|
174
|
+
|
253
|
175
|
##@brief Delete current session
|
254
|
176
|
@classmethod
|
255
|
177
|
def destroy(cls):
|
256
|
178
|
cls._assert_instance()
|
257
|
|
- Client._instance.__session.destroy()
|
|
179
|
+ SessionHandler.destroy(cls._instance.__session_token)
|
|
180
|
+ cls._instance.__session_token = None
|
|
181
|
+ cls._instance.__datas = dict()
|
258
|
182
|
|
259
|
183
|
##@brief Delete current client and save its session
|
260
|
184
|
@classmethod
|
261
|
185
|
def clean(cls):
|
262
|
|
- if Client._instance.__session.started:
|
263
|
|
- Client._instance.__session.save()
|
|
186
|
+ if cls._instance.__session_token is not None:
|
|
187
|
+ SessionHandler.save(cls._instance.__session_token, cls._instance.__datas)
|
264
|
188
|
if Client._instance is not None:
|
265
|
189
|
del(Client._instance)
|
266
|
190
|
Client._instance = None
|
|
@@ -269,16 +193,8 @@ class Client(object, metaclass = ClientMetaclass):
|
269
|
193
|
#@return True if client is anonymous
|
270
|
194
|
@classmethod
|
271
|
195
|
def is_anonymous(cls):
|
272
|
|
- return cls._assert_instance()
|
273
|
|
- #return Client._instance
|
|
196
|
+ return Client._instance.user() is None
|
274
|
197
|
|
275
|
|
- ##@brief Test wether a client is guest or logged in
|
276
|
|
- #@return True if client is anonymous
|
277
|
|
- #@ TODO : to be improved
|
278
|
|
- @classmethod
|
279
|
|
- def is_guest(cls):
|
280
|
|
- return len(cls._instance.__session.datas) == 1
|
281
|
|
-
|
282
|
198
|
##@brief Method to call on authentication failure
|
283
|
199
|
#@throw ClientAuthenticationFailure
|
284
|
200
|
#@throw LodelFatalError if no Client child instance found
|
|
@@ -358,9 +274,8 @@ login EmClass '%s' and password EmClass '%s'. Abording..." % (
|
358
|
274
|
#@param uid str : uniq id (in leo)
|
359
|
275
|
#@return None
|
360
|
276
|
@classmethod
|
361
|
|
- def __set_authenticated(self, leo, uid):
|
362
|
|
- self.__user = {'classname': leo.__name__, 'uid': uid, 'leoclass': leo}
|
|
277
|
+ def __set_authenticated(cls, leo, uid):
|
|
278
|
+ cls._instance.__user = {'classname': leo.__name__, 'uid': uid, 'leoclass': leo}
|
363
|
279
|
#Store auth infos in session
|
364
|
|
- self._instance.__session[self._instance.__class__._AUTH_DATANAME] = copy.copy(self.__user)
|
365
|
|
-
|
366
|
|
-
|
|
280
|
+ cls._instance.__datas[cls._instance.__class__._AUTH_DATANAME] = copy.copy(cls._instance.__user)
|
|
281
|
+
|