Coverage for src / local_deep_research / web / auth / password_utils.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-14 23:55 +0000

1""" 

2Shared utility for retrieving user passwords from available session sources. 

3 

4Centralises the 3-source fallback chain (session password store → Flask g → 

5temp auth store) so every route that needs the current user's DB password 

6uses the same logic. Without this, each route reimplemented the chain 

7independently, risking subtle divergence (e.g. one route forgetting to 

8check temp_auth, or using a different method alias). 

9""" 

10 

11from typing import Optional 

12 

13from flask import g, session 

14 

15 

16def get_user_password(username: str) -> Optional[str]: 

17 """Retrieve user password from available session sources. 

18 

19 Checks, in order: 

20 1. SessionPasswordStore (persistent per-session passwords) 

21 2. Flask ``g.user_password`` (set by middleware when temp_auth was used) 

22 3. TempAuthStore (one-time tokens stored during login redirect) 

23 

24 Returns ``None`` when no password can be found — callers must decide 

25 whether that is acceptable (e.g. non-encrypted databases) or an error 

26 (encrypted databases → 401). 

27 """ 

28 from ...database.session_passwords import session_password_store 

29 

30 session_id = session.get("session_id") 

31 if session_id: 

32 password = session_password_store.get_session_password( 

33 username, session_id 

34 ) 

35 if password: 

36 return password 

37 

38 password = getattr(g, "user_password", None) 

39 if password: 

40 return password 

41 

42 from ...database.temp_auth import temp_auth_store 

43 

44 auth_token = session.get("temp_auth_token") 

45 if auth_token: 

46 auth_data = temp_auth_store.peek_auth(auth_token) 

47 if auth_data and auth_data[0] == username: 

48 return auth_data[1] 

49 

50 return None