Merge branch 'ak-select-crypto-certificate' into application-wizard-2

* ak-select-crypto-certificate:
  web: display tests for CryptoCertificateKeypair search
  web: Replace ad-hoc search for CryptoCertificateKeyPairs with ak-crypto-certeficate-search
This commit is contained in:
Ken Sternberg 2023-08-07 09:58:49 -07:00
commit eed32b0235
12 changed files with 173 additions and 370 deletions

View File

@ -1,6 +1,7 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement } from "@goauthentik/elements/Base";
import { SearchSelect } from "@goauthentik/elements/forms/SearchSelect"; import { SearchSelect } from "@goauthentik/elements/forms/SearchSelect";
import "@goauthentik/elements/forms/SearchSelect";
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter"; import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { html } from "lit"; import { html } from "lit";
@ -29,7 +30,7 @@ const renderValue = (item: CertificateKeyPair | undefined): string | undefined =
*/ */
@customElement("ak-crypto-certificate-search") @customElement("ak-crypto-certificate-search")
export class CryptoCertificateSearch extends CustomListenerElement(AKElement) { export class AkCryptoCertificateSearch extends CustomListenerElement(AKElement) {
@property({ type: String, reflect: true }) @property({ type: String, reflect: true })
certificate?: string; certificate?: string;
@ -126,4 +127,4 @@ export class CryptoCertificateSearch extends CustomListenerElement(AKElement) {
} }
} }
export default CryptoCertificateSearch; export default AkCryptoCertificateSearch;

View File

@ -2,6 +2,7 @@ import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement } from "@goauthentik/elements/Base";
import { SearchSelect } from "@goauthentik/elements/forms/SearchSelect"; import { SearchSelect } from "@goauthentik/elements/forms/SearchSelect";
import "@goauthentik/elements/forms/SearchSelect";
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter"; import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { html } from "lit"; import { html } from "lit";

View File

@ -0,0 +1,91 @@
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/messages/MessageContainer";
import { Meta } from "@storybook/web-components";
import { TemplateResult, html } from "lit";
import "../ak-crypto-certificate-search";
import AkCryptoCertificateSearch from "../ak-crypto-certificate-search";
import { dummyCryptoCertsSearch } from "./samples";
const metadata: Meta<AkCryptoCertificateSearch> = {
title: "Components / Searches / CryptoCertificateKeyPair",
component: "ak-crypto-certificate-search",
parameters: {
docs: {
description: {
component: "A search function for cryptographic certificates in Authentik",
},
},
mockData: [
{
url: "/api/v3/crypto/certificatekeypairs/?has_key=true&include_details=false&ordering=name",
method: "GET",
status: 200,
response: dummyCryptoCertsSearch,
},
],
},
argTypes: {
// Typescript is unaware that arguments for components are treated as properties, and
// properties are typically renamed to lower case, even if the variable is not.
// @ts-expect-error
nokey: {
control: "boolean",
description:
"When true, certificates without valid keys will be included in the search",
},
singleton: {
control: "boolean",
description:
"Supports the SAML Source search: when true, if there is no certificate in the current form and there is one and only one certificate in the Authentik database, use that certificate by default.",
},
},
};
export default metadata;
const LIGHT = "pf-t-light";
function injectTheme() {
setTimeout(() => {
if (!document.body.classList.contains(LIGHT)) {
document.body.classList.add(LIGHT);
}
});
}
const container = (testItem: TemplateResult) => {
injectTheme();
return html` <div style="background: #fff; padding: 2em">
<style>
li {
display: block;
}
p {
margin-top: 1em;
}
</style>
<ak-message-container></ak-message-container>
${testItem}
<pre id="message-pad" style="margin-top: 1em"></pre>
</div>`;
};
export const CryptoCertificateSearch = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const showMessage = (ev: CustomEvent<any>) => {
const detail = ev.detail;
delete detail["target"];
document.getElementById("message-pad")!.innerText = `Event: ${JSON.stringify(
detail,
null,
2,
)}`;
};
return container(
html` <ak-form-element-horizontal name="test-crypto-certificate-search">
<ak-crypto-certificate-search @ak-change=${showMessage}></ak-crypto-certificate-search
></ak-form-element-horizontal>`,
);
};

