|
1 | | -import base64 |
2 | 1 | from collections import namedtuple |
3 | 2 | from importlib import import_module |
| 3 | +import os |
4 | 4 |
|
5 | 5 | from aiohttp import web, web_request |
6 | 6 | from aiohttp.web_exceptions import HTTPUnauthorized, HTTPForbidden |
|
10 | 10 | from aiohttp_security.abc import AbstractAuthorizationPolicy |
11 | 11 | from aiohttp_session import setup as setup_session |
12 | 12 | from aiohttp_session.cookie_storage import EncryptedCookieStorage |
13 | | -from cryptography import fernet |
14 | 13 |
|
15 | 14 | from app.service.interfaces.i_auth_svc import AuthServiceInterface |
16 | 15 | from app.service.interfaces.i_login_handler import LoginHandlerInterface |
@@ -73,9 +72,35 @@ async def apply(self, app, users): |
73 | 72 | for username, password in user.items(): |
74 | 73 | await self.create_user(username, password, group) |
75 | 74 | app.user_map = self.user_map |
76 | | - fernet_key = fernet.Fernet.generate_key() |
77 | | - secret_key = base64.urlsafe_b64decode(fernet_key) |
78 | | - storage = EncryptedCookieStorage(secret_key, cookie_name=COOKIE_SESSION) |
| 75 | + cookie_file = 'cookie_storage' |
| 76 | + expiration_days = self.get_config('session_expiration_days') |
| 77 | + file_svc = self.get_service('file_svc') |
| 78 | + cookie_path = os.path.join('data', cookie_file) |
| 79 | + |
| 80 | + # Safely calculate max_age in seconds, allowing for fractional days |
| 81 | + try: |
| 82 | + max_age = int(float(expiration_days) * 86400) if expiration_days else None |
| 83 | + except (ValueError, TypeError): |
| 84 | + max_age = None |
| 85 | + try: |
| 86 | + if os.path.exists(cookie_path): |
| 87 | + secret_key = file_svc._read(cookie_path) |
| 88 | + self.log.debug('Loaded persistent session key from data/cookie_storage') |
| 89 | + else: |
| 90 | + # Generate a new random 32-byte key for AES encryption if no valid key is found in the config or data folder |
| 91 | + secret_key = os.urandom(32) |
| 92 | + file_svc._save(cookie_path, secret_key, encrypt=True) |
| 93 | + self.log.debug('Generated and saved new persistent session key.') |
| 94 | + except Exception as e: |
| 95 | + # Fallback if file operations fail |
| 96 | + self.log.warning('Could not manage persistent key file, falling back to ephemeral: %s', e) |
| 97 | + secret_key = os.urandom(32) |
| 98 | + if len(secret_key) != 32: |
| 99 | + secret_key = os.urandom(32) |
| 100 | + self.log.warning('Loaded session key is not 32 bytes long. Generating new key.') |
| 101 | + |
| 102 | + # Pass max_age to the storage initializer |
| 103 | + storage = EncryptedCookieStorage(secret_key, cookie_name=COOKIE_SESSION, max_age=max_age) |
79 | 104 | setup_session(app, storage) |
80 | 105 | policy = SessionIdentityPolicy() |
81 | 106 | setup_security(app, policy, DictionaryAuthorizationPolicy(self.user_map)) |
|
0 commit comments