web/admin: migrate invitations to web
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
717282b4b7
commit
8a3b1ae29d
|
@ -10,7 +10,6 @@ from authentik.admin.views import (
|
|||
sources,
|
||||
stages,
|
||||
stages_bindings,
|
||||
stages_invitations,
|
||||
stages_prompts,
|
||||
)
|
||||
from authentik.providers.saml.views.metadata import MetadataImportView
|
||||
|
@ -86,12 +85,6 @@ urlpatterns = [
|
|||
stages_prompts.PromptUpdateView.as_view(),
|
||||
name="stage-prompt-update",
|
||||
),
|
||||
# Stage Invitations
|
||||
path(
|
||||
"stages/invitations/create/",
|
||||
stages_invitations.InvitationCreateView.as_view(),
|
||||
name="stage-invitation-create",
|
||||
),
|
||||
# Property Mappings
|
||||
path(
|
||||
"property-mappings/create/",
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
"""authentik Invitation administration"""
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib.auth.mixins import (
|
||||
PermissionRequiredMixin as DjangoPermissionRequiredMixin,
|
||||
)
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from authentik.lib.views import CreateAssignPermView
|
||||
from authentik.stages.invitation.forms import InvitationForm
|
||||
from authentik.stages.invitation.models import Invitation
|
||||
|
||||
|
||||
class InvitationCreateView(
|
||||
SuccessMessageMixin,
|
||||
LoginRequiredMixin,
|
||||
DjangoPermissionRequiredMixin,
|
||||
CreateAssignPermView,
|
||||
):
|
||||
"""Create new Invitation"""
|
||||
|
||||
model = Invitation
|
||||
form_class = InvitationForm
|
||||
permission_required = "authentik_stages_invitation.add_invitation"
|
||||
|
||||
template_name = "generic/create.html"
|
||||
success_url = reverse_lazy("authentik_core:if-admin")
|
||||
success_message = _("Successfully created Invitation")
|
||||
|
||||
def form_valid(self, form):
|
||||
obj = form.save(commit=False)
|
||||
obj.created_by = self.request.user
|
||||
obj.save()
|
||||
return HttpResponseRedirect(self.success_url)
|
|
@ -49,5 +49,4 @@ class InvitationViewSet(ModelViewSet):
|
|||
filterset_fields = ["created_by__username", "expires"]
|
||||
|
||||
def perform_create(self, serializer: InvitationSerializer):
|
||||
serializer.instance.created_by = self.request.user
|
||||
return super().perform_create(serializer)
|
||||
serializer.save(created_by=self.request.user)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
"""authentik flows invitation forms"""
|
||||
from django import forms
|
||||
|
||||
from authentik.admin.fields import CodeMirrorWidget, YAMLField
|
||||
from authentik.stages.invitation.models import Invitation, InvitationStage
|
||||
from authentik.stages.invitation.models import InvitationStage
|
||||
|
||||
|
||||
class InvitationStageForm(forms.ModelForm):
|
||||
|
@ -15,14 +14,3 @@ class InvitationStageForm(forms.ModelForm):
|
|||
widgets = {
|
||||
"name": forms.TextInput(),
|
||||
}
|
||||
|
||||
|
||||
class InvitationForm(forms.ModelForm):
|
||||
"""InvitationForm"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Invitation
|
||||
fields = ["expires", "fixed_data"]
|
||||
widgets = {"fixed_data": CodeMirrorWidget()}
|
||||
field_classes = {"fixed_data": YAMLField}
|
||||
|
|
|
@ -28,10 +28,6 @@ export class AdminURLManager {
|
|||
return `/administration/stages_prompts/${rest}`;
|
||||
}
|
||||
|
||||
static stageInvitations(rest: string): string {
|
||||
return `/administration/stages/invitations/${rest}`;
|
||||
}
|
||||
|
||||
static stageBindings(rest: string): string {
|
||||
return `/administration/stages/bindings/${rest}`;
|
||||
}
|
||||
|
@ -52,10 +48,6 @@ export class UserURLManager {
|
|||
return `/-/user/tokens/${rest}`;
|
||||
}
|
||||
|
||||
static authenticatorWebauthn(rest: string): string {
|
||||
return `/-/user/authenticator/webauthn/${rest}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AppURLManager {
|
||||
|
|
|
@ -84,6 +84,8 @@ export class Form<T> extends LitElement {
|
|||
const values = form._serializeElementValues(element);
|
||||
if (element.tagName.toLowerCase() === "select" && "multiple" in element.attributes) {
|
||||
json[element.name] = values;
|
||||
} else if (element.tagName.toLowerCase() === "input" && element.type === "date") {
|
||||
json[element.name] = element.valueAsDate;
|
||||
} else {
|
||||
for (let v = 0; v < values.length; v++) {
|
||||
form._addSerializedElement(json, element.name, values[v]);
|
||||
|
|
57
web/src/pages/stages/InvitationForm.ts
Normal file
57
web/src/pages/stages/InvitationForm.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Invitation, 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/CodeMirror";
|
||||
import YAML from "yaml";
|
||||
|
||||
@customElement("ak-stage-invitation-form")
|
||||
export class InvitationForm extends Form<Invitation> {
|
||||
|
||||
@property({attribute: false})
|
||||
invitation?: Invitation;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.invitation) {
|
||||
return gettext("Successfully updated invitation.");
|
||||
} else {
|
||||
return gettext("Successfully created invitation.");
|
||||
}
|
||||
}
|
||||
|
||||
send = (data: Invitation): Promise<Invitation> => {
|
||||
if (this.invitation) {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsUpdate({
|
||||
inviteUuid: this.invitation.pk || "",
|
||||
data: data
|
||||
});
|
||||
} else {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsCreate({
|
||||
data: data
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal
|
||||
label=${gettext("Expires")}
|
||||
?required=${true}
|
||||
name="expires">
|
||||
<input type="date" value="${ifDefined(this.invitation?.expires)}" class="pf-c-form-control" required>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${gettext("Attributes")}
|
||||
name="fixedData">
|
||||
<ak-codemirror mode="yaml" value="${YAML.stringify(this.invitation?.fixedData)}">
|
||||
</ak-codemirror>
|
||||
<p class="pf-c-form__helper-text">${gettext("Optional data which is loaded into the flow's 'prompt_data' context variable.")}</p>
|
||||
</ak-form-element-horizontal>
|
||||
</form>`;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,11 +6,12 @@ import { TablePage } from "../../elements/table/TablePage";
|
|||
import "../../elements/buttons/ModalButton";
|
||||
import "../../elements/buttons/SpinnerButton";
|
||||
import "../../elements/forms/DeleteForm";
|
||||
import "../../elements/forms/ModalForm";
|
||||
import "./InvitationForm";
|
||||
import { TableColumn } from "../../elements/table/Table";
|
||||
import { PAGE_SIZE } from "../../constants";
|
||||
import { Invitation, StagesApi } from "authentik-api";
|
||||
import { DEFAULT_CONFIG } from "../../api/Config";
|
||||
import { AdminURLManager } from "../../api/legacy";
|
||||
|
||||
@customElement("ak-stage-invitation-list")
|
||||
export class InvitationListPage extends TablePage<Invitation> {
|
||||
|
@ -71,12 +72,19 @@ export class InvitationListPage extends TablePage<Invitation> {
|
|||
|
||||
renderToolbar(): TemplateResult {
|
||||
return html`
|
||||
<ak-modal-button href=${AdminURLManager.stageInvitations("create/")}>
|
||||
<ak-spinner-button slot="trigger" class="pf-m-primary">
|
||||
<ak-forms-modal>
|
||||
<span slot="submit">
|
||||
${gettext("Create")}
|
||||
</ak-spinner-button>
|
||||
<div slot="modal"></div>
|
||||
</ak-modal-button>
|
||||
</span>
|
||||
<span slot="header">
|
||||
${gettext("Create Invitation")}
|
||||
</span>
|
||||
<ak-stage-invitation-form slot="form">
|
||||
</ak-stage-invitation-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">
|
||||
${gettext("Create")}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${super.renderToolbar()}
|
||||
`;
|
||||
}
|
||||
|
|
Reference in a new issue