From d70c8fbcc3ecbac7ec338847c5388e8a511e249a Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 30 Oct 2021 14:36:54 +0200 Subject: [PATCH] core: add API for all user-source connections Signed-off-by: Jens Langhammer --- authentik/api/v3/urls.py | 3 +- authentik/core/api/sources.py | 36 ++++- schema.yml | 281 ++++++++++++++++++++++++++++++++++ 3 files changed, 318 insertions(+), 2 deletions(-) diff --git a/authentik/api/v3/urls.py b/authentik/api/v3/urls.py index 2b915643b..00af22cc9 100644 --- a/authentik/api/v3/urls.py +++ b/authentik/api/v3/urls.py @@ -19,7 +19,7 @@ from authentik.core.api.devices import DeviceViewSet from authentik.core.api.groups import GroupViewSet from authentik.core.api.propertymappings import PropertyMappingViewSet from authentik.core.api.providers import ProviderViewSet -from authentik.core.api.sources import SourceViewSet +from authentik.core.api.sources import SourceViewSet, UserSourceConnectionViewSet from authentik.core.api.tokens import TokenViewSet from authentik.core.api.users import UserViewSet from authentik.crypto.api import CertificateKeyPairViewSet @@ -137,6 +137,7 @@ router.register("events/transports", NotificationTransportViewSet) router.register("events/rules", NotificationRuleViewSet) router.register("sources/all", SourceViewSet) +router.register("sources/user_connections/all", UserSourceConnectionViewSet) router.register("sources/user_connections/oauth", UserOAuthSourceConnectionViewSet) router.register("sources/user_connections/plex", PlexSourceConnectionViewSet) router.register("sources/ldap", LDAPSourceViewSet) diff --git a/authentik/core/api/sources.py b/authentik/core/api/sources.py index 18239ee16..db5a5974e 100644 --- a/authentik/core/api/sources.py +++ b/authentik/core/api/sources.py @@ -1,18 +1,21 @@ """Source API Views""" from typing import Iterable +from django_filters.rest_framework import DjangoFilterBackend from drf_spectacular.utils import extend_schema from rest_framework import mixins from rest_framework.decorators import action +from rest_framework.filters import OrderingFilter, SearchFilter from rest_framework.request import Request from rest_framework.response import Response from rest_framework.serializers import ModelSerializer, SerializerMethodField from rest_framework.viewsets import GenericViewSet from structlog.stdlib import get_logger +from authentik.api.authorization import OwnerFilter, OwnerPermissions from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer -from authentik.core.models import Source +from authentik.core.models import Source, UserSourceConnection from authentik.core.types import UserSettingSerializer from authentik.lib.utils.reflection import all_subclasses from authentik.policies.engine import PolicyEngine @@ -113,3 +116,34 @@ class SourceViewSet( LOGGER.warning(source_settings.errors) matching_sources.append(source_settings.validated_data) return Response(matching_sources) + + +class UserSourceConnectionSerializer(SourceSerializer): + """OAuth Source Serializer""" + + source = SourceSerializer(read_only=True) + + class Meta: + model = UserSourceConnection + fields = [ + "pk", + "user", + "source", + ] + + +class UserSourceConnectionViewSet( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + UsedByMixin, + mixins.ListModelMixin, + GenericViewSet, +): + """User-source connection Viewset""" + + queryset = UserSourceConnection.objects.all() + serializer_class = UserSourceConnectionSerializer + permission_classes = [OwnerPermissions] + filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter] + ordering = ["pk"] diff --git a/schema.yml b/schema.yml index eed2c0211..b9c9a2b70 100644 --- a/schema.yml +++ b/schema.yml @@ -13346,6 +13346,186 @@ paths: $ref: '#/components/schemas/ValidationError' '403': $ref: '#/components/schemas/GenericError' + /sources/user_connections/all/: + get: + operationId: sources_user_connections_all_list + description: User-source connection Viewset + parameters: + - name: ordering + required: false + in: query + description: Which field to use when ordering the results. + schema: + type: string + - name: page + required: false + in: query + description: A page number within the paginated result set. + schema: + type: integer + - name: page_size + required: false + in: query + description: Number of results to return per page. + schema: + type: integer + - name: search + required: false + in: query + description: A search term. + schema: + type: string + tags: + - sources + security: + - authentik: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedUserSourceConnectionList' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + /sources/user_connections/all/{id}/: + get: + operationId: sources_user_connections_all_retrieve + description: User-source connection Viewset + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this user source connection. + required: true + tags: + - sources + security: + - authentik: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UserSourceConnection' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + put: + operationId: sources_user_connections_all_update + description: User-source connection Viewset + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this user source connection. + required: true + tags: + - sources + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UserSourceConnectionRequest' + required: true + security: + - authentik: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UserSourceConnection' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + patch: + operationId: sources_user_connections_all_partial_update + description: User-source connection Viewset + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this user source connection. + required: true + tags: + - sources + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PatchedUserSourceConnectionRequest' + security: + - authentik: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UserSourceConnection' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + delete: + operationId: sources_user_connections_all_destroy + description: User-source connection Viewset + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this user source connection. + required: true + tags: + - sources + security: + - authentik: [] + responses: + '204': + description: No response body + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' + /sources/user_connections/all/{id}/used_by/: + get: + operationId: sources_user_connections_all_used_by_list + description: Get a list of all objects that use this object + parameters: + - in: path + name: id + schema: + type: integer + description: A unique integer value identifying this user source connection. + required: true + tags: + - sources + security: + - authentik: [] + responses: + '200': + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/UsedBy' + description: '' + '400': + $ref: '#/components/schemas/ValidationError' + '403': + $ref: '#/components/schemas/GenericError' /sources/user_connections/oauth/: get: operationId: sources_user_connections_oauth_list @@ -25616,6 +25796,41 @@ components: required: - pagination - results + PaginatedUserSourceConnectionList: + 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/UserSourceConnection' + required: + - pagination + - results PaginatedUserWriteStageList: type: object properties: @@ -27555,6 +27770,12 @@ components: attributes: type: object additionalProperties: {} + PatchedUserSourceConnectionRequest: + type: object + description: OAuth Source Serializer + properties: + user: + type: integer PatchedUserWriteStageRequest: type: object description: UserWriteStage Serializer @@ -29323,6 +29544,40 @@ components: - slug - verbose_name - verbose_name_plural + SourceRequest: + type: object + description: Source Serializer + properties: + name: + type: string + description: Source's display Name. + slug: + type: string + description: Internal source name, used in URLs. + maxLength: 50 + pattern: ^[-a-zA-Z0-9_]+$ + enabled: + type: boolean + authentication_flow: + type: string + format: uuid + nullable: true + description: Flow to use when authenticating existing users. + enrollment_flow: + type: string + format: uuid + nullable: true + description: Flow to use when enrolling new users. + policy_engine_mode: + $ref: '#/components/schemas/PolicyEngineMode' + user_matching_mode: + allOf: + - $ref: '#/components/schemas/UserMatchingModeEnum' + description: How the source determines if an existing user should be authenticated + or a new user enrolled. + required: + - name + - slug SourceType: type: object description: Serializer for SourceType @@ -30275,6 +30530,32 @@ components: - component - object_uid - title + UserSourceConnection: + type: object + description: OAuth Source Serializer + properties: + pk: + type: integer + readOnly: true + title: ID + user: + type: integer + source: + allOf: + - $ref: '#/components/schemas/Source' + readOnly: true + required: + - pk + - source + - user + UserSourceConnectionRequest: + type: object + description: OAuth Source Serializer + properties: + user: + type: integer + required: + - user UserWriteStage: type: object description: UserWriteStage Serializer