diff --git a/authentik/core/api/providers.py b/authentik/core/api/providers.py index e0e32b074..3a23f66b7 100644 --- a/authentik/core/api/providers.py +++ b/authentik/core/api/providers.py @@ -14,13 +14,26 @@ class ProviderSerializer(ModelSerializer): """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 - fields = ["pk", "name", "authorization_flow", "property_mappings", "__type__"] + fields = [ + "pk", + "name", + "application", + "authorization_flow", + "property_mappings", + "__type__", + ] -class ProviderViewSet(ReadOnlyModelViewSet): +class ProviderViewSet(ModelViewSet): """Provider Viewset""" queryset = Provider.objects.all() diff --git a/authentik/core/models.py b/authentik/core/models.py index d1fbd9d67..6f4a7c49f 100644 --- a/authentik/core/models.py +++ b/authentik/core/models.py @@ -14,6 +14,7 @@ from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from guardian.mixins import GuardianUserMixin from model_utils.managers import InheritanceManager +from rest_framework.serializers import Serializer from structlog import get_logger from authentik.core.exceptions import PropertyMappingExpressionException @@ -127,7 +128,7 @@ class User(GuardianUserMixin, AbstractUser): verbose_name_plural = _("Users") -class Provider(models.Model): +class Provider(SerializerModel): """Application-independent Provider instance. For example SAML2 Remote, OAuth2 Application""" name = models.TextField() @@ -156,6 +157,11 @@ class Provider(models.Model): """Return Form class used to edit this object""" raise NotImplementedError + @property + def serializer(self) -> Type[Serializer]: + """Get serializer for this model""" + raise NotImplementedError + def __str__(self): return self.name diff --git a/authentik/providers/oauth2/models.py b/authentik/providers/oauth2/models.py index ebaa96dc6..1d5a9a539 100644 --- a/authentik/providers/oauth2/models.py +++ b/authentik/providers/oauth2/models.py @@ -18,6 +18,7 @@ from django.utils import dateformat, timezone from django.utils.translation import gettext_lazy as _ from jwkest.jwk import Key, RSAKey, SYMKey, import_rsa_key from jwkest.jws import JWS +from rest_framework.serializers import Serializer from authentik.core.models import ExpiringModel, PropertyMapping, Provider, User from authentik.crypto.models import CertificateKeyPair @@ -263,6 +264,12 @@ class OAuth2Provider(Provider): launch_url = urlparse(main_url) return main_url.replace(launch_url.path, "") + @property + def serializer(self) -> Type[Serializer]: + from authentik.providers.oauth2.api import OAuth2ProviderSerializer + + return OAuth2ProviderSerializer + @property def form(self) -> Type[ModelForm]: from authentik.providers.oauth2.forms import OAuth2ProviderForm diff --git a/authentik/providers/proxy/models.py b/authentik/providers/proxy/models.py index badd62261..92195dc4f 100644 --- a/authentik/providers/proxy/models.py +++ b/authentik/providers/proxy/models.py @@ -8,6 +8,7 @@ from django.db import models from django.forms import ModelForm from django.http import HttpRequest from django.utils.translation import gettext as _ +from rest_framework.serializers import Serializer from authentik.crypto.models import CertificateKeyPair from authentik.lib.models import DomainlessURLValidator @@ -108,6 +109,12 @@ class ProxyProvider(OutpostModel, OAuth2Provider): return ProxyProviderForm + @property + def serializer(self) -> Type[Serializer]: + from authentik.providers.proxy.api import ProxyProviderSerializer + + return ProxyProviderSerializer + @property def launch_url(self) -> Optional[str]: """Use external_host as launch URL""" diff --git a/authentik/providers/saml/models.py b/authentik/providers/saml/models.py index c4dcbba78..eea7e9ee2 100644 --- a/authentik/providers/saml/models.py +++ b/authentik/providers/saml/models.py @@ -7,6 +7,7 @@ from django.forms import ModelForm from django.http import HttpRequest from django.shortcuts import reverse from django.utils.translation import gettext_lazy as _ +from rest_framework.serializers import Serializer from structlog import get_logger from authentik.core.models import PropertyMapping, Provider @@ -145,6 +146,12 @@ class SAMLProvider(Provider): launch_url = urlparse(self.acs_url) return self.acs_url.replace(launch_url.path, "") + @property + def serializer(self) -> Type[Serializer]: + from authentik.providers.saml.api import SAMLPropertyMappingSerializer + + return SAMLPropertyMappingSerializer + @property def form(self) -> Type[ModelForm]: from authentik.providers.saml.forms import SAMLProviderForm