This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/authentik/sources/oauth/api/source.py

97 lines
3.4 KiB
Python
Raw Normal View History

2019-10-28 16:40:57 +00:00
"""OAuth Source Serializer"""
2021-02-09 15:47:49 +00:00
from django.urls.base import reverse_lazy
from drf_spectacular.utils import extend_schema, extend_schema_field
from rest_framework.decorators import action
from rest_framework.fields import BooleanField, CharField, SerializerMethodField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ValidationError
2019-10-28 16:40:57 +00:00
from rest_framework.viewsets import ModelViewSet
2021-02-08 09:15:59 +00:00
from authentik.core.api.sources import SourceSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
2020-12-05 21:08:42 +00:00
from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.types.manager import MANAGER
2019-10-28 16:40:57 +00:00
class SourceTypeSerializer(PassiveSerializer):
"""Serializer for SourceType"""
name = CharField(required=True)
slug = CharField(required=True)
urls_customizable = BooleanField()
request_token_url = CharField(read_only=True, allow_null=True)
authorization_url = CharField(read_only=True, allow_null=True)
access_token_url = CharField(read_only=True, allow_null=True)
profile_url = CharField(read_only=True, allow_null=True)
2021-02-08 09:15:59 +00:00
class OAuthSourceSerializer(SourceSerializer):
2019-10-28 16:40:57 +00:00
"""OAuth Source Serializer"""
2021-02-09 15:47:49 +00:00
callback_url = SerializerMethodField()
def get_callback_url(self, instance: OAuthSource) -> str:
"""Get OAuth Callback URL"""
relative_url = reverse_lazy(
"authentik_sources_oauth:oauth-client-callback",
kwargs={"source_slug": instance.slug},
)
if "request" not in self.context:
return relative_url
return self.context["request"].build_absolute_uri(relative_url)
type = SerializerMethodField()
@extend_schema_field(SourceTypeSerializer)
def get_type(self, instace: OAuthSource) -> SourceTypeSerializer:
"""Get source's type configuration"""
return SourceTypeSerializer(instace.type).data
def validate(self, attrs: dict) -> dict:
provider_type = MANAGER.find_type(attrs.get("provider_type", ""))
for url in [
"authorization_url",
"access_token_url",
"profile_url",
]:
if getattr(provider_type, url, None) is None:
if url not in attrs:
raise ValidationError(
f"{url} is required for provider {provider_type.name}"
)
return attrs
2019-10-28 16:40:57 +00:00
class Meta:
model = OAuthSource
2021-02-08 09:15:59 +00:00
fields = SourceSerializer.Meta.fields + [
2019-12-31 11:51:16 +00:00
"provider_type",
"request_token_url",
"authorization_url",
"access_token_url",
"profile_url",
"consumer_key",
"consumer_secret",
2021-02-09 15:47:49 +00:00
"callback_url",
"type",
2019-12-31 11:51:16 +00:00
]
extra_kwargs = {"consumer_secret": {"write_only": True}}
2019-10-28 16:40:57 +00:00
class OAuthSourceViewSet(UsedByMixin, ModelViewSet):
2019-10-28 16:40:57 +00:00
"""Source Viewset"""
queryset = OAuthSource.objects.all()
serializer_class = OAuthSourceSerializer
lookup_field = "slug"
@extend_schema(responses={200: SourceTypeSerializer(many=True)})
@action(detail=False, pagination_class=None, filter_backends=[])
def source_types(self, request: Request) -> Response:
"""Get all creatable source types"""
data = []
for source_type in MANAGER.get():
data.append(SourceTypeSerializer(source_type).data)
return Response(data)