stages/invitation: add invitation name
closes #2583 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
933919c647
commit
c7a83e6182
|
@ -54,6 +54,7 @@ class InvitationSerializer(ModelSerializer):
|
|||
model = Invitation
|
||||
fields = [
|
||||
"pk",
|
||||
"name",
|
||||
"expires",
|
||||
"fixed_data",
|
||||
"created_by",
|
||||
|
@ -67,8 +68,8 @@ class InvitationViewSet(UsedByMixin, ModelViewSet):
|
|||
queryset = Invitation.objects.all()
|
||||
serializer_class = InvitationSerializer
|
||||
ordering = ["-expires"]
|
||||
search_fields = ["created_by__username", "expires"]
|
||||
filterset_fields = ["created_by__username", "expires"]
|
||||
search_fields = ["name", "created_by__username", "expires"]
|
||||
filterset_fields = ["name", "created_by__username", "expires"]
|
||||
|
||||
def perform_create(self, serializer: InvitationSerializer):
|
||||
serializer.save(created_by=self.request.user)
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
# Generated by Django 4.0.3 on 2022-03-26 17:24
|
||||
|
||||
import uuid
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.apps.registry import Apps
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
|
||||
import authentik.core.models
|
||||
|
||||
|
||||
def migrate_add_name(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
Invitation = apps.get_model("authentik_stages_invitation", "invitation")
|
||||
|
||||
for invite in Invitation.objects.using(db_alias).all():
|
||||
invite.name = invite.pk.hex
|
||||
invite.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
replaces = [
|
||||
("authentik_stages_invitation", "0001_initial"),
|
||||
("authentik_stages_invitation", "0002_auto_20201225_2143"),
|
||||
("authentik_stages_invitation", "0003_auto_20201227_1210"),
|
||||
("authentik_stages_invitation", "0004_invitation_single_use"),
|
||||
("authentik_stages_invitation", "0005_auto_20210901_1211"),
|
||||
("authentik_stages_invitation", "0006_invitation_name"),
|
||||
]
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
("authentik_flows", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="InvitationStage",
|
||||
fields=[
|
||||
(
|
||||
"stage_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="authentik_flows.stage",
|
||||
),
|
||||
),
|
||||
(
|
||||
"continue_flow_without_invitation",
|
||||
models.BooleanField(
|
||||
default=False,
|
||||
help_text="If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Invitation Stage",
|
||||
"verbose_name_plural": "Invitation Stages",
|
||||
},
|
||||
bases=("authentik_flows.stage",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Invitation",
|
||||
fields=[
|
||||
(
|
||||
"invite_uuid",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4, editable=False, primary_key=True, serialize=False
|
||||
),
|
||||
),
|
||||
(
|
||||
"expires",
|
||||
models.DateTimeField(default=authentik.core.models.default_token_duration),
|
||||
),
|
||||
(
|
||||
"fixed_data",
|
||||
models.JSONField(
|
||||
blank=True,
|
||||
default=dict,
|
||||
help_text="Optional fixed data to enforce on user enrollment.",
|
||||
),
|
||||
),
|
||||
(
|
||||
"created_by",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
|
||||
),
|
||||
),
|
||||
(
|
||||
"single_use",
|
||||
models.BooleanField(
|
||||
default=False,
|
||||
help_text="When enabled, the invitation will be deleted after usage.",
|
||||
),
|
||||
),
|
||||
("expiring", models.BooleanField(default=True)),
|
||||
("name", models.SlugField(default="")),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Invitation",
|
||||
"verbose_name_plural": "Invitations",
|
||||
},
|
||||
),
|
||||
migrations.RunPython(
|
||||
code=migrate_add_name,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="invitation",
|
||||
name="name",
|
||||
field=models.SlugField(),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -0,0 +1,38 @@
|
|||
# Generated by Django 4.0.3 on 2022-03-26 17:22
|
||||
|
||||
from django.apps.registry import Apps
|
||||
from django.db import migrations, models
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
|
||||
|
||||
def migrate_add_name(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
Invitation = apps.get_model("authentik_stages_invitation", "invitation")
|
||||
|
||||
for invite in Invitation.objects.using(db_alias).all():
|
||||
invite.name = invite.pk.hex
|
||||
invite.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_stages_invitation", "0005_auto_20210901_1211"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="invitation",
|
||||
name="name",
|
||||
field=models.SlugField(default=""),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.RunPython(migrate_add_name),
|
||||
migrations.AlterField(
|
||||
model_name="invitation",
|
||||
name="name",
|
||||
field=models.SlugField(),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -52,6 +52,8 @@ class Invitation(ExpiringModel):
|
|||
|
||||
invite_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
|
||||
|
||||
name = models.SlugField()
|
||||
|
||||
single_use = models.BooleanField(
|
||||
default=False,
|
||||
help_text=_("When enabled, the invitation will be deleted after usage."),
|
||||
|
|
23
schema.yml
23
schema.yml
|
@ -16924,6 +16924,10 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- in: query
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
- name: ordering
|
||||
required: false
|
||||
in: query
|
||||
|
@ -16973,6 +16977,7 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InvitationRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
|
@ -17031,6 +17036,7 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InvitationRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
|
@ -22105,6 +22111,10 @@ components:
|
|||
format: uuid
|
||||
readOnly: true
|
||||
title: Invite uuid
|
||||
name:
|
||||
type: string
|
||||
maxLength: 50
|
||||
pattern: ^[-a-zA-Z0-9_]+$
|
||||
expires:
|
||||
type: string
|
||||
format: date-time
|
||||
|
@ -22120,11 +22130,17 @@ components:
|
|||
description: When enabled, the invitation will be deleted after usage.
|
||||
required:
|
||||
- created_by
|
||||
- name
|
||||
- pk
|
||||
InvitationRequest:
|
||||
type: object
|
||||
description: Invitation Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 50
|
||||
pattern: ^[-a-zA-Z0-9_]+$
|
||||
expires:
|
||||
type: string
|
||||
format: date-time
|
||||
|
@ -22134,6 +22150,8 @@ components:
|
|||
single_use:
|
||||
type: boolean
|
||||
description: When enabled, the invitation will be deleted after usage.
|
||||
required:
|
||||
- name
|
||||
InvitationStage:
|
||||
type: object
|
||||
description: InvitationStage Serializer
|
||||
|
@ -27141,6 +27159,11 @@ components:
|
|||
type: object
|
||||
description: Invitation Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 50
|
||||
pattern: ^[-a-zA-Z0-9_]+$
|
||||
expires:
|
||||
type: string
|
||||
format: date-time
|
||||
|
|
|
@ -2350,7 +2350,6 @@ msgid "How to connect"
|
|||
msgstr "So verbinden Sie sich"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3048,6 +3047,8 @@ msgstr "Meine Anwendungen"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2383,7 +2383,6 @@ msgid "How to connect"
|
|||
msgstr "How to connect"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3093,6 +3092,8 @@ msgstr "My applications"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2341,7 +2341,6 @@ msgid "How to connect"
|
|||
msgstr "Cómo conectarse"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3041,6 +3040,8 @@ msgstr "Mis solicitudes"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2367,7 +2367,6 @@ msgid "How to connect"
|
|||
msgstr ""
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3072,6 +3071,8 @@ msgstr "Mes applications"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2338,7 +2338,6 @@ msgid "How to connect"
|
|||
msgstr "Jak się połączyć"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3038,6 +3037,8 @@ msgstr "Moje aplikacje"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2375,7 +2375,6 @@ msgid "How to connect"
|
|||
msgstr ""
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3083,6 +3082,8 @@ msgstr ""
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2341,7 +2341,6 @@ msgid "How to connect"
|
|||
msgstr "Nasıl bağlanır"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3042,6 +3041,8 @@ msgstr "Uygulamalarım"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2338,7 +2338,6 @@ msgid "How to connect"
|
|||
msgstr "如何连接"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3037,6 +3036,8 @@ msgstr "我的应用"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2338,7 +2338,6 @@ msgid "How to connect"
|
|||
msgstr "如何连接"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3037,6 +3036,8 @@ msgstr "我的应用"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -2338,7 +2338,6 @@ msgid "How to connect"
|
|||
msgstr "如何连接"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/users/RelatedUserList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
msgid "ID"
|
||||
|
@ -3037,6 +3036,8 @@ msgstr "我的应用"
|
|||
#: src/pages/stages/dummy/DummyStageForm.ts
|
||||
#: src/pages/stages/email/EmailStageForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/stages/invitation/InvitationForm.ts
|
||||
#: src/pages/stages/invitation/InvitationListPage.ts
|
||||
#: src/pages/stages/invitation/InvitationStageForm.ts
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
#: src/pages/stages/prompt/PromptStageForm.ts
|
||||
|
|
|
@ -44,6 +44,15 @@ export class InvitationForm extends ModelForm<Invitation, string> {
|
|||
|
||||
renderForm(): TemplateResult {
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
|
||||
<input
|
||||
type="text"
|
||||
value="${this.instance?.name || ""}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
data-ak-slug="true"
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Expires`} ?required=${true} name="expires">
|
||||
<input
|
||||
type="datetime-local"
|
||||
|
|
|
@ -65,7 +65,7 @@ export class InvitationListPage extends TablePage<Invitation> {
|
|||
|
||||
columns(): TableColumn[] {
|
||||
return [
|
||||
new TableColumn(t`ID`, "pk"),
|
||||
new TableColumn(t`Name`, "name"),
|
||||
new TableColumn(t`Created by`, "created_by"),
|
||||
new TableColumn(t`Expiry`),
|
||||
new TableColumn(t`Actions`),
|
||||
|
@ -96,7 +96,7 @@ export class InvitationListPage extends TablePage<Invitation> {
|
|||
|
||||
row(item: Invitation): TemplateResult[] {
|
||||
return [
|
||||
html`${item.pk}`,
|
||||
html`${item.name}`,
|
||||
html`${item.createdBy?.username}`,
|
||||
html`${item.expires?.toLocaleString() || t`-`}`,
|
||||
html` <ak-forms-modal>
|
||||
|
|
|
@ -2,7 +2,6 @@ import { t } from "@lingui/macro";
|
|||
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { InvitationStage, StagesApi } from "@goauthentik/api";
|
||||
|
||||
|
@ -49,7 +48,7 @@ export class InvitationStageForm extends ModelForm<InvitationStage, string> {
|
|||
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name || "")}"
|
||||
value="${this.instance?.name || ""}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
|
|
Reference in New Issue