web/admin: contextually add user to group when creating user from group page (#7586)
* move related user list to group folder Signed-off-by: Jens Langhammer <jens@goauthentik.io> * contextually add user to group when created from group view page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add banner Signed-off-by: Jens Langhammer <jens@goauthentik.io> * format Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
bac7e034f8
commit
99cecdb3ca
|
@ -1,5 +1,5 @@
|
||||||
import "@goauthentik/admin/groups/GroupForm";
|
import "@goauthentik/admin/groups/GroupForm";
|
||||||
import "@goauthentik/admin/users/RelatedUserList";
|
import "@goauthentik/app/admin/groups/RelatedUserList";
|
||||||
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
|
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { UserOption } from "@goauthentik/elements/user/utils";
|
||||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||||
|
|
||||||
import { msg, str } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { CSSResult, TemplateResult, html } from "lit";
|
import { CSSResult, TemplateResult, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
|
@ -402,7 +402,16 @@ export class RelatedUserList extends Table<User> {
|
||||||
<ak-forms-modal>
|
<ak-forms-modal>
|
||||||
<span slot="submit"> ${msg("Create")} </span>
|
<span slot="submit"> ${msg("Create")} </span>
|
||||||
<span slot="header"> ${msg("Create User")} </span>
|
<span slot="header"> ${msg("Create User")} </span>
|
||||||
<ak-user-form slot="form"> </ak-user-form>
|
${this.targetGroup
|
||||||
|
? html`
|
||||||
|
<div class="pf-c-banner pf-m-info" slot="above-form">
|
||||||
|
${msg(
|
||||||
|
str`This user will be added to the group "${this.targetGroup.name}".`,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
<ak-user-form .group=${this.targetGroup} slot="form"> </ak-user-form>
|
||||||
<a slot="trigger" class="pf-c-dropdown__menu-item">
|
<a slot="trigger" class="pf-c-dropdown__menu-item">
|
||||||
${msg("Create user")}
|
${msg("Create user")}
|
||||||
</a>
|
</a>
|
||||||
|
@ -415,7 +424,17 @@ export class RelatedUserList extends Table<User> {
|
||||||
>
|
>
|
||||||
<span slot="submit"> ${msg("Create")} </span>
|
<span slot="submit"> ${msg("Create")} </span>
|
||||||
<span slot="header"> ${msg("Create Service account")} </span>
|
<span slot="header"> ${msg("Create Service account")} </span>
|
||||||
<ak-user-service-account slot="form"> </ak-user-service-account>
|
${this.targetGroup
|
||||||
|
? html`
|
||||||
|
<div class="pf-c-banner pf-m-info" slot="above-form">
|
||||||
|
${msg(
|
||||||
|
str`This user will be added to the group "${this.targetGroup.name}".`,
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
<ak-user-service-account-form .group=${this.targetGroup} slot="form">
|
||||||
|
</ak-user-service-account-form>
|
||||||
<a slot="trigger" class="pf-c-dropdown__menu-item">
|
<a slot="trigger" class="pf-c-dropdown__menu-item">
|
||||||
${msg("Create Service account")}
|
${msg("Create Service account")}
|
||||||
</a>
|
</a>
|
|
@ -4,19 +4,30 @@ import { Form } from "@goauthentik/elements/forms/Form";
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
import { ModalForm } from "@goauthentik/elements/forms/ModalForm";
|
import { ModalForm } from "@goauthentik/elements/forms/ModalForm";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { TemplateResult, html } from "lit";
|
import { TemplateResult, html } from "lit";
|
||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
import { CoreApi, UserServiceAccountRequest, UserServiceAccountResponse } from "@goauthentik/api";
|
import {
|
||||||
|
CoreApi,
|
||||||
|
Group,
|
||||||
|
UserServiceAccountRequest,
|
||||||
|
UserServiceAccountResponse,
|
||||||
|
} from "@goauthentik/api";
|
||||||
|
|
||||||
@customElement("ak-user-service-account")
|
@customElement("ak-user-service-account-form")
|
||||||
export class ServiceAccountForm extends Form<UserServiceAccountRequest> {
|
export class ServiceAccountForm extends Form<UserServiceAccountRequest> {
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
result?: UserServiceAccountResponse;
|
result?: UserServiceAccountResponse;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
group?: Group;
|
||||||
|
|
||||||
getSuccessMessage(): string {
|
getSuccessMessage(): string {
|
||||||
|
if (this.group) {
|
||||||
|
return msg(str`Successfully created user and added to group ${this.group.name}`);
|
||||||
|
}
|
||||||
return msg("Successfully created user.");
|
return msg("Successfully created user.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +37,14 @@ export class ServiceAccountForm extends Form<UserServiceAccountRequest> {
|
||||||
});
|
});
|
||||||
this.result = result;
|
this.result = result;
|
||||||
(this.parentElement as ModalForm).showSubmitButton = false;
|
(this.parentElement as ModalForm).showSubmitButton = false;
|
||||||
|
if (this.group) {
|
||||||
|
await new CoreApi(DEFAULT_CONFIG).coreGroupsAddUserCreate({
|
||||||
|
groupUuid: this.group.pk,
|
||||||
|
userAccountRequest: {
|
||||||
|
pk: this.result.userPk,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,18 @@ import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||||
import "@goauthentik/elements/forms/Radio";
|
import "@goauthentik/elements/forms/Radio";
|
||||||
import YAML from "yaml";
|
import YAML from "yaml";
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
import { msg, str } from "@lit/localize";
|
||||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||||
import { customElement } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
import { CoreApi, User, UserTypeEnum } from "@goauthentik/api";
|
import { CoreApi, Group, User, UserTypeEnum } from "@goauthentik/api";
|
||||||
|
|
||||||
@customElement("ak-user-form")
|
@customElement("ak-user-form")
|
||||||
export class UserForm extends ModelForm<User, number> {
|
export class UserForm extends ModelForm<User, number> {
|
||||||
|
@property({ attribute: false })
|
||||||
|
group?: Group;
|
||||||
|
|
||||||
static get defaultUserAttributes(): { [key: string]: unknown } {
|
static get defaultUserAttributes(): { [key: string]: unknown } {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -42,6 +45,9 @@ export class UserForm extends ModelForm<User, number> {
|
||||||
if (this.instance) {
|
if (this.instance) {
|
||||||
return msg("Successfully updated user.");
|
return msg("Successfully updated user.");
|
||||||
} else {
|
} else {
|
||||||
|
if (this.group) {
|
||||||
|
return msg(str`Successfully created user and added to group ${this.group.name}`);
|
||||||
|
}
|
||||||
return msg("Successfully created user.");
|
return msg("Successfully created user.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,17 +56,27 @@ export class UserForm extends ModelForm<User, number> {
|
||||||
if (data.attributes === null) {
|
if (data.attributes === null) {
|
||||||
data.attributes = UserForm.defaultUserAttributes;
|
data.attributes = UserForm.defaultUserAttributes;
|
||||||
}
|
}
|
||||||
|
let user;
|
||||||
if (this.instance?.pk) {
|
if (this.instance?.pk) {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreUsersPartialUpdate({
|
user = await new CoreApi(DEFAULT_CONFIG).coreUsersPartialUpdate({
|
||||||
id: this.instance.pk,
|
id: this.instance.pk,
|
||||||
patchedUserRequest: data,
|
patchedUserRequest: data,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
data.groups = [];
|
data.groups = [];
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreUsersCreate({
|
user = await new CoreApi(DEFAULT_CONFIG).coreUsersCreate({
|
||||||
userRequest: data,
|
userRequest: data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (this.group) {
|
||||||
|
await new CoreApi(DEFAULT_CONFIG).coreGroupsAddUserCreate({
|
||||||
|
groupUuid: this.group.pk,
|
||||||
|
userAccountRequest: {
|
||||||
|
pk: user.pk,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderForm(): TemplateResult {
|
renderForm(): TemplateResult {
|
||||||
|
|
|
@ -399,7 +399,7 @@ export class UserListPage extends TablePage<User> {
|
||||||
<ak-forms-modal .closeAfterSuccessfulSubmit=${false} .cancelText=${msg("Close")}>
|
<ak-forms-modal .closeAfterSuccessfulSubmit=${false} .cancelText=${msg("Close")}>
|
||||||
<span slot="submit"> ${msg("Create")} </span>
|
<span slot="submit"> ${msg("Create")} </span>
|
||||||
<span slot="header"> ${msg("Create Service account")} </span>
|
<span slot="header"> ${msg("Create Service account")} </span>
|
||||||
<ak-user-service-account slot="form"> </ak-user-service-account>
|
<ak-user-service-account-form slot="form"> </ak-user-service-account-form>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||||
${msg("Create Service account")}
|
${msg("Create Service account")}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -6063,6 +6063,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -6340,6 +6340,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -5979,6 +5979,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -7965,6 +7965,9 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -6187,6 +6187,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -7865,4 +7865,7 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
|
</trans-unit>
|
||||||
</body></file></xliff>
|
</body></file></xliff>
|
||||||
|
|
|
@ -5972,6 +5972,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -7967,6 +7967,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -6020,6 +6020,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -6019,6 +6019,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="sd47f3d3c9741343d">
|
<trans-unit id="sd47f3d3c9741343d">
|
||||||
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &gt;= 10^10)</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="s3d2a8b86a4f5a810">
|
||||||
|
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
Reference in New Issue