From f6e0f0282d91b96d1e75fc7258f958aa3b3e9660 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 19 Sep 2021 16:08:30 +0200 Subject: [PATCH] core: fix tokens not being viewable but superusers Signed-off-by: Jens Langhammer --- authentik/api/authorization.py | 9 ++++++ authentik/api/decorators.py | 5 ++++ authentik/core/api/authenticated_sessions.py | 4 +-- authentik/core/api/tokens.py | 4 +-- web/src/elements/buttons/TokenCopyButton.ts | 6 +++- web/src/elements/events/ObjectChangelog.ts | 2 +- web/src/elements/events/UserEvents.ts | 2 +- web/src/elements/user/SessionList.ts | 6 ++++ web/src/locales/en.po | 28 +++++++++++++++++-- web/src/locales/pseudo-LOCALE.po | 28 +++++++++++++++++-- .../pages/applications/ApplicationListPage.ts | 2 +- web/src/pages/events/EventListPage.ts | 4 +-- web/src/pages/groups/GroupListPage.ts | 2 +- web/src/pages/groups/MemberSelectModal.ts | 2 +- .../oauth2/OAuth2ProviderViewPage.ts | 12 ++++---- .../stages/invitation/InvitationListPage.ts | 2 +- web/src/pages/tokens/TokenListPage.ts | 2 +- web/src/pages/users/UserListPage.ts | 2 +- .../UserSettingsAuthenticatorWebAuthn.ts | 2 +- .../user-settings/tokens/UserTokenList.ts | 2 +- 20 files changed, 97 insertions(+), 29 deletions(-) diff --git a/authentik/api/authorization.py b/authentik/api/authorization.py index 765f94637..059eeeaf6 100644 --- a/authentik/api/authorization.py +++ b/authentik/api/authorization.py @@ -33,3 +33,12 @@ class OwnerPermissions(BasePermission): if owner != request.user: return False return True + + +class OwnerSuperuserPermissions(OwnerPermissions): + """Similar to OwnerPermissions, except always allow access for superusers""" + + def has_object_permission(self, request: Request, view, obj: Model) -> bool: + if request.user.is_superuser: + return True + return super().has_object_permission(request, view, obj) diff --git a/authentik/api/decorators.py b/authentik/api/decorators.py index 2c253b234..a79cebc92 100644 --- a/authentik/api/decorators.py +++ b/authentik/api/decorators.py @@ -5,6 +5,9 @@ from typing import Callable, Optional from rest_framework.request import Request from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet +from structlog.stdlib import get_logger + +LOGGER = get_logger() def permission_required(perm: Optional[str] = None, other_perms: Optional[list[str]] = None): @@ -18,10 +21,12 @@ def permission_required(perm: Optional[str] = None, other_perms: Optional[list[s if perm: obj = self.get_object() if not request.user.has_perm(perm, obj): + LOGGER.debug("denying access for object", user=request.user, perm=perm, obj=obj) return self.permission_denied(request) if other_perms: for other_perm in other_perms: if not request.user.has_perm(other_perm): + LOGGER.debug("denying access for other", user=request.user, perm=perm) return self.permission_denied(request) return func(self, request, *args, **kwargs) diff --git a/authentik/core/api/authenticated_sessions.py b/authentik/core/api/authenticated_sessions.py index 7ff71b6ce..ba4546e7e 100644 --- a/authentik/core/api/authenticated_sessions.py +++ b/authentik/core/api/authenticated_sessions.py @@ -11,7 +11,7 @@ from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import GenericViewSet from ua_parser import user_agent_parser -from authentik.api.authorization import OwnerPermissions +from authentik.api.authorization import OwnerSuperuserPermissions from authentik.core.api.used_by import UsedByMixin from authentik.core.models import AuthenticatedSession from authentik.events.geo import GEOIP_READER, GeoIPDict @@ -103,7 +103,7 @@ class AuthenticatedSessionViewSet( search_fields = ["user__username", "last_ip", "last_user_agent"] filterset_fields = ["user__username", "last_ip", "last_user_agent"] ordering = ["user__username"] - permission_classes = [OwnerPermissions] + permission_classes = [OwnerSuperuserPermissions] filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter] def get_queryset(self): diff --git a/authentik/core/api/tokens.py b/authentik/core/api/tokens.py index 3a9438294..24c5b76e7 100644 --- a/authentik/core/api/tokens.py +++ b/authentik/core/api/tokens.py @@ -14,7 +14,7 @@ from rest_framework.response import Response from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet -from authentik.api.authorization import OwnerPermissions +from authentik.api.authorization import OwnerSuperuserPermissions from authentik.api.decorators import permission_required from authentik.core.api.used_by import UsedByMixin from authentik.core.api.users import UserSerializer @@ -84,7 +84,7 @@ class TokenViewSet(UsedByMixin, ModelViewSet): "expiring", ] ordering = ["identifier", "expires"] - permission_classes = [OwnerPermissions] + permission_classes = [OwnerSuperuserPermissions] filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter] def get_queryset(self): diff --git a/web/src/elements/buttons/TokenCopyButton.ts b/web/src/elements/buttons/TokenCopyButton.ts index 25b87612d..348caa748 100644 --- a/web/src/elements/buttons/TokenCopyButton.ts +++ b/web/src/elements/buttons/TokenCopyButton.ts @@ -1,6 +1,6 @@ import { customElement, property } from "lit-element"; import { CoreApi } from "@goauthentik/api"; -import { SECONDARY_CLASS, SUCCESS_CLASS } from "../../constants"; +import { ERROR_CLASS, SECONDARY_CLASS, SUCCESS_CLASS } from "../../constants"; import { DEFAULT_CONFIG } from "../../api/Config"; import { ActionButton } from "./ActionButton"; @@ -33,8 +33,12 @@ export class TokenCopyButton extends ActionButton { }); }) .catch((err: Response | undefined) => { + this.buttonClass = ERROR_CLASS; return err?.json().then((errResp) => { throw new Error(errResp["detail"]); + setTimeout(() => { + this.buttonClass = SECONDARY_CLASS; + }, 1500); }); }); }; diff --git a/web/src/elements/events/ObjectChangelog.ts b/web/src/elements/events/ObjectChangelog.ts index 11320cbd6..a05c98ba9 100644 --- a/web/src/elements/events/ObjectChangelog.ts +++ b/web/src/elements/events/ObjectChangelog.ts @@ -58,7 +58,7 @@ export class ObjectChangelog extends Table { ? html` ${t`On behalf of ${item.user.on_behalf_of.username}`} ` : html``}`, html`${item.created?.toLocaleString()}`, - html`${item.clientIp || "-"}`, + html`${item.clientIp || t`-`}`, ]; } diff --git a/web/src/elements/events/UserEvents.ts b/web/src/elements/events/UserEvents.ts index 17c0796f2..a10c6fb4b 100644 --- a/web/src/elements/events/UserEvents.ts +++ b/web/src/elements/events/UserEvents.ts @@ -49,7 +49,7 @@ export class ObjectChangelog extends Table { ? html` ${t`On behalf of ${item.user.on_behalf_of.username}`} ` : html``}`, html`${item.created?.toLocaleString()}`, - html`${item.clientIp || "-"}`, + html`${item.clientIp || t`-`}`, ]; } diff --git a/web/src/elements/user/SessionList.ts b/web/src/elements/user/SessionList.ts index c37595efb..3dbdbdaec 100644 --- a/web/src/elements/user/SessionList.ts +++ b/web/src/elements/user/SessionList.ts @@ -39,6 +39,12 @@ export class AuthenticatedSessionList extends Table { return html` { + return [ + { key: t`Last IP`, value: item.lastIp }, + { key: t`Expiry`, value: item.expires?.toLocaleString() || t`-` }, + ]; + }} .usedBy=${(item: AuthenticatedSession) => { return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsUsedByList({ uuid: item.uuid || "", diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 2d03005a1..777139104 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -21,7 +21,26 @@ msgstr "" msgid "(Format: hours=-1;minutes=-2;seconds=-3)." msgstr "(Format: hours=-1;minutes=-2;seconds=-3)." +#: src/elements/events/ObjectChangelog.ts +#: src/elements/events/UserEvents.ts +#: src/elements/user/SessionList.ts +#: src/pages/applications/ApplicationListPage.ts +#: src/pages/events/EventListPage.ts +#: src/pages/events/EventListPage.ts +#: src/pages/groups/GroupListPage.ts +#: src/pages/groups/MemberSelectModal.ts #: src/pages/policies/BoundPoliciesList.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/stages/invitation/InvitationListPage.ts +#: src/pages/tokens/TokenListPage.ts +#: src/pages/users/UserListPage.ts +#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts +#: src/user/user-settings/tokens/UserTokenList.ts msgid "-" msgstr "-" @@ -267,6 +286,7 @@ msgid "Application" msgstr "Application" #: src/pages/applications/ApplicationListPage.ts +#: src/user/LibraryApplication.ts msgid "Application Icon" msgstr "Application Icon" @@ -1645,6 +1665,7 @@ msgstr "Expiring" msgid "Expiring?" msgstr "Expiring?" +#: src/elements/user/SessionList.ts #: src/pages/crypto/CertificateKeyPairListPage.ts #: src/pages/stages/invitation/InvitationListPage.ts msgid "Expiry" @@ -2262,6 +2283,7 @@ msgstr "Label" msgid "Label shown next to/above the prompt." msgstr "Label shown next to/above the prompt." +#: src/elements/user/SessionList.ts #: src/elements/user/SessionList.ts msgid "Last IP" msgstr "Last IP" @@ -3464,9 +3486,9 @@ msgstr "Resources" msgid "Result" msgstr "Result" -#: src/pages/system-tasks/SystemTaskListPage.ts -msgid "Retry Task" -msgstr "Retry Task" +#: +#~ msgid "Retry Task" +#~ msgstr "Retry Task" #: src/flows/stages/authenticator_validate/AuthenticatorValidateStageWebAuthn.ts msgid "Retry authentication" diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index a205f30bd..6499e2603 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -21,7 +21,26 @@ msgstr "" msgid "(Format: hours=-1;minutes=-2;seconds=-3)." msgstr "" +#: src/elements/events/ObjectChangelog.ts +#: src/elements/events/UserEvents.ts +#: src/elements/user/SessionList.ts +#: src/pages/applications/ApplicationListPage.ts +#: src/pages/events/EventListPage.ts +#: src/pages/events/EventListPage.ts +#: src/pages/groups/GroupListPage.ts +#: src/pages/groups/MemberSelectModal.ts #: src/pages/policies/BoundPoliciesList.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +#: src/pages/stages/invitation/InvitationListPage.ts +#: src/pages/tokens/TokenListPage.ts +#: src/pages/users/UserListPage.ts +#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts +#: src/user/user-settings/tokens/UserTokenList.ts msgid "-" msgstr "" @@ -267,6 +286,7 @@ msgid "Application" msgstr "" #: src/pages/applications/ApplicationListPage.ts +#: src/user/LibraryApplication.ts msgid "Application Icon" msgstr "" @@ -1637,6 +1657,7 @@ msgstr "" msgid "Expiring?" msgstr "" +#: src/elements/user/SessionList.ts #: src/pages/crypto/CertificateKeyPairListPage.ts #: src/pages/stages/invitation/InvitationListPage.ts msgid "Expiry" @@ -2254,6 +2275,7 @@ msgstr "" msgid "Label shown next to/above the prompt." msgstr "" +#: src/elements/user/SessionList.ts #: src/elements/user/SessionList.ts msgid "Last IP" msgstr "" @@ -3456,9 +3478,9 @@ msgstr "" msgid "Result" msgstr "" -#: src/pages/system-tasks/SystemTaskListPage.ts -msgid "Retry Task" -msgstr "" +#: +#~ msgid "Retry Task" +#~ msgstr "" #: src/flows/stages/authenticator_validate/AuthenticatorValidateStageWebAuthn.ts msgid "Retry authentication" diff --git a/web/src/pages/applications/ApplicationListPage.ts b/web/src/pages/applications/ApplicationListPage.ts index 3a9b40b75..bbe28a03a 100644 --- a/web/src/pages/applications/ApplicationListPage.ts +++ b/web/src/pages/applications/ApplicationListPage.ts @@ -109,7 +109,7 @@ export class ApplicationListPage extends TablePage { ${item.providerObj?.name} ` : html`-`, - html`${item.providerObj?.verboseName || "-"}`, + html`${item.providerObj?.verboseName || t`-`}`, html` ${t`Update`} ${t`Update Application`} diff --git a/web/src/pages/events/EventListPage.ts b/web/src/pages/events/EventListPage.ts index 4d8c22126..5931e2999 100644 --- a/web/src/pages/events/EventListPage.ts +++ b/web/src/pages/events/EventListPage.ts @@ -63,8 +63,8 @@ export class EventListPage extends TablePage { : html``}` : html`-`, html`${item.created?.toLocaleString()}`, - html`${item.clientIp || "-"}`, - html`${item.tenant?.name || "-"}`, + html`${item.clientIp || t`-`}`, + html`${item.tenant?.name || t`-`}`, html` `, diff --git a/web/src/pages/groups/GroupListPage.ts b/web/src/pages/groups/GroupListPage.ts index 298e06837..42c032ba2 100644 --- a/web/src/pages/groups/GroupListPage.ts +++ b/web/src/pages/groups/GroupListPage.ts @@ -75,7 +75,7 @@ export class GroupListPage extends TablePage { row(item: Group): TemplateResult[] { return [ html`${item.name}`, - html`${item.parent || "-"}`, + html`${item.parent || t`-`}`, html`${Array.from(item.users || []).length}`, html`${item.isSuperuser ? t`Yes` : t`No`}`, html` diff --git a/web/src/pages/groups/MemberSelectModal.ts b/web/src/pages/groups/MemberSelectModal.ts index afcca4bfb..145cd8c19 100644 --- a/web/src/pages/groups/MemberSelectModal.ts +++ b/web/src/pages/groups/MemberSelectModal.ts @@ -48,7 +48,7 @@ export class MemberSelectTable extends TableModal { ${item.name} `, html`${item.isActive ? t`Yes` : t`No`}`, - html`${first(item.lastLogin?.toLocaleString(), "-")}`, + html`${first(item.lastLogin?.toLocaleString(), t`-`)}`, ]; } diff --git a/web/src/pages/providers/oauth2/OAuth2ProviderViewPage.ts b/web/src/pages/providers/oauth2/OAuth2ProviderViewPage.ts index db23a1b83..a87a53196 100644 --- a/web/src/pages/providers/oauth2/OAuth2ProviderViewPage.ts +++ b/web/src/pages/providers/oauth2/OAuth2ProviderViewPage.ts @@ -211,7 +211,7 @@ export class OAuth2ProviderViewPage extends LitElement { class="pf-c-form-control" readonly type="text" - value="${this.providerUrls?.providerInfo || "-"}" + value="${this.providerUrls?.providerInfo || t`-`}" />
@@ -227,7 +227,7 @@ export class OAuth2ProviderViewPage extends LitElement { class="pf-c-form-control" readonly type="text" - value="${this.providerUrls?.issuer || "-"}" + value="${this.providerUrls?.issuer || t`-`}" />

@@ -244,7 +244,7 @@ export class OAuth2ProviderViewPage extends LitElement { class="pf-c-form-control" readonly type="text" - value="${this.providerUrls?.authorize || "-"}" + value="${this.providerUrls?.authorize || t`-`}" />
@@ -260,7 +260,7 @@ export class OAuth2ProviderViewPage extends LitElement { class="pf-c-form-control" readonly type="text" - value="${this.providerUrls?.token || "-"}" + value="${this.providerUrls?.token || t`-`}" />
@@ -276,7 +276,7 @@ export class OAuth2ProviderViewPage extends LitElement { class="pf-c-form-control" readonly type="text" - value="${this.providerUrls?.userInfo || "-"}" + value="${this.providerUrls?.userInfo || t`-`}" />
@@ -292,7 +292,7 @@ export class OAuth2ProviderViewPage extends LitElement { class="pf-c-form-control" readonly type="text" - value="${this.providerUrls?.logout || "-"}" + value="${this.providerUrls?.logout || t`-`}" />
diff --git a/web/src/pages/stages/invitation/InvitationListPage.ts b/web/src/pages/stages/invitation/InvitationListPage.ts index 2e6ed1dd3..3cba80036 100644 --- a/web/src/pages/stages/invitation/InvitationListPage.ts +++ b/web/src/pages/stages/invitation/InvitationListPage.ts @@ -79,7 +79,7 @@ export class InvitationListPage extends TablePage { return [ html`${item.pk}`, html`${item.createdBy?.username}`, - html`${item.expires?.toLocaleString() || "-"}`, + html`${item.expires?.toLocaleString() || t`-`}`, ]; } diff --git a/web/src/pages/tokens/TokenListPage.ts b/web/src/pages/tokens/TokenListPage.ts index 82316b7e2..4be022cba 100644 --- a/web/src/pages/tokens/TokenListPage.ts +++ b/web/src/pages/tokens/TokenListPage.ts @@ -105,7 +105,7 @@ export class TokenListPage extends TablePage { html`${item.identifier}`, html`${item.userObj?.username}`, html`${item.expiring ? t`Yes` : t`No`}`, - html`${item.expiring ? item.expires?.toLocaleString() : "-"}`, + html`${item.expiring ? item.expires?.toLocaleString() : t`-`}`, html`${IntentToLabel(item.intent || IntentEnum.Api)}`, html` diff --git a/web/src/pages/users/UserListPage.ts b/web/src/pages/users/UserListPage.ts index d5e62277a..633150142 100644 --- a/web/src/pages/users/UserListPage.ts +++ b/web/src/pages/users/UserListPage.ts @@ -106,7 +106,7 @@ export class UserListPage extends TablePage { ${item.name} `, html`${item.isActive ? t`Yes` : t`No`}`, - html`${first(item.lastLogin?.toLocaleString(), "-")}`, + html`${first(item.lastLogin?.toLocaleString(), t`-`)}`, html` ${t`Update`} ${t`Update User`} diff --git a/web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts b/web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts index 0ee72d294..d806fc14c 100644 --- a/web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts +++ b/web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts @@ -94,7 +94,7 @@ export class UserSettingsAuthenticatorWebAuthn extends BaseUserSettings {
- ${device.name || "-"} + ${device.name || t`-`}
${t`Created ${device.createdOn?.toLocaleString()}`} diff --git a/web/src/user/user-settings/tokens/UserTokenList.ts b/web/src/user/user-settings/tokens/UserTokenList.ts index 54c7ce936..d85bd7057 100644 --- a/web/src/user/user-settings/tokens/UserTokenList.ts +++ b/web/src/user/user-settings/tokens/UserTokenList.ts @@ -97,7 +97,7 @@ export class UserTokenList extends Table {
- ${item.expiring ? item.expires?.toLocaleString() : "-"} + ${item.expiring ? item.expires?.toLocaleString() : t`-`}