ensure all viewsets have filter and search and add tests (#2946)

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens L 2022-05-24 22:01:18 +02:00 committed by Jens Langhammer
parent ab1840dd66
commit b8fdda50ec
46 changed files with 98 additions and 0 deletions

View File

@ -0,0 +1,29 @@
"""authentik API Modelviewset tests"""
from typing import Callable
from django.test import TestCase
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from authentik.api.v3.urls import router
class TestModelViewSets(TestCase):
"""Test Viewset"""
def viewset_tester_factory(test_viewset: type[ModelViewSet]) -> Callable:
"""Test Viewset"""
def tester(self: TestModelViewSets):
self.assertIsNotNone(getattr(test_viewset, "search_fields", None))
filterset_class = getattr(test_viewset, "filterset_class", None)
if not filterset_class:
self.assertIsNotNone(getattr(test_viewset, "filterset_fields", None))
return tester
for _, viewset, _ in router.registry:
if not issubclass(viewset, (ModelViewSet, ReadOnlyModelViewSet)):
continue
setattr(TestModelViewSets, f"test_viewset_{viewset.__name__}", viewset_tester_factory(viewset))

View File

@ -89,6 +89,7 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
"group",
]
lookup_field = "slug"
filterset_fields = ["name", "slug"]
ordering = ["name"]
def _filter_queryset_for_list(self, queryset: QuerySet) -> QuerySet:

View File

@ -66,6 +66,7 @@ class SourceViewSet(
queryset = Source.objects.none()
serializer_class = SourceSerializer
lookup_field = "slug"
search_fields = ["slug", "name"]
def get_queryset(self): # pragma: no cover
return Source.objects.select_subclasses()

View File

@ -26,3 +26,4 @@ class NotificationWebhookMappingViewSet(UsedByMixin, ModelViewSet):
serializer_class = NotificationWebhookMappingSerializer
filterset_fields = ["name"]
ordering = ["name"]
search_fields = ["name"]

View File

@ -32,3 +32,4 @@ class NotificationRuleViewSet(UsedByMixin, ModelViewSet):
serializer_class = NotificationRuleSerializer
filterset_fields = ["name", "severity", "group__name"]
ordering = ["name"]
search_fields = ["name", "group__name"]

View File

@ -68,6 +68,7 @@ class NotificationTransportViewSet(UsedByMixin, ModelViewSet):
queryset = NotificationTransport.objects.all()
serializer_class = NotificationTransportSerializer
filterset_fields = ["name", "mode", "webhook_url", "send_once"]
search_fields = ["name", "mode", "webhook_url"]
ordering = ["name"]
@permission_required("authentik_events.change_notificationtransport")

View File

@ -35,3 +35,4 @@ class FlowStageBindingViewSet(UsedByMixin, ModelViewSet):
queryset = FlowStageBinding.objects.all()
serializer_class = FlowStageBindingSerializer
filterset_fields = "__all__"
search_fields = ["stage__name"]

View File

@ -118,6 +118,7 @@ class DockerServiceConnectionViewSet(UsedByMixin, ModelViewSet):
serializer_class = DockerServiceConnectionSerializer
filterset_fields = ["name", "local", "url", "tls_verification", "tls_authentication"]
ordering = ["name"]
search_fields = ["name"]
class KubernetesServiceConnectionSerializer(ServiceConnectionSerializer):
@ -152,3 +153,4 @@ class KubernetesServiceConnectionViewSet(UsedByMixin, ModelViewSet):
serializer_class = KubernetesServiceConnectionSerializer
filterset_fields = ["name", "local"]
ordering = ["name"]
search_fields = ["name"]

View File

@ -21,3 +21,4 @@ class DummyPolicyViewSet(UsedByMixin, ModelViewSet):
serializer_class = DummyPolicySerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -25,3 +25,4 @@ class EventMatcherPolicyViewSet(UsedByMixin, ModelViewSet):
serializer_class = EventMatcherPolicySerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -21,3 +21,4 @@ class PasswordExpiryPolicyViewSet(UsedByMixin, ModelViewSet):
serializer_class = PasswordExpiryPolicySerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -28,3 +28,4 @@ class ExpressionPolicyViewSet(UsedByMixin, ModelViewSet):
serializer_class = ExpressionPolicySerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -20,4 +20,5 @@ class HaveIBeenPwendPolicyViewSet(UsedByMixin, ModelViewSet):
queryset = HaveIBeenPwendPolicy.objects.all()
serializer_class = HaveIBeenPwendPolicySerializer
filterset_fields = "__all__"
search_fields = ["name", "password_field"]
ordering = ["name"]

View File

@ -30,3 +30,4 @@ class PasswordPolicyViewSet(UsedByMixin, ModelViewSet):
serializer_class = PasswordPolicySerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -26,6 +26,7 @@ class ReputationPolicyViewSet(UsedByMixin, ModelViewSet):
queryset = ReputationPolicy.objects.all()
serializer_class = ReputationPolicySerializer
filterset_fields = "__all__"
search_fields = ["name", "threshold"]
ordering = ["name"]

View File

@ -47,6 +47,7 @@ class LDAPProviderViewSet(UsedByMixin, ModelViewSet):
"uid_start_number": ["iexact"],
"gid_start_number": ["iexact"],
}
search_fields = ["name"]
ordering = ["name"]
@ -81,3 +82,5 @@ class LDAPOutpostConfigViewSet(ReadOnlyModelViewSet):
queryset = LDAPProvider.objects.filter(application__isnull=False)
serializer_class = LDAPOutpostConfigSerializer
ordering = ["name"]
search_fields = ["name"]
filterset_fields = ["name"]

