|
3 | 3 | """ |
4 | 4 |
|
5 | 5 | import logging |
6 | | -import time |
7 | 6 |
|
8 | 7 | import aiohttp_session |
9 | 8 | from aiohttp import web |
10 | | -from aiohttp_session.cookie_storage import EncryptedCookieStorage |
11 | 9 | from servicelib.aiohttp.application_setup import ModuleCategory, app_module_setup |
12 | 10 | from settings_library.utils_session import DEFAULT_SESSION_COOKIE_NAME |
13 | 11 |
|
| 12 | +from ._cookie_storage import SharedCookieEncryptedCookieStorage |
14 | 13 | from .settings import SessionSettings, get_plugin_settings |
15 | 14 |
|
16 | 15 | _logger = logging.getLogger(__name__) |
17 | 16 |
|
18 | 17 |
|
19 | | -def _share_cookie_across_all_subdomains( |
20 | | - response: web.StreamResponse, params: aiohttp_session._CookieParams |
21 | | -) -> aiohttp_session._CookieParams: |
22 | | - # share cookie across all subdomains, by appending a dot (`.`) in front of the domain name |
23 | | - # overwrite domain from `None` (browser sets `example.com`) to `.example.com` |
24 | | - request = response._req # pylint:disable=protected-access # noqa: SLF001 |
25 | | - assert isinstance(request, web.Request) # nosec |
26 | | - params["domain"] = f".{request.url.host}" |
27 | | - return params |
28 | | - |
29 | | - |
30 | | -class SharedCookieEncryptedCookieStorage(EncryptedCookieStorage): |
31 | | - async def save_session( |
32 | | - self, |
33 | | - request: web.Request, |
34 | | - response: web.StreamResponse, |
35 | | - session: aiohttp_session.Session, |
36 | | - ) -> None: |
37 | | - # link response to originating request (allows to detect the orginal request url) |
38 | | - response._req = request # pylint:disable=protected-access # noqa: SLF001 |
39 | | - |
40 | | - await super().save_session(request, response, session) |
41 | | - |
42 | | - def save_cookie( |
43 | | - self, |
44 | | - response: web.StreamResponse, |
45 | | - cookie_data: str, |
46 | | - *, |
47 | | - max_age: int | None = None, |
48 | | - ) -> None: |
49 | | - # NOTE: WARNING: the only difference between the superclass and this implementation |
50 | | - # is the statement below where the domain name is set. Adjust in case the base library changes. |
51 | | - params = _share_cookie_across_all_subdomains( |
52 | | - response, self._cookie_params.copy() |
53 | | - ) |
54 | | - |
55 | | - if max_age is not None: |
56 | | - params["max_age"] = max_age |
57 | | - t = time.gmtime(time.time() + max_age) |
58 | | - params["expires"] = time.strftime("%a, %d-%b-%Y %T GMT", t) |
59 | | - if not cookie_data: |
60 | | - |
61 | | - response.del_cookie( |
62 | | - self._cookie_name, domain=params["domain"], path=params["path"] |
63 | | - ) |
64 | | - else: |
65 | | - response.set_cookie(self._cookie_name, cookie_data, **params) |
66 | | - |
67 | | - |
68 | 18 | @app_module_setup( |
69 | 19 | __name__, ModuleCategory.ADDON, settings_name="WEBSERVER_SESSION", logger=_logger |
70 | 20 | ) |
|
0 commit comments