Coverage for app/backend/src/couchers/abuse.py: 100%

26 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-15 03:31 +0000

1from couchers.context import CouchersContext 

2from couchers.db import session_scope 

3from couchers.metrics import observe_nonvisible_user_access 

4from couchers.models import ( 

5 NonvisibleUserAccess, 

6 NonvisibleUserAccessType, 

7 NonvisibleUserState, 

8 User, 

9) 

10 

11 

12def nonvisible_user_state(user: User) -> NonvisibleUserState | None: 

13 if user.banned_at is not None: 

14 return NonvisibleUserState.banned 

15 if user.shadowed_at is not None: 

16 return NonvisibleUserState.shadowed 

17 if user.deleted_at is not None: 

18 return NonvisibleUserState.deleted 

19 return None 

20 

21 

22def maybe_log_nonvisible_user_access( 

23 context: CouchersContext, 

24 user: User, 

25 *, 

26 access_type: NonvisibleUserAccessType, 

27 actor_user_id: int | None, 

28) -> None: 

29 target_state = nonvisible_user_state(user) 

30 if target_state is None: 

31 return 

32 

33 if actor_user_id == user.id: 

34 ip_address = context.get_header("x-couchers-real-ip") 

35 user_agent = context.get_header("user-agent") 

36 sofa = context._sofa 

37 else: 

38 ip_address = None 

39 user_agent = None 

40 sofa = None 

41 

42 with session_scope() as session: 

43 session.add( 

44 NonvisibleUserAccess( 

45 access_type=access_type, 

46 target_user_id=user.id, 

47 target_state=target_state, 

48 actor_user_id=actor_user_id, 

49 ip_address=ip_address, 

50 user_agent=user_agent, 

51 sofa=sofa, 

52 ) 

53 ) 

54 

55 observe_nonvisible_user_access(access_type, target_state)