web/admin: allow admins to create tokens

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-08-25 21:22:24 +02:00
parent 0ccec96490
commit 78578c6c9d
8 changed files with 236 additions and 16 deletions

14
web/package-lock.json generated
View File

@ -15,7 +15,7 @@
"@babel/preset-env": "^7.15.0",
"@babel/preset-typescript": "^7.15.0",
"@fortawesome/fontawesome-free": "^5.15.4",
"@goauthentik/api": "^2021.8.1-rc2-1629834308",
"@goauthentik/api": "^2021.8.1-rc2-1629919085",
"@lingui/cli": "^3.10.2",
"@lingui/core": "^3.10.4",
"@lingui/macro": "^3.10.2",
@ -1689,9 +1689,9 @@
}
},
"node_modules/@goauthentik/api": {
"version": "2021.8.1-rc2-1629834308",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.1-rc2-1629834308.tgz",
"integrity": "sha512-utzkI9UtpDvSdprk1a7CA9DU9Yd4D/Aj1NzE4dbtpPqmKvA0xAD28wwI7Y/yzJqBRhMzUbDxBxAXPqqIqkpnmw=="
"version": "2021.8.1-rc2-1629919085",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.1-rc2-1629919085.tgz",
"integrity": "sha512-TAMtEDdQaNtv9tCpBZuJPmTJfjTQ7nvhw4CSiXux8Pewl1youBaH+zhiCXV6Pkwt0vicnz41xzkdp0MAsxp+HQ=="
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.5.0",
@ -9566,9 +9566,9 @@
"integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="
},
"@goauthentik/api": {
"version": "2021.8.1-rc2-1629834308",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.1-rc2-1629834308.tgz",
"integrity": "sha512-utzkI9UtpDvSdprk1a7CA9DU9Yd4D/Aj1NzE4dbtpPqmKvA0xAD28wwI7Y/yzJqBRhMzUbDxBxAXPqqIqkpnmw=="
"version": "2021.8.1-rc2-1629919085",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.1-rc2-1629919085.tgz",
"integrity": "sha512-TAMtEDdQaNtv9tCpBZuJPmTJfjTQ7nvhw4CSiXux8Pewl1youBaH+zhiCXV6Pkwt0vicnz41xzkdp0MAsxp+HQ=="
},
"@humanwhocodes/config-array": {
"version": "0.5.0",

View File

@ -46,7 +46,7 @@
"@babel/preset-env": "^7.15.0",
"@babel/preset-typescript": "^7.15.0",
"@fortawesome/fontawesome-free": "^5.15.4",
"@goauthentik/api": "^2021.8.1-rc2-1629834308",
"@goauthentik/api": "^2021.8.1-rc2-1629919085",
"@lingui/cli": "^3.10.2",
"@lingui/core": "^3.10.4",
"@lingui/macro": "^3.10.2",

View File

@ -275,7 +275,7 @@ export class AdminInterface extends LitElement {
<span slot="label">${t`Certificates`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/tokens">
<span slot="label">${t`Tokens`}</span>
<span slot="label">${t`Tokens & App passwords`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
`;

View File

@ -75,6 +75,10 @@ msgstr "API Hostname"
msgid "API Requests"
msgstr "API Requests"
#: src/pages/tokens/TokenForm.ts
msgid "API Token (can be used to access the API programmatically)"
msgstr "API Token (can be used to access the API programmatically)"
#: src/elements/messages/Middleware.ts
msgid "API request failed"
msgstr "API request failed"
@ -239,6 +243,10 @@ msgstr "App"
msgid "App password"
msgstr "App password"
#: src/pages/tokens/TokenForm.ts
msgid "App password (can be used to login using a flow executor)"
msgstr "App password (can be used to login using a flow executor)"
#: src/elements/user/UserConsentList.ts
#: src/pages/admin-overview/TopApplicationsTable.ts
#: src/pages/providers/ProviderListPage.ts
@ -898,7 +906,6 @@ msgstr "Cookie domain"
msgid "Copy"
msgstr "Copy"
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Copy Key"
msgstr "Copy Key"
@ -954,6 +961,8 @@ msgstr "Copy recovery link"
#: src/pages/stages/prompt/PromptStageForm.ts
#: src/pages/tenants/TenantListPage.ts
#: src/pages/tenants/TenantListPage.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/users/UserListPage.ts
@ -1038,6 +1047,7 @@ msgstr "Create Stage binding"
msgid "Create Tenant"
msgstr "Create Tenant"
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Create Token"
@ -1221,6 +1231,7 @@ msgstr "Deny the user access"
#: src/pages/applications/ApplicationForm.ts
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
msgid "Description"
msgstr "Description"
@ -1581,6 +1592,10 @@ msgstr "Execution logging"
msgid "Expires"
msgstr "Expires"
#: src/pages/tokens/TokenForm.ts
msgid "Expires on"
msgstr "Expires on"
#: src/pages/tokens/TokenListPage.ts
msgid "Expires?"
msgstr "Expires?"
@ -1590,6 +1605,10 @@ msgstr "Expires?"
msgid "Expiring"
msgstr "Expiring"
#: src/pages/tokens/TokenForm.ts
msgid "Expiring?"
msgstr "Expiring?"
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/stages/invitation/InvitationListPage.ts
msgid "Expiry"
@ -1983,6 +2002,7 @@ msgstr "Icon shown in the browser tab."
#: src/pages/flows/FlowListPage.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
@ -2018,6 +2038,10 @@ msgstr "If set, users are able to unenroll themselves using this flow. If no flo
msgid "If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given."
msgstr "If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given."
#: src/pages/tokens/TokenForm.ts
msgid "If this is selected, the token will expire. Upon expiration, the token will be rotated."
msgstr "If this is selected, the token will expire. Upon expiration, the token will be rotated."
#: src/pages/outposts/OutpostDeploymentModal.ts
msgid "If your authentik Instance is using a self-signed certificate, set this value."
msgstr "If your authentik Instance is using a self-signed certificate, set this value."
@ -2076,6 +2100,7 @@ msgstr "Integration key"
msgid "Integrations"
msgstr "Integrations"
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Intent"
@ -2331,6 +2356,7 @@ msgstr "Loading"
#: src/pages/tenants/TenantForm.ts
#: src/pages/tenants/TenantForm.ts
#: src/pages/tenants/TenantForm.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/users/UserForm.ts
#: src/pages/users/UserResetEmailForm.ts
msgid "Loading..."
@ -3982,6 +4008,7 @@ msgstr "Successfully created stage."
msgid "Successfully created tenant."
msgstr "Successfully created tenant."
#: src/pages/tokens/TokenForm.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
msgid "Successfully created token."
msgstr "Successfully created token."
@ -4137,6 +4164,7 @@ msgstr "Successfully updated stage."
msgid "Successfully updated tenant."
msgstr "Successfully updated tenant."
#: src/pages/tokens/TokenForm.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
msgid "Successfully updated token."
msgstr "Successfully updated token."
@ -4431,11 +4459,14 @@ msgid "Token(s)"
msgstr "Token(s)"
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/tokens/TokenListPage.ts
msgid "Tokens"
msgstr "Tokens"
#: src/interfaces/AdminInterface.ts
msgid "Tokens & App passwords"
msgstr "Tokens & App passwords"
#: src/pages/user-settings/UserSettingsPage.ts
msgid "Tokens and App passwords"
msgstr "Tokens and App passwords"
@ -4545,6 +4576,10 @@ msgstr "Unhealthy"
msgid "Unhealthy outposts"
msgstr "Unhealthy outposts"
#: src/pages/tokens/TokenForm.ts
msgid "Unique identifier the token is referenced by."
msgstr "Unique identifier the token is referenced by."
#: src/pages/system-tasks/SystemTaskListPage.ts
msgid "Unknown"
msgstr "Unknown"
@ -4591,6 +4626,7 @@ msgstr "Up-to-date!"
#: src/pages/stages/StageListPage.ts
#: src/pages/stages/prompt/PromptListPage.ts
#: src/pages/tenants/TenantListPage.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/UserSelfForm.ts
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
@ -4680,6 +4716,7 @@ msgstr "Update Stage binding"
msgid "Update Tenant"
msgstr "Update Tenant"
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Update Token"
msgstr "Update Token"
@ -4769,6 +4806,7 @@ msgstr "Use this tenant for each domain that doesn't have a dedicated tenant."
#: src/pages/policies/PolicyBindingForm.ts
#: src/pages/policies/PolicyTestForm.ts
#: src/pages/property-mappings/PropertyMappingTestForm.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/users/UserListPage.ts

View File

@ -75,6 +75,10 @@ msgstr ""
msgid "API Requests"
msgstr ""
#: src/pages/tokens/TokenForm.ts
msgid "API Token (can be used to access the API programmatically)"
msgstr ""
#: src/elements/messages/Middleware.ts
msgid "API request failed"
msgstr ""
@ -239,6 +243,10 @@ msgstr ""
msgid "App password"
msgstr ""
#: src/pages/tokens/TokenForm.ts
msgid "App password (can be used to login using a flow executor)"
msgstr ""
#: src/elements/user/UserConsentList.ts
#: src/pages/admin-overview/TopApplicationsTable.ts
#: src/pages/providers/ProviderListPage.ts
@ -892,7 +900,6 @@ msgstr ""
msgid "Copy"
msgstr ""
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Copy Key"
msgstr ""
@ -948,6 +955,8 @@ msgstr ""
#: src/pages/stages/prompt/PromptStageForm.ts
#: src/pages/tenants/TenantListPage.ts
#: src/pages/tenants/TenantListPage.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/users/UserListPage.ts
@ -1032,6 +1041,7 @@ msgstr ""
msgid "Create Tenant"
msgstr ""
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Create Token"
@ -1213,6 +1223,7 @@ msgstr ""
#: src/pages/applications/ApplicationForm.ts
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
msgid "Description"
msgstr ""
@ -1573,6 +1584,10 @@ msgstr ""
msgid "Expires"
msgstr ""
#: src/pages/tokens/TokenForm.ts
msgid "Expires on"
msgstr ""
#: src/pages/tokens/TokenListPage.ts
msgid "Expires?"
msgstr ""
@ -1582,6 +1597,10 @@ msgstr ""
msgid "Expiring"
msgstr ""
#: src/pages/tokens/TokenForm.ts
msgid "Expiring?"
msgstr ""
#: src/pages/crypto/CertificateKeyPairListPage.ts
#: src/pages/stages/invitation/InvitationListPage.ts
msgid "Expiry"
@ -1975,6 +1994,7 @@ msgstr ""
#: src/pages/flows/FlowListPage.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
@ -2010,6 +2030,10 @@ msgstr ""
msgid "If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given."
msgstr ""
#: src/pages/tokens/TokenForm.ts
msgid "If this is selected, the token will expire. Upon expiration, the token will be rotated."
msgstr ""
#: src/pages/outposts/OutpostDeploymentModal.ts
msgid "If your authentik Instance is using a self-signed certificate, set this value."
msgstr ""
@ -2068,6 +2092,7 @@ msgstr ""
msgid "Integrations"
msgstr ""
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Intent"
@ -2323,6 +2348,7 @@ msgstr ""
#: src/pages/tenants/TenantForm.ts
#: src/pages/tenants/TenantForm.ts
#: src/pages/tenants/TenantForm.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/users/UserForm.ts
#: src/pages/users/UserResetEmailForm.ts
msgid "Loading..."
@ -3974,6 +4000,7 @@ msgstr ""
msgid "Successfully created tenant."
msgstr ""
#: src/pages/tokens/TokenForm.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
msgid "Successfully created token."
msgstr ""
@ -4129,6 +4156,7 @@ msgstr ""
msgid "Successfully updated tenant."
msgstr ""
#: src/pages/tokens/TokenForm.ts
#: src/pages/user-settings/tokens/UserTokenForm.ts
msgid "Successfully updated token."
msgstr ""
@ -4416,11 +4444,14 @@ msgid "Token(s)"
msgstr ""
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/tokens/TokenListPage.ts
msgid "Tokens"
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Tokens & App passwords"
msgstr ""
#: src/pages/user-settings/UserSettingsPage.ts
msgid "Tokens and App passwords"
msgstr ""
@ -4530,6 +4561,10 @@ msgstr ""
msgid "Unhealthy outposts"
msgstr ""
#: src/pages/tokens/TokenForm.ts
msgid "Unique identifier the token is referenced by."
msgstr ""
#: src/pages/system-tasks/SystemTaskListPage.ts
msgid "Unknown"
msgstr ""
@ -4576,6 +4611,7 @@ msgstr ""
#: src/pages/stages/StageListPage.ts
#: src/pages/stages/prompt/PromptListPage.ts
#: src/pages/tenants/TenantListPage.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/UserSelfForm.ts
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
@ -4665,6 +4701,7 @@ msgstr ""
msgid "Update Tenant"
msgstr ""
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
msgid "Update Token"
msgstr ""
@ -4754,6 +4791,7 @@ msgstr ""
#: src/pages/policies/PolicyBindingForm.ts
#: src/pages/policies/PolicyTestForm.ts
#: src/pages/property-mappings/PropertyMappingTestForm.ts
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
#: src/pages/user-settings/tokens/UserTokenList.ts
#: src/pages/users/UserListPage.ts

View File

@ -75,7 +75,7 @@ export class TenantListPage extends TablePage<Tenant> {
return [
html`${item.domain}`,
html`${item._default ? t`Yes` : t`No`}`,
html` <ak-forms-modal>
html`<ak-forms-modal>
<span slot="submit"> ${t`Update`} </span>
<span slot="header"> ${t`Update Tenant`} </span>
<ak-tenant-form slot="form" .instancePk=${item.tenantUuid}> </ak-tenant-form>

View File

@ -0,0 +1,120 @@
import { CoreApi, IntentEnum, Token } from "@goauthentik/api";
import { t } from "@lingui/macro";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/forms/FormGroup";
import { first } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
import { until } from "lit-html/directives/until";
@customElement("ak-token-form")
export class TokenForm extends ModelForm<Token, string> {
loadInstance(pk: string): Promise<Token> {
return new CoreApi(DEFAULT_CONFIG).coreTokensRetrieve({
identifier: pk,
});
}
getSuccessMessage(): string {
if (this.instance) {
return t`Successfully updated token.`;
} else {
return t`Successfully created token.`;
}
}
send = (data: Token): Promise<Token> => {
if (this.instance?.identifier) {
return new CoreApi(DEFAULT_CONFIG).coreTokensUpdate({
identifier: this.instance.identifier,
tokenRequest: data,
});
} else {
return new CoreApi(DEFAULT_CONFIG).coreTokensCreate({
tokenRequest: data,
});
}
};
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal label=${t`Identifier`} name="identifier" ?required=${true}>
<input
type="text"
value="${first(this.instance?.identifier, "")}"
class="pf-c-form-control"
required
/>
<p class="pf-c-form__helper-text">
${t`Unique identifier the token is referenced by.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`User`} ?required=${true} name="user">
<select class="pf-c-form-control">
${until(
new CoreApi(DEFAULT_CONFIG)
.coreUsersList({
ordering: "username",
})
.then((users) => {
return users.results.map((user) => {
return html`<option
value=${user.pk}
?selected=${this.instance?.user === user}
>
${user.username}
</option>`;
});
}),
html`<option>${t`Loading...`}</option>`,
)}
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Intent`} ?required=${true} name="intent">
<select class="pf-c-form-control">
<option
value=${IntentEnum.Api}
?selected=${this.instance?.intent === IntentEnum.Api}
>
${t`API Token (can be used to access the API programmatically)`}
</option>
<option
value=${IntentEnum.AppPassword}
?selected=${this.instance?.intent === IntentEnum.AppPassword}
>
${t`App password (can be used to login using a flow executor)`}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Description`} name="description">
<input
type="text"
value="${first(this.instance?.description, "")}"
class="pf-c-form-control"
/>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="expiring">
<div class="pf-c-check">
<input
type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.expiring, true)}
/>
<label class="pf-c-check__label"> ${t`Expiring?`} </label>
</div>
<p class="pf-c-form__helper-text">
${t`If this is selected, the token will expire. Upon expiration, the token will be rotated.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Expires on`} name="expires">
<input
type="datetime-local"
.valueAsNumber="${first(this.instance?.expires, new Date()).getTime()}"
class="pf-c-form-control"
/>
</ak-form-element-horizontal>
</form>`;
}
}

View File

@ -6,6 +6,8 @@ import { TablePage } from "../../elements/table/TablePage";
import "../../elements/buttons/Dropdown";
import "../../elements/buttons/TokenCopyButton";
import "../../elements/forms/DeleteBulkForm";
import "../../elements/forms/ModalForm";
import "./TokenForm";
import { TableColumn } from "../../elements/table/Table";
import { PAGE_SIZE } from "../../constants";
import { CoreApi, IntentEnum, Token } from "@goauthentik/api";
@ -86,16 +88,38 @@ export class TokenListPage extends TablePage<Token> {
</ak-forms-delete-bulk>`;
}
renderToolbar(): TemplateResult {
return html`
<ak-forms-modal>
<span slot="submit"> ${t`Create`} </span>
<span slot="header"> ${t`Create Token`} </span>
<ak-token-form slot="form"> </ak-token-form>
<button slot="trigger" class="pf-c-button pf-m-primary">${t`Create`}</button>
</ak-forms-modal>
${super.renderToolbar()}
`;
}
row(item: Token): TemplateResult[] {
return [
html`${item.identifier}`,
html`${item.user?.username}`,
html`${item.userObj?.username}`,
html`${item.expiring ? t`Yes` : t`No`}`,
html`${item.expiring ? item.expires?.toLocaleString() : "-"}`,
html`${IntentToLabel(item.intent || IntentEnum.Api)}`,
html`
${item.managed
? html``
: html`<ak-forms-modal>
<span slot="submit"> ${t`Update`} </span>
<span slot="header"> ${t`Update Token`} </span>
<ak-token-form slot="form" .instancePk=${item.identifier}></ak-token-form>
<button slot="trigger" class="pf-c-button pf-m-plain">
<i class="fas fa-edit"></i>
</button>
</ak-forms-modal>`}
<ak-token-copy-button identifier="${item.identifier}">
${t`Copy Key`}
<i class="fas fa-copy"></i>
</ak-token-copy-button>
`,
];