From c1c47c5f300f8ac69c901d488d9a5f0d653f53b9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 3 Apr 2021 00:46:40 +0200 Subject: [PATCH] stages/email: migrate to web Signed-off-by: Jens Langhammer --- authentik/stages/email/api.py | 2 + authentik/stages/email/forms.py | 41 ----- authentik/stages/email/models.py | 8 +- web/src/pages/stages/email/EmailStageForm.ts | 171 +++++++++++++++++++ 4 files changed, 176 insertions(+), 46 deletions(-) delete mode 100644 authentik/stages/email/forms.py create mode 100644 web/src/pages/stages/email/EmailStageForm.ts diff --git a/authentik/stages/email/api.py b/authentik/stages/email/api.py index 2a41c0f823..116538b806 100644 --- a/authentik/stages/email/api.py +++ b/authentik/stages/email/api.py @@ -37,3 +37,5 @@ class EmailStageViewSet(ModelViewSet): queryset = EmailStage.objects.all() serializer_class = EmailStageSerializer + + # TODO: Validate connection settings when use_global_settings is unchecked diff --git a/authentik/stages/email/forms.py b/authentik/stages/email/forms.py deleted file mode 100644 index 5e87b65448..0000000000 --- a/authentik/stages/email/forms.py +++ /dev/null @@ -1,41 +0,0 @@ -"""authentik administration forms""" -from django import forms -from django.utils.translation import gettext_lazy as _ - -from authentik.stages.email.models import EmailStage, get_template_choices - - -class EmailStageForm(forms.ModelForm): - """Form to create/edit Email Stage""" - - template = forms.ChoiceField(choices=get_template_choices) - - class Meta: - - model = EmailStage - fields = [ - "name", - "use_global_settings", - "token_expiry", - "subject", - "template", - "host", - "port", - "username", - "password", - "use_tls", - "use_ssl", - "timeout", - "from_address", - ] - widgets = { - "name": forms.TextInput(), - "host": forms.TextInput(), - "subject": forms.TextInput(), - "username": forms.TextInput(), - "password": forms.TextInput(), - } - labels = { - "use_tls": _("Use TLS"), - "use_ssl": _("Use SSL"), - } diff --git a/authentik/stages/email/models.py b/authentik/stages/email/models.py index 936952b152..65c155f4b6 100644 --- a/authentik/stages/email/models.py +++ b/authentik/stages/email/models.py @@ -7,7 +7,6 @@ from django.conf import settings from django.core.mail import get_connection from django.core.mail.backends.base import BaseEmailBackend from django.db import models -from django.forms import ModelForm from django.utils.translation import gettext as _ from django.views import View from rest_framework.serializers import BaseSerializer @@ -31,6 +30,7 @@ class EmailTemplates(models.TextChoices): ) +# TODO: Create api for choices def get_template_choices(): """Get all available Email templates, including dynamically mounted ones. Directories are taken from TEMPLATES.DIR setting""" @@ -95,10 +95,8 @@ class EmailStage(Stage): return EmailStageView @property - def form(self) -> Type[ModelForm]: - from authentik.stages.email.forms import EmailStageForm - - return EmailStageForm + def component(self) -> str: + return "ak-stage-email-form" @property def backend(self) -> BaseEmailBackend: diff --git a/web/src/pages/stages/email/EmailStageForm.ts b/web/src/pages/stages/email/EmailStageForm.ts new file mode 100644 index 0000000000..272b6d1898 --- /dev/null +++ b/web/src/pages/stages/email/EmailStageForm.ts @@ -0,0 +1,171 @@ +import { EmailStage, EmailStageTemplateEnum, StagesApi } from "authentik-api"; +import { gettext } from "django"; +import { customElement, property } from "lit-element"; +import { html, TemplateResult } from "lit-html"; +import { DEFAULT_CONFIG } from "../../../api/Config"; +import { Form } from "../../../elements/forms/Form"; +import { ifDefined } from "lit-html/directives/if-defined"; +import "../../../elements/forms/HorizontalFormElement"; +import "../../../elements/forms/FormGroup"; + +@customElement("ak-stage-email-form") +export class EmailStageForm extends Form { + + set stageUUID(value: string) { + new StagesApi(DEFAULT_CONFIG).stagesEmailRead({ + stageUuid: value, + }).then(stage => { + this.stage = stage; + }); + } + + @property({attribute: false}) + stage?: EmailStage; + + @property({type: Boolean}) + showConnectionSettings = false; + + getSuccessMessage(): string { + if (this.stage) { + return gettext("Successfully updated stage."); + } else { + return gettext("Successfully created stage."); + } + } + + send = (data: EmailStage): Promise => { + if (this.stage) { + return new StagesApi(DEFAULT_CONFIG).stagesEmailUpdate({ + stageUuid: this.stage.pk || "", + data: data + }); + } else { + return new StagesApi(DEFAULT_CONFIG).stagesEmailCreate({ + data: data + }); + } + }; + + renderConnectionSettings(): TemplateResult { + if (!this.showConnectionSettings) { + return html``; + } + return html` + + ${gettext("Connection settings")} + +
+ + + + + + + + + + + + + +
+ + +
+
+ +
+ + +
+
+ + + + + + +
+
`; + } + + renderForm(): TemplateResult { + return html`
+ + + + + + ${gettext("Stage-specific settings")} + +
+ +
+ { + const target = ev.target as HTMLInputElement; + this.showConnectionSettings = !target.checked; + }}> + +
+

${gettext("When enabled, global Email connection settings will be used and connection settings below will be ignored.")}

+
+ + +

${gettext("Time in minutes the token sent is valid.")}

+
+ + + + + + +
+
+ ${this.renderConnectionSettings()} +
`; + } + +}