diff --git a/authentik/stages/authenticator_webauthn/forms.py b/authentik/stages/authenticator_webauthn/forms.py index 78368c190..881bf54d7 100644 --- a/authentik/stages/authenticator_webauthn/forms.py +++ b/authentik/stages/authenticator_webauthn/forms.py @@ -1,7 +1,10 @@ """Webauthn stage forms""" from django import forms -from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage +from authentik.stages.authenticator_webauthn.models import ( + AuthenticateWebAuthnStage, + WebAuthnDevice, +) class AuthenticateWebAuthnStageForm(forms.ModelForm): @@ -15,3 +18,16 @@ class AuthenticateWebAuthnStageForm(forms.ModelForm): widgets = { "name": forms.TextInput(), } + + +class DeviceEditForm(forms.ModelForm): + """Form to edit webauthn device""" + + class Meta: + + model = WebAuthnDevice + fields = ["name"] + + widgets = { + "name": forms.TextInput(), + } diff --git a/authentik/stages/authenticator_webauthn/models.py b/authentik/stages/authenticator_webauthn/models.py index f84c0b799..cc63da205 100644 --- a/authentik/stages/authenticator_webauthn/models.py +++ b/authentik/stages/authenticator_webauthn/models.py @@ -79,3 +79,8 @@ class WebAuthnDevice(Device): def __str__(self): return self.name or str(self.user) + + class Meta: + + verbose_name = _("WebAuthn Device") + verbose_name_plural = _("WebAuthn Devices") diff --git a/authentik/stages/authenticator_webauthn/templates/stages/authenticator_webauthn/user_settings.html b/authentik/stages/authenticator_webauthn/templates/stages/authenticator_webauthn/user_settings.html index 89a26a8a3..38daec51a 100644 --- a/authentik/stages/authenticator_webauthn/templates/stages/authenticator_webauthn/user_settings.html +++ b/authentik/stages/authenticator_webauthn/templates/stages/authenticator_webauthn/user_settings.html @@ -17,6 +17,20 @@ Created {{ created_on }} {% endblocktrans %} +
+ + + {% trans 'Update' %} + +
+
+ + + {% trans 'Delete' %} + +
+
+
diff --git a/authentik/stages/authenticator_webauthn/urls.py b/authentik/stages/authenticator_webauthn/urls.py index d163dcc39..bcd10e496 100644 --- a/authentik/stages/authenticator_webauthn/urls.py +++ b/authentik/stages/authenticator_webauthn/urls.py @@ -1,10 +1,16 @@ """WebAuthn urls""" from django.urls import path -from authentik.stages.authenticator_webauthn.views import UserSettingsView +from authentik.stages.authenticator_webauthn.views import ( + DeviceDeleteView, + DeviceUpdateView, + UserSettingsView, +) urlpatterns = [ path( "/settings/", UserSettingsView.as_view(), name="user-settings" ), + path("devices//delete/", DeviceDeleteView.as_view(), name="device-delete"), + path("devices//update/", DeviceUpdateView.as_view(), name="device-update"), ] diff --git a/authentik/stages/authenticator_webauthn/views.py b/authentik/stages/authenticator_webauthn/views.py index 6881fb571..c8954f586 100644 --- a/authentik/stages/authenticator_webauthn/views.py +++ b/authentik/stages/authenticator_webauthn/views.py @@ -1,8 +1,13 @@ """webauthn views""" from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.messages.views import SuccessMessageMixin +from django.http.response import Http404 from django.shortcuts import get_object_or_404 -from django.views.generic import TemplateView +from django.utils.translation import gettext as _ +from django.views.generic import TemplateView, UpdateView +from authentik.admin.views.utils import DeleteMessageView +from authentik.stages.authenticator_webauthn.forms import DeviceEditForm from authentik.stages.authenticator_webauthn.models import ( AuthenticateWebAuthnStage, WebAuthnDevice, @@ -22,3 +27,34 @@ class UserSettingsView(LoginRequiredMixin, TemplateView): ) kwargs["stage"] = stage return kwargs + + +class DeviceUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): + """Update device""" + + model = WebAuthnDevice + form_class = DeviceEditForm + template_name = "generic/update.html" + success_url = "/" + success_message = _("Successfully updated Device") + + def get_object(self) -> WebAuthnDevice: + device: WebAuthnDevice = super().get_object() + if device.user != self.request.user: + raise Http404 + return device + + +class DeviceDeleteView(LoginRequiredMixin, DeleteMessageView): + """Delete device""" + + model = WebAuthnDevice + template_name = "generic/delete.html" + success_url = "/" + success_message = _("Successfully deleted Device") + + def get_object(self) -> WebAuthnDevice: + device: WebAuthnDevice = super().get_object() + if device.user != self.request.user: + raise Http404 + return device