*: fix static response descriptions

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-05-16 13:26:58 +02:00
parent 1324d03815
commit 0bac738090
22 changed files with 136 additions and 64 deletions

View file

@ -26,7 +26,7 @@ lint:
pylint authentik tests lifecycle pylint authentik tests lifecycle
gen: gen:
./manage.py spectacular --file schema.yml ./manage.py spectacular --file schema.yaml --validate --fail-on-warn
docker run \ docker run \
--rm -v ${PWD}:/local \ --rm -v ${PWD}:/local \
openapitools/openapi-generator-cli generate \ openapitools/openapi-generator-cli generate \

View file

@ -4,7 +4,7 @@ from importlib import import_module
from django.contrib import messages from django.contrib import messages
from django.http.response import Http404 from django.http.response import Http404
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import CharField, ChoiceField, DateTimeField, ListField from rest_framework.fields import CharField, ChoiceField, DateTimeField, ListField
from rest_framework.permissions import IsAdminUser from rest_framework.permissions import IsAdminUser
@ -34,8 +34,14 @@ class TaskViewSet(ViewSet):
"""Read-only view set that returns all background tasks""" """Read-only view set that returns all background tasks"""
permission_classes = [IsAdminUser] permission_classes = [IsAdminUser]
serializer_class = TaskSerializer
@extend_schema(responses={200: TaskSerializer(many=False), 404: "Task not found"}) @extend_schema(
responses={
200: TaskSerializer(many=False),
404: OpenApiResponse(description="Task not found"),
}
)
# pylint: disable=invalid-name # pylint: disable=invalid-name
def retrieve(self, request: Request, pk=None) -> Response: def retrieve(self, request: Request, pk=None) -> Response:
"""Get a single system task""" """Get a single system task"""
@ -52,9 +58,9 @@ class TaskViewSet(ViewSet):
@extend_schema( @extend_schema(
responses={ responses={
204: "Task retried successfully", 204: OpenApiResponse(description="Task retried successfully"),
404: "Task not found", 404: OpenApiResponse(description="Task not found"),
500: "Failed to retry task", 500: OpenApiResponse(description="Failed to retry task"),
} }
) )
@action(detail=True, methods=["post"]) @action(detail=True, methods=["post"])

View file

@ -3,11 +3,11 @@ from base64 import b64decode
from binascii import Error from binascii import Error
from typing import Any, Optional, Union from typing import Any, Optional, Union
from drf_spectacular.authentication import OpenApiAuthenticationExtension
from rest_framework.authentication import BaseAuthentication, get_authorization_header from rest_framework.authentication import BaseAuthentication, get_authorization_header
from rest_framework.exceptions import AuthenticationFailed from rest_framework.exceptions import AuthenticationFailed
from rest_framework.request import Request from rest_framework.request import Request
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from drf_spectacular.authentication import OpenApiAuthenticationExtension
from authentik.core.models import Token, TokenIntents, User from authentik.core.models import Token, TokenIntents, User
@ -60,11 +60,11 @@ class AuthentikTokenAuthentication(BaseAuthentication):
class TokenSchema(OpenApiAuthenticationExtension): class TokenSchema(OpenApiAuthenticationExtension):
target_class = AuthentikTokenAuthentication target_class = AuthentikTokenAuthentication
name = 'authentik' name = "authentik"
def get_security_definition(self, auto_schema): def get_security_definition(self, auto_schema):
return { return {
'type': 'apiKey', "type": "apiKey",
'in': 'header', "in": "header",
'name': 'Authorization', "name": "Authorization",
} }

View file

