Coverage for baibu/users/middleware.py: 100%
26 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-10-06 13:07 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-10-06 13:07 +0000
1from urllib.parse import urlencode
3from django.conf import settings
4from django.http import HttpRequest
5from django.http import HttpResponseRedirect
6from django.urls import reverse
9def missing_profile_fields(user) -> list[str]:
10 return [field for field in settings.PROFILE_REQUIRED_FIELDS if not getattr(user, field, "")]
13class ProfileCompletionMiddleware:
14 """Send signed-in users with an incomplete profile to the completion form.
16 Which fields are required is set by PROFILE_REQUIRED_FIELDS.
17 """
19 def __init__(self, get_response):
20 self.get_response = get_response
22 def __call__(self, request: HttpRequest):
23 return self._maybe_redirect(request) or self.get_response(request)
25 def _maybe_redirect(self, request: HttpRequest):
26 user = getattr(request, "user", None)
27 if not user or not user.is_authenticated or not missing_profile_fields(user):
28 return None
30 completion_path = reverse("users:complete_profile")
31 path = request.path
32 exempt_prefixes = [
33 completion_path,
34 reverse("terms"),
35 reverse("privacy"),
36 "/health/",
37 "/i18n/",
38 settings.STATIC_URL,
39 settings.MEDIA_URL,
40 ]
41 # Sign-in and sign-out pages, unprefixed and in every language.
42 language_prefixes = ["/", *(f"/{code}/" for code, _name in settings.LANGUAGES)]
43 exempt_prefixes += [f"{prefix}accounts/" for prefix in language_prefixes]
44 if user.is_staff:
45 exempt_prefixes += [f"{prefix}{settings.ADMIN_URL}" for prefix in language_prefixes]
46 if any(path.startswith(prefix) for prefix in exempt_prefixes):
47 return None
48 return HttpResponseRedirect(f"{completion_path}?{urlencode({'next': path})}")