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
« 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
5from mesh.model.roles.role_handler import ROLE_HANDLER_CACHE, RoleHandler
6from mesh.models.user_models import UserToken
9class TokenBackend(ModelBackend):
10 """
11 Authenticates against `UserToken`.
12 Only succeeds if the derived user is allowed to use the token authentication.
14 Only the authenticate method is overwritten. The standard get_user from an user ID
15 stays the same as the default `ModelBackend`.
16 """
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
24 try:
25 token_obj = UserToken.objects.select_related("user").get(key=token)
26 except UserToken.DoesNotExist:
27 return None
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
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
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
45 setattr(request, ROLE_HANDLER_CACHE, role_handler)
46 return token_obj.user