Merge branch 'main' into web/sidebar-with-live-content-2

* main: (24 commits)
  internal: remove special route for /outpost.goauthentik.io (#7539)
  providers/proxy: Fix duplicate cookies when using file system store. (#7541)
  web: bump API Client version (#7543)
  sources/ldap: add check command to verify ldap connectivity (#7263)
  internal: remove deprecated metrics (#7540)
  core: compile backend translations (#7538)
  web: bump prettier from 3.0.3 to 3.1.0 in /web (#7528)
  web: bump @trivago/prettier-plugin-sort-imports from 4.2.1 to 4.3.0 in /web (#7531)
  web: bump rollup from 4.3.0 to 4.4.0 in /web (#7529)
  core: bump celery from 5.3.4 to 5.3.5 (#7536)
  web: bump @formatjs/intl-listformat from 7.5.1 to 7.5.2 in /web (#7530)
  web: bump prettier from 3.0.3 to 3.1.0 in /tests/wdio (#7532)
  web: bump @trivago/prettier-plugin-sort-imports from 4.2.1 to 4.3.0 in /tests/wdio (#7533)
  website: bump prettier from 3.0.3 to 3.1.0 in /website (#7534)
  website: bump prism-react-renderer from 2.1.0 to 2.2.0 in /website (#7535)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_TW (#7537)
  root: Restructure broker / cache / channel / result configuration (#7097)
  core: bump twilio from 8.10.0 to 8.10.1 (#7474)
  web: bump axios from 1.5.0 to 1.6.1 in /web (#7518)
  web: bump wdio-wait-for from 3.0.7 to 3.0.8 in /tests/wdio (#7514)
  ...
This commit is contained in:
Ken Sternberg
2023-11-14 10:25:04 -08:00
63 changed files with 3032 additions and 1726 deletions

View File

@ -44,11 +44,11 @@ export class LDAPSyncStatusChart extends AKChart<SyncStatus[]> {
await Promise.all(
sources.results.map(async (element) => {
try {
const health = await api.sourcesLdapSyncStatusList({
const health = await api.sourcesLdapSyncStatusRetrieve({
slug: element.slug,
});
health.forEach((task) => {
health.tasks.forEach((task) => {
if (task.status !== TaskStatusEnum.Successful) {
metrics.failed += 1;
}
@ -60,7 +60,7 @@ export class LDAPSyncStatusChart extends AKChart<SyncStatus[]> {
metrics.healthy += 1;
}
});
if (health.length < 1) {
if (health.tasks.length < 1) {
metrics.unsynced += 1;
}
} catch {

View File

@ -0,0 +1,50 @@
import { AKElement } from "@goauthentik/app/elements/Base";
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 PFList from "@patternfly/patternfly/components/List/list.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
@customElement("ak-source-ldap-connectivity")
export class LDAPSourceConnectivity extends AKElement {
@property()
connectivity?: {
[key: string]: {
[key: string]: string;
};
};
static get styles(): CSSResult[] {
return [PFBase, PFList];
}
render(): TemplateResult {
if (!this.connectivity) {
return html``;
}
return html`<ul class="pf-c-list">
${Object.keys(this.connectivity).map((serverKey) => {
let serverLabel = html`${serverKey}`;
if (serverKey === "__all__") {
serverLabel = html`<b>${msg("Global status")}</b>`;
}
const server = this.connectivity![serverKey];
const content = html`${serverLabel}: ${server.status}`;
let tooltip = html`${content}`;
if (server.status === "ok") {
tooltip = html`<pf-tooltip position="top">
<ul slot="content" class="pf-c-list">
<li>${msg("Vendor")}: ${server.vendor}</li>
<li>${msg("Version")}: ${server.version}</li>
</ul>
${content}
</pf-tooltip>`;
}
return html`<li>${tooltip}</li>`;
})}
</ul>`;
}
}

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/sources/ldap/LDAPSourceConnectivity";
import "@goauthentik/admin/sources/ldap/LDAPSourceForm";
import "@goauthentik/app/elements/rbac/ObjectPermissionsPage";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
@ -25,9 +26,9 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import {
LDAPSource,
LDAPSyncStatus,
RbacPermissionsAssignedByUsersListModelEnum,
SourcesApi,
Task,
TaskStatusEnum,
} from "@goauthentik/api";
@ -48,7 +49,7 @@ export class LDAPSourceViewPage extends AKElement {
source!: LDAPSource;
@state()
syncState: Task[] = [];
syncState?: LDAPSyncStatus;
static get styles(): CSSResult[] {
return [PFBase, PFPage, PFButton, PFGrid, PFContent, PFCard, PFDescriptionList, PFList];
@ -62,6 +63,51 @@ export class LDAPSourceViewPage extends AKElement {
});
}
renderSyncStatus(): TemplateResult {
if (!this.syncState) {
return html`${msg("No sync status.")}`;
}
if (this.syncState.isRunning) {
return html`${msg("Sync currently running.")}`;
}
if (this.syncState.tasks.length < 1) {
return html`${msg("Not synced yet.")}`;
}
return html`
<ul class="pf-c-list">
${this.syncState.tasks.map((task) => {
let header = "";
if (task.status === TaskStatusEnum.Warning) {
header = msg("Task finished with warnings");
} else if (task.status === TaskStatusEnum.Error) {
header = msg("Task finished with errors");
} else {
header = msg(str`Last sync: ${task.taskFinishTimestamp.toLocaleString()}`);
}
return html`<li>
<p>${task.taskName}</p>
<ul class="pf-c-list">
<li>${header}</li>
${task.messages.map((m) => {
return html`<li>${m}</li>`;
})}
</ul>
</li> `;
})}
</ul>
`;
}
load(): void {
new SourcesApi(DEFAULT_CONFIG)
.sourcesLdapSyncStatusRetrieve({
slug: this.source.slug,
})
.then((state) => {
this.syncState = state;
});
}
render(): TemplateResult {
if (!this.source) {
return html``;
@ -72,13 +118,7 @@ export class LDAPSourceViewPage extends AKElement {
data-tab-title="${msg("Overview")}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
@activate=${() => {
new SourcesApi(DEFAULT_CONFIG)
.sourcesLdapSyncStatusList({
slug: this.source.slug,
})
.then((state) => {
this.syncState = state;
});
this.load();
}}
>
<div class="pf-l-grid pf-m-gutter">
@ -137,42 +177,25 @@ export class LDAPSourceViewPage extends AKElement {
</ak-forms-modal>
</div>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
<div class="pf-c-card pf-l-grid__item pf-m-2-col">
<div class="pf-c-card__title">
<p>${msg("Connectivity")}</p>
</div>
<div class="pf-c-card__body">
<ak-source-ldap-connectivity
.connectivity=${this.source.connectivity}
></ak-source-ldap-connectivity>
</div>
</div>
<div class="pf-c-card pf-l-grid__item pf-m-10-col">
<div class="pf-c-card__title">
<p>${msg("Sync status")}</p>
</div>
<div class="pf-c-card__body">
${this.syncState.length < 1
? html`<p>${msg("Not synced yet.")}</p>`
: html`
<ul class="pf-c-list">
${this.syncState.map((task) => {
let header = "";
if (task.status === TaskStatusEnum.Warning) {
header = msg("Task finished with warnings");
} else if (task.status === TaskStatusEnum.Error) {
header = msg("Task finished with errors");
} else {
header = msg(
str`Last sync: ${task.taskFinishTimestamp.toLocaleString()}`,
);
}
return html`<li>
<p>${task.taskName}</p>
<ul class="pf-c-list">
<li>${header}</li>
${task.messages.map((m) => {
return html`<li>${m}</li>`;
})}
</ul>
</li> `;
})}
</ul>
`}
</div>
<div class="pf-c-card__body">${this.renderSyncStatus()}</div>
<div class="pf-c-card__footer">
<ak-action-button
class="pf-m-secondary"
?disabled=${this.syncState?.isRunning}
.apiRequest=${() => {
return new SourcesApi(DEFAULT_CONFIG)
.sourcesLdapPartialUpdate({
@ -186,6 +209,7 @@ export class LDAPSourceViewPage extends AKElement {
composed: true,
}),
);
this.load();
});
}}
>

View File

@ -39,9 +39,8 @@ const container = (testItem: TemplateResult) =>
export const NumberInput = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const displayChange = (ev: any) => {
document.getElementById(
"number-message-pad",
)!.innerText = `Value selected: ${JSON.stringify(ev.target.value, null, 2)}`;
document.getElementById("number-message-pad")!.innerText =
`Value selected: ${JSON.stringify(ev.target.value, null, 2)}`;
};
return container(

View File

@ -46,9 +46,8 @@ export const SwitchInput = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const displayChange = (ev: any) => {
document.getElementById(
"switch-message-pad",
)!.innerText = `Value selected: ${JSON.stringify(ev.target.checked, null, 2)}`;
document.getElementById("switch-message-pad")!.innerText =
`Value selected: ${JSON.stringify(ev.target.checked, null, 2)}`;
};
return container(

View File

@ -39,9 +39,8 @@ const container = (testItem: TemplateResult) =>
export const TextareaInput = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const displayChange = (ev: any) => {
document.getElementById(
"textarea-message-pad",
)!.innerText = `Value selected: ${JSON.stringify(ev.target.value, null, 2)}`;
document.getElementById("textarea-message-pad")!.innerText =
`Value selected: ${JSON.stringify(ev.target.value, null, 2)}`;
};
return container(

View File

@ -54,9 +54,8 @@ const testOptions = [
export const ToggleGroup = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const displayChange = (ev: any) => {
document.getElementById(
"toggle-message-pad",
)!.innerText = `Value selected: ${ev.detail.value}`;
document.getElementById("toggle-message-pad")!.innerText =
`Value selected: ${ev.detail.value}`;
};
return container(

View File

@ -5,6 +5,7 @@ import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { Task, TaskStatus } from "@lit-labs/task";
import { css, html } from "lit";
import { property } from "lit/decorators.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFSpinner from "@patternfly/patternfly/components/Spinner/spinner.css";
@ -57,6 +58,9 @@ export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
actionTask: Task;
@property({ type: Boolean })
disabled = false;
constructor() {
super();
this.onSuccess = this.onSuccess.bind(this);
@ -121,6 +125,7 @@ export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
part="spinner-button"
class="pf-c-button pf-m-progress ${this.buttonClasses}"
@click=${this.onClick}
?disabled=${this.disabled}
>
${this.actionTask.render({ pending: () => this.spinner })}
<slot></slot>