Coverage for src/mesh/model/user/auth.py: 87%

23 statements  

« prev     ^ index     » next       coverage.py v7.7.0, created at 2025-04-28 07:45 +0000

1from django.contrib.auth.backends import ModelBackend 

2from django.contrib.auth.base_user import AbstractBaseUser 

3from django.http.request import HttpRequest 

4 

5from mesh.model.roles.role_handler import ROLE_HANDLER_CACHE, RoleHandler 

6from mesh.models.user_models import UserToken 

7 

8 

9class TokenBackend(ModelBackend): 

10 """ 

11 Authenticates against `UserToken`. 

12 Only succeeds if the derived user is allowed to use the token authentication. 

13 

14 Only the authenticate method is overwritten. The standard get_user from an user ID 

15 stays the same as the default `ModelBackend`. 

16 """ 

17 

18 def authenticate( 

19 self, request: HttpRequest, token: str | None = None 

20 ) -> AbstractBaseUser | None: 

21 if token is None: 21 ↛ 22line 21 didn't jump to line 22 because the condition on line 21 was never true

22 return None 

23 

24 try: 

25 token_obj = UserToken.objects.select_related("user").get(key=token) 

26 except UserToken.DoesNotExist: 

27 return None 

28 

29 if token_obj.is_expired: 29 ↛ 30line 29 didn't jump to line 30 because the condition on line 29 was never true

30 return None 

31 

32 user = token_obj.user 

33 # Token authentication might be forbidden at User object level. 

34 if not getattr(user, "is_token_authentication_allowed", False): 

35 return None 

36 

37 # We need the role handler logic in order to derive whether 

38 # the user is allowed to authenticate using the token method. 

39 # As this is quite expensive, we cache the `RoleHandler` in the request 

40 # to avoid having to repopulate it later. 

41 role_handler = RoleHandler(user, request, partial_init=True) 

42 if not role_handler.token_authentication_allowed(): 

43 return None 

44 

45 setattr(request, ROLE_HANDLER_CACHE, role_handler) 

46 return token_obj.user