From a76cbf8b707d0fadbc45763ac6171318f1b31348 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 19 Feb 2021 19:14:16 +0100 Subject: [PATCH] flows: separate flows api into smaller files --- authentik/api/v2/urls.py | 4 +- authentik/flows/api/__init__.py | 0 authentik/flows/api/bindings.py | 35 ++++++++ authentik/flows/{api.py => api/flows.py} | 87 +------------------ authentik/flows/api/stages.py | 58 +++++++++++++ authentik/flows/models.py | 6 +- authentik/flows/tests/test_api.py | 2 +- authentik/stages/authenticator_static/api.py | 2 +- authentik/stages/authenticator_totp/api.py | 2 +- .../stages/authenticator_validate/api.py | 2 +- .../stages/authenticator_webauthn/api.py | 2 +- authentik/stages/captcha/api.py | 2 +- authentik/stages/consent/api.py | 2 +- authentik/stages/dummy/api.py | 2 +- authentik/stages/email/api.py | 2 +- authentik/stages/identification/api.py | 2 +- authentik/stages/invitation/api.py | 2 +- authentik/stages/password/api.py | 2 +- authentik/stages/prompt/api.py | 2 +- authentik/stages/user_delete/api.py | 2 +- authentik/stages/user_login/api.py | 2 +- authentik/stages/user_logout/api.py | 2 +- authentik/stages/user_write/api.py | 2 +- 23 files changed, 120 insertions(+), 104 deletions(-) create mode 100644 authentik/flows/api/__init__.py create mode 100644 authentik/flows/api/bindings.py rename authentik/flows/{api.py => api/flows.py} (66%) create mode 100644 authentik/flows/api/stages.py diff --git a/authentik/api/v2/urls.py b/authentik/api/v2/urls.py index 87c13e86a..20323b7d4 100644 --- a/authentik/api/v2/urls.py +++ b/authentik/api/v2/urls.py @@ -23,7 +23,9 @@ from authentik.events.api.event import EventViewSet from authentik.events.api.notification import NotificationViewSet from authentik.events.api.notification_rule import NotificationRuleViewSet from authentik.events.api.notification_transport import NotificationTransportViewSet -from authentik.flows.api import FlowStageBindingViewSet, FlowViewSet, StageViewSet +from authentik.flows.api.bindings import FlowStageBindingViewSet +from authentik.flows.api.flows import FlowViewSet +from authentik.flows.api.stages import StageViewSet from authentik.outposts.api.outpost_service_connections import ( DockerServiceConnectionViewSet, KubernetesServiceConnectionViewSet, diff --git a/authentik/flows/api/__init__.py b/authentik/flows/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/authentik/flows/api/bindings.py b/authentik/flows/api/bindings.py new file mode 100644 index 000000000..32d127ffb --- /dev/null +++ b/authentik/flows/api/bindings.py @@ -0,0 +1,35 @@ +"""Flow Binding API Views""" +from rest_framework.serializers import ModelSerializer +from rest_framework.viewsets import ModelViewSet + +from authentik.flows.api.stages import StageSerializer +from authentik.flows.models import FlowStageBinding + + +class FlowStageBindingSerializer(ModelSerializer): + """FlowStageBinding Serializer""" + + stage_obj = StageSerializer(read_only=True, source="stage") + + class Meta: + + model = FlowStageBinding + fields = [ + "pk", + "policybindingmodel_ptr_id", + "target", + "stage", + "stage_obj", + "evaluate_on_plan", + "re_evaluate_policies", + "order", + "policies", + ] + + +class FlowStageBindingViewSet(ModelViewSet): + """FlowStageBinding Viewset""" + + queryset = FlowStageBinding.objects.all() + serializer_class = FlowStageBindingSerializer + filterset_fields = "__all__" diff --git a/authentik/flows/api.py b/authentik/flows/api/flows.py similarity index 66% rename from authentik/flows/api.py rename to authentik/flows/api/flows.py index 7a88df19e..5979ce12f 100644 --- a/authentik/flows/api.py +++ b/authentik/flows/api/flows.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from django.core.cache import cache from django.db.models import Model -from django.shortcuts import get_object_or_404, reverse +from django.shortcuts import get_object_or_404 from drf_yasg2.utils import swagger_auto_schema from guardian.shortcuts import get_objects_for_user from rest_framework.decorators import action @@ -15,17 +15,11 @@ from rest_framework.serializers import ( Serializer, SerializerMethodField, ) -from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet +from rest_framework.viewsets import ModelViewSet -from authentik.core.api.utils import ( - CacheSerializer, - MetaNameSerializer, - TypeCreateSerializer, -) -from authentik.flows.models import Flow, FlowStageBinding, Stage +from authentik.core.api.utils import CacheSerializer +from authentik.flows.models import Flow from authentik.flows.planner import cache_key -from authentik.lib.templatetags.authentik_utils import verbose_name -from authentik.lib.utils.reflection import all_subclasses class FlowSerializer(ModelSerializer): @@ -164,76 +158,3 @@ class FlowViewSet(ModelViewSet): ) diagram = "\n".join([str(x) for x in header + body + footer]) return Response({"diagram": diagram}) - - -class StageSerializer(ModelSerializer, MetaNameSerializer): - """Stage Serializer""" - - object_type = SerializerMethodField() - - def get_object_type(self, obj): - """Get object type so that we know which API Endpoint to use to get the full object""" - return obj._meta.object_name.lower().replace("stage", "") - - class Meta: - - model = Stage - fields = ["pk", "name", "object_type", "verbose_name", "verbose_name_plural"] - - -class StageViewSet(ReadOnlyModelViewSet): - """Stage Viewset""" - - queryset = Stage.objects.all() - serializer_class = StageSerializer - search_fields = ["name"] - filterset_fields = ["name"] - - def get_queryset(self): - return Stage.objects.select_subclasses() - - @swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)}) - @action(detail=False) - def types(self, request: Request) -> Response: - """Get all creatable stage types""" - data = [] - for subclass in all_subclasses(self.queryset.model, False): - data.append( - { - "name": verbose_name(subclass), - "description": subclass.__doc__, - "link": reverse("authentik_admin:stage-create") - + f"?type={subclass.__name__}", - } - ) - data = sorted(data, key=lambda x: x["name"]) - return Response(TypeCreateSerializer(data, many=True).data) - - -class FlowStageBindingSerializer(ModelSerializer): - """FlowStageBinding Serializer""" - - stage_obj = StageSerializer(read_only=True, source="stage") - - class Meta: - - model = FlowStageBinding - fields = [ - "pk", - "policybindingmodel_ptr_id", - "target", - "stage", - "stage_obj", - "evaluate_on_plan", - "re_evaluate_policies", - "order", - "policies", - ] - - -class FlowStageBindingViewSet(ModelViewSet): - """FlowStageBinding Viewset""" - - queryset = FlowStageBinding.objects.all() - serializer_class = FlowStageBindingSerializer - filterset_fields = "__all__" diff --git a/authentik/flows/api/stages.py b/authentik/flows/api/stages.py new file mode 100644 index 000000000..000294cf7 --- /dev/null +++ b/authentik/flows/api/stages.py @@ -0,0 +1,58 @@ +"""Flow Stage API Views""" +from django.shortcuts import reverse +from drf_yasg2.utils import swagger_auto_schema +from rest_framework.decorators import action +from rest_framework.request import Request +from rest_framework.response import Response +from rest_framework.serializers import ModelSerializer, SerializerMethodField +from rest_framework.viewsets import ReadOnlyModelViewSet + +from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer +from authentik.flows.models import Stage +from authentik.flows.planner import cache_key +from authentik.lib.templatetags.authentik_utils import verbose_name +from authentik.lib.utils.reflection import all_subclasses + + +class StageSerializer(ModelSerializer, MetaNameSerializer): + """Stage Serializer""" + + object_type = SerializerMethodField() + + def get_object_type(self, obj: Stage) -> str: + """Get object type so that we know which API Endpoint to use to get the full object""" + return obj._meta.object_name.lower().replace("stage", "") + + class Meta: + + model = Stage + fields = ["pk", "name", "object_type", "verbose_name", "verbose_name_plural"] + + +class StageViewSet(ReadOnlyModelViewSet): + """Stage Viewset""" + + queryset = Stage.objects.all() + serializer_class = StageSerializer + search_fields = ["name"] + filterset_fields = ["name"] + + def get_queryset(self): + return Stage.objects.select_subclasses() + + @swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)}) + @action(detail=False) + def types(self, request: Request) -> Response: + """Get all creatable stage types""" + data = [] + for subclass in all_subclasses(self.queryset.model, False): + data.append( + { + "name": verbose_name(subclass), + "description": subclass.__doc__, + "link": reverse("authentik_admin:stage-create") + + f"?type={subclass.__name__}", + } + ) + data = sorted(data, key=lambda x: x["name"]) + return Response(TypeCreateSerializer(data, many=True).data) diff --git a/authentik/flows/models.py b/authentik/flows/models.py index 63702ac46..3a0acbe08 100644 --- a/authentik/flows/models.py +++ b/authentik/flows/models.py @@ -118,7 +118,7 @@ class Flow(SerializerModel, PolicyBindingModel): @property def serializer(self) -> BaseSerializer: - from authentik.flows.api import FlowSerializer + from authentik.flows.api.flows import FlowSerializer return FlowSerializer @@ -189,12 +189,12 @@ class FlowStageBinding(SerializerModel, PolicyBindingModel): @property def serializer(self) -> BaseSerializer: - from authentik.flows.api import FlowStageBindingSerializer + from authentik.flows.api.bindings import FlowStageBindingSerializer return FlowStageBindingSerializer def __str__(self) -> str: - return f"{self.target} #{self.order} -> {self.stage}" + return f"{self.target} #{self.order}" class Meta: diff --git a/authentik/flows/tests/test_api.py b/authentik/flows/tests/test_api.py index 4aa1400aa..f242b95e8 100644 --- a/authentik/flows/tests/test_api.py +++ b/authentik/flows/tests/test_api.py @@ -3,7 +3,7 @@ from django.shortcuts import reverse from rest_framework.test import APITestCase from authentik.core.models import User -from authentik.flows.api import StageSerializer, StageViewSet +from authentik.flows.api.stages import StageSerializer, StageViewSet from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, Stage from authentik.policies.dummy.models import DummyPolicy from authentik.policies.models import PolicyBinding diff --git a/authentik/stages/authenticator_static/api.py b/authentik/stages/authenticator_static/api.py index 0663863ca..8ac6fc8c6 100644 --- a/authentik/stages/authenticator_static/api.py +++ b/authentik/stages/authenticator_static/api.py @@ -1,7 +1,7 @@ """AuthenticatorStaticStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.authenticator_static.models import AuthenticatorStaticStage diff --git a/authentik/stages/authenticator_totp/api.py b/authentik/stages/authenticator_totp/api.py index 6a8dab0d8..b7e40fc6c 100644 --- a/authentik/stages/authenticator_totp/api.py +++ b/authentik/stages/authenticator_totp/api.py @@ -1,7 +1,7 @@ """AuthenticatorTOTPStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage diff --git a/authentik/stages/authenticator_validate/api.py b/authentik/stages/authenticator_validate/api.py index 54bfa25b0..23a0738dd 100644 --- a/authentik/stages/authenticator_validate/api.py +++ b/authentik/stages/authenticator_validate/api.py @@ -1,7 +1,7 @@ """AuthenticatorValidateStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage diff --git a/authentik/stages/authenticator_webauthn/api.py b/authentik/stages/authenticator_webauthn/api.py index d3ecaed79..6fcebd119 100644 --- a/authentik/stages/authenticator_webauthn/api.py +++ b/authentik/stages/authenticator_webauthn/api.py @@ -1,7 +1,7 @@ """AuthenticateWebAuthnStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage diff --git a/authentik/stages/captcha/api.py b/authentik/stages/captcha/api.py index a60103666..6cd61185f 100644 --- a/authentik/stages/captcha/api.py +++ b/authentik/stages/captcha/api.py @@ -1,7 +1,7 @@ """CaptchaStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.captcha.models import CaptchaStage diff --git a/authentik/stages/consent/api.py b/authentik/stages/consent/api.py index 3e106c937..926c3d3b8 100644 --- a/authentik/stages/consent/api.py +++ b/authentik/stages/consent/api.py @@ -1,7 +1,7 @@ """ConsentStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.consent.models import ConsentStage diff --git a/authentik/stages/dummy/api.py b/authentik/stages/dummy/api.py index 3b677bbac..02e1c9463 100644 --- a/authentik/stages/dummy/api.py +++ b/authentik/stages/dummy/api.py @@ -1,7 +1,7 @@ """DummyStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.dummy.models import DummyStage diff --git a/authentik/stages/email/api.py b/authentik/stages/email/api.py index ffe5d6089..2a41c0f82 100644 --- a/authentik/stages/email/api.py +++ b/authentik/stages/email/api.py @@ -1,7 +1,7 @@ """EmailStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.email.models import EmailStage, get_template_choices diff --git a/authentik/stages/identification/api.py b/authentik/stages/identification/api.py index aba1629ec..677467b70 100644 --- a/authentik/stages/identification/api.py +++ b/authentik/stages/identification/api.py @@ -1,7 +1,7 @@ """Identification Stage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.identification.models import IdentificationStage diff --git a/authentik/stages/invitation/api.py b/authentik/stages/invitation/api.py index e8aadea19..a96363f38 100644 --- a/authentik/stages/invitation/api.py +++ b/authentik/stages/invitation/api.py @@ -2,7 +2,7 @@ from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.invitation.models import Invitation, InvitationStage diff --git a/authentik/stages/password/api.py b/authentik/stages/password/api.py index e5ca7dc22..48499663e 100644 --- a/authentik/stages/password/api.py +++ b/authentik/stages/password/api.py @@ -1,7 +1,7 @@ """PasswordStage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.password.models import PasswordStage diff --git a/authentik/stages/prompt/api.py b/authentik/stages/prompt/api.py index a04f021a8..b6bdbf30b 100644 --- a/authentik/stages/prompt/api.py +++ b/authentik/stages/prompt/api.py @@ -3,7 +3,7 @@ from rest_framework.serializers import CharField, ModelSerializer from rest_framework.validators import UniqueValidator from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.prompt.models import Prompt, PromptStage diff --git a/authentik/stages/user_delete/api.py b/authentik/stages/user_delete/api.py index 0f60f1479..195fdcca7 100644 --- a/authentik/stages/user_delete/api.py +++ b/authentik/stages/user_delete/api.py @@ -1,7 +1,7 @@ """User Delete Stage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.user_delete.models import UserDeleteStage diff --git a/authentik/stages/user_login/api.py b/authentik/stages/user_login/api.py index 406267fb0..55ff8a00c 100644 --- a/authentik/stages/user_login/api.py +++ b/authentik/stages/user_login/api.py @@ -1,7 +1,7 @@ """Login Stage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.user_login.models import UserLoginStage diff --git a/authentik/stages/user_logout/api.py b/authentik/stages/user_logout/api.py index 8d67c7d99..89017e3b9 100644 --- a/authentik/stages/user_logout/api.py +++ b/authentik/stages/user_logout/api.py @@ -1,7 +1,7 @@ """Logout Stage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.user_logout.models import UserLogoutStage diff --git a/authentik/stages/user_write/api.py b/authentik/stages/user_write/api.py index 121285eb6..f1dadc769 100644 --- a/authentik/stages/user_write/api.py +++ b/authentik/stages/user_write/api.py @@ -1,7 +1,7 @@ """User Write Stage API Views""" from rest_framework.viewsets import ModelViewSet -from authentik.flows.api import StageSerializer +from authentik.flows.api.stages import StageSerializer from authentik.stages.user_write.models import UserWriteStage