View File

@ -0,0 +1,29 @@
export const dummyCryptoCertsSearch = {
pagination: {
next: 0,
previous: 0,
count: 1,
current: 1,
total_pages: 1,
start_index: 1,
end_index: 1,
},
results: [
{
pk: "63efd1b8-6c39-4f65-8157-9a406cb37447",
name: "authentik Self-signed Certificate",
fingerprint_sha256: null,
fingerprint_sha1: null,
cert_expiry: null,
cert_subject: null,
private_key_available: true,
private_key_type: null,
certificate_download_url:
"/api/v3/crypto/certificatekeypairs/63efd1b8-6c39-4f65-8157-9a406cb37447/view_certificate/?download",
private_key_download_url:
"/api/v3/crypto/certificatekeypairs/63efd1b8-6c39-4f65-8157-9a406cb37447/view_private_key/?download",
managed: null,
},
],
};

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
@ -9,13 +10,7 @@ import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { import { DockerServiceConnection, OutpostsApi } from "@goauthentik/api";
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
DockerServiceConnection,
OutpostsApi,
} from "@goauthentik/api";
@customElement("ak-service-connection-docker-form") @customElement("ak-service-connection-docker-form")
export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnection, string> { export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnection, string> {
@ -93,33 +88,9 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
label=${msg("TLS Verification Certificate")} label=${msg("TLS Verification Certificate")}
name="tlsVerification" name="tlsVerification"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => { certificate=${this.instance?.tlsVerification}
const args: CryptoCertificatekeypairsListRequest = { ></ak-crypto-certificate-search>
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return this.instance?.tlsVerification === item.pk;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"CA which the endpoint's Certificate is verified against. Can be left empty for no validation.", "CA which the endpoint's Certificate is verified against. Can be left empty for no validation.",
@ -130,33 +101,9 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
label=${msg("TLS Authentication Certificate/SSH Keypair")} label=${msg("TLS Authentication Certificate/SSH Keypair")}
name="tlsAuthentication" name="tlsAuthentication"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => { certificate=${this.instance?.tlsAuthentication}
const args: CryptoCertificatekeypairsListRequest = { ></ak-crypto-certificate-search>
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return this.instance?.tlsAuthentication === item.pk;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"Certificate/Key used for authentication. Can be left empty for no authentication.", "Certificate/Key used for authentication. Can be left empty for no authentication.",

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search"; import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
@ -14,11 +15,8 @@ import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { import {
CertificateKeyPair,
CoreApi, CoreApi,
CoreGroupsListRequest, CoreGroupsListRequest,
CryptoApi,
CryptoCertificatekeypairsListRequest,
FlowsInstancesListDesignationEnum, FlowsInstancesListDesignationEnum,
Group, Group,
LDAPAPIAccessMode, LDAPAPIAccessMode,
@ -208,35 +206,9 @@ export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Certificate")} name="certificate"> <ak-form-element-horizontal label=${msg("Certificate")} name="certificate">
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.certificate}
query?: string, ></ak-crypto-certificate-search>
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.certificate;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"The certificate for the above configured Base DN. As a fallback, the provider uses a self-signed certificate.", "The certificate for the above configured Base DN. As a fallback, the provider uses a self-signed certificate.",

View File

@ -247,11 +247,10 @@ export class OAuth2ProviderFormPage extends ModelForm<OAuth2Provider, number> {
<ak-form-element-horizontal label=${msg("Signing Key")} name="signingKey"> <ak-form-element-horizontal label=${msg("Signing Key")} name="signingKey">
<ak-crypto-certificate-search <ak-crypto-certificate-search
certificate=${ifDefined(provider?.signingKey ?? nothing)}
name="certificate" name="certificate"
certificate=${ifDefined(this.instance?.signingKey ?? undefined)}
singleton singleton
> ></ak-crypto-certificate-search>
</ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">${msg("Key used to sign the tokens.")}</p> <p class="pf-c-form__helper-text">${msg("Key used to sign the tokens.")}</p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
</div> </div>

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search"; import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
@ -18,9 +19,6 @@ import PFList from "@patternfly/patternfly/components/List/list.css";
import PFSpacing from "@patternfly/patternfly/utilities/Spacing/spacing.css"; import PFSpacing from "@patternfly/patternfly/utilities/Spacing/spacing.css";
import { import {
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
FlowsInstancesListDesignationEnum, FlowsInstancesListDesignationEnum,
PaginatedOAuthSourceList, PaginatedOAuthSourceList,
PaginatedScopeMappingList, PaginatedScopeMappingList,
@ -103,7 +101,6 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
> >
</ak-text-input> </ak-text-input>
<<<<<<< HEAD
<ak-text-input <ak-text-input
name="basicAuthPasswordAttribute" name="basicAuthPasswordAttribute"
label=${msg("HTTP-Basic Password Key")} label=${msg("HTTP-Basic Password Key")}
@ -112,7 +109,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
"User/Group Attribute used for the password part of the HTTP-Basic Header.", "User/Group Attribute used for the password part of the HTTP-Basic Header.",
)} )}
> >
</ak-text-input>`; </ak-text-input>`;
} }
renderModeSelector(): TemplateResult { renderModeSelector(): TemplateResult {
@ -308,26 +305,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
</ak-form-element-horizontal> </ak-form-element-horizontal>
<div class="pf-c-card pf-m-selectable pf-m-selected"> <div class="pf-c-card pf-m-selectable pf-m-selected">
<<<<<<< HEAD
<div class="pf-c-card__body">
<ak-toggle-group
value=${this.mode}
@ak-toggle=${(ev: CustomEvent<{ value: ProxyMode }>) => {
this.mode = ev.detail.value;
}}
>
<option value=${ProxyMode.Proxy}>${msg("Proxy")}</option>
<option value=${ProxyMode.ForwardSingle}>
${msg("Forward auth (single application)")}
</option>
<option value=${ProxyMode.ForwardDomain}>
${msg("Forward auth (domain level)")}
</option>
</ak-toggle-group>
</div>
=======
<div class="pf-c-card__body">${this.renderModeSelector()}</div> <div class="pf-c-card__body">${this.renderModeSelector()}</div>
>>>>>>> ak-toggle-group
<div class="pf-c-card__footer">${this.renderSettings()}</div> <div class="pf-c-card__footer">${this.renderSettings()}</div>
</div> </div>
<ak-form-element-horizontal label=${msg("Token validity")} name="accessTokenValidity"> <ak-form-element-horizontal label=${msg("Token validity")} name="accessTokenValidity">
@ -346,35 +324,9 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
<span slot="header">${msg("Advanced protocol settings")}</span> <span slot="header">${msg("Advanced protocol settings")}</span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal label=${msg("Certificate")} name="certificate"> <ak-form-element-horizontal label=${msg("Certificate")} name="certificate">
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.certificate}
query?: string, ></ak-crypto-certificate-search>
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.certificate;
}}
?blankable=${true}
>
</ak-search-select>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${msg("Additional scopes")} label=${msg("Additional scopes")}

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search"; import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/elements/forms/FormGroup"; import "@goauthentik/elements/forms/FormGroup";
@ -13,9 +14,6 @@ import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { import {
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
DigestAlgorithmEnum, DigestAlgorithmEnum,
FlowsInstancesListDesignationEnum, FlowsInstancesListDesignationEnum,
PaginatedSAMLPropertyMappingList, PaginatedSAMLPropertyMappingList,
@ -177,35 +175,9 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
label=${msg("Signing Certificate")} label=${msg("Signing Certificate")}
name="signingKp" name="signingKp"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.signingKp}
query?: string, ></ak-crypto-certificate-search>
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.signingKp;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"Certificate used to sign outgoing Responses going to the Service Provider.", "Certificate used to sign outgoing Responses going to the Service Provider.",
@ -216,41 +188,16 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
label=${msg("Verification Certificate")} label=${msg("Verification Certificate")}
name="verificationKp" name="verificationKp"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.verificationKp}
query?: string, nokey
): Promise<CertificateKeyPair[]> => { ></ak-crypto-certificate-search>
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.verificationKp;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.", "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.",
)} )}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${msg("Property mappings")} label=${msg("Property mappings")}
?required=${true} ?required=${true}

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import { placeholderHelperText } from "@goauthentik/admin/helperText"; import { placeholderHelperText } from "@goauthentik/admin/helperText";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
@ -12,11 +13,8 @@ import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { import {
CertificateKeyPair,
CoreApi, CoreApi,
CoreGroupsListRequest, CoreGroupsListRequest,
CryptoApi,
CryptoCertificatekeypairsListRequest,
Group, Group,
LDAPSource, LDAPSource,
LDAPSourceRequest, LDAPSourceRequest,
@ -208,34 +206,10 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
label=${msg("TLS Verification Certificate")} label=${msg("TLS Verification Certificate")}
name="peerCertificate" name="peerCertificate"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.peerCertificate}
query?: string, nokey
): Promise<CertificateKeyPair[]> => { ></ak-crypto-certificate-search>
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.peerCertificate;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.", "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.",
@ -246,35 +220,9 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
label=${msg("TLS Client authentication certificate")} label=${msg("TLS Client authentication certificate")}
name="clientCertificate" name="clientCertificate"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.clientCertificate}
query?: string, ></ak-crypto-certificate-search>
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.clientCertificate;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"Client certificate keypair to authenticate against the LDAP Server's Certificate.", "Client certificate keypair to authenticate against the LDAP Server's Certificate.",

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-source-flow-search"; import "@goauthentik/admin/common/ak-flow-search/ak-source-flow-search";
import { iconHelperText, placeholderHelperText } from "@goauthentik/admin/helperText"; import { iconHelperText, placeholderHelperText } from "@goauthentik/admin/helperText";
import { UserMatchingModeToLabel } from "@goauthentik/admin/sources/oauth/utils"; import { UserMatchingModeToLabel } from "@goauthentik/admin/sources/oauth/utils";
@ -18,9 +19,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { import {
BindingTypeEnum, BindingTypeEnum,
CapabilitiesEnum, CapabilitiesEnum,
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
DigestAlgorithmEnum, DigestAlgorithmEnum,
FlowsInstancesListDesignationEnum, FlowsInstancesListDesignationEnum,
NameIdPolicyEnum, NameIdPolicyEnum,
@ -274,35 +272,9 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
</ak-radio> </ak-radio>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Signing keypair")} name="signingKp"> <ak-form-element-horizontal label=${msg("Signing keypair")} name="signingKp">
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.signingKp}
query?: string, ></ak-crypto-certificate-search>
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.signingKp;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"Keypair which is used to sign outgoing requests. Leave empty to disable signing.", "Keypair which is used to sign outgoing requests. Leave empty to disable signing.",
@ -313,34 +285,10 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
label=${msg("Verification Certificate")} label=${msg("Verification Certificate")}
name="verificationKp" name="verificationKp"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.verificationKp}
query?: string, nokey
): Promise<CertificateKeyPair[]> => { ></ak-crypto-certificate-search>
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.verificationKp;
}}
?blankable=${true}
>
</ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${msg( ${msg(
"When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.", "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.",

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search"; import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
@ -13,14 +14,7 @@ import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { import { CoreApi, FlowsInstancesListDesignationEnum, Tenant } from "@goauthentik/api";
CertificateKeyPair,
CoreApi,
CryptoApi,
CryptoCertificatekeypairsListRequest,
FlowsInstancesListDesignationEnum,
Tenant,
} from "@goauthentik/api";
@customElement("ak-tenant-form") @customElement("ak-tenant-form")
export class TenantForm extends ModelForm<Tenant, string> { export class TenantForm extends ModelForm<Tenant, string> {
@ -236,35 +230,9 @@ export class TenantForm extends ModelForm<Tenant, string> {
label=${msg("Web Certificate")} label=${msg("Web Certificate")}
name="webCertificate" name="webCertificate"
> >
<ak-search-select <ak-crypto-certificate-search
.fetchObjects=${async ( certificate=${this.instance?.webCertificate}
query?: string, ></ak-crypto-certificate-search>
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.webCertificate;
}}
?blankable=${true}
>
</ak-search-select>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${msg("Event retention")} label=${msg("Event retention")}