navigator-session 0.4.3__py3-none-any.whl → 0.4.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- navigator_session/data.py +3 -3
- navigator_session/middleware.py +2 -2
- navigator_session/session.py +3 -4
- navigator_session/storages/abstract.py +4 -4
- navigator_session/storages/cookie.py +3 -2
- navigator_session/storages/redis.py +26 -18
- navigator_session/version.py +1 -1
- {navigator_session-0.4.3.dist-info → navigator_session-0.4.5.dist-info}/METADATA +3 -2
- navigator_session-0.4.5.dist-info/RECORD +15 -0
- navigator_session-0.4.3.dist-info/RECORD +0 -15
- {navigator_session-0.4.3.dist-info → navigator_session-0.4.5.dist-info}/LICENSE +0 -0
- {navigator_session-0.4.3.dist-info → navigator_session-0.4.5.dist-info}/WHEEL +0 -0
- {navigator_session-0.4.3.dist-info → navigator_session-0.4.5.dist-info}/top_level.txt +0 -0
navigator_session/data.py
CHANGED
|
@@ -54,10 +54,10 @@ class SessionData(MutableMapping[str, Any]):
|
|
|
54
54
|
self._new = new if data != {} else True
|
|
55
55
|
self._max_age = max_age if max_age else None
|
|
56
56
|
created = data.get('created', None) if data else None
|
|
57
|
-
self._now = pendulum.now('UTC')
|
|
57
|
+
self._now = pendulum.now('UTC') # time for this instance creation
|
|
58
58
|
self.__created__ = self._now
|
|
59
59
|
now = int(self._now.int_timestamp)
|
|
60
|
-
self._now = now
|
|
60
|
+
self._now = now # time for this instance creation
|
|
61
61
|
age = now - created if created else now
|
|
62
62
|
if max_age is not None and age > max_age:
|
|
63
63
|
data = None
|
|
@@ -75,7 +75,7 @@ class SessionData(MutableMapping[str, Any]):
|
|
|
75
75
|
self.args = args
|
|
76
76
|
|
|
77
77
|
def __repr__(self) -> str:
|
|
78
|
-
return '<{} [new:{}, created:{}] {!r}>'.format(
|
|
78
|
+
return '<{} [new:{}, created:{}] {!r}>'.format( # pylint: disable=C0209
|
|
79
79
|
'NAV-Session ', self.new, self.created, self._data
|
|
80
80
|
)
|
|
81
81
|
|
navigator_session/middleware.py
CHANGED
|
@@ -14,14 +14,14 @@ Middleware = Callable[[web.Request, Handler], Awaitable[web.StreamResponse]]
|
|
|
14
14
|
|
|
15
15
|
### Basic Middleware for Session System
|
|
16
16
|
def session_middleware(
|
|
17
|
-
app: web.Application,
|
|
17
|
+
app: web.Application, # pylint: disable=W0613
|
|
18
18
|
storage: AbstractStorage
|
|
19
19
|
) -> Middleware:
|
|
20
20
|
"""Middleware to attach Session Storage to every Request."""
|
|
21
21
|
if not isinstance(storage, AbstractStorage):
|
|
22
22
|
raise RuntimeError(
|
|
23
23
|
f"Expected an AbstractStorage got {storage!s}"
|
|
24
|
-
|
|
24
|
+
)
|
|
25
25
|
|
|
26
26
|
@web.middleware
|
|
27
27
|
async def middleware(
|
navigator_session/session.py
CHANGED
|
@@ -8,7 +8,7 @@ class SessionHandler:
|
|
|
8
8
|
"""Authentication Backend for Navigator."""
|
|
9
9
|
storage: Callable = None
|
|
10
10
|
|
|
11
|
-
def __init__(self,storage: str = 'redis', **kwargs) -> None:
|
|
11
|
+
def __init__(self, storage: str = 'redis', **kwargs) -> None:
|
|
12
12
|
# TODO: Session Support with parametrization (other storages):
|
|
13
13
|
if storage == 'redis':
|
|
14
14
|
self.storage = RedisStorage(**kwargs)
|
|
@@ -19,9 +19,9 @@ class SessionHandler:
|
|
|
19
19
|
|
|
20
20
|
def setup(self, app: web.Application) -> None:
|
|
21
21
|
if isinstance(app, web.Application):
|
|
22
|
-
self.app = app
|
|
22
|
+
self.app = app # register the app into the Extension
|
|
23
23
|
else:
|
|
24
|
-
self.app = app.get_app()
|
|
24
|
+
self.app = app.get_app() # Nav Application
|
|
25
25
|
## Configure the Middleware for NAV Session.
|
|
26
26
|
self.app.middlewares.append(
|
|
27
27
|
session_middleware(app, self.storage)
|
|
@@ -38,7 +38,6 @@ class SessionHandler:
|
|
|
38
38
|
# register the Auth extension into the app
|
|
39
39
|
self.app['nav_session'] = self
|
|
40
40
|
|
|
41
|
-
|
|
42
41
|
async def session_startup(self, app: web.Application):
|
|
43
42
|
"""
|
|
44
43
|
Calling Session (and Storage) Startup.
|
|
@@ -43,7 +43,7 @@ class AbstractStorage(metaclass=abc.ABCMeta):
|
|
|
43
43
|
httponly: bool = True,
|
|
44
44
|
samesite: Optional[str] = 'Lax',
|
|
45
45
|
**kwargs
|
|
46
|
-
|
|
46
|
+
) -> None:
|
|
47
47
|
if not max_age:
|
|
48
48
|
self.max_age = SESSION_TIMEOUT
|
|
49
49
|
else:
|
|
@@ -105,7 +105,8 @@ class AbstractStorage(metaclass=abc.ABCMeta):
|
|
|
105
105
|
return SessionData(None, data=None, new=True, max_age=self.max_age)
|
|
106
106
|
|
|
107
107
|
@abc.abstractmethod
|
|
108
|
-
async def save_session(
|
|
108
|
+
async def save_session(
|
|
109
|
+
self,
|
|
109
110
|
request: web.Request,
|
|
110
111
|
response: web.StreamResponse,
|
|
111
112
|
session: SessionData
|
|
@@ -128,7 +129,7 @@ class AbstractStorage(metaclass=abc.ABCMeta):
|
|
|
128
129
|
try:
|
|
129
130
|
del request[SESSION_KEY]
|
|
130
131
|
del request[SESSION_OBJECT]
|
|
131
|
-
except Exception as err:
|
|
132
|
+
except Exception as err: # pylint: disable=W0703
|
|
132
133
|
logging.warning(
|
|
133
134
|
f'Session: Error on Forgot Method: {err}'
|
|
134
135
|
)
|
|
@@ -180,7 +181,6 @@ class AbstractStorage(metaclass=abc.ABCMeta):
|
|
|
180
181
|
else:
|
|
181
182
|
response.set_cookie(self.__name__, cookie_data, **params)
|
|
182
183
|
|
|
183
|
-
|
|
184
184
|
def session_info(self, session: SessionData, request: web.Request) -> SessionData:
|
|
185
185
|
"""session_info.
|
|
186
186
|
Session Helper for adding more information extracted from Request.
|
|
@@ -24,7 +24,7 @@ class CookieStorage(AbstractStorage):
|
|
|
24
24
|
path: str = "/",
|
|
25
25
|
secret_key: Union[str, bytes, bytearray, fernet.Fernet] = None,
|
|
26
26
|
**kwargs
|
|
27
|
-
|
|
27
|
+
) -> None:
|
|
28
28
|
super(
|
|
29
29
|
CookieStorage, self
|
|
30
30
|
).__init__(
|
|
@@ -75,7 +75,8 @@ class CookieStorage(AbstractStorage):
|
|
|
75
75
|
async def get_session(self, request: web.Request) -> SessionData:
|
|
76
76
|
pass
|
|
77
77
|
|
|
78
|
-
async def save_session(
|
|
78
|
+
async def save_session(
|
|
79
|
+
self,
|
|
79
80
|
request: web.Request,
|
|
80
81
|
response: web.StreamResponse,
|
|
81
82
|
session: SessionData
|
|
@@ -4,7 +4,7 @@ import logging
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
from collections.abc import Callable
|
|
6
6
|
from aiohttp import web
|
|
7
|
-
import aioredis
|
|
7
|
+
from redis import asyncio as aioredis
|
|
8
8
|
from navigator_session.conf import (
|
|
9
9
|
SESSION_URL,
|
|
10
10
|
SESSION_KEY,
|
|
@@ -24,7 +24,7 @@ class RedisStorage(AbstractStorage):
|
|
|
24
24
|
domain: Optional[str] = None,
|
|
25
25
|
path: str = "/",
|
|
26
26
|
**kwargs
|
|
27
|
-
|
|
27
|
+
) -> None:
|
|
28
28
|
self._redis: Callable = None
|
|
29
29
|
super(
|
|
30
30
|
RedisStorage, self
|
|
@@ -43,20 +43,24 @@ class RedisStorage(AbstractStorage):
|
|
|
43
43
|
decode_responses=True,
|
|
44
44
|
encoding='utf-8'
|
|
45
45
|
)
|
|
46
|
-
except Exception as err:
|
|
46
|
+
except Exception as err: # pylint: disable=W0703
|
|
47
47
|
logging.exception(err, stack_info=True)
|
|
48
48
|
return False
|
|
49
49
|
|
|
50
50
|
async def on_cleanup(self, app: web.Application):
|
|
51
51
|
try:
|
|
52
|
-
await self._redis.disconnect(inuse_connections
|
|
53
|
-
except Exception as ex:
|
|
52
|
+
await self._redis.disconnect(inuse_connections=True)
|
|
53
|
+
except Exception as ex: # pylint: disable=W0703
|
|
54
54
|
logging.warning(ex)
|
|
55
55
|
|
|
56
|
-
async def get_session(
|
|
56
|
+
async def get_session(
|
|
57
|
+
self,
|
|
58
|
+
request: web.Request,
|
|
59
|
+
userdata: dict = None
|
|
60
|
+
) -> SessionData:
|
|
57
61
|
try:
|
|
58
62
|
session = request.get(SESSION_OBJECT)
|
|
59
|
-
except Exception as err:
|
|
63
|
+
except Exception as err: # pylint: disable=W0703
|
|
60
64
|
logging.debug(f'Redis Storage: Error on get Session: {err!s}')
|
|
61
65
|
session = None
|
|
62
66
|
if session is None:
|
|
@@ -83,8 +87,8 @@ class RedisStorage(AbstractStorage):
|
|
|
83
87
|
try:
|
|
84
88
|
# delete the ID of the session
|
|
85
89
|
await conn.delete(session.identity)
|
|
86
|
-
session.invalidate()
|
|
87
|
-
except Exception as err:
|
|
90
|
+
session.invalidate() # invalidate this session object
|
|
91
|
+
except Exception as err: # pylint: disable=W0703
|
|
88
92
|
logging.error(err)
|
|
89
93
|
return False
|
|
90
94
|
return True
|
|
@@ -108,7 +112,7 @@ class RedisStorage(AbstractStorage):
|
|
|
108
112
|
"""
|
|
109
113
|
# TODO: first: for security, check if cookie csrf_secure exists
|
|
110
114
|
session_id = None
|
|
111
|
-
if ignore_cookie is False and
|
|
115
|
+
if ignore_cookie is False and self.use_cookie is True:
|
|
112
116
|
cookie = self.load_cookie(request)
|
|
113
117
|
try:
|
|
114
118
|
session_id = cookie['session_id']
|
|
@@ -135,7 +139,7 @@ class RedisStorage(AbstractStorage):
|
|
|
135
139
|
logging.debug(f':::::: LOAD SESSION FOR {session_id} ::::: ')
|
|
136
140
|
try:
|
|
137
141
|
data = await conn.get(session_id)
|
|
138
|
-
except Exception as err:
|
|
142
|
+
except Exception as err: # pylint: disable=W0703
|
|
139
143
|
logging.error(
|
|
140
144
|
f'Redis Storage: Error Getting Session data: {err!s}'
|
|
141
145
|
)
|
|
@@ -154,7 +158,7 @@ class RedisStorage(AbstractStorage):
|
|
|
154
158
|
new=False,
|
|
155
159
|
max_age=self.max_age
|
|
156
160
|
)
|
|
157
|
-
except Exception as err:
|
|
161
|
+
except Exception as err: # pylint: disable=W0703
|
|
158
162
|
logging.warning(err)
|
|
159
163
|
session = SessionData(
|
|
160
164
|
identity=None,
|
|
@@ -176,7 +180,8 @@ class RedisStorage(AbstractStorage):
|
|
|
176
180
|
self.save_cookie(response, cookie_data=cookie_data, max_age=self.max_age)
|
|
177
181
|
return session
|
|
178
182
|
|
|
179
|
-
async def save_session(
|
|
183
|
+
async def save_session(
|
|
184
|
+
self,
|
|
180
185
|
request: web.Request,
|
|
181
186
|
response: web.StreamResponse,
|
|
182
187
|
session: SessionData
|
|
@@ -198,7 +203,7 @@ class RedisStorage(AbstractStorage):
|
|
|
198
203
|
result = await conn.set(
|
|
199
204
|
session_id, data, expire
|
|
200
205
|
)
|
|
201
|
-
except Exception as err:
|
|
206
|
+
except Exception as err: # pylint: disable=W0703
|
|
202
207
|
print('Error Saving Session: ', err)
|
|
203
208
|
logging.exception(err, stack_info=True)
|
|
204
209
|
return False
|
|
@@ -232,7 +237,7 @@ class RedisStorage(AbstractStorage):
|
|
|
232
237
|
session_id, dt, self.max_age
|
|
233
238
|
)
|
|
234
239
|
logging.info(f'Creation of New Session: {result}')
|
|
235
|
-
except Exception as err:
|
|
240
|
+
except Exception as err: # pylint: disable=W0703
|
|
236
241
|
logging.exception(err)
|
|
237
242
|
return False
|
|
238
243
|
try:
|
|
@@ -248,9 +253,12 @@ class RedisStorage(AbstractStorage):
|
|
|
248
253
|
"session_id": session_id
|
|
249
254
|
}
|
|
250
255
|
cookie_data = self._encoder(cookie_data)
|
|
251
|
-
self.save_cookie(
|
|
252
|
-
|
|
253
|
-
|
|
256
|
+
self.save_cookie(
|
|
257
|
+
response,
|
|
258
|
+
cookie_data=cookie_data,
|
|
259
|
+
max_age=self.max_age
|
|
260
|
+
)
|
|
261
|
+
except Exception as err: # pylint: disable=W0703
|
|
254
262
|
logging.exception(f'Error creating Session Data: {err!s}')
|
|
255
263
|
# Saving Session Object:
|
|
256
264
|
## add other options to session:
|
navigator_session/version.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
__title__ = 'navigator_session'
|
|
6
6
|
__description__ = ('Navigator Session allows us to store user-specific data '
|
|
7
7
|
'into session object.')
|
|
8
|
-
__version__ = '0.4.
|
|
8
|
+
__version__ = '0.4.5'
|
|
9
9
|
__author__ = 'Jesus Lara'
|
|
10
10
|
__author_email__ = 'jesuslarag@gmail.com'
|
|
11
11
|
__license__ = 'Apache-2.0'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: navigator-session
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
4
4
|
Summary: Navigator Session allows us to store user-specific data into session object.
|
|
5
5
|
Home-page: https://github.com/phenobarbital/navigator-session
|
|
6
6
|
Author: Jesus Lara
|
|
@@ -27,12 +27,13 @@ Requires-Python: >=3.9.16
|
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
29
|
Requires-Dist: PyNaCl (==1.5.0)
|
|
30
|
-
Requires-Dist: aiohttp (==3.8.
|
|
30
|
+
Requires-Dist: aiohttp (==3.8.5)
|
|
31
31
|
Requires-Dist: uvloop (==0.17.0)
|
|
32
32
|
Requires-Dist: asyncio (==3.4.3)
|
|
33
33
|
Requires-Dist: navconfig[default] (>=1.0.15)
|
|
34
34
|
Requires-Dist: jsonpickle (==3.0.1)
|
|
35
35
|
Requires-Dist: aioredis (==2.0.1)
|
|
36
|
+
Requires-Dist: redis (==4.5.5)
|
|
36
37
|
Requires-Dist: pendulum (==2.1.2)
|
|
37
38
|
Requires-Dist: python-datamodel (>=0.2.1)
|
|
38
39
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
navigator_session/__init__.py,sha256=xsmc90K04EgQEtYidPN7bsXn0WIqw6GucNwy138Mmno,3038
|
|
2
|
+
navigator_session/conf.py,sha256=PwCGoYpg_2MEq5_zObvbx4yXKf7AIKObO-lzTh2AvxM,1466
|
|
3
|
+
navigator_session/data.py,sha256=9XEaLDRIs3qrIVmeouN2Tx_mTPa2QbLZlB6s4ewelG8,5815
|
|
4
|
+
navigator_session/middleware.py,sha256=kbTFWwY-NrFE-yen7DyOEyWjy8Pfol-5qiXCnm0vGa8,1959
|
|
5
|
+
navigator_session/session.py,sha256=I6qWkMbqIpVX1RjxmccGsk1sCcqWZ_ZBVGwLXjV8wjw,2188
|
|
6
|
+
navigator_session/version.py,sha256=fkvyKMVYoGczSFva3uyYFfnF5fTiOIZWsjHvhZyeGrM,394
|
|
7
|
+
navigator_session/storages/__init__.py,sha256=ln0Xli0lppUopDMrvQGt69BFtUAe1Grmy2DGkEpANNU,132
|
|
8
|
+
navigator_session/storages/abstract.py,sha256=mgtCvUD5KKlkWa-xOUBAoZbtZyPG_R7MbxIDOKGANYU,6074
|
|
9
|
+
navigator_session/storages/cookie.py,sha256=_qL5kIGbT4rtCMze4yj1h4J7Zauz_e7HnorPnFbi90w,2468
|
|
10
|
+
navigator_session/storages/redis.py,sha256=XSNEJ_xuyM-8y6xrraDyF6w_BT_JR4eGyclfa8ZvODo,9361
|
|
11
|
+
navigator_session-0.4.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
+
navigator_session-0.4.5.dist-info/METADATA,sha256=jfelSp2_PhNfw36rwnTKScWJaLCxT-jVc2u6T8Gr574,2403
|
|
13
|
+
navigator_session-0.4.5.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
14
|
+
navigator_session-0.4.5.dist-info/top_level.txt,sha256=ZpOEy3wLKGsxG2rc0nHqcqJCV3HIOG_XCfE6mtsYYYY,18
|
|
15
|
+
navigator_session-0.4.5.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
navigator_session/__init__.py,sha256=xsmc90K04EgQEtYidPN7bsXn0WIqw6GucNwy138Mmno,3038
|
|
2
|
-
navigator_session/conf.py,sha256=PwCGoYpg_2MEq5_zObvbx4yXKf7AIKObO-lzTh2AvxM,1466
|
|
3
|
-
navigator_session/data.py,sha256=CwvOqi0ZfJU4wsppMQ-m-he0PEgim3xdhBhTEYgPucs,5812
|
|
4
|
-
navigator_session/middleware.py,sha256=EE2efxSzcCmh13tDu7_-qGROk6xlD174Fo3j3vCVcx4,1954
|
|
5
|
-
navigator_session/session.py,sha256=k0RuyWix41rmlcTsSHRg5ZDxsU20n4igrRYCwTT6L8M,2186
|
|
6
|
-
navigator_session/version.py,sha256=D8Lt03n0mQ6PxA0E4eMd8aYOcZoWkG0PRzqz5r2JxHw,394
|
|
7
|
-
navigator_session/storages/__init__.py,sha256=ln0Xli0lppUopDMrvQGt69BFtUAe1Grmy2DGkEpANNU,132
|
|
8
|
-
navigator_session/storages/abstract.py,sha256=ceVOCPV7SOEfTq5iKFdjvP9139qQBvvXPFwJsXc9Nis,6069
|
|
9
|
-
navigator_session/storages/cookie.py,sha256=2jmpC4asep_qPH-Lte2aGXLEHi2v4P1U5dpkziP0foY,2463
|
|
10
|
-
navigator_session/storages/redis.py,sha256=CUa05CmMJDLV5lsGqvySrReqUcUD-ylJkuSV2rU838Y,9242
|
|
11
|
-
navigator_session-0.4.3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
12
|
-
navigator_session-0.4.3.dist-info/METADATA,sha256=c_9CBvtXkqWAxwpt8672etLbF3z0hrLulf__gs2BiA4,2372
|
|
13
|
-
navigator_session-0.4.3.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
14
|
-
navigator_session-0.4.3.dist-info/top_level.txt,sha256=ZpOEy3wLKGsxG2rc0nHqcqJCV3HIOG_XCfE6mtsYYYY,18
|
|
15
|
-
navigator_session-0.4.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|