enterprise/providers/rac: connection token management (#8467)
This commit is contained in:
@ -1,3 +1,4 @@
|
||||
import { EVENT_REFRESH_ENTERPRISE } from "@goauthentik/app/common/constants";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import "@goauthentik/elements/CodeMirror";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
@ -34,14 +35,19 @@ export class EnterpriseLicenseForm extends ModelForm<License, string> {
|
||||
}
|
||||
|
||||
async send(data: License): Promise<License> {
|
||||
return this.instance
|
||||
? new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicensePartialUpdate({
|
||||
licenseUuid: this.instance.licenseUuid || "",
|
||||
patchedLicenseRequest: data,
|
||||
})
|
||||
: new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseCreate({
|
||||
licenseRequest: data,
|
||||
});
|
||||
return (
|
||||
this.instance
|
||||
? new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicensePartialUpdate({
|
||||
licenseUuid: this.instance.licenseUuid || "",
|
||||
patchedLicenseRequest: data,
|
||||
})
|
||||
: new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseCreate({
|
||||
licenseRequest: data,
|
||||
})
|
||||
).then((data) => {
|
||||
window.dispatchEvent(new CustomEvent(EVENT_REFRESH_ENTERPRISE));
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { first } from "@goauthentik/app/common/utils";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { docLink } from "@goauthentik/common/global";
|
||||
import "@goauthentik/elements/CodeMirror";
|
||||
@ -6,6 +5,8 @@ import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
|
||||
import "@goauthentik/elements/forms/Radio";
|
||||
import type { RadioOption } from "@goauthentik/elements/forms/Radio";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
@ -14,6 +15,23 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { PropertymappingsApi, RACPropertyMapping } from "@goauthentik/api";
|
||||
|
||||
export const staticSettingOptions: RadioOption<string | undefined>[] = [
|
||||
{
|
||||
label: msg("Unconfigured"),
|
||||
value: undefined,
|
||||
default: true,
|
||||
description: html`${msg("This option will not be changed by this mapping.")}`,
|
||||
},
|
||||
{
|
||||
label: msg("Enabled"),
|
||||
value: "true",
|
||||
},
|
||||
{
|
||||
label: msg("Disabled"),
|
||||
value: "false",
|
||||
},
|
||||
];
|
||||
|
||||
@customElement("ak-property-mapping-rac-form")
|
||||
export class PropertyMappingLDAPForm extends ModelForm<RACPropertyMapping, string> {
|
||||
loadInstance(pk: string): Promise<RACPropertyMapping> {
|
||||
@ -58,7 +76,6 @@ export class PropertyMappingLDAPForm extends ModelForm<RACPropertyMapping, strin
|
||||
<div slot="body" class="pf-c-form">
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Username")}
|
||||
?required=${true}
|
||||
name="staticSettings.username"
|
||||
>
|
||||
<input
|
||||
@ -70,7 +87,6 @@ export class PropertyMappingLDAPForm extends ModelForm<RACPropertyMapping, strin
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Password")}
|
||||
?required=${true}
|
||||
name="staticSettings.password"
|
||||
>
|
||||
<input
|
||||
@ -85,81 +101,45 @@ export class PropertyMappingLDAPForm extends ModelForm<RACPropertyMapping, strin
|
||||
<ak-form-group>
|
||||
<span slot="header"> ${msg("RDP settings")} </span>
|
||||
<div slot="body" class="pf-c-form">
|
||||
<ak-form-element-horizontal name="staticSettings.ignore-cert">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
type="checkbox"
|
||||
?checked=${first(
|
||||
this.instance?.staticSettings["ignore-cert"],
|
||||
false,
|
||||
)}
|
||||
/>
|
||||
<span class="pf-c-switch__toggle">
|
||||
<span class="pf-c-switch__toggle-icon">
|
||||
<i class="fas fa-check" aria-hidden="true"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="pf-c-switch__label"
|
||||
>${msg("Ignore server certificate")}</span
|
||||
>
|
||||
</label>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Ignore server certificate")}
|
||||
name="staticSettings.ignore-cert"
|
||||
>
|
||||
<ak-radio
|
||||
.options=${staticSettingOptions}
|
||||
.value=${this.instance?.staticSettings["ignore-cert"]}
|
||||
>
|
||||
</ak-radio>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="staticSettings.enable-wallpaper">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
type="checkbox"
|
||||
?checked=${first(
|
||||
this.instance?.staticSettings["enable-wallpaper"],
|
||||
false,
|
||||
)}
|
||||
/>
|
||||
<span class="pf-c-switch__toggle">
|
||||
<span class="pf-c-switch__toggle-icon">
|
||||
<i class="fas fa-check" aria-hidden="true"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="pf-c-switch__label">${msg("Enable wallpaper")}</span>
|
||||
</label>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Enable wallpaper")}
|
||||
name="staticSettings.enable-wallpaper"
|
||||
>
|
||||
<ak-radio
|
||||
.options=${staticSettingOptions}
|
||||
.value=${this.instance?.staticSettings["enable-wallpaper"]}
|
||||
>
|
||||
</ak-radio>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="staticSettings.enable-font-smoothing">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
type="checkbox"
|
||||
?checked=${first(
|
||||
this.instance?.staticSettings["enable-font-smoothing"],
|
||||
false,
|
||||
)}
|
||||
/>
|
||||
<span class="pf-c-switch__toggle">
|
||||
<span class="pf-c-switch__toggle-icon">
|
||||
<i class="fas fa-check" aria-hidden="true"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="pf-c-switch__label">${msg("Enable font-smoothing")}</span>
|
||||
</label>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Enable font-smoothing")}
|
||||
name="staticSettings.enable-font-smoothing"
|
||||
>
|
||||
<ak-radio
|
||||
.options=${staticSettingOptions}
|
||||
.value=${this.instance?.staticSettings["enable-font-smoothing"]}
|
||||
>
|
||||
</ak-radio>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="staticSettings.enable-full-window-drag">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
type="checkbox"
|
||||
?checked=${first(
|
||||
this.instance?.staticSettings["enable-full-window-drag"],
|
||||
false,
|
||||
)}
|
||||
/>
|
||||
<span class="pf-c-switch__toggle">
|
||||
<span class="pf-c-switch__toggle-icon">
|
||||
<i class="fas fa-check" aria-hidden="true"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="pf-c-switch__label"
|
||||
>${msg("Enable full window dragging")}</span
|
||||
>
|
||||
</label>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Enable full window dragging")}
|
||||
name="staticSettings.enable-full-window-drag"
|
||||
>
|
||||
<ak-radio
|
||||
.options=${staticSettingOptions}
|
||||
.value=${this.instance?.staticSettings["enable-full-window-drag"]}
|
||||
>
|
||||
</ak-radio>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
|
98
web/src/admin/providers/rac/ConnectionTokenList.ts
Normal file
98
web/src/admin/providers/rac/ConnectionTokenList.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { uiConfig } from "@goauthentik/common/ui/config";
|
||||
import "@goauthentik/elements/buttons/SpinnerButton";
|
||||
import "@goauthentik/elements/forms/DeleteBulkForm";
|
||||
import "@goauthentik/elements/forms/ModalForm";
|
||||
import { PaginatedResponse, Table } from "@goauthentik/elements/table/Table";
|
||||
import { TableColumn } from "@goauthentik/elements/table/Table";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
||||
|
||||
import { ConnectionToken, Endpoint, RACProvider, RacApi } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-rac-connection-token-list")
|
||||
export class ConnectionTokenListPage extends Table<ConnectionToken> {
|
||||
checkbox = true;
|
||||
clearOnRefresh = true;
|
||||
|
||||
searchEnabled(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
@property()
|
||||
order = "name";
|
||||
|
||||
@property({ attribute: false })
|
||||
provider?: RACProvider;
|
||||
|
||||
@property({ type: Number })
|
||||
userId?: number;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(PFDescriptionList);
|
||||
}
|
||||
|
||||
async apiEndpoint(page: number): Promise<PaginatedResponse<ConnectionToken>> {
|
||||
return new RacApi(DEFAULT_CONFIG).racConnectionTokensList({
|
||||
ordering: this.order,
|
||||
page: page,
|
||||
pageSize: (await uiConfig()).pagination.perPage,
|
||||
search: this.search || "",
|
||||
provider: this.provider?.pk,
|
||||
sessionUser: this.userId,
|
||||
});
|
||||
}
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
const disabled = this.selectedElements.length < 1;
|
||||
return html`<ak-forms-delete-bulk
|
||||
objectLabel=${msg("Connection Token(s)")}
|
||||
.objects=${this.selectedElements}
|
||||
.metadata=${(item: Endpoint) => {
|
||||
return [
|
||||
{ key: msg("Name"), value: item.name },
|
||||
{ key: msg("Host"), value: item.host },
|
||||
];
|
||||
}}
|
||||
.usedBy=${(item: Endpoint) => {
|
||||
return new RacApi(DEFAULT_CONFIG).racConnectionTokensUsedByList({
|
||||
connectionTokenUuid: item.pk,
|
||||
});
|
||||
}}
|
||||
.delete=${(item: Endpoint) => {
|
||||
return new RacApi(DEFAULT_CONFIG).racConnectionTokensDestroy({
|
||||
connectionTokenUuid: item.pk,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
|
||||
${msg("Delete")}
|
||||
</button>
|
||||
</ak-forms-delete-bulk>`;
|
||||
}
|
||||
|
||||
columns(): TableColumn[] {
|
||||
if (this.provider) {
|
||||
return [
|
||||
new TableColumn(msg("Endpoint"), "endpoint__name"),
|
||||
new TableColumn(msg("User"), "session__user"),
|
||||
];
|
||||
}
|
||||
return [
|
||||
new TableColumn(msg("Provider"), "provider__name"),
|
||||
new TableColumn(msg("Endpoint"), "endpoint__name"),
|
||||
];
|
||||
}
|
||||
|
||||
row(item: ConnectionToken): TemplateResult[] {
|
||||
if (this.provider) {
|
||||
return [html`${item.endpointObj.name}`, html`${item.user.username}`];
|
||||
}
|
||||
return [html`${item.providerObj.name}`, html`${item.endpointObj.name}`];
|
||||
}
|
||||
}
|
@ -107,6 +107,28 @@ export class RACProviderFormPage extends ModelForm<RACProvider, number> {
|
||||
</p>
|
||||
<ak-utils-time-delta-help></ak-utils-time-delta-help>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="deleteTokenOnDisconnect">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
type="checkbox"
|
||||
?checked=${first(this.instance?.deleteTokenOnDisconnect, false)}
|
||||
/>
|
||||
<span class="pf-c-switch__toggle">
|
||||
<span class="pf-c-switch__toggle-icon">
|
||||
<i class="fas fa-check" aria-hidden="true"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="pf-c-switch__label"
|
||||
>${msg("Delete authorization on disconnect")}</span
|
||||
>
|
||||
</label>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"When enabled, connection authorizations will be deleted when a client disconnects. This will force clients with flaky internet connections to re-authorize the endpoint.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<ak-form-group .expanded=${true}>
|
||||
<span slot="header"> ${msg("Protocol settings")} </span>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "@goauthentik/admin/providers/RelatedApplicationButton";
|
||||
import "@goauthentik/admin/providers/rac/ConnectionTokenList";
|
||||
import "@goauthentik/admin/providers/rac/EndpointForm";
|
||||
import "@goauthentik/admin/providers/rac/EndpointList";
|
||||
import "@goauthentik/admin/providers/rac/RACProviderForm";
|
||||
@ -86,6 +87,15 @@ export class RACProviderViewPage extends AKElement {
|
||||
<section slot="page-overview" data-tab-title="${msg("Overview")}">
|
||||
${this.renderTabOverview()}
|
||||
</section>
|
||||
<section slot="page-connections" data-tab-title="${msg("Connections")}">
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__body">
|
||||
<ak-rac-connection-token-list
|
||||
.provider=${this.provider}
|
||||
></ak-rac-connection-token-list>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
slot="page-changelog"
|
||||
data-tab-title="${msg("Changelog")}"
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "@goauthentik/admin/groups/RelatedGroupList";
|
||||
import "@goauthentik/admin/providers/rac/ConnectionTokenList";
|
||||
import "@goauthentik/admin/users/UserActiveForm";
|
||||
import "@goauthentik/admin/users/UserApplicationTable";
|
||||
import "@goauthentik/admin/users/UserChart";
|
||||
@ -329,6 +330,16 @@ export class UserViewPage extends WithCapabilitiesConfig(AKElement) {
|
||||
</ak-user-settings-source>
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
slot="page-rac-connection-tokens"
|
||||
data-tab-title="${msg("RAC Connections")}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
<div class="pf-c-card">
|
||||
<ak-rac-connection-token-list userId=${user.pk}>
|
||||
</ak-rac-connection-token-list>
|
||||
</div>
|
||||
</section>
|
||||
</ak-tabs>
|
||||
`;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ export const EVENT_LOCALE_REQUEST = "ak-locale-request";
|
||||
export const EVENT_REQUEST_POST = "ak-request-post";
|
||||
export const EVENT_MESSAGE = "ak-message";
|
||||
export const EVENT_THEME_CHANGE = "ak-theme-change";
|
||||
export const EVENT_REFRESH_ENTERPRISE = "ak-refresh-enterprise";
|
||||
|
||||
export const WS_MSG_TYPE_MESSAGE = "message";
|
||||
export const WS_MSG_TYPE_REFRESH = "refresh";
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { EVENT_REFRESH_ENTERPRISE } from "@goauthentik/app/common/constants";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { brand, config } from "@goauthentik/common/api/config";
|
||||
import { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
|
||||
@ -109,8 +110,16 @@ export class EnterpriseAwareInterface extends Interface {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
new EnterpriseApi(DEFAULT_CONFIG).enterpriseLicenseSummaryRetrieve().then((enterprise) => {
|
||||
this.licenseSummary = enterprise;
|
||||
const refreshStatus = () => {
|
||||
new EnterpriseApi(DEFAULT_CONFIG)
|
||||
.enterpriseLicenseSummaryRetrieve()
|
||||
.then((enterprise) => {
|
||||
this.licenseSummary = enterprise;
|
||||
});
|
||||
};
|
||||
refreshStatus();
|
||||
window.addEventListener(EVENT_REFRESH_ENTERPRISE, () => {
|
||||
refreshStatus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import { randomId } from "../utils/randomId";
|
||||
export interface RadioOption<T> {
|
||||
label: string;
|
||||
description?: TemplateResult;
|
||||
default: boolean;
|
||||
default?: boolean;
|
||||
value: T;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user