From cec47c3cfc3fc4ed80fe4883263569242fed507b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 2 Jun 2021 22:04:19 +0200 Subject: [PATCH] providers/oauth2: show id_token issues for refresh token Signed-off-by: Jens Langhammer --- authentik/providers/oauth2/api/tokens.py | 31 +++++++- .../0003_tenant_branding_favicon.py | 8 +-- authentik/tenants/models.py | 4 +- schema.yml | 71 ++++++++++++++++++- web/src/elements/oauth/UserRefreshList.ts | 34 +++++++-- web/src/locales/en.po | 4 ++ web/src/locales/pseudo-LOCALE.po | 4 ++ web/src/pages/users/UserViewPage.ts | 8 +-- 8 files changed, 144 insertions(+), 20 deletions(-) diff --git a/authentik/providers/oauth2/api/tokens.py b/authentik/providers/oauth2/api/tokens.py index e509b0ce8..3ff200da8 100644 --- a/authentik/providers/oauth2/api/tokens.py +++ b/authentik/providers/oauth2/api/tokens.py @@ -1,8 +1,11 @@ """OAuth2Provider API Views""" +from dataclasses import asdict +from json import dumps + from django_filters.rest_framework import DjangoFilterBackend from guardian.utils import get_anonymous_user from rest_framework import mixins -from rest_framework.fields import CharField, ListField +from rest_framework.fields import CharField, ListField, SerializerMethodField from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import GenericViewSet @@ -27,6 +30,30 @@ class ExpiringBaseGrantModelSerializer(ModelSerializer, MetaNameSerializer): depth = 2 +class RefreshTokenModelSerializer(ExpiringBaseGrantModelSerializer): + """Serializer for BaseGrantModel and RefreshToken""" + + id_token = SerializerMethodField() + + def get_id_token(self, instance: RefreshToken) -> str: + """Get the token's id_token as JSON String""" + return dumps(asdict(instance.id_token), indent=4) + + class Meta: + + model = RefreshToken + fields = [ + "pk", + "provider", + "user", + "is_expired", + "expires", + "scope", + "id_token", + ] + depth = 2 + + class AuthorizationCodeViewSet( mixins.RetrieveModelMixin, mixins.DestroyModelMixin, @@ -61,7 +88,7 @@ class RefreshTokenViewSet( """RefreshToken Viewset""" queryset = RefreshToken.objects.all() - serializer_class = ExpiringBaseGrantModelSerializer + serializer_class = RefreshTokenModelSerializer filterset_fields = ["user", "provider"] ordering = ["provider", "expires"] filter_backends = [ diff --git a/authentik/tenants/migrations/0003_tenant_branding_favicon.py b/authentik/tenants/migrations/0003_tenant_branding_favicon.py index 32b88dc64..590353d18 100644 --- a/authentik/tenants/migrations/0003_tenant_branding_favicon.py +++ b/authentik/tenants/migrations/0003_tenant_branding_favicon.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('authentik_tenants', '0002_default'), + ("authentik_tenants", "0002_default"), ] operations = [ migrations.AddField( - model_name='tenant', - name='branding_favicon', - field=models.TextField(default='/static/dist/assets/icons/icon.png'), + model_name="tenant", + name="branding_favicon", + field=models.TextField(default="/static/dist/assets/icons/icon.png"), ), ] diff --git a/authentik/tenants/models.py b/authentik/tenants/models.py index 1bc618914..c777ff283 100644 --- a/authentik/tenants/models.py +++ b/authentik/tenants/models.py @@ -25,9 +25,7 @@ class Tenant(models.Model): branding_logo = models.TextField( default="/static/dist/assets/icons/icon_left_brand.svg" ) - branding_favicon = models.TextField( - default="/static/dist/assets/icons/icon.png" - ) + branding_favicon = models.TextField(default="/static/dist/assets/icons/icon.png") flow_authentication = models.ForeignKey( Flow, null=True, on_delete=models.SET_NULL, related_name="tenant_authentication" diff --git a/schema.yml b/schema.yml index 5ca821759..78e4dc98f 100644 --- a/schema.yml +++ b/schema.yml @@ -4772,7 +4772,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/PaginatedExpiringBaseGrantModelList' + $ref: '#/components/schemas/PaginatedRefreshTokenModelList' description: '' '400': $ref: '#/components/schemas/ValidationError' @@ -4799,7 +4799,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ExpiringBaseGrantModel' + $ref: '#/components/schemas/RefreshTokenModel' description: '' '400': $ref: '#/components/schemas/ValidationError' @@ -20827,6 +20827,41 @@ components: required: - pagination - results + PaginatedRefreshTokenModelList: + type: object + properties: + pagination: + type: object + properties: + next: + type: number + previous: + type: number + count: + type: number + current: + type: number + total_pages: + type: number + start_index: + type: number + end_index: + type: number + required: + - next + - previous + - count + - current + - total_pages + - start_index + - end_index + results: + type: array + items: + $ref: '#/components/schemas/RefreshTokenModel' + required: + - pagination + - results PaginatedReputationPolicyList: type: object properties: @@ -24150,6 +24185,38 @@ components: required: - to - type + RefreshTokenModel: + type: object + description: Serializer for BaseGrantModel and RefreshToken + properties: + pk: + type: integer + readOnly: true + title: ID + provider: + $ref: '#/components/schemas/OAuth2Provider' + user: + $ref: '#/components/schemas/User' + is_expired: + type: boolean + readOnly: true + expires: + type: string + format: date-time + scope: + type: array + items: + type: string + id_token: + type: string + readOnly: true + required: + - id_token + - is_expired + - pk + - provider + - scope + - user ReputationPolicy: type: object description: Reputation Policy Serializer diff --git a/web/src/elements/oauth/UserRefreshList.ts b/web/src/elements/oauth/UserRefreshList.ts index 7d50c5361..a4e33b6be 100644 --- a/web/src/elements/oauth/UserRefreshList.ts +++ b/web/src/elements/oauth/UserRefreshList.ts @@ -1,19 +1,26 @@ import { t } from "@lingui/macro"; -import { customElement, html, property, TemplateResult } from "lit-element"; +import { CSSResult, customElement, html, property, TemplateResult } from "lit-element"; import { AKResponse } from "../../api/Client"; import { Table, TableColumn } from "../table/Table"; +import PFFlex from "@patternfly/patternfly/layouts/Flex/flex.css"; import "../forms/DeleteForm"; import { PAGE_SIZE } from "../../constants"; -import { ExpiringBaseGrantModel, Oauth2Api } from "authentik-api"; +import { RefreshTokenModel, Oauth2Api } from "authentik-api"; import { DEFAULT_CONFIG } from "../../api/Config"; @customElement("ak-user-oauth-refresh-list") -export class UserOAuthRefreshList extends Table { +export class UserOAuthRefreshList extends Table { + expandable = true; + @property({ type: Number }) userId?: number; - apiEndpoint(page: number): Promise> { + static get styles(): CSSResult[] { + return super.styles.concat(PFFlex); + } + + apiEndpoint(page: number): Promise> { return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensList({ user: this.userId, ordering: "expires", @@ -33,7 +40,24 @@ export class UserOAuthRefreshList extends Table { ]; } - row(item: ExpiringBaseGrantModel): TemplateResult[] { + renderExpanded(item: RefreshTokenModel): TemplateResult { + return html` + +
+
+
+

${t`ID Token`}

+
${item.idToken}
+
+
+
+ + + + `; + } + + row(item: RefreshTokenModel): TemplateResult[] { return [ html` ${item.provider?.name} diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 30f52546a..7aefa76cd 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -1717,6 +1717,10 @@ msgstr "How many attempts a user has before the flow is canceled. To lock the us msgid "ID" msgstr "ID" +#: src/elements/oauth/UserRefreshList.ts +msgid "ID Token" +msgstr "ID Token" + #: src/pages/policies/reputation/IPReputationListPage.ts msgid "IP" msgstr "IP" diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 5d85052ca..5cca96990 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -1709,6 +1709,10 @@ msgstr "" msgid "ID" msgstr "" +#: +msgid "ID Token" +msgstr "" + #: msgid "IP" msgstr "" diff --git a/web/src/pages/users/UserViewPage.ts b/web/src/pages/users/UserViewPage.ts index 097c14ed9..e4276908c 100644 --- a/web/src/pages/users/UserViewPage.ts +++ b/web/src/pages/users/UserViewPage.ts @@ -197,7 +197,7 @@ export class UserViewPage extends LitElement {
@@ -207,7 +207,7 @@ export class UserViewPage extends LitElement {
- +
@@ -215,7 +215,7 @@ export class UserViewPage extends LitElement {
- +
@@ -223,7 +223,7 @@ export class UserViewPage extends LitElement {
- +