stages/user_write: allow setting user type when creating new user (#7293)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
94ad839437
commit
28053059ff
|
@ -15,6 +15,7 @@ class UserWriteStageSerializer(StageSerializer):
|
|||
"user_creation_mode",
|
||||
"create_users_as_inactive",
|
||||
"create_users_group",
|
||||
"user_type",
|
||||
"user_path_template",
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 4.2.6 on 2023-10-25 15:19
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("authentik_stages_user_write", "0007_remove_userwritestage_can_create_users_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="userwritestage",
|
||||
name="user_type",
|
||||
field=models.TextField(
|
||||
choices=[
|
||||
("internal", "Internal"),
|
||||
("external", "External"),
|
||||
("service_account", "Service Account"),
|
||||
("internal_service_account", "Internal Service Account"),
|
||||
],
|
||||
default="external",
|
||||
),
|
||||
),
|
||||
]
|
|
@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from django.views import View
|
||||
from rest_framework.serializers import BaseSerializer
|
||||
|
||||
from authentik.core.models import Group
|
||||
from authentik.core.models import Group, UserTypes
|
||||
from authentik.flows.models import Stage
|
||||
|
||||
|
||||
|
@ -39,6 +39,10 @@ class UserWriteStage(Stage):
|
|||
help_text=_("Optionally add newly created users to this group."),
|
||||
)
|
||||
|
||||
user_type = models.TextField(
|
||||
choices=UserTypes.choices,
|
||||
default=UserTypes.EXTERNAL,
|
||||
)
|
||||
user_path_template = models.TextField(
|
||||
default="",
|
||||
blank=True,
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.utils.translation import gettext as _
|
|||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from authentik.core.middleware import SESSION_KEY_IMPERSONATE_USER
|
||||
from authentik.core.models import USER_ATTRIBUTE_SOURCES, User, UserSourceConnection
|
||||
from authentik.core.models import USER_ATTRIBUTE_SOURCES, User, UserSourceConnection, UserTypes
|
||||
from authentik.core.sources.stage import PLAN_CONTEXT_SOURCES_CONNECTION
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||
from authentik.flows.stage import StageView
|
||||
|
@ -22,6 +22,7 @@ from authentik.stages.user_write.models import UserCreationMode
|
|||
from authentik.stages.user_write.signals import user_write
|
||||
|
||||
PLAN_CONTEXT_GROUPS = "groups"
|
||||
PLAN_CONTEXT_USER_TYPE = "user_type"
|
||||
PLAN_CONTEXT_USER_PATH = "user_path"
|
||||
|
||||
|
||||
|
@ -55,6 +56,19 @@ class UserWriteStageView(StageView):
|
|||
)
|
||||
if path == "":
|
||||
path = User.default_path()
|
||||
|
||||
try:
|
||||
user_type = UserTypes(
|
||||
self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_USER_TYPE,
|
||||
self.executor.current_stage.user_type,
|
||||
)
|
||||
)
|
||||
except ValueError:
|
||||
user_type = self.executor.current_stage.user_type
|
||||
if user_type == UserTypes.INTERNAL_SERVICE_ACCOUNT:
|
||||
user_type = UserTypes.SERVICE_ACCOUNT
|
||||
|
||||
if not self.request.user.is_anonymous:
|
||||
self.executor.plan.context.setdefault(PLAN_CONTEXT_PENDING_USER, self.request.user)
|
||||
if (
|
||||
|
@ -66,6 +80,7 @@ class UserWriteStageView(StageView):
|
|||
self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] = User(
|
||||
is_active=not self.executor.current_stage.create_users_as_inactive,
|
||||
path=path,
|
||||
type=user_type,
|
||||
)
|
||||
self.executor.plan.context[PLAN_CONTEXT_AUTHENTICATION_BACKEND] = BACKEND_INBUILT
|
||||
self.logger.debug(
|
||||
|
|
|
@ -8368,6 +8368,16 @@
|
|||
"title": "Create users group",
|
||||
"description": "Optionally add newly created users to this group."
|
||||
},
|
||||
"user_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"internal",
|
||||
"external",
|
||||
"service_account",
|
||||
"internal_service_account"
|
||||
],
|
||||
"title": "User type"
|
||||
},
|
||||
"user_path_template": {
|
||||
"type": "string",
|
||||
"title": "User path template"
|
||||
|
|
20
schema.yml
20
schema.yml
|
@ -27494,6 +27494,20 @@ paths:
|
|||
name: user_path_template
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: user_type
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- external
|
||||
- internal
|
||||
- internal_service_account
|
||||
- service_account
|
||||
description: |-
|
||||
* `internal` - Internal
|
||||
* `external` - External
|
||||
* `service_account` - Service Account
|
||||
* `internal_service_account` - Internal Service Account
|
||||
tags:
|
||||
- stages
|
||||
security:
|
||||
|
@ -38052,6 +38066,8 @@ components:
|
|||
format: uuid
|
||||
nullable: true
|
||||
description: Optionally add newly created users to this group.
|
||||
user_type:
|
||||
$ref: '#/components/schemas/UserTypeEnum'
|
||||
user_path_template:
|
||||
type: string
|
||||
PatchedWebAuthnDeviceRequest:
|
||||
|
@ -42422,6 +42438,8 @@ components:
|
|||
format: uuid
|
||||
nullable: true
|
||||
description: Optionally add newly created users to this group.
|
||||
user_type:
|
||||
$ref: '#/components/schemas/UserTypeEnum'
|
||||
user_path_template:
|
||||
type: string
|
||||
required:
|
||||
|
@ -42452,6 +42470,8 @@ components:
|
|||
format: uuid
|
||||
nullable: true
|
||||
description: Optionally add newly created users to this group.
|
||||
user_type:
|
||||
$ref: '#/components/schemas/UserTypeEnum'
|
||||
user_path_template:
|
||||
type: string
|
||||
required:
|
||||
|
|
|
@ -12,7 +12,14 @@ import { TemplateResult, html } from "lit";
|
|||
import { customElement } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { CoreApi, CoreGroupsListRequest, Group, StagesApi, UserWriteStage } from "@goauthentik/api";
|
||||
import {
|
||||
CoreApi,
|
||||
CoreGroupsListRequest,
|
||||
Group,
|
||||
StagesApi,
|
||||
UserTypeEnum,
|
||||
UserWriteStage,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-stage-user-write-form")
|
||||
export class UserWriteStageForm extends ModelForm<UserWriteStage, string> {
|
||||
|
@ -111,6 +118,42 @@ export class UserWriteStageForm extends ModelForm<UserWriteStage, string> {
|
|||
${msg("Mark newly created users as inactive.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("User path template")}
|
||||
name="userPathTemplate"
|
||||
>
|
||||
<ak-radio
|
||||
.options=${[
|
||||
{
|
||||
label: "Internal",
|
||||
value: UserTypeEnum.Internal,
|
||||
default: true,
|
||||
description: html`${msg(
|
||||
"Internal users might be users such as company employees, which will get access to the full Enterprise feature set.",
|
||||
)}`,
|
||||
},
|
||||
{
|
||||
label: "External",
|
||||
value: UserTypeEnum.External,
|
||||
description: html`${msg(
|
||||
"External users might be external consultants or B2C customers. These users don't get access to enterprise features.",
|
||||
)}`,
|
||||
},
|
||||
{
|
||||
label: "Service account",
|
||||
value: UserTypeEnum.ServiceAccount,
|
||||
description: html`${msg(
|
||||
"Service accounts should be used for machine-to-machine authentication or other automations.",
|
||||
)}`,
|
||||
},
|
||||
]}
|
||||
.value=${this.instance?.userType}
|
||||
>
|
||||
</ak-radio>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("User type used for newly created users.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("User path template")}
|
||||
name="userPathTemplate"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import "@goauthentik/admin/users/GroupSelectModal";
|
||||
import { UserTypeEnum } from "@goauthentik/api/dist/models/UserTypeEnum";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { first } from "@goauthentik/common/utils";
|
||||
import "@goauthentik/elements/CodeMirror";
|
||||
|
@ -14,7 +13,7 @@ import { CSSResult, TemplateResult, css, html } from "lit";
|
|||
import { customElement } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { CoreApi, User } from "@goauthentik/api";
|
||||
import { CoreApi, User, UserTypeEnum } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-user-form")
|
||||
export class UserForm extends ModelForm<User, number> {
|
||||
|
|
|
@ -7930,6 +7930,15 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
|||
<trans-unit id="s0924f51b028233a3">
|
||||
<source><No name set></source>
|
||||
<target><No name set></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s66313b45b69cfc88">
|
||||
<source>Check the release notes</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb4d7bae2440d9781">
|
||||
<source>User Statistics</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s32babfed740fd3c1">
|
||||
<source>User type used for newly created users.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -120,6 +120,14 @@ If set, this must be a list of group objects and not group names.
|
|||
|
||||
Path the `pending_user` will be written to. If not set in the flow, falls back to the value set in the user_write stage, and otherwise to the `users` path.
|
||||
|
||||
##### `user_type` (string)
|
||||
|
||||
:::info
|
||||
Requires authentik 2023.10
|
||||
:::
|
||||
|
||||
Type the `pending_user` will be created as. Must be one of `internal`, `external` or `service_account`.
|
||||
|
||||
#### Password stage
|
||||
|
||||
##### `user_backend` (string)
|
||||
|
|
Reference in New Issue