core: fix tokens not being viewable but superusers

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-09-19 16:08:30 +02:00
parent 3f42067a8f
commit f6e0f0282d
20 changed files with 97 additions and 29 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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):

View file

@ -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):

View file

@ -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);
});
});
};

View file

@ -58,7 +58,7 @@ export class ObjectChangelog extends Table<Event> {
? html`<small> ${t`On behalf of ${item.user.on_behalf_of.username}`} </small>`
: html``}`,
html`<span>${item.created?.toLocaleString()}</span>`,
html`<span>${item.clientIp || "-"}</span>`,
html`<span>${item.clientIp || t`-`}</span>`,
];
}

View file

@ -49,7 +49,7 @@ export class ObjectChangelog extends Table<Event> {
? html`<small> ${t`On behalf of ${item.user.on_behalf_of.username}`} </small>`
: html``}`,
html`<span>${item.created?.toLocaleString()}</span>`,
html`<span>${item.clientIp || "-"}</span>`,
html`<span>${item.clientIp || t`-`}</span>`,
];
}

View file

@ -39,6 +39,12 @@ export class AuthenticatedSessionList extends Table<AuthenticatedSession> {
return html`<ak-forms-delete-bulk
objectLabel=${t`Session(s)`}
.objects=${this.selectedElements}
.metadata=${(item: AuthenticatedSession) => {
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 || "",

View file

@ -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"

View file

@ -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"

View file

@ -109,7 +109,7 @@ export class ApplicationListPage extends TablePage<Application> {
${item.providerObj?.name}
</a>`
: html`-`,
html`${item.providerObj?.verboseName || "-"}`,
html`${item.providerObj?.verboseName || t`-`}`,
html` <ak-forms-modal>
<span slot="submit"> ${t`Update`} </span>
<span slot="header"> ${t`Update Application`} </span>

View file

@ -63,8 +63,8 @@ export class EventListPage extends TablePage<Event> {
: html``}`
: html`-`,
html`<span>${item.created?.toLocaleString()}</span>`,
html`<span>${item.clientIp || "-"}</span>`,
html`<span>${item.tenant?.name || "-"}</span>`,
html`<span>${item.clientIp || t`-`}</span>`,
html`<span>${item.tenant?.name || t`-`}</span>`,
html`<a href="#/events/log/${item.pk}">
<i class="fas fas fa-share-square"></i>
</a>`,

View file

@ -75,7 +75,7 @@ export class GroupListPage extends TablePage<Group> {
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` <ak-forms-modal>

View file

@ -48,7 +48,7 @@ export class MemberSelectTable extends TableModal<User> {
<small>${item.name}</small>
</div>`,
html`${item.isActive ? t`Yes` : t`No`}`,
html`${first(item.lastLogin?.toLocaleString(), "-")}`,
html`${first(item.lastLogin?.toLocaleString(), t`-`)}`,
];
}

View file

@ -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`-`}"
/>
</div>
<div class="pf-c-form__group">
@ -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`-`}"
/>
</div>
<hr />
@ -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`-`}"
/>
</div>
<div class="pf-c-form__group">
@ -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`-`}"
/>
</div>
<div class="pf-c-form__group">
@ -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`-`}"
/>
</div>
<div class="pf-c-form__group">
@ -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`-`}"
/>
</div>
</form>

View file

@ -79,7 +79,7 @@ export class InvitationListPage extends TablePage<Invitation> {
return [
html`${item.pk}`,
html`${item.createdBy?.username}`,
html`${item.expires?.toLocaleString() || "-"}`,
html`${item.expires?.toLocaleString() || t`-`}`,
];
}

View file

@ -105,7 +105,7 @@ export class TokenListPage extends TablePage<Token> {
html`${item.identifier}`,
html`<a href="#/identity/users/${item.userObj?.pk}">${item.userObj?.username}</a>`,
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`
<ak-forms-modal>

View file

@ -106,7 +106,7 @@ export class UserListPage extends TablePage<User> {
<small>${item.name}</small>
</a>`,
html`${item.isActive ? t`Yes` : t`No`}`,
html`${first(item.lastLogin?.toLocaleString(), "-")}`,
html`${first(item.lastLogin?.toLocaleString(), t`-`)}`,
html` <ak-forms-modal>
<span slot="submit"> ${t`Update`} </span>
<span slot="header"> ${t`Update User`} </span>

View file

@ -94,7 +94,7 @@ export class UserSettingsAuthenticatorWebAuthn extends BaseUserSettings {
<div class="pf-c-data-list__item-row">
<div class="pf-c-data-list__item-content">
<div class="pf-c-data-list__cell">
${device.name || "-"}
${device.name || t`-`}
</div>
<div class="pf-c-data-list__cell">
${t`Created ${device.createdOn?.toLocaleString()}`}

View file

@ -97,7 +97,7 @@ export class UserTokenList extends Table<Token> {
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
${item.expiring ? item.expires?.toLocaleString() : "-"}
${item.expiring ? item.expires?.toLocaleString() : t`-`}
</div>
</dd>
</div>