diff --git a/aleksis/core/models.py b/aleksis/core/models.py index 109db7158ede8899691b65c179d0298dee79d6c3..d076019ea175fcc03be612154af937bc655605ef 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -246,6 +246,20 @@ class Person(ExtensibleModel): self.primary_group = self.member_of.filter(name__regex=pattern).first() +class DummyPerson(Person): + """ A dummy person that is not stored into the database. + + Used to temporarily inject a Person object into a User. + """ + + class Meta: + managed = False + proxy = True + + def save(self, *args, **kwargs): + pass + + class Group(ExtensibleModel): """Any kind of group of persons in a school, including, but not limited classes, clubs, and the like. diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py index 6fd8e14951bb0585f2138a37fe384d726f0b4ccc..9d8cf2acfa3e1f9cea3ccde4e1cddfcd95572fa5 100644 --- a/aleksis/core/settings.py +++ b/aleksis/core/settings.py @@ -117,6 +117,7 @@ MIDDLEWARE = [ "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", + "aleksis.core.util.middlewares.EnsurePersonMiddleware", "debug_toolbar.middleware.DebugToolbarMiddleware", "django_otp.middleware.OTPMiddleware", "impersonate.middleware.ImpersonateMiddleware", diff --git a/aleksis/core/util/middlewares.py b/aleksis/core/util/middlewares.py new file mode 100644 index 0000000000000000000000000000000000000000..49d5c2e3eb6a2c36b4f7d2bdcfc915487ff8bee1 --- /dev/null +++ b/aleksis/core/util/middlewares.py @@ -0,0 +1,33 @@ +from typing import Callable + +from django.core.exceptions import PermissionDenied +from django.http import HttpRequest, HttpResponse +from django.util.translation import gettext_lazy as _ + +from .core_helpers import has_person +from .messages import warning +from ..models import DummyPerson + + +class EnsurePersonMiddleware: + """ Middleware that ensures that the logged-in user is linked to a person. + + It is needed to inject a dummy person to a superuser that would otherwise + not have an associated person, in order they can get their account set up + without external help. + """ + + def __init__(self, get_response: Callable): + self.get_response = get_response + + def __call__(self, request: HttpRequest) -> HttpResponse: + if not has_person(request): + if request.user.is_superuser: + # Super-users get a dummy person linked + dummy_person = DummyPerson(first_name=request.user.first_name, last_name=request.user.last_name) + request.user.person = dummy_person + + warning(request, _("A dummy user has been linked to your user account.")) + + response = self.get_response(request) + return response