web/admin: show warning when adding user to superuser group (#5091)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-03-27 16:27:34 +02:00 committed by GitHub
parent 5600261852
commit a7fc579202
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 7 deletions

View File

@ -81,7 +81,7 @@ export class GroupListPage extends TablePage<Group> {
html`<a href="#/identity/groups/${item.pk}">${item.name}</a>`, html`<a href="#/identity/groups/${item.pk}">${item.name}</a>`,
html`${item.parentName || t`-`}`, html`${item.parentName || t`-`}`,
html`${Array.from(item.users || []).length}`, html`${Array.from(item.users || []).length}`,
html` <ak-label color=${item.isSuperuser ? PFColor.Green : PFColor.Grey}> html`<ak-label color=${item.isSuperuser ? PFColor.Green : PFColor.Grey}>
${item.isSuperuser ? t`Yes` : t`No`} ${item.isSuperuser ? t`Yes` : t`No`}
</ak-label>`, </ak-label>`,
html` <ak-forms-modal> html` <ak-forms-modal>

View File

@ -32,7 +32,7 @@ export class RelatedGroupAdd extends Form<{ groups: string[] }> {
return t`Successfully added user to group(s).`; return t`Successfully added user to group(s).`;
} }
send = async (data: { groups: string[] }): Promise<{ groups: string[] }> => { async send(data: { groups: string[] }): Promise<unknown> {
await Promise.all( await Promise.all(
data.groups.map((group) => { data.groups.map((group) => {
return new CoreApi(DEFAULT_CONFIG).coreGroupsAddUserCreate({ return new CoreApi(DEFAULT_CONFIG).coreGroupsAddUserCreate({
@ -44,7 +44,7 @@ export class RelatedGroupAdd extends Form<{ groups: string[] }> {
}), }),
); );
return data; return data;
}; }
renderForm(): TemplateResult { renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal"> return html`<form class="pf-c-form pf-m-horizontal">

View File

@ -8,9 +8,11 @@ import { TableModal } from "@goauthentik/elements/table/TableModal";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit"; import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
import { CoreApi, Group } from "@goauthentik/api"; import { CoreApi, Group } from "@goauthentik/api";
@customElement("ak-user-group-select-table") @customElement("ak-user-group-select-table")
@ -27,6 +29,10 @@ export class GroupSelectModal extends TableModal<Group> {
order = "name"; order = "name";
static get styles(): CSSResult[] {
return super.styles.concat(PFBanner);
}
async apiEndpoint(page: number): Promise<PaginatedResponse<Group>> { async apiEndpoint(page: number): Promise<PaginatedResponse<Group>> {
return new CoreApi(DEFAULT_CONFIG).coreGroupsList({ return new CoreApi(DEFAULT_CONFIG).coreGroupsList({
ordering: this.order, ordering: this.order,
@ -61,11 +67,19 @@ export class GroupSelectModal extends TableModal<Group> {
} }
renderModalInner(): TemplateResult { renderModalInner(): TemplateResult {
const willSuperuser = this.selectedElements.filter((g) => g.isSuperuser).length > 0;
return html`<section class="pf-c-modal-box__header pf-c-page__main-section pf-m-light"> return html`<section class="pf-c-modal-box__header pf-c-page__main-section pf-m-light">
<div class="pf-c-content"> <div class="pf-c-content">
<h1 class="pf-c-title pf-m-2xl">${t`Select groups to add user to`}</h1> <h1 class="pf-c-title pf-m-2xl">${t`Select groups to add user to`}</h1>
</div> </div>
</section> </section>
${willSuperuser
? html`
<div class="pf-c-banner pf-m-warning">
${t`Warning: Adding the user to the selected group(s) will give them superuser permissions.`}
</div>
`
: html``}
<section class="pf-c-modal-box__body pf-m-light">${this.renderTable()}</section> <section class="pf-c-modal-box__body pf-m-light">${this.renderTable()}</section>
<footer class="pf-c-modal-box__footer"> <footer class="pf-c-modal-box__footer">
<ak-spinner-button <ak-spinner-button

View File

@ -28,6 +28,7 @@ import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
import { CapabilitiesEnum, CoreApi, Group, ResponseError, User } from "@goauthentik/api"; import { CapabilitiesEnum, CoreApi, Group, ResponseError, User } from "@goauthentik/api";
@ -44,7 +45,7 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
return t`Successfully added user(s).`; return t`Successfully added user(s).`;
} }
send = async (data: { users: number[] }): Promise<{ users: number[] }> => { async send(data: { users: number[] }): Promise<{ users: number[] }> {
await Promise.all( await Promise.all(
data.users.map((user) => { data.users.map((user) => {
return new CoreApi(DEFAULT_CONFIG).coreGroupsAddUserCreate({ return new CoreApi(DEFAULT_CONFIG).coreGroupsAddUserCreate({
@ -56,10 +57,11 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
}), }),
); );
return data; return data;
}; }
renderForm(): TemplateResult { renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal"> return html`<form class="pf-c-form pf-m-horizontal">
${this.group?.isSuperuser ? html`` : html``}
<ak-form-element-horizontal label=${t`Users to add`} name="users"> <ak-form-element-horizontal label=${t`Users to add`} name="users">
<div class="pf-c-input-group"> <div class="pf-c-input-group">
<ak-group-member-select-table <ak-group-member-select-table
@ -115,7 +117,7 @@ export class RelatedUserList extends Table<User> {
hideServiceAccounts = getURLParam<boolean>("hideServiceAccounts", true); hideServiceAccounts = getURLParam<boolean>("hideServiceAccounts", true);
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return super.styles.concat(PFDescriptionList, PFAlert); return super.styles.concat(PFDescriptionList, PFAlert, PFBanner);
} }
async apiEndpoint(page: number): Promise<PaginatedResponse<User>> { async apiEndpoint(page: number): Promise<PaginatedResponse<User>> {
@ -334,6 +336,13 @@ export class RelatedUserList extends Table<User> {
? html`<ak-forms-modal> ? html`<ak-forms-modal>
<span slot="submit"> ${t`Add`} </span> <span slot="submit"> ${t`Add`} </span>
<span slot="header"> ${t`Add User`} </span> <span slot="header"> ${t`Add User`} </span>
${this.targetGroup.isSuperuser
? html`
<div class="pf-c-banner pf-m-warning" slot="above-form">
${t`Warning: This group is configured with superuser access. Added users will have superuser access.`}
</div>
`
: html``}
<ak-user-related-add .group=${this.targetGroup} slot="form"> <ak-user-related-add .group=${this.targetGroup} slot="form">
</ak-user-related-add> </ak-user-related-add>
<button slot="trigger" class="pf-c-button pf-m-primary"> <button slot="trigger" class="pf-c-button pf-m-primary">

View File

@ -65,6 +65,7 @@ export class ModalForm extends ModalButton {
</h1> </h1>
</div> </div>
</section> </section>
<slot name="above-form"></slot>
<section <section
class="pf-c-modal-box__body" class="pf-c-modal-box__body"
@scroll=${() => { @scroll=${() => {