sources/saml: revamp SAML Source (#3785)

* update saml source to use user connections, add all attributes to flow context

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* check for SAML Status in response, add tests

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* package apple icon

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* add webui for connections

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens L
2022-10-14 18:04:47 +03:00
committed by GitHub
parent 5e620c74f9
commit 363872715d
20 changed files with 780 additions and 113 deletions

View File

@ -1,3 +1,4 @@
import { UserMatchingModeToLabel } from "@goauthentik/admin/sources/oauth/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/forms/FormGroup";
@ -22,6 +23,7 @@ import {
SAMLSource,
SignatureAlgorithmEnum,
SourcesApi,
UserMatchingModeEnum,
} from "@goauthentik/api";
@customElement("ak-source-saml-form")
@ -81,6 +83,49 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
<label class="pf-c-check__label"> ${t`Enabled`} </label>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`User matching mode`}
?required=${true}
name="userMatchingMode"
>
<select class="pf-c-form-control">
<option
value=${UserMatchingModeEnum.Identifier}
?selected=${this.instance?.userMatchingMode ===
UserMatchingModeEnum.Identifier}
>
${UserMatchingModeToLabel(UserMatchingModeEnum.Identifier)}
</option>
<option
value=${UserMatchingModeEnum.EmailLink}
?selected=${this.instance?.userMatchingMode ===
UserMatchingModeEnum.EmailLink}
>
${UserMatchingModeToLabel(UserMatchingModeEnum.EmailLink)}
</option>
<option
value=${UserMatchingModeEnum.EmailDeny}
?selected=${this.instance?.userMatchingMode ===
UserMatchingModeEnum.EmailDeny}
>
${UserMatchingModeToLabel(UserMatchingModeEnum.EmailDeny)}
</option>
<option
value=${UserMatchingModeEnum.UsernameLink}
?selected=${this.instance?.userMatchingMode ===
UserMatchingModeEnum.UsernameLink}
>
${UserMatchingModeToLabel(UserMatchingModeEnum.UsernameLink)}
</option>
<option
value=${UserMatchingModeEnum.UsernameDeny}
?selected=${this.instance?.userMatchingMode ===
UserMatchingModeEnum.UsernameDeny}
>
${UserMatchingModeToLabel(UserMatchingModeEnum.UsernameDeny)}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Protocol settings`} </span>

View File

@ -534,7 +534,7 @@ export class FlowExecutor extends AKElement implements StageHost {
? html`
<li>
<a
href="https://unsplash.com/@impatrickt"
href="https://unsplash.com/@brendan_k_steeves"
>${t`Background image`}</a
>
</li>

View File

@ -4,6 +4,7 @@ import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/EmptyState";
import "@goauthentik/user/user-settings/sources/SourceSettingsOAuth";
import "@goauthentik/user/user-settings/sources/SourceSettingsPlex";
import "@goauthentik/user/user-settings/sources/SourceSettingsSAML";
import { t } from "@lingui/macro";
@ -95,6 +96,15 @@ export class UserSourceSettingsPage extends AKElement {
.configureUrl=${source.configureUrl}
>
</ak-user-settings-source-plex>`;
case "ak-user-settings-source-saml":
return html`<ak-user-settings-source-saml
class="pf-c-data-list__item-row"
objectId=${source.objectUid}
title=${source.title}
connectionPk=${connectionPk}
.configureUrl=${source.configureUrl}
>
</ak-user-settings-source-saml>`;
default:
return html`<p>${t`Error: unsupported source settings: ${source.component}`}</p>`;
}

View File

@ -0,0 +1,70 @@
import { AndNext, DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { MessageLevel } from "@goauthentik/common/messages";
import "@goauthentik/elements/Spinner";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { BaseUserSettings } from "@goauthentik/user/user-settings/BaseUserSettings";
import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import { SourcesApi } from "@goauthentik/api";
@customElement("ak-user-settings-source-saml")
export class SourceSettingsSAML extends BaseUserSettings {
@property()
title!: string;
@property({ type: Number })
connectionPk = 0;
render(): TemplateResult {
if (this.connectionPk === -1) {
return html`<ak-spinner></ak-spinner>`;
}
if (this.connectionPk > 0) {
return html`<button
class="pf-c-button pf-m-danger"
@click=${() => {
return new SourcesApi(DEFAULT_CONFIG)
.sourcesUserConnectionsSamlDestroy({
id: this.connectionPk,
})
.then(() => {
showMessage({
level: MessageLevel.info,
message: t`Successfully disconnected source`,
});
})
.catch((exc) => {
showMessage({
level: MessageLevel.error,
message: t`Failed to disconnected source: ${exc}`,
});
})
.finally(() => {
this.parentElement?.dispatchEvent(
new CustomEvent(EVENT_REFRESH, {
bubbles: true,
composed: true,
}),
);
});
}}
>
${t`Disconnect`}
</button>`;
}
return html`<a
class="pf-c-button pf-m-primary"
href="${ifDefined(this.configureUrl)}${AndNext(
`/if/user/#/settings;${JSON.stringify({ page: "page-sources" })}`,
)}"
>
${t`Connect`}
</a>`;
}
}