diff --git a/authentik/stages/user_write/api.py b/authentik/stages/user_write/api.py index 5acaa6ae19..9abac9ef2e 100644 --- a/authentik/stages/user_write/api.py +++ b/authentik/stages/user_write/api.py @@ -12,7 +12,7 @@ class UserWriteStageSerializer(StageSerializer): class Meta: model = UserWriteStage - fields = StageSerializer.Meta.fields + fields = StageSerializer.Meta.fields + ["create_users_as_inactive"] class UserWriteStageViewSet(UsedByMixin, ModelViewSet): diff --git a/authentik/stages/user_write/migrations/0003_userwritestage_create_users_as_inactive.py b/authentik/stages/user_write/migrations/0003_userwritestage_create_users_as_inactive.py new file mode 100644 index 0000000000..5ca4102914 --- /dev/null +++ b/authentik/stages/user_write/migrations/0003_userwritestage_create_users_as_inactive.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.4 on 2021-06-28 20:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_stages_user_write", "0002_auto_20200918_1653"), + ] + + operations = [ + migrations.AddField( + model_name="userwritestage", + name="create_users_as_inactive", + field=models.BooleanField( + default=False, + help_text="When set, newly created users are inactive and cannot login.", + ), + ), + ] diff --git a/authentik/stages/user_write/models.py b/authentik/stages/user_write/models.py index eb37a89f64..be5b8d1d02 100644 --- a/authentik/stages/user_write/models.py +++ b/authentik/stages/user_write/models.py @@ -1,6 +1,7 @@ """write stage models""" from typing import Type +from django.db import models from django.utils.translation import gettext_lazy as _ from django.views import View from rest_framework.serializers import BaseSerializer @@ -12,6 +13,11 @@ class UserWriteStage(Stage): """Writes currently pending data into the pending user, or if no user exists, creates a new user with the data.""" + create_users_as_inactive = models.BooleanField( + default=False, + help_text=_("When set, newly created users are inactive and cannot login."), + ) + @property def serializer(self) -> BaseSerializer: from authentik.stages.user_write.api import UserWriteStageSerializer diff --git a/authentik/stages/user_write/stage.py b/authentik/stages/user_write/stage.py index 61f3eb2756..554cd36d63 100644 --- a/authentik/stages/user_write/stage.py +++ b/authentik/stages/user_write/stage.py @@ -35,7 +35,9 @@ class UserWriteStageView(StageView): data = self.executor.plan.context[PLAN_CONTEXT_PROMPT] user_created = False if PLAN_CONTEXT_PENDING_USER not in self.executor.plan.context: - self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] = User() + self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] = User( + is_active=not self.executor.current_stage.create_users_as_inactive + ) self.executor.plan.context[ PLAN_CONTEXT_AUTHENTICATION_BACKEND ] = class_to_path(ModelBackend) diff --git a/schema.yml b/schema.yml index 40a26b97de..026a7f49ac 100644 --- a/schema.yml +++ b/schema.yml @@ -25778,6 +25778,9 @@ components: type: array items: $ref: '#/components/schemas/FlowRequest' + create_users_as_inactive: + type: boolean + description: When set, newly created users are inactive and cannot login. PatchedWebAuthnDeviceRequest: type: object description: Serializer for WebAuthn authenticator devices @@ -28272,6 +28275,9 @@ components: type: array items: $ref: '#/components/schemas/Flow' + create_users_as_inactive: + type: boolean + description: When set, newly created users are inactive and cannot login. required: - component - name @@ -28288,6 +28294,9 @@ components: type: array items: $ref: '#/components/schemas/FlowRequest' + create_users_as_inactive: + type: boolean + description: When set, newly created users are inactive and cannot login. required: - name ValidationError: diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 406594bcea..a4ff46ed91 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -945,6 +945,10 @@ msgstr "Create User" msgid "Create provider" msgstr "Create provider" +#: src/pages/stages/user_write/UserWriteStageForm.ts +msgid "Create users as inactive" +msgstr "Create users as inactive" + #: src/pages/applications/ApplicationForm.ts #: src/pages/flows/BoundStagesList.ts #: src/pages/outposts/ServiceConnectionListPage.ts @@ -2151,6 +2155,10 @@ msgstr "Logs" msgid "Long-running operations which authentik executes in the background." msgstr "Long-running operations which authentik executes in the background." +#: src/pages/stages/user_write/UserWriteStageForm.ts +msgid "Mark newly created users as inactive." +msgstr "Mark newly created users as inactive." + #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts msgid "Match created events with this action type. When left empty, all action types will be matched." msgstr "Match created events with this action type. When left empty, all action types will be matched." @@ -3384,6 +3392,7 @@ msgstr "Stage used to validate any authenticator. This stage should be used duri #: src/pages/stages/password/PasswordStageForm.ts #: src/pages/stages/prompt/PromptStageForm.ts #: src/pages/stages/user_login/UserLoginStageForm.ts +#: src/pages/stages/user_write/UserWriteStageForm.ts msgid "Stage-specific settings" msgstr "Stage-specific settings" diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 15917a8a81..b5dab26463 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -939,6 +939,10 @@ msgstr "" msgid "Create provider" msgstr "" +#: +msgid "Create users as inactive" +msgstr "" + #: #: #: @@ -2143,6 +2147,10 @@ msgstr "" msgid "Long-running operations which authentik executes in the background." msgstr "" +#: +msgid "Mark newly created users as inactive." +msgstr "" + #: msgid "Match created events with this action type. When left empty, all action types will be matched." msgstr "" @@ -3376,6 +3384,7 @@ msgstr "" #: #: #: +#: msgid "Stage-specific settings" msgstr "" diff --git a/web/src/pages/stages/user_write/UserWriteStageForm.ts b/web/src/pages/stages/user_write/UserWriteStageForm.ts index aebd2143cf..58e7fa6045 100644 --- a/web/src/pages/stages/user_write/UserWriteStageForm.ts +++ b/web/src/pages/stages/user_write/UserWriteStageForm.ts @@ -5,7 +5,9 @@ import { html, TemplateResult } from "lit-html"; import { DEFAULT_CONFIG } from "../../../api/Config"; import { ifDefined } from "lit-html/directives/if-defined"; import "../../../elements/forms/HorizontalFormElement"; +import "../../../elements/forms/FormGroup"; import { ModelForm } from "../../../elements/forms/ModelForm"; +import { first } from "../../../utils"; @customElement("ak-stage-user-write-form") export class UserWriteStageForm extends ModelForm { @@ -49,6 +51,22 @@ export class UserWriteStageForm extends ModelForm { name="name"> + + + ${t`Stage-specific settings`} + +
+ +
+ + +
+

${t`Mark newly created users as inactive.`}

+
+
+
`; } diff --git a/website/docs/releases/v2021.6.md b/website/docs/releases/v2021.6.md index 2053142ec3..8ce50f86c3 100644 --- a/website/docs/releases/v2021.6.md +++ b/website/docs/releases/v2021.6.md @@ -132,6 +132,8 @@ slug: "2021.6" - providers/oauth2: fix exp of JWT when not using seconds - sources/ldap: improve error handling when checking for password complexity on non-ad setups - stages/authenticator_duo: fix component not being set in API +- stages/prompt: ensure hidden and static fields keep the value they had set +- stages/user_write: add flag to create new users as inactive - tenants: include all default flows in current_tenant - web/admin: fix deletion of authenticator not reloading the state correctly - web/admin: fix only recovery flows being selectable for unenrollment flow in tenant form diff --git a/website/static/flows/enrollment-email-verification.akflow b/website/static/flows/enrollment-email-verification.akflow index ebf7af9d18..da7bd5b757 100644 --- a/website/static/flows/enrollment-email-verification.akflow +++ b/website/static/flows/enrollment-email-verification.akflow @@ -145,7 +145,9 @@ "name": "default-enrollment-user-write" }, "model": "authentik_stages_user_write.userwritestage", - "attrs": {} + "attrs": { + "create_users_as_inactive": true + } }, { "identifiers": {