Files
authentik/web/src/admin/AdminInterface.ts
T
Jens L 41af486006 enterprise: initial enterprise (#5721)
* initial

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add user type

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add external users

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add ui, add more logic, add public JWT validation key

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* revert to not use install_id as session jwt signing key

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix more

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* switch to PKI

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add more licensing stuff

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add install ID to form

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix bugs

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start adding tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fixes

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use x5c correctly

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* license checks

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use production CA

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* more

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* more UI stuff

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* rename to summary

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update locale, improve ui

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add direct button

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update link

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format and such

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove old attributes from ldap

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove is_enterprise_licensed

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix admin interface styling issue

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* Update authentik/core/models.py

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Jens L. <jens@beryju.org>

* fix default case

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens L. <jens@beryju.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2023-07-17 17:57:08 +02:00

343 lines
14 KiB
TypeScript

import { ROUTES } from "@goauthentik/admin/Routes";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import {
EVENT_API_DRAWER_TOGGLE,
EVENT_NOTIFICATION_DRAWER_TOGGLE,
EVENT_SIDEBAR_TOGGLE,
VERSION,
} from "@goauthentik/common/constants";
import { configureSentry } from "@goauthentik/common/sentry";
import { me } from "@goauthentik/common/users";
import { WebsocketClient } from "@goauthentik/common/ws";
import { Interface } from "@goauthentik/elements/Base";
import "@goauthentik/elements/ak-locale-context";
import "@goauthentik/elements/enterprise/EnterpriseStatusBanner";
import "@goauthentik/elements/messages/MessageContainer";
import "@goauthentik/elements/messages/MessageContainer";
import "@goauthentik/elements/notifications/APIDrawer";
import "@goauthentik/elements/notifications/NotificationDrawer";
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route";
import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
import "@goauthentik/elements/router/RouterOutlet";
import "@goauthentik/elements/sidebar/Sidebar";
import "@goauthentik/elements/sidebar/SidebarItem";
import { msg, str } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import {
AdminApi,
CapabilitiesEnum,
CoreApi,
SessionUser,
UiThemeEnum,
Version,
} from "@goauthentik/api";
@customElement("ak-interface-admin")
export class AdminInterface extends Interface {
@property({ type: Boolean })
sidebarOpen = true;
@property({ type: Boolean })
notificationDrawerOpen = getURLParam("notificationDrawerOpen", false);
@property({ type: Boolean })
apiDrawerOpen = getURLParam("apiDrawerOpen", false);
ws: WebsocketClient;
@state()
version?: Version;
@state()
user?: SessionUser;
static get styles(): CSSResult[] {
return [
PFBase,
PFPage,
PFButton,
PFDrawer,
css`
.pf-c-page__main,
.pf-c-drawer__content,
.pf-c-page__drawer {
z-index: auto !important;
background-color: transparent;
}
.display-none {
display: none;
}
:host {
display: flex;
flex-direction: column;
height: 100%;
}
ak-locale-context {
display: flex;
flex-grow: 1;
}
.pf-c-page {
flex-grow: 1;
background-color: var(--pf-c-page--BackgroundColor) !important;
}
/* Global page background colour */
:host([theme="dark"]) .pf-c-page {
--pf-c-page--BackgroundColor: var(--ak-dark-background);
}
`,
];
}
constructor() {
super();
this.ws = new WebsocketClient();
this.sidebarOpen = window.innerWidth >= 1280;
window.addEventListener("resize", () => {
this.sidebarOpen = window.innerWidth >= 1280;
});
window.addEventListener(EVENT_SIDEBAR_TOGGLE, () => {
this.sidebarOpen = !this.sidebarOpen;
});
window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => {
this.notificationDrawerOpen = !this.notificationDrawerOpen;
updateURLParams({
notificationDrawerOpen: this.notificationDrawerOpen,
});
});
window.addEventListener(EVENT_API_DRAWER_TOGGLE, () => {
this.apiDrawerOpen = !this.apiDrawerOpen;
updateURLParams({
apiDrawerOpen: this.apiDrawerOpen,
});
});
}
async firstUpdated(): Promise<void> {
configureSentry(true);
this.version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
this.user = await me();
if (!this.user.user.isSuperuser && this.user.user.pk > 0) {
window.location.assign("/if/user");
}
}
render(): TemplateResult {
return html` <ak-locale-context
><ak-enterprise-status interface="admin"></ak-enterprise-status>
<div class="pf-c-page">
<ak-sidebar
class="pf-c-page__sidebar ${this.sidebarOpen
? "pf-m-expanded"
: "pf-m-collapsed"} ${this.activeTheme === UiThemeEnum.Light
? "pf-m-light"
: ""}"
>
${this.renderSidebarItems()}
</ak-sidebar>
<div class="pf-c-page__drawer">
<div
class="pf-c-drawer ${this.notificationDrawerOpen || this.apiDrawerOpen
? "pf-m-expanded"
: "pf-m-collapsed"}"
>
<div class="pf-c-drawer__main">
<div class="pf-c-drawer__content">
<div class="pf-c-drawer__body">
<main class="pf-c-page__main">
<ak-router-outlet
role="main"
class="pf-c-page__main"
tabindex="-1"
id="main-content"
defaultUrl="/administration/overview"
.routes=${ROUTES}
>
</ak-router-outlet>
</main>
</div>
</div>
<ak-notification-drawer
class="pf-c-drawer__panel pf-m-width-33 ${this
.notificationDrawerOpen
? ""
: "display-none"}"
?hidden=${!this.notificationDrawerOpen}
></ak-notification-drawer>
<ak-api-drawer
class="pf-c-drawer__panel pf-m-width-33 ${this.apiDrawerOpen
? ""
: "display-none"}"
?hidden=${!this.apiDrawerOpen}
></ak-api-drawer>
</div>
</div>
</div></div
></ak-locale-context>`;
}
renderSidebarItems(): TemplateResult {
return html`
${this.version && this.version.versionCurrent !== VERSION
? html`
<ak-sidebar-item ?highlight=${true}>
<span slot="label"
>${msg("A newer version of the frontend is available.")}</span
>
</ak-sidebar-item>
`
: html``}
${this.user?.original
? html`<ak-sidebar-item
?highlight=${true}
@click=${() => {
new CoreApi(DEFAULT_CONFIG).coreUsersImpersonateEndRetrieve().then(() => {
window.location.reload();
});
}}
>
<span slot="label"
>${msg(
str`You're currently impersonating ${this.user.user.username}. Click to stop.`,
)}</span
>
</ak-sidebar-item>`
: html``}
<ak-sidebar-item path="/if/user/" ?isAbsoluteLink=${true} ?highlight=${true}>
<span slot="label">${msg("User interface")}</span>
</ak-sidebar-item>
<ak-sidebar-item .expanded=${true}>
<span slot="label">${msg("Dashboards")}</span>
<ak-sidebar-item path="/administration/overview">
<span slot="label">${msg("Overview")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/administration/dashboard/users">
<span slot="label">${msg("Users")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/administration/system-tasks">
<span slot="label">${msg("System Tasks")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("Applications")}</span>
<ak-sidebar-item
path="/core/providers"
.activeWhen=${[`^/core/providers/(?<id>${ID_REGEX})$`]}
>
<span slot="label">${msg("Providers")}</span>
</ak-sidebar-item>
<ak-sidebar-item
path="/core/applications"
.activeWhen=${[`^/core/applications/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${msg("Applications")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/outpost/outposts">
<span slot="label">${msg("Outposts")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("Events")}</span>
<ak-sidebar-item
path="/events/log"
.activeWhen=${[`^/events/log/(?<id>${UUID_REGEX})$`]}
>
<span slot="label">${msg("Logs")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/events/rules">
<span slot="label">${msg("Notification Rules")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/events/transports">
<span slot="label">${msg("Notification Transports")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("Customisation")}</span>
<ak-sidebar-item path="/policy/policies">
<span slot="label">${msg("Policies")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/property-mappings">
<span slot="label">${msg("Property Mappings")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/blueprints/instances">
<span slot="label">${msg("Blueprints")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/policy/reputation">
<span slot="label">${msg("Reputation scores")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("Flows & Stages")}</span>
<ak-sidebar-item
path="/flow/flows"
.activeWhen=${[`^/flow/flows/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${msg("Flows")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/flow/stages">
<span slot="label">${msg("Stages")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/flow/stages/prompts">
<span slot="label">${msg("Prompts")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("Directory")}</span>
<ak-sidebar-item
path="/identity/users"
.activeWhen=${[`^/identity/users/(?<id>${ID_REGEX})$`]}
>
<span slot="label">${msg("Users")}</span>
</ak-sidebar-item>
<ak-sidebar-item
path="/identity/groups"
.activeWhen=${[`^/identity/groups/(?<id>${UUID_REGEX})$`]}
>
<span slot="label">${msg("Groups")}</span>
</ak-sidebar-item>
<ak-sidebar-item
path="/core/sources"
.activeWhen=${[`^/core/sources/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${msg("Federation & Social login")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/tokens">
<span slot="label">${msg("Tokens & App passwords")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/flow/stages/invitations">
<span slot="label">${msg("Invitations")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${msg("System")}</span>
<ak-sidebar-item path="/core/tenants">
<span slot="label">${msg("Tenants")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/crypto/certificates">
<span slot="label">${msg("Certificates")}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/outpost/integrations">
<span slot="label">${msg("Outpost Integrations")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
${this.config?.capabilities.includes(CapabilitiesEnum.IsEnterprise)
? html`
<ak-sidebar-item>
<span slot="label">${msg("Enterprise")}</span>
<ak-sidebar-item path="/enterprise/licenses">
<span slot="label">${msg("Licenses")}</span>
</ak-sidebar-item>
</ak-sidebar-item>
`
: html``}
`;
}
}