From 509f21a9b42bf63da582e9e371f27080231a057d Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 1 Apr 2021 20:36:31 +0200 Subject: [PATCH] providers/oauth2: add validation and tests to API Signed-off-by: Jens Langhammer --- authentik/providers/oauth2/api/provider.py | 25 ++++++++----- authentik/providers/oauth2/tests/test_api.py | 37 ++++++++++++++++++++ authentik/providers/proxy/api.py | 11 ++---- 3 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 authentik/providers/oauth2/tests/test_api.py diff --git a/authentik/providers/oauth2/api/provider.py b/authentik/providers/oauth2/api/provider.py index 2e9046529..4a6e5d05d 100644 --- a/authentik/providers/oauth2/api/provider.py +++ b/authentik/providers/oauth2/api/provider.py @@ -1,22 +1,35 @@ """OAuth2Provider API Views""" from django.urls import reverse +from django.utils.translation import gettext_lazy as _ from drf_yasg.utils import swagger_auto_schema from rest_framework.decorators import action from rest_framework.fields import ReadOnlyField from rest_framework.generics import get_object_or_404 from rest_framework.request import Request from rest_framework.response import Response -from rest_framework.serializers import Serializer +from rest_framework.serializers import ValidationError from rest_framework.viewsets import ModelViewSet from authentik.core.api.providers import ProviderSerializer +from authentik.core.api.utils import PassiveSerializer from authentik.core.models import Provider -from authentik.providers.oauth2.models import OAuth2Provider +from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider class OAuth2ProviderSerializer(ProviderSerializer): """OAuth2Provider Serializer""" + def validate_jwt_alg(self, value): + """Ensure that when RS256 is selected, a certificate-key-pair is selected""" + if ( + self.initial_data.get("rsa_key", None) is None + and value == JWTAlgorithms.RS256 + ): + raise ValidationError( + _("RS256 requires a Certificate-Key-Pair to be selected.") + ) + return value + class Meta: model = OAuth2Provider @@ -36,7 +49,7 @@ class OAuth2ProviderSerializer(ProviderSerializer): ] -class OAuth2ProviderSetupURLs(Serializer): +class OAuth2ProviderSetupURLs(PassiveSerializer): """OAuth2 Provider Metadata serializer""" issuer = ReadOnlyField() @@ -46,12 +59,6 @@ class OAuth2ProviderSetupURLs(Serializer): provider_info = ReadOnlyField() logout = ReadOnlyField() - def create(self, request: Request) -> Response: - raise NotImplementedError - - def update(self, request: Request) -> Response: - raise NotImplementedError - class OAuth2ProviderViewSet(ModelViewSet): """OAuth2Provider Viewset""" diff --git a/authentik/providers/oauth2/tests/test_api.py b/authentik/providers/oauth2/tests/test_api.py new file mode 100644 index 000000000..6ff1dbfb5 --- /dev/null +++ b/authentik/providers/oauth2/tests/test_api.py @@ -0,0 +1,37 @@ +"""Test oauth2 provider API""" +from django.urls import reverse +from rest_framework.test import APITestCase + +from authentik.core.models import User +from authentik.flows.models import Flow, FlowDesignation +from authentik.providers.oauth2.models import JWTAlgorithms + + +class TestOAuth2ProviderAPI(APITestCase): + """Test oauth2 provider API""" + + def setUp(self) -> None: + super().setUp() + self.user = User.objects.get(username="akadmin") + self.client.force_login(self.user) + + def test_validate(self): + """Test OAuth2 Provider validation""" + response = self.client.post( + reverse( + "authentik_api:oauth2provider-list", + ), + data={ + "name": "test", + "jwt_alg": str(JWTAlgorithms.RS256), + "authorization_flow": Flow.objects.filter( + designation=FlowDesignation.AUTHORIZATION + ) + .first() + .pk, + }, + ) + self.assertJSONEqual( + response.content.decode(), + {"jwt_alg": ["RS256 requires a Certificate-Key-Pair to be selected."]}, + ) diff --git a/authentik/providers/proxy/api.py b/authentik/providers/proxy/api.py index ff9fc94a2..4e3090c81 100644 --- a/authentik/providers/proxy/api.py +++ b/authentik/providers/proxy/api.py @@ -1,17 +1,16 @@ """ProxyProvider API Views""" from drf_yasg.utils import swagger_serializer_method 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.providers import ProviderSerializer +from authentik.core.api.utils import PassiveSerializer from authentik.providers.oauth2.views.provider import ProviderInfoView from authentik.providers.proxy.models import ProxyProvider -class OpenIDConnectConfigurationSerializer(Serializer): +class OpenIDConnectConfigurationSerializer(PassiveSerializer): """rest_framework Serializer for OIDC Configuration""" issuer = CharField() @@ -27,12 +26,6 @@ class OpenIDConnectConfigurationSerializer(Serializer): subject_types_supported = ListField(child=CharField()) token_endpoint_auth_methods_supported = ListField(child=CharField()) - def create(self, request: Request) -> Response: - raise NotImplementedError - - def update(self, request: Request) -> Response: - raise NotImplementedError - class ProxyProviderSerializer(ProviderSerializer): """ProxyProvider Serializer"""