From 91d6a3c8c75b877c51a4ce6187e9cb1053c3fac3 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 6 Feb 2021 17:31:29 +0100 Subject: [PATCH] providers/*: simplify provider API --- authentik/core/api/providers.py | 12 +- authentik/providers/oauth2/api.py | 15 +-- authentik/providers/proxy/api.py | 22 +--- authentik/providers/saml/api.py | 41 +++++-- swagger.yaml | 190 +++++++++++++++++++++--------- 5 files changed, 174 insertions(+), 106 deletions(-) diff --git a/authentik/core/api/providers.py b/authentik/core/api/providers.py index 90a27437d..429e7e29b 100644 --- a/authentik/core/api/providers.py +++ b/authentik/core/api/providers.py @@ -1,4 +1,5 @@ """Provider API Views""" +from rest_framework.fields import ReadOnlyField from rest_framework.serializers import ModelSerializer, SerializerMethodField from rest_framework.viewsets import ModelViewSet @@ -9,18 +10,15 @@ from authentik.core.models import Provider class ProviderSerializer(ModelSerializer, MetaNameSerializer): """Provider Serializer""" + assigned_application_slug = ReadOnlyField(source="application.slug") + assigned_application_name = ReadOnlyField(source="application.name") + object_type = SerializerMethodField() def get_object_type(self, obj): """Get object type so that we know which API Endpoint to use to get the full object""" return obj._meta.object_name.lower().replace("provider", "") - def to_representation(self, instance: Provider): - # pyright: reportGeneralTypeIssues=false - if instance.__class__ == Provider: - return super().to_representation(instance) - return instance.serializer(instance=instance).data - class Meta: model = Provider @@ -31,6 +29,8 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer): "authorization_flow", "property_mappings", "object_type", + "assigned_application_slug", + "assigned_application_name", "verbose_name", "verbose_name_plural", ] diff --git a/authentik/providers/oauth2/api.py b/authentik/providers/oauth2/api.py index 1c2da3e21..a9286229b 100644 --- a/authentik/providers/oauth2/api.py +++ b/authentik/providers/oauth2/api.py @@ -1,24 +1,19 @@ """OAuth2Provider API Views""" -from rest_framework.fields import ReadOnlyField from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet +from authentik.core.api.providers import ProviderSerializer from authentik.core.api.utils import MetaNameSerializer from authentik.providers.oauth2.models import OAuth2Provider, ScopeMapping -class OAuth2ProviderSerializer(ModelSerializer, MetaNameSerializer): +class OAuth2ProviderSerializer(ProviderSerializer): """OAuth2Provider Serializer""" - assigned_application_slug = ReadOnlyField(source="application.slug") - assigned_application_name = ReadOnlyField(source="application.name") - class Meta: model = OAuth2Provider - fields = [ - "pk", - "name", + fields = ProviderSerializer.Meta.fields + [ "authorization_flow", "client_type", "client_id", @@ -31,10 +26,6 @@ class OAuth2ProviderSerializer(ModelSerializer, MetaNameSerializer): "sub_mode", "property_mappings", "issuer_mode", - "assigned_application_slug", - "assigned_application_name", - "verbose_name", - "verbose_name_plural", ] diff --git a/authentik/providers/proxy/api.py b/authentik/providers/proxy/api.py index e01f55e1f..40ac49bea 100644 --- a/authentik/providers/proxy/api.py +++ b/authentik/providers/proxy/api.py @@ -1,17 +1,12 @@ """ProxyProvider API Views""" from drf_yasg2.utils import swagger_serializer_method -from rest_framework.fields import ( - CharField, - ListField, - ReadOnlyField, - SerializerMethodField, -) +from rest_framework.fields import CharField, ListField, SerializerMethodField from rest_framework.request import Request from rest_framework.response import Response from rest_framework.serializers import ModelSerializer, Serializer from rest_framework.viewsets import ModelViewSet -from authentik.core.api.utils import MetaNameSerializer +from authentik.core.api.providers import ProviderSerializer from authentik.providers.oauth2.views.provider import ProviderInfoView from authentik.providers.proxy.models import ProxyProvider @@ -39,12 +34,9 @@ class OpenIDConnectConfigurationSerializer(Serializer): raise NotImplementedError -class ProxyProviderSerializer(MetaNameSerializer, ModelSerializer): +class ProxyProviderSerializer(ProviderSerializer): """ProxyProvider Serializer""" - assigned_application_slug = ReadOnlyField(source="application.slug") - assigned_application_name = ReadOnlyField(source="application.name") - def create(self, validated_data): instance: ProxyProvider = super().create(validated_data) instance.set_oauth_defaults() @@ -58,9 +50,7 @@ class ProxyProviderSerializer(MetaNameSerializer, ModelSerializer): class Meta: model = ProxyProvider - fields = [ - "pk", - "name", + fields = ProviderSerializer.Meta.fields + [ "internal_host", "external_host", "internal_host_ssl_validation", @@ -69,10 +59,6 @@ class ProxyProviderSerializer(MetaNameSerializer, ModelSerializer): "basic_auth_enabled", "basic_auth_password_attribute", "basic_auth_user_attribute", - "assigned_application_slug", - "assigned_application_name", - "verbose_name", - "verbose_name_plural", ] diff --git a/authentik/providers/saml/api.py b/authentik/providers/saml/api.py index d8272bdbd..a9beb0641 100644 --- a/authentik/providers/saml/api.py +++ b/authentik/providers/saml/api.py @@ -1,24 +1,26 @@ """SAMLProvider API Views""" +from drf_yasg2.utils import swagger_auto_schema from rest_framework.fields import ReadOnlyField -from rest_framework.serializers import ModelSerializer +from authentik.providers.saml.views import DescriptorDownloadView +from rest_framework.generics import get_object_or_404 +from rest_framework.serializers import ModelSerializer, Serializer from rest_framework.viewsets import ModelViewSet - +from rest_framework.decorators import action +from rest_framework.request import Request +from rest_framework.response import Response +from guardian.shortcuts import get_objects_for_user +from authentik.core.api.providers import ProviderSerializer from authentik.core.api.utils import MetaNameSerializer from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider -class SAMLProviderSerializer(ModelSerializer, MetaNameSerializer): +class SAMLProviderSerializer(ProviderSerializer): """SAMLProvider Serializer""" - assigned_application_slug = ReadOnlyField(source="application.slug") - assigned_application_name = ReadOnlyField(source="application.name") - class Meta: model = SAMLProvider - fields = [ - "pk", - "name", + fields = ProviderSerializer.Meta.fields + [ "acs_url", "audience", "issuer", @@ -31,19 +33,32 @@ class SAMLProviderSerializer(ModelSerializer, MetaNameSerializer): "signature_algorithm", "signing_kp", "verification_kp", - "assigned_application_slug", - "assigned_application_name", - "verbose_name", - "verbose_name_plural", ] +class SAMLMetadataSerializer(Serializer): + """SAML Provider Metadata serializer""" + + metadata = ReadOnlyField() + + class SAMLProviderViewSet(ModelViewSet): """SAMLProvider Viewset""" queryset = SAMLProvider.objects.all() serializer_class = SAMLProviderSerializer + @action(methods=["GET"], detail=True) + @swagger_auto_schema(responses={200: SAMLMetadataSerializer(many=False)}) + # pylint: disable=invalid-name + def metadata(self, request: Request, pk: int) -> str: + """Return metadata as XML string""" + provider = get_object_or_404(SAMLProvider, pk=pk) + metadata = DescriptorDownloadView.get_metadata(request, provider) + return Response({ + "metadata": metadata + }) + class SAMLPropertyMappingSerializer(ModelSerializer, MetaNameSerializer): """SAMLPropertyMapping Serializer""" diff --git a/swagger.yaml b/swagger.yaml index 9f4ca7d58..2955a7f79 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -4557,6 +4557,24 @@ paths: description: A unique integer value identifying this SAML Provider. required: true type: integer + /providers/saml/{id}/metadata/: + get: + operationId: providers_saml_metadata + description: Return metadata as XML string + parameters: [] + responses: + '200': + description: SAML Provider Metadata serializer + schema: + $ref: '#/definitions/SAMLMetadata' + tags: + - providers + parameters: + - name: id + in: path + description: A unique integer value identifying this SAML Provider. + required: true + type: integer /root/config/: get: operationId: root_config_list @@ -7364,6 +7382,14 @@ definitions: title: Object type type: string readOnly: true + assigned_application_slug: + title: Assigned application slug + type: string + readOnly: true + assigned_application_name: + title: Assigned application name + type: string + readOnly: true verbose_name: title: Verbose name type: string @@ -8671,6 +8697,7 @@ definitions: description: OAuth2Provider Serializer required: - name + - application - authorization_flow type: object properties: @@ -8682,11 +8709,40 @@ definitions: title: Name type: string minLength: 1 + application: + title: Application + type: string authorization_flow: title: Authorization flow description: Flow used when authorizing this provider. type: string format: uuid + property_mappings: + type: array + items: + type: string + format: uuid + uniqueItems: true + object_type: + title: Object type + type: string + readOnly: true + assigned_application_slug: + title: Assigned application slug + type: string + readOnly: true + assigned_application_name: + title: Assigned application name + type: string + readOnly: true + verbose_name: + title: Verbose name + type: string + readOnly: true + verbose_name_plural: + title: Verbose name plural + type: string + readOnly: true client_type: title: Client Type description: |- @@ -8745,12 +8801,6 @@ definitions: - user_username - user_email - user_upn - property_mappings: - type: array - items: - type: string - format: uuid - uniqueItems: true issuer_mode: title: Issuer mode description: Configure how the issuer field of the ID Token should be filled. @@ -8758,6 +8808,42 @@ definitions: enum: - global - per_provider + ProxyProvider: + description: ProxyProvider Serializer + required: + - name + - application + - authorization_flow + - internal_host + - external_host + type: object + properties: + pk: + title: ID + type: integer + readOnly: true + name: + title: Name + type: string + minLength: 1 + application: + title: Application + type: string + authorization_flow: + title: Authorization flow + description: Flow used when authorizing this provider. + type: string + format: uuid + property_mappings: + type: array + items: + type: string + format: uuid + uniqueItems: true + object_type: + title: Object type + type: string + readOnly: true assigned_application_slug: title: Assigned application slug type: string @@ -8774,22 +8860,6 @@ definitions: title: Verbose name plural type: string readOnly: true - ProxyProvider: - description: ProxyProvider Serializer - required: - - name - - internal_host - - external_host - type: object - properties: - pk: - title: ID - type: integer - readOnly: true - name: - title: Name - type: string - minLength: 1 internal_host: title: Internal host type: string @@ -8827,6 +8897,41 @@ definitions: description: User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used. type: string + SAMLProvider: + description: SAMLProvider Serializer + required: + - name + - application + - authorization_flow + - acs_url + type: object + properties: + pk: + title: ID + type: integer + readOnly: true + name: + title: Name + type: string + minLength: 1 + application: + title: Application + type: string + authorization_flow: + title: Authorization flow + description: Flow used when authorizing this provider. + type: string + format: uuid + property_mappings: + type: array + items: + type: string + format: uuid + uniqueItems: true + object_type: + title: Object type + type: string + readOnly: true assigned_application_slug: title: Assigned application slug type: string @@ -8843,21 +8948,6 @@ definitions: title: Verbose name plural type: string readOnly: true - SAMLProvider: - description: SAMLProvider Serializer - required: - - name - - acs_url - type: object - properties: - pk: - title: ID - type: integer - readOnly: true - name: - title: Name - type: string - minLength: 1 acs_url: title: ACS URL type: string @@ -8892,12 +8982,6 @@ definitions: hours=1;minutes=2;seconds=3).' type: string minLength: 1 - property_mappings: - type: array - items: - type: string - format: uuid - uniqueItems: true name_id_mapping: title: NameID Property Mapping description: Configure how the NameID value will be created. When left empty, @@ -8935,20 +9019,12 @@ definitions: type: string format: uuid x-nullable: true - assigned_application_slug: - title: Assigned application slug - type: string - readOnly: true - assigned_application_name: - title: Assigned application name - type: string - readOnly: true - verbose_name: - title: Verbose name - type: string - readOnly: true - verbose_name_plural: - title: Verbose name plural + SAMLMetadata: + description: SAML Provider Metadata serializer + type: object + properties: + metadata: + title: Metadata type: string readOnly: true Config: