Coverage for nexios\session\signed_cookies.py: 72%

40 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-21 20:31 +0100

1from itsdangerous import URLSafeTimedSerializer, BadSignature # type:ignore 

2import typing 

3from nexios.config import get_config 

4from .base import BaseSessionInterface 

5 

6 

7class SignedSessionManager(BaseSessionInterface): 

8 def __init__(self, session_key: str): 

9 super().__init__(session_key) 

10 config = get_config() 

11 self.secret_key = config.secret_key 

12 self.serializer = URLSafeTimedSerializer( 

13 secret_key=config.secret_key, # type:ignore 

14 salt="nexio.session.signed_cookie", 

15 ) 

16 session_key = session_key 

17 

18 def sign_session_data(self, session_data: typing.Dict[str, typing.Any]) -> str: 

19 """ 

20 Sign the session data and return a signed token (cookie value). 

21 """ 

22 return self.serializer.dumps(session_data) # type:ignore 

23 

24 def verify_session_data( 

25 self, token: str 

26 ) -> typing.Optional[typing.Dict[str, typing.Any]]: 

27 """ 

28 Verify and deserialize the signed session token. 

29 Returns the session data if valid, or None if invalid. 

30 """ 

31 if not token: 

32 return {} 

33 try: 

34 session_data = self.serializer.loads(token) # type:ignore 

35 

36 return session_data # type:ignore 

37 except BadSignature: 

38 

39 return {} 

40 

41 def get_session_cookie(self) -> str: 

42 """ 

43 Returns the session cookie that contains the signed session data. 

44 """ 

45 return self.sign_session_data(self._session_cache) 

46 

47 def load_session_from_cookie( 

48 self, cookie: str 

49 ) -> typing.Optional[typing.Dict[str, typing.Any]]: 

50 cookie = self.session_key 

51 

52 """ 

53 Load the session data from a signed cookie, and verify it. 

54 """ 

55 return self.verify_session_data(cookie) 

56 

57 async def save(self): # type:ignore 

58 """ 

59 Save the current session state as a signed cookie. 

60 """ 

61 signed_session = self.get_session_cookie() 

62 self.session_key = signed_session 

63 return signed_session 

64 

65 async def load(self): 

66 cookie = self.session_key 

67 """ 

68 Load the session data from a signed cookie. 

69 """ 

70 session_data = self.load_session_from_cookie(cookie) 

71 

72 if session_data: 

73 self._session_cache.update(session_data) 

74 else: 

75 self._session_cache = {} 

76 

77 def clear(self): 

78 self._session_cache.clear()