Coverage for paperless/auth.py: 60%
48 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 09:07 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 09:07 +0000
1import logging
3from allauth.mfa.adapter import get_adapter as get_mfa_adapter
4from django.conf import settings
5from django.contrib import auth
6from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
7from django.contrib.auth.models import User
8from django.http import HttpRequest
9from django.utils.deprecation import MiddlewareMixin
10from rest_framework import authentication
11from rest_framework import exceptions
13logger = logging.getLogger("paperless.auth")
16class AutoLoginMiddleware(MiddlewareMixin):
17 def process_request(self, request: HttpRequest) -> None:
18 # Dont use auto-login with token request
19 if request.path.startswith("/api/token/") and request.method == "POST":
20 return None
21 try:
22 request.user = User.objects.get(
23 username=settings.AUTO_LOGIN_USERNAME,
24 is_active=True,
25 )
26 auth.login(
27 request=request,
28 user=request.user,
29 backend="django.contrib.auth.backends.ModelBackend",
30 )
31 except User.DoesNotExist:
32 pass
35class AngularApiAuthenticationOverride(authentication.BaseAuthentication):
36 """This class is here to provide authentication to the angular dev server
37 during development. This is disabled in production.
38 """
40 def authenticate(self, request):
41 if (
42 settings.DEBUG
43 and "Referer" in request.headers
44 and request.headers["Referer"].startswith("http://localhost:4200/")
45 ):
46 user = User.objects.filter(is_staff=True).first()
47 logger.debug(f"Auto-Login with user {user}")
48 return (user, None)
49 else:
50 return None
53class HttpRemoteUserMiddleware(PersistentRemoteUserMiddleware):
54 """This class allows authentication via HTTP_REMOTE_USER which is set for
55 example by certain SSO applications.
56 """
58 header = settings.HTTP_REMOTE_USER_HEADER_NAME
60 def __call__(self, request: HttpRequest) -> None:
61 # If remote user auth is enabled only for the frontend, not the API,
62 # then we need dont want to authenticate the user for API requests.
63 if (
64 "/api/" in request.path
65 and "paperless.auth.PaperlessRemoteUserAuthentication"
66 not in settings.REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]
67 ):
68 return self.get_response(request)
69 return super().__call__(request)
72class PaperlessRemoteUserAuthentication(authentication.RemoteUserAuthentication):
73 """
74 REMOTE_USER authentication for DRF which overrides the default header.
75 """
77 header = settings.HTTP_REMOTE_USER_HEADER_NAME
80class PaperlessBasicAuthentication(authentication.BasicAuthentication):
81 def authenticate(self, request):
82 user_tuple = super().authenticate(request)
83 user = user_tuple[0] if user_tuple else None
84 mfa_adapter = get_mfa_adapter()
85 if user and mfa_adapter.is_mfa_enabled(user): 85 ↛ 86line 85 didn't jump to line 86 because the condition on line 85 was never true
86 raise exceptions.AuthenticationFailed("MFA required")
88 return user_tuple
90 def authenticate_header(self, request):
91 auth_header = request.META.get("HTTP_AUTHORIZATION", "")
92 if auth_header.lower().startswith("basic "):
93 return super().authenticate_header(request)
95 # Still 401 for anonymous API access
96 return authentication.TokenAuthentication.keyword