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
|
2021-05-15 21:57:28 +00:00
|
|
|
from drf_spectacular.utils import extend_schema, extend_schema_field
|
2021-04-02 11:26:42 +00:00
|
|
|
from rest_framework.decorators import action
|
2021-04-02 12:59:58 +00:00
|
|
|
from rest_framework.fields import BooleanField, CharField, SerializerMethodField
|
2021-04-02 11:26:42 +00:00
|
|
|
from rest_framework.request import Request
|
|
|
|
from rest_framework.response import Response
|
2021-04-16 07:49:25 +00:00
|
|
|
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
|
2021-06-10 09:58:12 +00:00
|
|
|
from authentik.core.api.used_by import UsedByMixin
|
2021-04-02 11:26:42 +00:00
|
|
|
from authentik.core.api.utils import PassiveSerializer
|
2020-12-05 21:08:42 +00:00
|
|
|
from authentik.sources.oauth.models import OAuthSource
|
2021-04-02 11:26:42 +00:00
|
|
|
from authentik.sources.oauth.types.manager import MANAGER
|
2019-10-28 16:40:57 +00:00
|
|
|
|
|
|
|
|
2021-04-02 12:59:58 +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)
|
|
|
|
|
2021-04-02 12:59:58 +00:00
|
|
|
type = SerializerMethodField()
|
|
|
|
|
2021-05-15 21:57:28 +00:00
|
|
|
@extend_schema_field(SourceTypeSerializer)
|
2021-04-02 12:59:58 +00:00
|
|
|
def get_type(self, instace: OAuthSource) -> SourceTypeSerializer:
|
|
|
|
"""Get source's type configuration"""
|
|
|
|
return SourceTypeSerializer(instace.type).data
|
|
|
|
|
2021-04-16 07:49:25 +00:00
|
|
|
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",
|
2021-04-02 12:59:58 +00:00
|
|
|
"type",
|
2019-12-31 11:51:16 +00:00
|
|
|
]
|
2021-05-09 19:40:22 +00:00
|
|
|
extra_kwargs = {"consumer_secret": {"write_only": True}}
|
2019-10-28 16:40:57 +00:00
|
|
|
|
|
|
|
|
2021-06-10 09:58:12 +00:00
|
|
|
class OAuthSourceViewSet(UsedByMixin, ModelViewSet):
|
2019-10-28 16:40:57 +00:00
|
|
|
"""Source Viewset"""
|
|
|
|
|
|
|
|
queryset = OAuthSource.objects.all()
|
|
|
|
serializer_class = OAuthSourceSerializer
|
2021-02-09 15:08:24 +00:00
|
|
|
lookup_field = "slug"
|
2021-04-02 11:26:42 +00:00
|
|
|
|
2021-05-15 21:57:28 +00:00
|
|
|
@extend_schema(responses={200: SourceTypeSerializer(many=True)})
|
2021-04-02 11:26:42 +00:00
|
|
|
@action(detail=False, pagination_class=None, filter_backends=[])
|
2021-04-02 12:59:58 +00:00
|
|
|
def source_types(self, request: Request) -> Response:
|
2021-04-02 11:26:42 +00:00
|
|
|
"""Get all creatable source types"""
|
|
|
|
data = []
|
2021-04-02 12:59:58 +00:00
|
|
|
for source_type in MANAGER.get():
|
|
|
|
data.append(SourceTypeSerializer(source_type).data)
|
|
|
|
return Response(data)
|