diff --git a/src/dgsi/mixins.py b/src/dgsi/mixins.py
index 63b796c..0a74c14 100644
--- a/src/dgsi/mixins.py
+++ b/src/dgsi/mixins.py
@@ -1,11 +1,50 @@
-from django.contrib.auth.mixins import UserPassesTestMixin
-from django.http import HttpRequest
+from typing import Any
+
+from django.contrib import messages
+from django.contrib.auth.mixins import AccessMixin, UserPassesTestMixin
+from django.http import HttpRequest, HttpResponseBase, HttpResponseRedirect
+from django.urls import reverse_lazy
+from django.utils.translation import gettext_lazy as _
from django.views.generic.base import ContextMixin, TemplateResponseMixin
from django.views.generic.detail import SingleObjectMixin
from dgsi.models import User
+class KanidmAccountRequiredMixin(AccessMixin):
+ """
+ Mixin used to require the existence of a kanidm account.
+ """
+
+ require_radius_secret: bool = False
+
+ def dispatch(
+ self, request: HttpRequest, *args: Any, **kwargs: Any
+ ) -> HttpResponseBase:
+ if not request.user.is_authenticated:
+ return self.handle_no_permission()
+
+ self._user = User.from_request(request)
+
+ if self._user.kanidm is None:
+ messages.add_message(
+ request,
+ messages.WARNING,
+ _("Veuillez créer un compte DGNum."),
+ )
+ return HttpResponseRedirect(reverse_lazy("dgsi:dgn-create_self_account"))
+
+ if self.require_radius_secret and self._user.kanidm.radius_secret is None:
+ messages.add_message(
+ request,
+ messages.WARNING,
+ _("Veuillez générer un mot de passe Wi-Fi."),
+ )
+ return HttpResponseRedirect(reverse_lazy("dgsi:dgn-profile"))
+
+ return super().dispatch(request, *args, **kwargs) # type: ignore
+
+
class StaffRequiredMixin(UserPassesTestMixin):
request: HttpRequest
diff --git a/src/dgsi/views.py b/src/dgsi/views.py
index 5ce1e5e..205216b 100644
--- a/src/dgsi/views.py
+++ b/src/dgsi/views.py
@@ -17,7 +17,11 @@ from django.views.generic import FormView, ListView, RedirectView, TemplateView,
from django.views.generic.detail import SingleObjectMixin
from dgsi.forms import CreateKanidmAccountForm, CreateSelfAccountForm
-from dgsi.mixins import HtmxPostObjectMixin, StaffRequiredMixin
+from dgsi.mixins import (
+ HtmxPostObjectMixin,
+ KanidmAccountRequiredMixin,
+ StaffRequiredMixin,
+)
from dgsi.models import Archive, Bylaws, Service, Statutes, User
from shared.kanidm import klient
@@ -72,37 +76,11 @@ class ProfileView(LoginRequiredMixin, TemplateView):
template_name = "dgsi/profile.html"
-class AppleProfileView(AccessMixin, TemplateView):
+class AppleProfileView(KanidmAccountRequiredMixin, TemplateView):
content_type = "application/x-apple-aspen-config"
template_name = "dgnum_profile.mobileconfig"
extra_context = {"dgnum_ssid": "DGNum 2G (N)"}
-
- def dispatch(
- self, request: HttpRequest, *args: Any, **kwargs: Any
- ) -> HttpResponseBase:
- if not request.user.is_authenticated:
- return self.handle_no_permission()
-
- u = User.from_request(request)
-
- # Check that the user does not already exist
- if u.kanidm is None:
- messages.add_message(
- request,
- messages.WARNING,
- _("Veuillez créer un compte DGNum."),
- )
- return HttpResponseRedirect(reverse_lazy("dgsi:dgn-create_self_account"))
-
- if u.kanidm.radius_secret is None:
- messages.add_message(
- request,
- messages.WARNING,
- _("Veuillez générer un mot de passe Wi-Fi."),
- )
- return HttpResponseRedirect(reverse_lazy("dgsi:dgn-profile"))
-
- return super().dispatch(request, *args, **kwargs)
+ require_radius_secret = True
def render_to_response(
self, context: dict[str, Any], **response_kwargs: Any