2021-08-15 19:32:28 +00:00
|
|
|
import { CoreApi, PoliciesApi, Policy, PolicyBinding } from "@goauthentik/api";
|
2021-04-03 17:26:43 +00:00
|
|
|
import { t } from "@lingui/macro";
|
2021-09-21 09:19:26 +00:00
|
|
|
import { css, CSSResult } from "lit";
|
|
|
|
import { customElement, property } from "lit/decorators";
|
|
|
|
import { html, TemplateResult } from "lit";
|
2021-03-31 17:15:28 +00:00
|
|
|
import { DEFAULT_CONFIG } from "../../api/Config";
|
2021-09-21 09:19:26 +00:00
|
|
|
import { until } from "lit/directives/until";
|
|
|
|
import { ifDefined } from "lit/directives/if-defined";
|
2021-04-03 09:41:11 +00:00
|
|
|
import { first, groupBy } from "../../utils";
|
2021-03-31 17:15:28 +00:00
|
|
|
import "../../elements/forms/HorizontalFormElement";
|
2021-04-04 20:56:28 +00:00
|
|
|
import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";
|
|
|
|
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
2021-05-11 10:05:30 +00:00
|
|
|
import { ModelForm } from "../../elements/forms/ModelForm";
|
2021-04-04 20:56:28 +00:00
|
|
|
|
|
|
|
enum target {
|
2021-08-03 15:52:21 +00:00
|
|
|
policy,
|
|
|
|
group,
|
|
|
|
user,
|
2021-04-04 21:19:08 +00:00
|
|
|
}
|
2021-03-31 17:15:28 +00:00
|
|
|
|
|
|
|
@customElement("ak-policy-binding-form")
|
2021-05-11 10:05:30 +00:00
|
|
|
export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
|
|
|
|
loadInstance(pk: string): Promise<PolicyBinding> {
|
2021-08-03 15:52:21 +00:00
|
|
|
return new PoliciesApi(DEFAULT_CONFIG)
|
|
|
|
.policiesBindingsRetrieve({
|
|
|
|
policyBindingUuid: pk,
|
|
|
|
})
|
|
|
|
.then((binding) => {
|
|
|
|
if (binding?.policyObj) {
|
|
|
|
this.policyGroupUser = target.policy;
|
|
|
|
}
|
|
|
|
if (binding?.groupObj) {
|
|
|
|
this.policyGroupUser = target.group;
|
|
|
|
}
|
|
|
|
if (binding?.userObj) {
|
|
|
|
this.policyGroupUser = target.user;
|
|
|
|
}
|
|
|
|
return binding;
|
|
|
|
});
|
2021-04-04 20:56:28 +00:00
|
|
|
}
|
|
|
|
|
2021-03-31 17:15:28 +00:00
|
|
|
@property()
|
|
|
|
targetPk?: string;
|
|
|
|
|
2021-08-03 15:52:21 +00:00
|
|
|
@property({ type: Number })
|
2021-04-06 10:11:59 +00:00
|
|
|
policyGroupUser: target = target.policy;
|
2021-04-04 20:56:28 +00:00
|
|
|
|
2021-08-03 15:52:21 +00:00
|
|
|
@property({ type: Boolean })
|
2021-04-20 21:30:37 +00:00
|
|
|
policyOnly = false;
|
|
|
|
|
2021-03-31 17:15:28 +00:00
|
|
|
getSuccessMessage(): string {
|
2021-05-11 10:05:30 +00:00
|
|
|
if (this.instance) {
|
2021-04-03 17:26:43 +00:00
|
|
|
return t`Successfully updated binding.`;
|
2021-03-31 17:15:28 +00:00
|
|
|
} else {
|
2021-04-03 17:26:43 +00:00
|
|
|
return t`Successfully created binding.`;
|
2021-03-31 17:15:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-04 20:56:28 +00:00
|
|
|
static get styles(): CSSResult[] {
|
2021-08-03 15:52:21 +00:00
|
|
|
return super.styles.concat(
|
|
|
|
PFToggleGroup,
|
|
|
|
PFContent,
|
|
|
|
css`
|
|
|
|
.pf-c-toggle-group {
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
);
|
2021-04-04 20:56:28 +00:00
|
|
|
}
|
|
|
|
|
2021-03-31 17:15:28 +00:00
|
|
|
send = (data: PolicyBinding): Promise<PolicyBinding> => {
|
2021-05-11 10:05:30 +00:00
|
|
|
if (this.instance) {
|
2021-03-31 17:15:28 +00:00
|
|
|
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsUpdate({
|
2021-05-11 10:05:30 +00:00
|
|
|
policyBindingUuid: this.instance.pk || "",
|
2021-08-03 15:52:21 +00:00
|
|
|
policyBindingRequest: data,
|
2021-03-31 17:15:28 +00:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsCreate({
|
2021-08-03 15:52:21 +00:00
|
|
|
policyBindingRequest: data,
|
2021-03-31 17:15:28 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
groupPolicies(policies: Policy[]): TemplateResult {
|
|
|
|
return html`
|
2021-08-03 15:52:21 +00:00
|
|
|
${groupBy<Policy>(policies, (p) => p.verboseName || "").map(([group, policies]) => {
|
2021-03-31 17:15:28 +00:00
|
|
|
return html`<optgroup label=${group}>
|
2021-08-03 15:52:21 +00:00
|
|
|
${policies.map((p) => {
|
|
|
|
const selected = this.instance?.policy === p.pk;
|
|
|
|
return html`<option ?selected=${selected} value=${ifDefined(p.pk)}>
|
|
|
|
${p.name}
|
|
|
|
</option>`;
|
2021-03-31 17:15:28 +00:00
|
|
|
})}
|
|
|
|
</optgroup>`;
|
|
|
|
})}
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
|
|
|
getOrder(): Promise<number> {
|
2021-05-11 10:05:30 +00:00
|
|
|
if (this.instance) {
|
|
|
|
return Promise.resolve(this.instance.order);
|
2021-03-31 17:15:28 +00:00
|
|
|
}
|
2021-08-03 15:52:21 +00:00
|
|
|
return new PoliciesApi(DEFAULT_CONFIG)
|
|
|
|
.policiesBindingsList({
|
|
|
|
target: this.targetPk || "",
|
|
|
|
})
|
|
|
|
.then((bindings) => {
|
|
|
|
const orders = bindings.results.map((binding) => binding.order);
|
|
|
|
if (orders.length < 1) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return Math.max(...orders) + 1;
|
|
|
|
});
|
2021-03-31 17:15:28 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 21:30:37 +00:00
|
|
|
renderModeSelector(): TemplateResult {
|
|
|
|
if (this.policyOnly) {
|
|
|
|
this.policyGroupUser = target.policy;
|
2021-08-03 15:52:21 +00:00
|
|
|
return html` <div class="pf-c-toggle-group__item">
|
|
|
|
<button class="pf-c-toggle-group__button pf-m-selected" type="button">
|
|
|
|
<span class="pf-c-toggle-group__text">${t`Policy`}</span>
|
|
|
|
</button>
|
|
|
|
</div>`;
|
2021-04-20 21:30:37 +00:00
|
|
|
}
|
2021-08-03 15:52:21 +00:00
|
|
|
return html` <div class="pf-c-toggle-group__item">
|
|
|
|
<button
|
|
|
|
class="pf-c-toggle-group__button ${this.policyGroupUser === target.policy
|
|
|
|
? "pf-m-selected"
|
|
|
|
: ""}"
|
|
|
|
type="button"
|
|
|
|
@click=${() => {
|
|
|
|
this.policyGroupUser = target.policy;
|
|
|
|
}}
|
|
|
|
>
|
2021-04-20 21:30:37 +00:00
|
|
|
<span class="pf-c-toggle-group__text">${t`Policy`}</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
|
|
|
|
<div class="pf-c-toggle-group__item">
|
2021-08-03 15:52:21 +00:00
|
|
|
<button
|
|
|
|
class="pf-c-toggle-group__button ${this.policyGroupUser === target.group
|
|
|
|
? "pf-m-selected"
|
|
|
|
: ""}"
|
|
|
|
type="button"
|
|
|
|
@click=${() => {
|
|
|
|
this.policyGroupUser = target.group;
|
|
|
|
}}
|
|
|
|
>
|
2021-04-20 21:30:37 +00:00
|
|
|
<span class="pf-c-toggle-group__text">${t`Group`}</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
|
|
|
|
<div class="pf-c-toggle-group__item">
|
2021-08-03 15:52:21 +00:00
|
|
|
<button
|
|
|
|
class="pf-c-toggle-group__button ${this.policyGroupUser === target.user
|
|
|
|
? "pf-m-selected"
|
|
|
|
: ""}"
|
|
|
|
type="button"
|
|
|
|
@click=${() => {
|
|
|
|
this.policyGroupUser = target.user;
|
|
|
|
}}
|
|
|
|
>
|
2021-04-20 21:30:37 +00:00
|
|
|
<span class="pf-c-toggle-group__text">${t`User`}</span>
|
|
|
|
</button>
|
|
|
|
</div>`;
|
|
|
|
}
|
|
|
|
|
2021-03-31 17:15:28 +00:00
|
|
|
renderForm(): TemplateResult {
|
|
|
|
return html`<form class="pf-c-form pf-m-horizontal">
|
2021-04-04 20:56:28 +00:00
|
|
|
<div class="pf-c-card pf-m-selectable pf-m-selected">
|
|
|
|
<div class="pf-c-card__body">
|
2021-08-03 15:52:21 +00:00
|
|
|
<div class="pf-c-toggle-group">${this.renderModeSelector()}</div>
|
2021-04-04 20:56:28 +00:00
|
|
|
</div>
|
|
|
|
<div class="pf-c-card__footer">
|
|
|
|
<ak-form-element-horizontal
|
|
|
|
label=${t`Policy`}
|
|
|
|
name="policy"
|
2021-08-03 15:52:21 +00:00
|
|
|
?hidden=${this.policyGroupUser !== target.policy}
|
|
|
|
>
|
2021-04-04 20:56:28 +00:00
|
|
|
<select class="pf-c-form-control">
|
2021-08-03 15:52:21 +00:00
|
|
|
<option value="" ?selected=${this.instance?.policy === undefined}>
|
|
|
|
---------
|
|
|
|
</option>
|
|
|
|
${until(
|
|
|
|
new PoliciesApi(DEFAULT_CONFIG)
|
|
|
|
.policiesAllList({
|
|
|
|
ordering: "pk",
|
|
|
|
})
|
|
|
|
.then((policies) => {
|
|
|
|
return this.groupPolicies(policies.results);
|
|
|
|
}),
|
|
|
|
html`<option>${t`Loading...`}</option>`,
|
|
|
|
)}
|
2021-04-04 20:56:28 +00:00
|
|
|
</select>
|
|
|
|
</ak-form-element-horizontal>
|
|
|
|
<ak-form-element-horizontal
|
|
|
|
label=${t`Group`}
|
|
|
|
name="group"
|
2021-08-03 15:52:21 +00:00
|
|
|
?hidden=${this.policyGroupUser !== target.group}
|
|
|
|
>
|
2021-04-04 20:56:28 +00:00
|
|
|
<select class="pf-c-form-control">
|
2021-08-03 15:52:21 +00:00
|
|
|
<option value="" ?selected=${this.instance?.group === undefined}>
|
|
|
|
---------
|
|
|
|
</option>
|
|
|
|
${until(
|
|
|
|
new CoreApi(DEFAULT_CONFIG)
|
|
|
|
.coreGroupsList({
|
|
|
|
ordering: "pk",
|
|
|
|
})
|
|
|
|
.then((groups) => {
|
|
|
|
return groups.results.map((group) => {
|
|
|
|
return html`<option
|
|
|
|
value=${ifDefined(group.pk)}
|
|
|
|
?selected=${group.pk === this.instance?.group}
|
|
|
|
>
|
|
|
|
${group.name}
|
|
|
|
</option>`;
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
html`<option>${t`Loading...`}</option>`,
|
|
|
|
)}
|
2021-04-04 20:56:28 +00:00
|
|
|
</select>
|
|
|
|
</ak-form-element-horizontal>
|
|
|
|
<ak-form-element-horizontal
|
|
|
|
label=${t`User`}
|
|
|
|
name="user"
|
2021-08-03 15:52:21 +00:00
|
|
|
?hidden=${this.policyGroupUser !== target.user}
|
|
|
|
>
|
2021-04-04 20:56:28 +00:00
|
|
|
<select class="pf-c-form-control">
|
2021-08-03 15:52:21 +00:00
|
|
|
<option value="" ?selected=${this.instance?.user === undefined}>
|
|
|
|
---------
|
|
|
|
</option>
|
|
|
|
${until(
|
|
|
|
new CoreApi(DEFAULT_CONFIG)
|
|
|
|
.coreUsersList({
|
|
|
|
ordering: "pk",
|
|
|
|
})
|
|
|
|
.then((users) => {
|
|
|
|
return users.results.map((user) => {
|
|
|
|
return html`<option
|
|
|
|
value=${ifDefined(user.pk)}
|
|
|
|
?selected=${user.pk === this.instance?.user}
|
|
|
|
>
|
|
|
|
${user.name}
|
|
|
|
</option>`;
|
|
|
|
});
|
|
|
|
}),
|
|
|
|
html`<option>${t`Loading...`}</option>`,
|
|
|
|
)}
|
2021-04-04 20:56:28 +00:00
|
|
|
</select>
|
|
|
|
</ak-form-element-horizontal>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-08-03 15:52:21 +00:00
|
|
|
<input
|
|
|
|
required
|
|
|
|
name="target"
|
|
|
|
type="hidden"
|
|
|
|
value=${ifDefined(this.instance?.target || this.targetPk)}
|
|
|
|
/>
|
2021-03-31 17:15:28 +00:00
|
|
|
<ak-form-element-horizontal name="enabled">
|
|
|
|
<div class="pf-c-check">
|
2021-08-03 15:52:21 +00:00
|
|
|
<input
|
|
|
|
type="checkbox"
|
|
|
|
class="pf-c-check__input"
|
|
|
|
?checked=${first(this.instance?.enabled, true)}
|
|
|
|
/>
|
|
|
|
<label class="pf-c-check__label"> ${t`Enabled`} </label>
|
2021-03-31 17:15:28 +00:00
|
|
|
</div>
|
|
|
|
</ak-form-element-horizontal>
|
2021-05-31 09:50:29 +00:00
|
|
|
<ak-form-element-horizontal name="negate">
|
|
|
|
<div class="pf-c-check">
|
2021-08-03 15:52:21 +00:00
|
|
|
<input
|
|
|
|
type="checkbox"
|
|
|
|
class="pf-c-check__input"
|
|
|
|
?checked=${first(this.instance?.negate, false)}
|
|
|
|
/>
|
|
|
|
<label class="pf-c-check__label"> ${t`Negate result`} </label>
|
2021-05-31 09:50:29 +00:00
|
|
|
</div>
|
|
|
|
<p class="pf-c-form__helper-text">
|
|
|
|
${t`Negates the outcome of the binding. Messages are unaffected.`}
|
|
|
|
</p>
|
|
|
|
</ak-form-element-horizontal>
|
2021-08-03 15:52:21 +00:00
|
|
|
<ak-form-element-horizontal label=${t`Order`} ?required=${true} name="order">
|
2021-09-21 09:19:26 +00:00
|
|
|
<!-- @ts-ignore -->
|
2021-08-03 15:52:21 +00:00
|
|
|
<input
|
|
|
|
type="number"
|
|
|
|
value="${until(this.getOrder())}"
|
|
|
|
class="pf-c-form-control"
|
|
|
|
required
|
|
|
|
/>
|
2021-03-31 17:15:28 +00:00
|
|
|
</ak-form-element-horizontal>
|
2021-08-03 15:52:21 +00:00
|
|
|
<ak-form-element-horizontal label=${t`Timeout`} ?required=${true} name="timeout">
|
|
|
|
<input
|
|
|
|
type="number"
|
|
|
|
value="${first(this.instance?.timeout, 30)}"
|
|
|
|
class="pf-c-form-control"
|
|
|
|
required
|
|
|
|
/>
|
2021-03-31 17:15:28 +00:00
|
|
|
</ak-form-element-horizontal>
|
|
|
|
</form>`;
|
|
|
|
}
|
|
|
|
}
|