Coverage for src/lexigram/auth/web/middleware/session_authenticator.py: 52%

21 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-26 00:58 +0800

1"""Session-based authentication component.""" 

2 

3from __future__ import annotations 

4 

5from typing import Any 

6 

7from lexigram.contracts import AuthProviderProtocol 

8 

9 

10class SessionAuthenticator: 

11 """Handles session validation and user resolution.""" 

12 

13 def __init__(self, auth_provider: AuthProviderProtocol): 

14 self.auth_provider = auth_provider 

15 

16 async def authenticate(self, request: Any) -> Any: 

17 """Validate session from cookies and return user if valid.""" 

18 session_id = request.cookies.get("session_id") 

19 if not session_id or not self.auth_provider.session_manager: 

20 return None 

21 

22 session = await self.auth_provider.session_manager.validate_session( 

23 session_id, 

24 ) 

25 if not session: 

26 return None 

27 

28 user = await self.auth_provider.get_user(session.user_id) 

29 if not user: 

30 return None 

31 

32 # Store session in request state for downstream use 

33 request.state.session = session 

34 

35 # Pre-fetch delegations for sync check_access 

36 if self.auth_provider.delegation_manager: 

37 request.state.delegations = ( 

38 await self.auth_provider.delegation_manager.get_active_delegations( 

39 user.user_id, 

40 ) 

41 ) 

42 

43 return user 

44 

45 

46__all__ = [ 

47 "SessionAuthenticator", 

48]