providers/oauth2: add validation and tests to API

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-04-01 20:36:31 +02:00
parent b299451cab
commit 509f21a9b4
3 changed files with 55 additions and 18 deletions

View File

@ -1,22 +1,35 @@
"""OAuth2Provider API Views""" """OAuth2Provider API Views"""
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import ReadOnlyField from rest_framework.fields import ReadOnlyField
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response 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 rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Provider from authentik.core.models import Provider
from authentik.providers.oauth2.models import OAuth2Provider from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
class OAuth2ProviderSerializer(ProviderSerializer): class OAuth2ProviderSerializer(ProviderSerializer):
"""OAuth2Provider Serializer""" """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: class Meta:
model = OAuth2Provider model = OAuth2Provider
@ -36,7 +49,7 @@ class OAuth2ProviderSerializer(ProviderSerializer):
] ]
class OAuth2ProviderSetupURLs(Serializer): class OAuth2ProviderSetupURLs(PassiveSerializer):
"""OAuth2 Provider Metadata serializer""" """OAuth2 Provider Metadata serializer"""
issuer = ReadOnlyField() issuer = ReadOnlyField()
@ -46,12 +59,6 @@ class OAuth2ProviderSetupURLs(Serializer):
provider_info = ReadOnlyField() provider_info = ReadOnlyField()
logout = ReadOnlyField() logout = ReadOnlyField()
def create(self, request: Request) -> Response:
raise NotImplementedError
def update(self, request: Request) -> Response:
raise NotImplementedError
class OAuth2ProviderViewSet(ModelViewSet): class OAuth2ProviderViewSet(ModelViewSet):
"""OAuth2Provider Viewset""" """OAuth2Provider Viewset"""

View File

@ -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."]},
)

View File

@ -1,17 +1,16 @@
"""ProxyProvider API Views""" """ProxyProvider API Views"""
from drf_yasg.utils import swagger_serializer_method from drf_yasg.utils import swagger_serializer_method
from rest_framework.fields import CharField, ListField, 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.serializers import ModelSerializer, Serializer
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer 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.oauth2.views.provider import ProviderInfoView
from authentik.providers.proxy.models import ProxyProvider from authentik.providers.proxy.models import ProxyProvider
class OpenIDConnectConfigurationSerializer(Serializer): class OpenIDConnectConfigurationSerializer(PassiveSerializer):
"""rest_framework Serializer for OIDC Configuration""" """rest_framework Serializer for OIDC Configuration"""
issuer = CharField() issuer = CharField()
@ -27,12 +26,6 @@ class OpenIDConnectConfigurationSerializer(Serializer):
subject_types_supported = ListField(child=CharField()) subject_types_supported = ListField(child=CharField())
token_endpoint_auth_methods_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): class ProxyProviderSerializer(ProviderSerializer):
"""ProxyProvider Serializer""" """ProxyProvider Serializer"""