View File

@ -71,6 +71,7 @@ class OAuth2ProviderViewSet(UsedByMixin, ModelViewSet):
"property_mappings",
"issuer_mode",
]
search_fields = ["name"]
ordering = ["name"]
@extend_schema(

View File

@ -39,3 +39,4 @@ class ScopeMappingViewSet(UsedByMixin, ModelViewSet):
serializer_class = ScopeMappingSerializer
filterset_class = ScopeMappingFilter
ordering = ["scope_name", "name"]
search_fields = ["name", "scope_name"]

View File

@ -103,6 +103,7 @@ class ProxyProviderViewSet(UsedByMixin, ModelViewSet):
"redirect_uris": ["iexact"],
"cookie_domain": ["iexact"],
}
search_fields = ["name"]
ordering = ["name"]
@ -166,3 +167,5 @@ class ProxyOutpostConfigViewSet(ReadOnlyModelViewSet):
queryset = ProxyProvider.objects.filter(application__isnull=False)
serializer_class = ProxyOutpostConfigSerializer
ordering = ["name"]
search_fields = ["name"]
filterset_fields = ["name"]

View File

@ -99,6 +99,7 @@ class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
serializer_class = SAMLProviderSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
@extend_schema(
responses={
@ -216,4 +217,5 @@ class SAMLPropertyMappingViewSet(UsedByMixin, ModelViewSet):
queryset = SAMLPropertyMapping.objects.all()
serializer_class = SAMLPropertyMappingSerializer
filterset_class = SAMLPropertyMappingFilter
search_fields = ["name"]
ordering = ["name"]

View File

@ -91,6 +91,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
"property_mappings",
"property_mappings_group",
]
search_fields = ["name", "slug"]
ordering = ["name"]
@extend_schema(
@ -142,4 +143,5 @@ class LDAPPropertyMappingViewSet(UsedByMixin, ModelViewSet):
queryset = LDAPPropertyMapping.objects.all()
serializer_class = LDAPPropertyMappingSerializer
filterset_class = LDAPPropertyMappingFilter
search_fields = ["name"]
ordering = ["name"]

View File

@ -102,6 +102,7 @@ class OAuthSourceViewSet(UsedByMixin, ModelViewSet):
"consumer_key",
"additional_scopes",
]
search_fields = ["name", "slug"]
ordering = ["name"]
@extend_schema(

View File

@ -26,6 +26,7 @@ class UserOAuthSourceConnectionViewSet(UsedByMixin, ModelViewSet):
queryset = UserOAuthSourceConnection.objects.all()
serializer_class = UserOAuthSourceConnectionSerializer
filterset_fields = ["source__slug"]
search_fields = ["source__slug"]
permission_classes = [OwnerSuperuserPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
ordering = ["source__slug"]

View File

@ -60,6 +60,7 @@ class PlexSourceViewSet(UsedByMixin, ModelViewSet):
"client_id",
"allow_friends",
]
search_fields = ["name", "slug"]
ordering = ["name"]
@permission_required(None)

View File

@ -35,3 +35,4 @@ class PlexSourceConnectionViewSet(UsedByMixin, ModelViewSet):
permission_classes = [OwnerSuperuserPermissions]
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
ordering = ["pk"]
search_fields = ["source__slug"]

View File

@ -41,6 +41,7 @@ class SAMLSourceViewSet(UsedByMixin, ModelViewSet):
serializer_class = SAMLSourceSerializer
lookup_field = "slug"
filterset_fields = "__all__"
search_fields = ["name", "slug"]
ordering = ["name"]
@extend_schema(responses={200: SAMLMetadataSerializer(many=False)})

View File

@ -51,6 +51,7 @@ class AuthenticatorDuoStageViewSet(UsedByMixin, ModelViewSet):
"client_id",
"api_hostname",
]
search_fields = ["name"]
ordering = ["name"]
@extend_schema(

View File

@ -36,6 +36,7 @@ class AuthenticatorSMSStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = AuthenticatorSMSStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class SMSDeviceSerializer(ModelSerializer):

View File

@ -29,6 +29,7 @@ class AuthenticatorStaticStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = AuthenticatorStaticStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class StaticDeviceTokenSerializer(ModelSerializer):

View File

@ -29,6 +29,7 @@ class AuthenticatorTOTPStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = AuthenticatorTOTPStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class TOTPDeviceSerializer(ModelSerializer):

View File

@ -41,3 +41,4 @@ class AuthenticatorValidateStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = AuthenticatorValidateStageSerializer
filterset_fields = ["name", "not_configured_action", "configuration_stages"]
ordering = ["name"]
search_fields = ["name"]

View File

@ -33,6 +33,7 @@ class AuthenticateWebAuthnStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = AuthenticateWebAuthnStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class WebAuthnDeviceSerializer(ModelSerializer):

View File

@ -22,4 +22,5 @@ class CaptchaStageViewSet(UsedByMixin, ModelViewSet):
queryset = CaptchaStage.objects.all()
serializer_class = CaptchaStageSerializer
filterset_fields = ["name", "public_key"]
search_fields = ["name"]
ordering = ["name"]

View File

@ -28,6 +28,7 @@ class ConsentStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = ConsentStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class UserConsentSerializer(StageSerializer):
@ -60,6 +61,7 @@ class UserConsentViewSet(
OrderingFilter,
SearchFilter,
]
search_fields = ["user__username"]
def get_queryset(self):
user = self.request.user if self.request else get_anonymous_user()

View File

@ -22,3 +22,4 @@ class DenyStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = DenyStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -21,4 +21,5 @@ class DummyStageViewSet(UsedByMixin, ModelViewSet):
queryset = DummyStage.objects.all()
serializer_class = DummyStageSerializer
filterset_fields = "__all__"
search_fields = ["name"]
ordering = ["name"]

View File

@ -68,6 +68,7 @@ class EmailStageViewSet(UsedByMixin, ModelViewSet):
"template",
"activate_user_on_success",
]
search_fields = ["name"]
ordering = ["name"]
@extend_schema(responses={200: TypeCreateSerializer(many=True)})

View File

@ -40,4 +40,5 @@ class IdentificationStageViewSet(UsedByMixin, ModelViewSet):
"passwordless_flow",
"show_source_labels",
]
search_fields = ["name"]
ordering = ["name"]