@ -6,7 +6,7 @@ from django.db.models import QuerySet
from django.http.response import HttpResponseBadRequest from django.http.response import HttpResponseBadRequest
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import SerializerMethodField from rest_framework.fields import SerializerMethodField
from rest_framework.parsers import MultiPartParser from rest_framework.parsers import MultiPartParser
@ -94,8 +94,8 @@ class ApplicationViewSet(ModelViewSet):
@extend_schema( @extend_schema(
responses={ responses={
204: "Access granted", 204: OpenApiResponse(description="Access granted"),
403: "Access denied", 403: OpenApiResponse(description="Access denied"),
} }
) )
@action(detail=True, methods=["GET"]) @action(detail=True, methods=["GET"])
@ -161,7 +161,10 @@ class ApplicationViewSet(ModelViewSet):
required=True, required=True,
) )
], ],
responses={200: "Success", 400: "Bad request"}, responses={
200: OpenApiResponse(description="Success"),
400: OpenApiResponse(description="Bad request"),
},
) )
@action( @action(
detail=True, detail=True,

View file

@ -2,7 +2,7 @@
from json import dumps from json import dumps
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from guardian.shortcuts import get_objects_for_user from guardian.shortcuts import get_objects_for_user
from rest_framework import mixins from rest_framework import mixins
from rest_framework.decorators import action from rest_framework.decorators import action
@ -102,7 +102,10 @@ class PropertyMappingViewSet(
@permission_required("authentik_core.view_propertymapping") @permission_required("authentik_core.view_propertymapping")
@extend_schema( @extend_schema(
request=PolicyTestSerializer(), request=PolicyTestSerializer(),
responses={200: PropertyMappingTestResultSerializer, 400: "Invalid parameters"}, responses={
200: PropertyMappingTestResultSerializer,
400: OpenApiResponse(description="Invalid parameters"),
},
parameters=[ parameters=[
OpenApiParameter( OpenApiParameter(
name="format_result", name="format_result",

View file

@ -22,7 +22,7 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer):
component = SerializerMethodField() component = SerializerMethodField()
def get_component(self, obj: Provider): # pragma: no cover def get_component(self, obj: Provider) -> str: # pragma: no cover
"""Get object component so that we know how to edit the object""" """Get object component so that we know how to edit the object"""
# pyright: reportGeneralTypeIssues=false # pyright: reportGeneralTypeIssues=false
if obj.__class__ == Provider: if obj.__class__ == Provider:

View file

@ -24,7 +24,7 @@ class SourceSerializer(ModelSerializer, MetaNameSerializer):
component = SerializerMethodField() component = SerializerMethodField()
def get_component(self, obj: Source): def get_component(self, obj: Source) -> str:
"""Get object component so that we know how to edit the object""" """Get object component so that we know how to edit the object"""
# pyright: reportGeneralTypeIssues=false # pyright: reportGeneralTypeIssues=false
if obj.__class__ == Source: if obj.__class__ == Source:

View file

@ -1,6 +1,6 @@
"""Tokens API Viewset""" """Tokens API Viewset"""
from django.http.response import Http404 from django.http.response import Http404
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import CharField from rest_framework.fields import CharField
from rest_framework.request import Request from rest_framework.request import Request
@ -70,7 +70,7 @@ class TokenViewSet(ModelViewSet):
@extend_schema( @extend_schema(
responses={ responses={
200: TokenViewSerializer(many=False), 200: TokenViewSerializer(many=False),
404: "Token not found or expired", 404: OpenApiResponse(description="Token not found or expired"),
} }
) )
@action(detail=True, pagination_class=None, filter_backends=[]) @action(detail=True, pagination_class=None, filter_backends=[])

View file

@ -7,7 +7,7 @@ from django.urls import reverse_lazy
from django.utils.http import urlencode from django.utils.http import urlencode
from django_filters.filters import BooleanFilter, CharFilter from django_filters.filters import BooleanFilter, CharFilter
from django_filters.filterset import FilterSet from django_filters.filterset import FilterSet
from drf_spectacular.utils import extend_schema, extend_schema_field from drf_spectacular.utils import OpenApiResponse, extend_schema, extend_schema_field
from guardian.utils import get_anonymous_user from guardian.utils import get_anonymous_user
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import CharField, JSONField, SerializerMethodField from rest_framework.fields import CharField, JSONField, SerializerMethodField
@ -170,7 +170,10 @@ class UserViewSet(ModelViewSet):
@permission_required("authentik_core.reset_user_password") @permission_required("authentik_core.reset_user_password")
@extend_schema( @extend_schema(
responses={"200": LinkSerializer(many=False), "404": "No recovery flow found."}, responses={
"200": LinkSerializer(many=False),
"404": OpenApiResponse(description="No recovery flow found."),
},
) )
@action(detail=True, pagination_class=None, filter_backends=[]) @action(detail=True, pagination_class=None, filter_backends=[])
# pylint: disable=invalid-name, unused-argument # pylint: disable=invalid-name, unused-argument

View file

@ -6,7 +6,7 @@ from cryptography.x509 import load_pem_x509_certificate
from django.http.response import HttpResponse from django.http.response import HttpResponse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import ( from rest_framework.fields import (
CharField, CharField,
@ -127,7 +127,10 @@ class CertificateKeyPairViewSet(ModelViewSet):
@permission_required(None, ["authentik_crypto.add_certificatekeypair"]) @permission_required(None, ["authentik_crypto.add_certificatekeypair"])
@extend_schema( @extend_schema(
request=CertificateGenerationSerializer(), request=CertificateGenerationSerializer(),
responses={200: CertificateKeyPairSerializer, 400: "Bad request"}, responses={
200: CertificateKeyPairSerializer,
400: OpenApiResponse(description="Bad request"),
},
) )
@action(detail=False, methods=["POST"]) @action(detail=False, methods=["POST"])
def generate(self, request: Request) -> Response: def generate(self, request: Request) -> Response:

View file

@ -1,8 +1,8 @@
"""Events API Views""" """Events API Views"""
from drf_spectacular.types import OpenApiTypes
import django_filters import django_filters
from django.db.models.aggregates import Count from django.db.models.aggregates import Count
from django.db.models.fields.json import KeyTextTransform from django.db.models.fields.json import KeyTextTransform
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, extend_schema
from guardian.shortcuts import get_objects_for_user from guardian.shortcuts import get_objects_for_user
from rest_framework.decorators import action from rest_framework.decorators import action
@ -116,7 +116,7 @@ class EventViewSet(ReadOnlyModelViewSet):
location=OpenApiParameter.QUERY, location=OpenApiParameter.QUERY,
required=False, required=False,
) )
] ],
) )
@action(detail=False, methods=["GET"]) @action(detail=False, methods=["GET"])
def top_per_user(self, request: Request): def top_per_user(self, request: Request):

View file

@ -1,6 +1,6 @@
"""NotificationTransport API Views""" """NotificationTransport API Views"""
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
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.request import Request
@ -23,7 +23,7 @@ class NotificationTransportSerializer(ModelSerializer):
mode_verbose = SerializerMethodField() mode_verbose = SerializerMethodField()
def get_mode_verbose(self, instance: NotificationTransport): def get_mode_verbose(self, instance: NotificationTransport) -> str:
"""Return selected mode with a UI Label""" """Return selected mode with a UI Label"""
return TransportMode(instance.mode).label return TransportMode(instance.mode).label
@ -62,7 +62,7 @@ class NotificationTransportViewSet(ModelViewSet):
@extend_schema( @extend_schema(
responses={ responses={
200: NotificationTransportTestSerializer(many=False), 200: NotificationTransportTestSerializer(many=False),
503: "Failed to test transport", 500: OpenApiResponse(description="Failed to test transport"),
}, },
request=OpenApiTypes.NONE, request=OpenApiTypes.NONE,
) )
@ -84,4 +84,4 @@ class NotificationTransportViewSet(ModelViewSet):
response.is_valid() response.is_valid()
return Response(response.data) return Response(response.data)
except NotificationTransportError as exc: except NotificationTransportError as exc:
return Response(str(exc.__cause__ or None), status=503) return Response(str(exc.__cause__ or None), status=500)

View file

@ -7,12 +7,7 @@ from django.http.response import HttpResponseBadRequest, JsonResponse
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import ( from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
OpenApiParameter,
OpenApiResponse,
OpenApiSchemaBase,
extend_schema,
)
from guardian.shortcuts import get_objects_for_user from guardian.shortcuts import get_objects_for_user
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.parsers import MultiPartParser from rest_framework.parsers import MultiPartParser
@ -46,7 +41,7 @@ class FlowSerializer(ModelSerializer):
cache_count = SerializerMethodField() cache_count = SerializerMethodField()
def get_cache_count(self, flow: Flow): def get_cache_count(self, flow: Flow) -> int:
"""Get count of cached flows""" """Get count of cached flows"""
return len(cache.keys(f"{cache_key(flow)}*")) return len(cache.keys(f"{cache_key(flow)}*"))
@ -111,7 +106,10 @@ class FlowViewSet(ModelViewSet):
@permission_required(None, ["authentik_flows.clear_flow_cache"]) @permission_required(None, ["authentik_flows.clear_flow_cache"])
@extend_schema( @extend_schema(
request=OpenApiTypes.NONE, request=OpenApiTypes.NONE,
responses={204: "Successfully cleared cache", 400: "Bad request"}, responses={
204: OpenApiResponse(description="Successfully cleared cache"),
400: OpenApiResponse(description="Bad request"),
},
) )
@action(detail=False, methods=["POST"]) @action(detail=False, methods=["POST"])
def cache_clear(self, request: Request) -> Response: def cache_clear(self, request: Request) -> Response:
@ -148,7 +146,10 @@ class FlowViewSet(ModelViewSet):
required=True, required=True,
) )
], ],
responses={204: "Successfully imported flow", 400: "Bad request"}, responses={
204: OpenApiResponse(description="Successfully imported flow"),
400: OpenApiResponse(description="Bad request"),
},
) )
@action(detail=False, methods=["POST"], parser_classes=(MultiPartParser,)) @action(detail=False, methods=["POST"], parser_classes=(MultiPartParser,))
def import_flow(self, request: Request) -> Response: def import_flow(self, request: Request) -> Response:
@ -178,9 +179,7 @@ class FlowViewSet(ModelViewSet):
) )
@extend_schema( @extend_schema(
responses={ responses={
"200": OpenApiResponse( "200": OpenApiResponse(response=OpenApiTypes.BINARY),
response=OpenApiParameter("File Attachment", type=OpenApiTypes.BINARY)
),
}, },
) )
@action(detail=True, pagination_class=None, filter_backends=[]) @action(detail=True, pagination_class=None, filter_backends=[])
@ -274,7 +273,10 @@ class FlowViewSet(ModelViewSet):
required=True, required=True,
) )
], ],
responses={200: "Success", 400: "Bad request"}, responses={
200: OpenApiResponse(description="Success"),
400: OpenApiResponse(description="Bad request"),
},
) )
@action( @action(
detail=True, detail=True,
@ -295,7 +297,10 @@ class FlowViewSet(ModelViewSet):
return Response({}) return Response({})
@extend_schema( @extend_schema(
responses={200: LinkSerializer(many=False), 400: "Flow not applicable"}, responses={
200: LinkSerializer(many=False),
400: OpenApiResponse(description="Flow not applicable"),
},
) )
@action(detail=True, pagination_class=None, filter_backends=[]) @action(detail=True, pagination_class=None, filter_backends=[])
# pylint: disable=unused-argument # pylint: disable=unused-argument

View file

@ -11,7 +11,7 @@ from django.utils.decorators import method_decorator
from django.views.decorators.clickjacking import xframe_options_sameorigin from django.views.decorators.clickjacking import xframe_options_sameorigin
from django.views.generic import View from django.views.generic import View
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
from rest_framework.views import APIView from rest_framework.views import APIView
from sentry_sdk import capture_exception from sentry_sdk import capture_exception
@ -128,7 +128,9 @@ class FlowExecutorView(APIView):
@extend_schema( @extend_schema(
responses={ responses={
200: Challenge(), 200: Challenge(),
404: "No Token found", # This error can be raised by the email stage 404: OpenApiResponse(
description="No Token found"
), # This error can be raised by the email stage
}, },
request=OpenApiTypes.NONE, request=OpenApiTypes.NONE,
parameters=[ parameters=[

View file

@ -1,7 +1,7 @@
"""policy API Views""" """policy API Views"""
from django.core.cache import cache from django.core.cache import cache
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import OpenApiResponse, extend_schema
from guardian.shortcuts import get_objects_for_user from guardian.shortcuts import get_objects_for_user
from rest_framework import mixins from rest_framework import mixins
from rest_framework.decorators import action from rest_framework.decorators import action
@ -124,7 +124,10 @@ class PolicyViewSet(
@permission_required(None, ["authentik_policies.clear_policy_cache"]) @permission_required(None, ["authentik_policies.clear_policy_cache"])
@extend_schema( @extend_schema(
request=OpenApiTypes.NONE, request=OpenApiTypes.NONE,
responses={204: "Successfully cleared cache", 400: "Bad request"}, responses={
204: OpenApiResponse(description="Successfully cleared cache"),
400: OpenApiResponse(description="Bad request"),
},
) )
@action(detail=False, methods=["POST"]) @action(detail=False, methods=["POST"])
def cache_clear(self, request: Request) -> Response: def cache_clear(self, request: Request) -> Response:
@ -140,7 +143,10 @@ class PolicyViewSet(
@permission_required("authentik_policies.view_policy") @permission_required("authentik_policies.view_policy")
@extend_schema( @extend_schema(
request=PolicyTestSerializer(), request=PolicyTestSerializer(),
responses={200: PolicyTestResultSerializer(), 400: "Invalid parameters"}, responses={
200: PolicyTestResultSerializer(),
400: OpenApiResponse(description="Invalid parameters"),
},
) )
@action(detail=True, pagination_class=None, filter_backends=[], methods=["POST"]) @action(detail=True, pagination_class=None, filter_backends=[], methods=["POST"])
# pylint: disable=unused-argument, invalid-name # pylint: disable=unused-argument, invalid-name

View file

@ -2,7 +2,7 @@
from django.db.models.base import Model from django.db.models.base import Model
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import OpenApiResponse, extend_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
@ -61,9 +61,6 @@ class OAuth2ProviderSetupURLs(PassiveSerializer):
provider_info = ReadOnlyField() provider_info = ReadOnlyField()
logout = ReadOnlyField() logout = ReadOnlyField()
class Meta:
model = Model
class OAuth2ProviderViewSet(ModelViewSet): class OAuth2ProviderViewSet(ModelViewSet):
"""OAuth2Provider Viewset""" """OAuth2Provider Viewset"""
@ -74,7 +71,7 @@ class OAuth2ProviderViewSet(ModelViewSet):
@extend_schema( @extend_schema(
responses={ responses={
200: OAuth2ProviderSetupURLs, 200: OAuth2ProviderSetupURLs,
404: "Provider has no application assigned", 404: OpenApiResponse(description="Provider has no application assigned"),
} }
) )
@action(methods=["GET"], detail=True) @action(methods=["GET"], detail=True)

View file

@ -6,7 +6,7 @@ from django.http.response import HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema, extend_schema_field
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import CharField, FileField, ReadOnlyField from rest_framework.fields import CharField, FileField, ReadOnlyField
from rest_framework.parsers import MultiPartParser from rest_framework.parsers import MultiPartParser
@ -83,7 +83,7 @@ class SAMLProviderViewSet(ModelViewSet):
@extend_schema( @extend_schema(
responses={ responses={
200: SAMLMetadataSerializer(many=False), 200: SAMLMetadataSerializer(many=False),
404: "Provider has no application assigned", 404: OpenApiResponse(description="Provider has no application assigned"),
}, },
parameters=[ parameters=[
OpenApiParameter( OpenApiParameter(
@ -120,7 +120,10 @@ class SAMLProviderViewSet(ModelViewSet):
) )
@extend_schema( @extend_schema(
request=SAMLProviderImportSerializer(), request=SAMLProviderImportSerializer(),
responses={204: "Successfully imported provider", 400: "Bad request"}, responses={
204: OpenApiResponse(description="Successfully imported provider"),
400: OpenApiResponse(description="Bad request"),
},
) )
@action(detail=False, methods=["POST"], parser_classes=(MultiPartParser,)) @action(detail=False, methods=["POST"], parser_classes=(MultiPartParser,))
def import_metadata(self, request: Request) -> Response: def import_metadata(self, request: Request) -> Response:

View file

@ -151,6 +151,9 @@ SPECTACULAR_SETTINGS = {
"name": "GNU GPLv3", "name": "GNU GPLv3",
"url": "https://github.com/goauthentik/authentik/blob/master/LICENSE", "url": "https://github.com/goauthentik/authentik/blob/master/LICENSE",
}, },
"ENUM_NAME_OVERRIDES": {
"ChallengeChoices": "authentik.flows.challenge.ChallengeTypes"
},
} }
REST_FRAMEWORK = { REST_FRAMEWORK = {

View file

@ -1,7 +1,7 @@
"""Source API Views""" """Source API Views"""
from django.http.response import Http404 from django.http.response import Http404
from django.utils.text import slugify from django.utils.text import slugify
from drf_spectacular.utils import extend_schema from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.request import Request from rest_framework.request import Request
from rest_framework.response import Response from rest_framework.response import Response
@ -48,7 +48,12 @@ class LDAPSourceViewSet(ModelViewSet):
serializer_class = LDAPSourceSerializer serializer_class = LDAPSourceSerializer
lookup_field = "slug" lookup_field = "slug"
@extend_schema(responses={200: TaskSerializer(many=False), 404: "Task not found"}) @extend_schema(
responses={
200: TaskSerializer(many=False),
404: OpenApiResponse(description="Task not found"),
}
)
@action(methods=["GET"], detail=True) @action(methods=["GET"], detail=True)
# pylint: disable=unused-argument # pylint: disable=unused-argument
def sync_status(self, request: Request, slug: str) -> Response: def sync_status(self, request: Request, slug: str) -> Response:

View file

@ -1,7 +1,7 @@
"""Plex Source Serializer""" """Plex Source Serializer"""
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
from rest_framework.fields import CharField from rest_framework.fields import CharField
@ -54,8 +54,8 @@ class PlexSourceViewSet(ModelViewSet):
request=PlexTokenRedeemSerializer(), request=PlexTokenRedeemSerializer(),
responses={ responses={
200: RedirectChallenge(), 200: RedirectChallenge(),
400: "Token not found", 400: OpenApiResponse(description="Token not found"),
403: "Access denied", 403: OpenApiResponse(description="Access denied"),
}, },
parameters=[ parameters=[
OpenApiParameter( OpenApiParameter(

View file

@ -34,7 +34,6 @@ class StaticDeviceSerializer(ModelSerializer):
model = StaticDevice model = StaticDevice
fields = ["name", "token_set", "pk"] fields = ["name", "token_set", "pk"]
depth = 2
class StaticDeviceViewSet(ModelViewSet): class StaticDeviceViewSet(ModelViewSet):

View file

@ -105,6 +105,18 @@ paths:
required: true required: true
tags: tags:
- admin - admin
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TaskRequest'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/TaskRequest'
multipart/form-data:
schema:
$ref: '#/components/schemas/TaskRequest'
required: true
security: security:
- authentik: [] - authentik: []
- cookieAuth: [] - cookieAuth: []
@ -21190,6 +21202,28 @@ components:
- task_description - task_description
- task_finish_timestamp - task_finish_timestamp
- task_name - task_name
TaskRequest:
type: object
description: Serialize TaskInfo and TaskResult
properties:
task_name:
type: string
task_description:
type: string
task_finish_timestamp:
type: string
format: date-time
status:
$ref: '#/components/schemas/StatusEnum'
messages:
type: array
items: {}
required:
- messages
- status
- task_description
- task_finish_timestamp
- task_name
Token: Token:
type: object type: object
description: Token Serializer description: Token Serializer