stages/password: migrate settings to webcomponents

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-03-24 18:01:21 +01:00
parent ab5d6dbea1
commit 1ef5a8e6c5
10 changed files with 47 additions and 62 deletions

View File

@ -1,5 +1,4 @@
"""WebAuthn stage""" """WebAuthn stage"""
from authentik.core.types import UserSettingSerializer
from typing import Optional, Type from typing import Optional, Type
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
@ -11,6 +10,7 @@ from django.views import View
from django_otp.models import Device from django_otp.models import Device
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage from authentik.flows.models import ConfigurableStage, Stage

View File

@ -1,9 +1,7 @@
"""WebAuthn urls""" """WebAuthn urls"""
from django.urls import path from django.urls import path
from authentik.stages.authenticator_webauthn.views import ( from authentik.stages.authenticator_webauthn.views import DeviceUpdateView
DeviceUpdateView,
)
urlpatterns = [ urlpatterns = [
path("devices/<int:pk>/update/", DeviceUpdateView.as_view(), name="device-update"), path("devices/<int:pk>/update/", DeviceUpdateView.as_view(), name="device-update"),

View File

@ -6,9 +6,8 @@ from django.utils.translation import gettext as _
from django.views.generic import UpdateView from django.views.generic import UpdateView
from authentik.stages.authenticator_webauthn.forms import DeviceEditForm from authentik.stages.authenticator_webauthn.forms import DeviceEditForm
from authentik.stages.authenticator_webauthn.models import ( from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
WebAuthnDevice,
)
class DeviceUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView): class DeviceUpdateView(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
"""Update device""" """Update device"""

View File

@ -8,4 +8,3 @@ class AuthentikStagePasswordConfig(AppConfig):
name = "authentik.stages.password" name = "authentik.stages.password"
label = "authentik_stages_password" label = "authentik_stages_password"
verbose_name = "authentik Stages.Password" verbose_name = "authentik Stages.Password"
mountpoint = "-/user/password/"

View File

@ -4,12 +4,11 @@ from typing import Optional, Type
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.db import models from django.db import models
from django.forms import ModelForm from django.forms import ModelForm
from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views import View from django.views import View
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
from authentik.flows.challenge import Challenge, ChallengeTypes from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage from authentik.flows.models import ConfigurableStage, Stage
@ -49,17 +48,13 @@ class PasswordStage(ConfigurableStage, Stage):
return PasswordStageForm return PasswordStageForm
@property @property
def ui_user_settings(self) -> Optional[Challenge]: def ui_user_settings(self) -> Optional[UserSettingSerializer]:
if not self.configure_flow: if not self.configure_flow:
return None return None
return Challenge( return UserSettingSerializer(
data={ data={
"type": ChallengeTypes.shell.value,
"title": str(self._meta.verbose_name), "title": str(self._meta.verbose_name),
"component": reverse( "component": "ak-user-settings-password",
"authentik_stages_password:user-settings",
kwargs={"stage_uuid": self.pk},
),
} }
) )

View File

@ -1,13 +0,0 @@
{% load i18n %}
{% load authentik_utils %}
<div class="pf-c-card">
<div class="pf-c-card__title">
{% trans 'Reset your password' %}
</div>
<div class="pf-c-card__body">
<a class="pf-c-button pf-m-primary ak-root-link" href="{% url 'authentik_flows:configure' stage_uuid=stage.stage_uuid %}?next=/%23user">
{% trans 'Change password' %}
</a>
</div>
</div>

View File

@ -1,12 +0,0 @@
"""Password stage urls"""
from django.urls import path
from authentik.stages.password.views import UserSettingsCardView
urlpatterns = [
path(
"<uuid:stage_uuid>/change-card/",
UserSettingsCardView.as_view(),
name="user-settings",
),
]

View File

@ -1,20 +0,0 @@
"""password stage user settings card"""
from typing import Any
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import get_object_or_404
from django.views.generic import TemplateView
from authentik.stages.password.models import PasswordStage
class UserSettingsCardView(LoginRequiredMixin, TemplateView):
"""Card shown on user settings page to allow user to change their password"""
template_name = "stages/password/user-settings-card.html"
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
stage = get_object_or_404(PasswordStage, pk=self.kwargs["stage_uuid"])
kwargs = super().get_context_data(**kwargs)
kwargs["stage"] = stage
return kwargs

View File

@ -21,6 +21,7 @@ import "../../elements/Tabs";
import "../tokens/UserTokenList"; import "../tokens/UserTokenList";
import "../generic/SiteShell"; import "../generic/SiteShell";
import "./settings/AuthenticatorWebAuthnDevices"; import "./settings/AuthenticatorWebAuthnDevices";
import "./settings/Password";
@customElement("ak-user-settings") @customElement("ak-user-settings")
export class UserSettingsPage extends LitElement { export class UserSettingsPage extends LitElement {
@ -34,6 +35,9 @@ export class UserSettingsPage extends LitElement {
case "ak-user-settings-authenticator-webauthn": case "ak-user-settings-authenticator-webauthn":
return html`<ak-user-settings-authenticator-webauthn stageId=${stage.objectUid}> return html`<ak-user-settings-authenticator-webauthn stageId=${stage.objectUid}>
</ak-user-settings-authenticator-webauthn>`; </ak-user-settings-authenticator-webauthn>`;
case "ak-user-settings-password":
return html`<ak-user-settings-password stageId=${stage.objectUid}>
</ak-user-settings-password>`;
default: default:
return html`<div class="pf-u-display-flex pf-u-justify-content-center"> return html`<div class="pf-u-display-flex pf-u-justify-content-center">
<div class="pf-u-w-75"> <div class="pf-u-w-75">

View File

@ -0,0 +1,35 @@
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import AKGlobal from "../../../authentik.css";
import { gettext } from "django";
import { FlowURLManager } from "../../../api/legacy";
@customElement("ak-user-settings-password")
export class UserSettingsPassword extends LitElement {
@property()
stageId!: string;
static get styles(): CSSResult[] {
return [PFBase, PFCard, PFButton, AKGlobal];
}
render(): TemplateResult {
// For this stage we don't need to check for a configureFlow,
// as the stage won't return any UI Elements if no configureFlow is set.
return html`<div class="pf-c-card">
<div class="pf-c-card__title">
${gettext('Change your password')}
</div>
<div class="pf-c-card__body">
<a href="${FlowURLManager.configure(this.stageId, '?next=/%23user')}"
class="pf-c-button pf-m-primary">
${gettext('Change password')}
</a>
</div>
</div>`;
}
}