View File

@ -41,6 +41,7 @@ class InvitationStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = InvitationStageSerializer
filterset_class = InvitationStageFilter
ordering = ["name"]
search_fields = ["name"]
class InvitationSerializer(ModelSerializer):

View File

@ -29,4 +29,5 @@ class PasswordStageViewSet(UsedByMixin, ModelViewSet):
"configure_flow",
"failed_attempts_before_cancel",
]
search_fields = ["name"]
ordering = ["name"]

View File

@ -29,6 +29,7 @@ class PromptStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = PromptStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]
class PromptSerializer(ModelSerializer):
@ -59,3 +60,4 @@ class PromptViewSet(UsedByMixin, ModelViewSet):
queryset = Prompt.objects.all().prefetch_related("promptstage_set")
serializer_class = PromptSerializer
filterset_fields = ["field_key", "label", "type", "placeholder"]
search_fields = ["field_key", "label", "type", "placeholder"]

View File

@ -22,3 +22,4 @@ class UserDeleteStageViewSet(UsedByMixin, ModelViewSet):
serializer_class = UserDeleteStageSerializer
filterset_fields = "__all__"
ordering = ["name"]
search_fields = ["name"]

View File

@ -23,4 +23,5 @@ class UserLoginStageViewSet(UsedByMixin, ModelViewSet):
queryset = UserLoginStage.objects.all()
serializer_class = UserLoginStageSerializer
filterset_fields = "__all__"
search_fields = ["name"]
ordering = ["name"]

View File

@ -21,4 +21,5 @@ class UserLogoutStageViewSet(UsedByMixin, ModelViewSet):
queryset = UserLogoutStage.objects.all()
serializer_class = UserLogoutStageSerializer
filterset_fields = "__all__"
search_fields = ["name"]
ordering = ["name"]

View File

@ -21,4 +21,5 @@ class UserWriteStageViewSet(UsedByMixin, ModelViewSet):
queryset = UserWriteStage.objects.all()
serializer_class = UserWriteStageSerializer
filterset_fields = "__all__"
search_fields = ["name"]
ordering = ["name"]

View File

@ -1601,6 +1601,10 @@ paths:
operationId: core_applications_list
description: Custom list method that checks Policy based access instead of guardian
parameters:
- in: query
name: name
schema:
type: string
- name: ordering
required: false
in: query
@ -1625,6 +1629,10 @@ paths:
description: A search term.
schema:
type: string
- in: query
name: slug
schema:
type: string
- in: query
name: superuser_full_list
schema:
@ -6114,6 +6122,10 @@ paths:
operationId: outposts_ldap_list
description: LDAPProvider Viewset
parameters:
- in: query
name: name
schema:
type: string
- name: ordering
required: false
in: query
@ -6184,6 +6196,10 @@ paths:
operationId: outposts_proxy_list
description: ProxyProvider Viewset
parameters:
- in: query
name: name
schema:
type: string
- name: ordering
required: false
in: query