diff --git a/authentik/core/api/applications.py b/authentik/core/api/applications.py
index 8acf6f78b..ffc1c1e74 100644
--- a/authentik/core/api/applications.py
+++ b/authentik/core/api/applications.py
@@ -29,6 +29,7 @@ from structlog.stdlib import get_logger
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
from authentik.api.decorators import permission_required
from authentik.core.api.providers import ProviderSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.models import Application, User
from authentik.events.models import EventAction
from authentik.policies.api.exec import PolicyTestResultSerializer
@@ -73,7 +74,7 @@ class ApplicationSerializer(ModelSerializer):
}
-class ApplicationViewSet(ModelViewSet):
+class ApplicationViewSet(UsedByMixin, ModelViewSet):
"""Application Viewset"""
queryset = Application.objects.all()
diff --git a/authentik/core/api/authenticated_sessions.py b/authentik/core/api/authenticated_sessions.py
index c3cdb69a7..55989fa04 100644
--- a/authentik/core/api/authenticated_sessions.py
+++ b/authentik/core/api/authenticated_sessions.py
@@ -11,6 +11,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from ua_parser import user_agent_parser
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.models import AuthenticatedSession
from authentik.events.geo import GEOIP_READER, GeoIPDict
@@ -92,6 +93,7 @@ class AuthenticatedSessionSerializer(ModelSerializer):
class AuthenticatedSessionViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/core/api/groups.py b/authentik/core/api/groups.py
index de30d1ee4..d003d9fd2 100644
--- a/authentik/core/api/groups.py
+++ b/authentik/core/api/groups.py
@@ -5,6 +5,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework_guardian.filters import ObjectPermissionsFilter
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import is_dict
from authentik.core.models import Group
@@ -20,7 +21,7 @@ class GroupSerializer(ModelSerializer):
fields = ["pk", "name", "is_superuser", "parent", "users", "attributes"]
-class GroupViewSet(ModelViewSet):
+class GroupViewSet(UsedByMixin, ModelViewSet):
"""Group Viewset"""
queryset = Group.objects.all()
diff --git a/authentik/core/api/propertymappings.py b/authentik/core/api/propertymappings.py
index 4eff31150..2593dc089 100644
--- a/authentik/core/api/propertymappings.py
+++ b/authentik/core/api/propertymappings.py
@@ -14,6 +14,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import GenericViewSet
from authentik.api.decorators import permission_required
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import (
MetaNameSerializer,
PassiveSerializer,
@@ -65,6 +66,7 @@ class PropertyMappingSerializer(ManagedSerializer, ModelSerializer, MetaNameSeri
class PropertyMappingViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/core/api/providers.py b/authentik/core/api/providers.py
index 86e210736..3c489e641 100644
--- a/authentik/core/api/providers.py
+++ b/authentik/core/api/providers.py
@@ -9,6 +9,7 @@ from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import GenericViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
from authentik.core.models import Provider
from authentik.lib.utils.reflection import all_subclasses
@@ -48,6 +49,7 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer):
class ProviderViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/core/api/sources.py b/authentik/core/api/sources.py
index 4ee717ed3..97f966cf9 100644
--- a/authentik/core/api/sources.py
+++ b/authentik/core/api/sources.py
@@ -10,6 +10,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import GenericViewSet
from structlog.stdlib import get_logger
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
from authentik.core.models import Source
from authentik.core.types import UserSettingSerializer
@@ -52,6 +53,7 @@ class SourceSerializer(ModelSerializer, MetaNameSerializer):
class SourceViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/core/api/tokens.py b/authentik/core/api/tokens.py
index 9ef14ac9b..10d74ec6b 100644
--- a/authentik/core/api/tokens.py
+++ b/authentik/core/api/tokens.py
@@ -9,6 +9,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Token, TokenIntents
@@ -43,7 +44,7 @@ class TokenViewSerializer(PassiveSerializer):
key = CharField(read_only=True)
-class TokenViewSet(ModelViewSet):
+class TokenViewSet(UsedByMixin, ModelViewSet):
"""Token Viewset"""
lookup_field = "identifier"
diff --git a/authentik/core/api/used_by.py b/authentik/core/api/used_by.py
new file mode 100644
index 000000000..b1143d989
--- /dev/null
+++ b/authentik/core/api/used_by.py
@@ -0,0 +1,102 @@
+"""used_by mixin"""
+from enum import Enum
+from inspect import getmembers
+
+from django.db.models.base import Model
+from django.db.models.deletion import SET_DEFAULT, SET_NULL
+from django.db.models.manager import Manager
+from drf_spectacular.utils import extend_schema
+from guardian.shortcuts import get_objects_for_user
+from rest_framework.decorators import action
+from rest_framework.fields import CharField, ChoiceField
+from rest_framework.request import Request
+from rest_framework.response import Response
+
+from authentik.core.api.utils import PassiveSerializer
+
+
+class DeleteAction(Enum):
+ """Which action a delete will have on a used object"""
+
+ CASCADE = "cascade"
+ CASCADE_MANY = "cascade_many"
+ SET_NULL = "set_null"
+ SET_DEFAULT = "set_default"
+
+
+class UsedBySerializer(PassiveSerializer):
+ """A list of all objects referencing the queried object"""
+
+ app = CharField()
+ model_name = CharField()
+ pk = CharField()
+ name = CharField()
+ action = ChoiceField(choices=[(x.name, x.name) for x in DeleteAction])
+
+
+def get_delete_action(manager: Manager) -> str:
+ """Get the delete action from the Foreign key, falls back to cascade"""
+ if hasattr(manager, "field"):
+ if manager.field.remote_field.on_delete.__name__ == SET_NULL.__name__:
+ return DeleteAction.SET_NULL.name
+ if manager.field.remote_field.on_delete.__name__ == SET_DEFAULT.__name__:
+ return DeleteAction.SET_DEFAULT.name
+ if hasattr(manager, "source_field"):
+ return DeleteAction.CASCADE_MANY.name
+ return DeleteAction.CASCADE.name
+
+
+class UsedByMixin:
+ """Mixin to add a used_by endpoint to return a list of all objects using this object"""
+
+ @extend_schema(
+ responses={200: UsedBySerializer(many=True)},
+ )
+ @action(detail=True, pagination_class=None, filter_backends=[])
+ # pylint: disable=invalid-name, unused-argument, too-many-locals
+ def used_by(self, request: Request, *args, **kwargs) -> Response:
+ """Get a list of all objects that use this object"""
+ # pyright: reportGeneralTypeIssues=false
+ model: Model = self.get_object()
+ used_by = []
+ shadows = []
+ for attr_name, manager in getmembers(model, lambda x: isinstance(x, Manager)):
+ if attr_name == "objects": # pragma: no cover
+ continue
+ manager: Manager
+ if manager.model._meta.abstract:
+ continue
+ app = manager.model._meta.app_label
+ model_name = manager.model._meta.model_name
+ delete_action = get_delete_action(manager)
+
+ # To make sure we only apply shadows when there are any objects,
+ # but so we only apply them once, have a simple flag for the first object
+ first_object = True
+
+ for obj in get_objects_for_user(
+ request.user, f"{app}.view_{model_name}", manager
+ ).all():
+ # Only merge shadows on first object
+ if first_object:
+ shadows += getattr(
+ manager.model._meta, "authentik_used_by_shadows", []
+ )
+ first_object = False
+ serializer = UsedBySerializer(
+ data={
+ "app": app,
+ "model_name": model_name,
+ "pk": str(obj.pk),
+ "name": str(obj),
+ "action": delete_action,
+ }
+ )
+ serializer.is_valid()
+ used_by.append(serializer.data)
+ # Check the shadows map and remove anything that should be shadowed
+ for idx, user in enumerate(used_by):
+ full_model_name = f"{user['app']}.{user['model_name']}"
+ if full_model_name in shadows:
+ del used_by[idx]
+ return Response(used_by)
diff --git a/authentik/core/api/users.py b/authentik/core/api/users.py
index 566a8d39a..379958bd5 100644
--- a/authentik/core/api/users.py
+++ b/authentik/core/api/users.py
@@ -25,6 +25,7 @@ from rest_framework_guardian.filters import ObjectPermissionsFilter
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
from authentik.api.decorators import permission_required
from authentik.core.api.groups import GroupSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import LinkSerializer, PassiveSerializer, is_dict
from authentik.core.middleware import (
SESSION_IMPERSONATE_ORIGINAL_USER,
@@ -131,7 +132,7 @@ class UsersFilter(FilterSet):
fields = ["username", "name", "is_active", "is_superuser", "attributes"]
-class UserViewSet(ModelViewSet):
+class UserViewSet(UsedByMixin, ModelViewSet):
"""User Viewset"""
queryset = User.objects.none()
diff --git a/authentik/core/models.py b/authentik/core/models.py
index a262fe2b4..677627d64 100644
--- a/authentik/core/models.py
+++ b/authentik/core/models.py
@@ -5,6 +5,7 @@ from typing import Any, Optional, Type
from urllib.parse import urlencode
from uuid import uuid4
+import django.db.models.options as options
from django.conf import settings
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import UserManager as DjangoUserManager
@@ -41,6 +42,9 @@ GRAVATAR_URL = "https://secure.gravatar.com"
DEFAULT_AVATAR = static("dist/assets/images/user_default.png")
+options.DEFAULT_NAMES = options.DEFAULT_NAMES + ("authentik_used_by_shadows",)
+
+
def default_token_duration():
"""Default duration a Token is valid"""
return now() + timedelta(minutes=30)
diff --git a/authentik/crypto/api.py b/authentik/crypto/api.py
index e7b54cb68..a74914404 100644
--- a/authentik/crypto/api.py
+++ b/authentik/crypto/api.py
@@ -1,10 +1,11 @@
"""Crypto API Views"""
-import django_filters
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509 import load_pem_x509_certificate
from django.http.response import HttpResponse
from django.utils.translation import gettext_lazy as _
+from django_filters import FilterSet
+from django_filters.filters import BooleanFilter
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from rest_framework.decorators import action
@@ -20,6 +21,7 @@ from rest_framework.serializers import ModelSerializer, ValidationError
from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.crypto.builder import CertificateBuilder
from authentik.crypto.models import CertificateKeyPair
@@ -100,10 +102,10 @@ class CertificateGenerationSerializer(PassiveSerializer):
validity_days = IntegerField(initial=365)
-class CertificateKeyPairFilter(django_filters.FilterSet):
+class CertificateKeyPairFilter(FilterSet):
"""Filter for certificates"""
- has_key = django_filters.BooleanFilter(
+ has_key = BooleanFilter(
label="Only return certificate-key pairs with keys", method="filter_has_key"
)
@@ -117,7 +119,7 @@ class CertificateKeyPairFilter(django_filters.FilterSet):
fields = ["name"]
-class CertificateKeyPairViewSet(ModelViewSet):
+class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
"""CertificateKeyPair Viewset"""
queryset = CertificateKeyPair.objects.all()
diff --git a/authentik/crypto/tests.py b/authentik/crypto/tests.py
index af9764078..22d800651 100644
--- a/authentik/crypto/tests.py
+++ b/authentik/crypto/tests.py
@@ -4,10 +4,14 @@ import datetime
from django.test import TestCase
from django.urls import reverse
+from authentik.core.api.used_by import DeleteAction
from authentik.core.models import User
from authentik.crypto.api import CertificateKeyPairSerializer
from authentik.crypto.builder import CertificateBuilder
from authentik.crypto.models import CertificateKeyPair
+from authentik.flows.models import Flow
+from authentik.providers.oauth2.generators import generate_client_secret
+from authentik.providers.oauth2.models import OAuth2Provider
class TestCrypto(TestCase):
@@ -91,3 +95,35 @@ class TestCrypto(TestCase):
)
self.assertEqual(200, response.status_code)
self.assertIn("Content-Disposition", response)
+
+ def test_used_by(self):
+ """Test used_by endpoint"""
+ self.client.force_login(User.objects.get(username="akadmin"))
+ keypair = CertificateKeyPair.objects.first()
+ provider = OAuth2Provider.objects.create(
+ name="test",
+ client_id="test",
+ client_secret=generate_client_secret(),
+ authorization_flow=Flow.objects.first(),
+ redirect_uris="http://localhost",
+ rsa_key=CertificateKeyPair.objects.first(),
+ )
+ response = self.client.get(
+ reverse(
+ "authentik_api:certificatekeypair-used-by",
+ kwargs={"pk": keypair.pk},
+ )
+ )
+ self.assertEqual(200, response.status_code)
+ self.assertJSONEqual(
+ response.content.decode(),
+ [
+ {
+ "app": "authentik_providers_oauth2",
+ "model_name": "oauth2provider",
+ "pk": str(provider.pk),
+ "name": str(provider),
+ "action": DeleteAction.SET_NULL.name,
+ }
+ ],
+ )
diff --git a/authentik/events/api/notification.py b/authentik/events/api/notification.py
index 07b2ac49e..2162e021f 100644
--- a/authentik/events/api/notification.py
+++ b/authentik/events/api/notification.py
@@ -7,6 +7,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
+from authentik.core.api.used_by import UsedByMixin
from authentik.events.api.event import EventSerializer
from authentik.events.models import Notification
@@ -35,6 +36,7 @@ class NotificationViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/events/api/notification_rule.py b/authentik/events/api/notification_rule.py
index fbe0788c3..253a53ab4 100644
--- a/authentik/events/api/notification_rule.py
+++ b/authentik/events/api/notification_rule.py
@@ -3,6 +3,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.groups import GroupSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.events.models import NotificationRule
@@ -24,7 +25,7 @@ class NotificationRuleSerializer(ModelSerializer):
]
-class NotificationRuleViewSet(ModelViewSet):
+class NotificationRuleViewSet(UsedByMixin, ModelViewSet):
"""NotificationRule Viewset"""
queryset = NotificationRule.objects.all()
diff --git a/authentik/events/api/notification_transport.py b/authentik/events/api/notification_transport.py
index 05b857e87..3b34e8287 100644
--- a/authentik/events/api/notification_transport.py
+++ b/authentik/events/api/notification_transport.py
@@ -9,6 +9,7 @@ from rest_framework.serializers import ModelSerializer, Serializer
from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
+from authentik.core.api.used_by import UsedByMixin
from authentik.events.models import (
Notification,
NotificationSeverity,
@@ -52,7 +53,7 @@ class NotificationTransportTestSerializer(Serializer):
raise NotImplementedError
-class NotificationTransportViewSet(ModelViewSet):
+class NotificationTransportViewSet(UsedByMixin, ModelViewSet):
"""NotificationTransport Viewset"""
queryset = NotificationTransport.objects.all()
diff --git a/authentik/flows/api/bindings.py b/authentik/flows/api/bindings.py
index 4a1f93a49..74b97ca99 100644
--- a/authentik/flows/api/bindings.py
+++ b/authentik/flows/api/bindings.py
@@ -2,6 +2,7 @@
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.flows.models import FlowStageBinding
@@ -27,7 +28,7 @@ class FlowStageBindingSerializer(ModelSerializer):
]
-class FlowStageBindingViewSet(ModelViewSet):
+class FlowStageBindingViewSet(UsedByMixin, ModelViewSet):
"""FlowStageBinding Viewset"""
queryset = FlowStageBinding.objects.all()
diff --git a/authentik/flows/api/flows.py b/authentik/flows/api/flows.py
index 4515da098..97fda014c 100644
--- a/authentik/flows/api/flows.py
+++ b/authentik/flows/api/flows.py
@@ -24,6 +24,7 @@ from rest_framework.viewsets import ModelViewSet
from structlog.stdlib import get_logger
from authentik.api.decorators import permission_required
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import CacheSerializer, LinkSerializer
from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import Flow
@@ -94,7 +95,7 @@ class DiagramElement:
return f"{self.identifier}=>{self.type}: {self.rest}"
-class FlowViewSet(ModelViewSet):
+class FlowViewSet(UsedByMixin, ModelViewSet):
"""Flow Viewset"""
queryset = Flow.objects.all()
diff --git a/authentik/flows/api/stages.py b/authentik/flows/api/stages.py
index 0b83dbf8b..3ed2e4d0b 100644
--- a/authentik/flows/api/stages.py
+++ b/authentik/flows/api/stages.py
@@ -11,6 +11,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import GenericViewSet
from structlog.stdlib import get_logger
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
from authentik.core.types import UserSettingSerializer
from authentik.flows.api.flows import FlowSerializer
@@ -49,6 +50,7 @@ class StageSerializer(ModelSerializer, MetaNameSerializer):
class StageViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/flows/models.py b/authentik/flows/models.py
index f5e02aa0c..6e9663882 100644
--- a/authentik/flows/models.py
+++ b/authentik/flows/models.py
@@ -72,7 +72,7 @@ class Stage(SerializerModel):
def __str__(self):
if hasattr(self, "__in_memory_type"):
return f"In-memory Stage {getattr(self, '__in_memory_type')}"
- return self.name
+ return f"Stage {self.name}"
def in_memory_stage(view: Type["StageView"]) -> Stage:
@@ -212,7 +212,7 @@ class FlowStageBinding(SerializerModel, PolicyBindingModel):
return FlowStageBindingSerializer
def __str__(self) -> str:
- return f"{self.target} #{self.order}"
+ return f"Flow-stage binding #{self.order} to {self.target}"
class Meta:
diff --git a/authentik/outposts/api/outposts.py b/authentik/outposts/api/outposts.py
index 604bd8189..4cf47d907 100644
--- a/authentik/outposts/api/outposts.py
+++ b/authentik/outposts/api/outposts.py
@@ -11,6 +11,7 @@ from rest_framework.serializers import JSONField, ModelSerializer, ValidationErr
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer, is_dict
from authentik.core.models import Provider
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
@@ -95,7 +96,7 @@ class OutpostHealthSerializer(PassiveSerializer):
version_outdated = BooleanField(read_only=True)
-class OutpostViewSet(ModelViewSet):
+class OutpostViewSet(UsedByMixin, ModelViewSet):
"""Outpost Viewset"""
queryset = Outpost.objects.all()
diff --git a/authentik/outposts/api/service_connections.py b/authentik/outposts/api/service_connections.py
index 8f2b04bd1..566ed7dd6 100644
--- a/authentik/outposts/api/service_connections.py
+++ b/authentik/outposts/api/service_connections.py
@@ -14,6 +14,7 @@ from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import (
MetaNameSerializer,
PassiveSerializer,
@@ -55,6 +56,7 @@ class ServiceConnectionStateSerializer(PassiveSerializer):
class ServiceConnectionViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
@@ -105,7 +107,7 @@ class DockerServiceConnectionSerializer(ServiceConnectionSerializer):
]
-class DockerServiceConnectionViewSet(ModelViewSet):
+class DockerServiceConnectionViewSet(UsedByMixin, ModelViewSet):
"""DockerServiceConnection Viewset"""
queryset = DockerServiceConnection.objects.all()
@@ -139,7 +141,7 @@ class KubernetesServiceConnectionSerializer(ServiceConnectionSerializer):
fields = ServiceConnectionSerializer.Meta.fields + ["kubeconfig"]
-class KubernetesServiceConnectionViewSet(ModelViewSet):
+class KubernetesServiceConnectionViewSet(UsedByMixin, ModelViewSet):
"""KubernetesServiceConnection Viewset"""
queryset = KubernetesServiceConnection.objects.all()
diff --git a/authentik/policies/api/bindings.py b/authentik/policies/api/bindings.py
index 3a4ad831e..62603834e 100644
--- a/authentik/policies/api/bindings.py
+++ b/authentik/policies/api/bindings.py
@@ -11,6 +11,7 @@ from rest_framework.viewsets import ModelViewSet
from structlog.stdlib import get_logger
from authentik.core.api.groups import GroupSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.models import PolicyBinding, PolicyBindingModel
@@ -99,7 +100,7 @@ class PolicyBindingSerializer(ModelSerializer):
return data
-class PolicyBindingViewSet(ModelViewSet):
+class PolicyBindingViewSet(UsedByMixin, ModelViewSet):
"""PolicyBinding Viewset"""
queryset = (
diff --git a/authentik/policies/api/policies.py b/authentik/policies/api/policies.py
index 1f08cc6ec..6be8b36b6 100644
--- a/authentik/policies/api/policies.py
+++ b/authentik/policies/api/policies.py
@@ -14,6 +14,7 @@ from structlog.stdlib import get_logger
from authentik.api.decorators import permission_required
from authentik.core.api.applications import user_app_cache_key
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import (
CacheSerializer,
MetaNameSerializer,
@@ -79,6 +80,7 @@ class PolicySerializer(ModelSerializer, MetaNameSerializer):
class PolicyViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/policies/dummy/api.py b/authentik/policies/dummy/api.py
index 66d837063..789d18de4 100644
--- a/authentik/policies/dummy/api.py
+++ b/authentik/policies/dummy/api.py
@@ -1,6 +1,7 @@
"""Dummy Policy API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.dummy.models import DummyPolicy
@@ -13,7 +14,7 @@ class DummyPolicySerializer(PolicySerializer):
fields = PolicySerializer.Meta.fields + ["result", "wait_min", "wait_max"]
-class DummyPolicyViewSet(ModelViewSet):
+class DummyPolicyViewSet(UsedByMixin, ModelViewSet):
"""Dummy Viewset"""
queryset = DummyPolicy.objects.all()
diff --git a/authentik/policies/event_matcher/api.py b/authentik/policies/event_matcher/api.py
index 0dda645f1..9e998bb53 100644
--- a/authentik/policies/event_matcher/api.py
+++ b/authentik/policies/event_matcher/api.py
@@ -1,6 +1,7 @@
"""Event Matcher Policy API"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.event_matcher.models import EventMatcherPolicy
@@ -17,7 +18,7 @@ class EventMatcherPolicySerializer(PolicySerializer):
]
-class EventMatcherPolicyViewSet(ModelViewSet):
+class EventMatcherPolicyViewSet(UsedByMixin, ModelViewSet):
"""Event Matcher Policy Viewset"""
queryset = EventMatcherPolicy.objects.all()
diff --git a/authentik/policies/expiry/api.py b/authentik/policies/expiry/api.py
index 70f12a62d..e83ac2fbf 100644
--- a/authentik/policies/expiry/api.py
+++ b/authentik/policies/expiry/api.py
@@ -1,6 +1,7 @@
"""Password Expiry Policy API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.expiry.models import PasswordExpiryPolicy
@@ -13,7 +14,7 @@ class PasswordExpiryPolicySerializer(PolicySerializer):
fields = PolicySerializer.Meta.fields + ["days", "deny_only"]
-class PasswordExpiryPolicyViewSet(ModelViewSet):
+class PasswordExpiryPolicyViewSet(UsedByMixin, ModelViewSet):
"""Password Expiry Viewset"""
queryset = PasswordExpiryPolicy.objects.all()
diff --git a/authentik/policies/expression/api.py b/authentik/policies/expression/api.py
index d4975e097..26a39ff1f 100644
--- a/authentik/policies/expression/api.py
+++ b/authentik/policies/expression/api.py
@@ -1,6 +1,7 @@
"""Expression Policy API"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.expression.evaluator import PolicyEvaluator
from authentik.policies.expression.models import ExpressionPolicy
@@ -20,7 +21,7 @@ class ExpressionPolicySerializer(PolicySerializer):
fields = PolicySerializer.Meta.fields + ["expression"]
-class ExpressionPolicyViewSet(ModelViewSet):
+class ExpressionPolicyViewSet(UsedByMixin, ModelViewSet):
"""Source Viewset"""
queryset = ExpressionPolicy.objects.all()
diff --git a/authentik/policies/hibp/api.py b/authentik/policies/hibp/api.py
index 66acd8877..86cbfdb95 100644
--- a/authentik/policies/hibp/api.py
+++ b/authentik/policies/hibp/api.py
@@ -1,6 +1,7 @@
"""Source API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.hibp.models import HaveIBeenPwendPolicy
@@ -13,7 +14,7 @@ class HaveIBeenPwendPolicySerializer(PolicySerializer):
fields = PolicySerializer.Meta.fields + ["password_field", "allowed_count"]
-class HaveIBeenPwendPolicyViewSet(ModelViewSet):
+class HaveIBeenPwendPolicyViewSet(UsedByMixin, ModelViewSet):
"""Source Viewset"""
queryset = HaveIBeenPwendPolicy.objects.all()
diff --git a/authentik/policies/password/api.py b/authentik/policies/password/api.py
index f0171095c..fc11a1c6d 100644
--- a/authentik/policies/password/api.py
+++ b/authentik/policies/password/api.py
@@ -1,6 +1,7 @@
"""Password Policy API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.password.models import PasswordPolicy
@@ -21,7 +22,7 @@ class PasswordPolicySerializer(PolicySerializer):
]
-class PasswordPolicyViewSet(ModelViewSet):
+class PasswordPolicyViewSet(UsedByMixin, ModelViewSet):
"""Password Policy Viewset"""
queryset = PasswordPolicy.objects.all()
diff --git a/authentik/policies/reputation/api.py b/authentik/policies/reputation/api.py
index f10d690e0..e3bf747be 100644
--- a/authentik/policies/reputation/api.py
+++ b/authentik/policies/reputation/api.py
@@ -3,6 +3,7 @@ from rest_framework import mixins
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.policies.api.policies import PolicySerializer
from authentik.policies.reputation.models import (
IPReputation,
@@ -23,7 +24,7 @@ class ReputationPolicySerializer(PolicySerializer):
]
-class ReputationPolicyViewSet(ModelViewSet):
+class ReputationPolicyViewSet(UsedByMixin, ModelViewSet):
"""Reputation Policy Viewset"""
queryset = ReputationPolicy.objects.all()
@@ -46,6 +47,7 @@ class IPReputationSerializer(ModelSerializer):
class IPReputationViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
@@ -74,6 +76,7 @@ class UserReputationSerializer(ModelSerializer):
class UserReputationViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/providers/ldap/api.py b/authentik/providers/ldap/api.py
index d9900f3c5..5c10eb6ea 100644
--- a/authentik/providers/ldap/api.py
+++ b/authentik/providers/ldap/api.py
@@ -4,6 +4,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from authentik.core.api.providers import ProviderSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.providers.ldap.models import LDAPProvider
@@ -19,7 +20,7 @@ class LDAPProviderSerializer(ProviderSerializer):
]
-class LDAPProviderViewSet(ModelViewSet):
+class LDAPProviderViewSet(UsedByMixin, ModelViewSet):
"""LDAPProvider Viewset"""
queryset = LDAPProvider.objects.all()
diff --git a/authentik/providers/oauth2/api/provider.py b/authentik/providers/oauth2/api/provider.py
index 9d1b3bb98..daa099bd1 100644
--- a/authentik/providers/oauth2/api/provider.py
+++ b/authentik/providers/oauth2/api/provider.py
@@ -11,6 +11,7 @@ from rest_framework.serializers import ValidationError
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Provider
from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
@@ -61,7 +62,7 @@ class OAuth2ProviderSetupURLs(PassiveSerializer):
logout = ReadOnlyField()
-class OAuth2ProviderViewSet(ModelViewSet):
+class OAuth2ProviderViewSet(UsedByMixin, ModelViewSet):
"""OAuth2Provider Viewset"""
queryset = OAuth2Provider.objects.all()
diff --git a/authentik/providers/oauth2/api/scope.py b/authentik/providers/oauth2/api/scope.py
index 6ddc12310..20aaf06dc 100644
--- a/authentik/providers/oauth2/api/scope.py
+++ b/authentik/providers/oauth2/api/scope.py
@@ -2,6 +2,7 @@
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.propertymappings import PropertyMappingSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.providers.oauth2.models import ScopeMapping
@@ -17,7 +18,7 @@ class ScopeMappingSerializer(PropertyMappingSerializer):
]
-class ScopeMappingViewSet(ModelViewSet):
+class ScopeMappingViewSet(UsedByMixin, ModelViewSet):
"""ScopeMapping Viewset"""
queryset = ScopeMapping.objects.all()
diff --git a/authentik/providers/oauth2/api/tokens.py b/authentik/providers/oauth2/api/tokens.py
index 3ff200da8..8d77ff4ce 100644
--- a/authentik/providers/oauth2/api/tokens.py
+++ b/authentik/providers/oauth2/api/tokens.py
@@ -10,6 +10,7 @@ from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import MetaNameSerializer
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
@@ -57,6 +58,7 @@ class RefreshTokenModelSerializer(ExpiringBaseGrantModelSerializer):
class AuthorizationCodeViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
@@ -82,6 +84,7 @@ class AuthorizationCodeViewSet(
class RefreshTokenViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/providers/oauth2/migrations/0014_alter_oauth2provider_rsa_key.py b/authentik/providers/oauth2/migrations/0014_alter_oauth2provider_rsa_key.py
new file mode 100644
index 000000000..5376b9ea8
--- /dev/null
+++ b/authentik/providers/oauth2/migrations/0014_alter_oauth2provider_rsa_key.py
@@ -0,0 +1,26 @@
+# Generated by Django 3.2.3 on 2021-06-09 21:52
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("authentik_crypto", "0002_create_self_signed_kp"),
+ ("authentik_providers_oauth2", "0013_alter_authorizationcode_nonce"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="oauth2provider",
+ name="rsa_key",
+ field=models.ForeignKey(
+ help_text="Key used to sign the tokens. Only required when JWT Algorithm is set to RS256.",
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ to="authentik_crypto.certificatekeypair",
+ verbose_name="RSA Key",
+ ),
+ ),
+ ]
diff --git a/authentik/providers/oauth2/models.py b/authentik/providers/oauth2/models.py
index 30f84cf5e..a9b82bf84 100644
--- a/authentik/providers/oauth2/models.py
+++ b/authentik/providers/oauth2/models.py
@@ -215,8 +215,7 @@ class OAuth2Provider(Provider):
rsa_key = models.ForeignKey(
CertificateKeyPair,
verbose_name=_("RSA Key"),
- on_delete=models.CASCADE,
- blank=True,
+ on_delete=models.SET_NULL,
null=True,
help_text=_(
"Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
diff --git a/authentik/providers/proxy/api.py b/authentik/providers/proxy/api.py
index 3d3075bdd..5665e68b0 100644
--- a/authentik/providers/proxy/api.py
+++ b/authentik/providers/proxy/api.py
@@ -8,6 +8,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from authentik.core.api.providers import ProviderSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.providers.oauth2.views.provider import ProviderInfoView
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
@@ -76,7 +77,7 @@ class ProxyProviderSerializer(ProviderSerializer):
]
-class ProxyProviderViewSet(ModelViewSet):
+class ProxyProviderViewSet(UsedByMixin, ModelViewSet):
"""ProxyProvider Viewset"""
queryset = ProxyProvider.objects.all()
diff --git a/authentik/providers/proxy/models.py b/authentik/providers/proxy/models.py
index 9672d9f31..c1fbe7ec9 100644
--- a/authentik/providers/proxy/models.py
+++ b/authentik/providers/proxy/models.py
@@ -167,3 +167,4 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
verbose_name = _("Proxy Provider")
verbose_name_plural = _("Proxy Providers")
+ authentik_used_by_shadows = ["authentik_providers_oauth2.oauth2provider"]
diff --git a/authentik/providers/saml/api.py b/authentik/providers/saml/api.py
index 52fbe2061..0806b8959 100644
--- a/authentik/providers/saml/api.py
+++ b/authentik/providers/saml/api.py
@@ -21,6 +21,7 @@ from structlog.stdlib import get_logger
from authentik.api.decorators import permission_required
from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.providers import ProviderSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Provider
from authentik.flows.models import Flow, FlowDesignation
@@ -75,7 +76,7 @@ class SAMLProviderImportSerializer(PassiveSerializer):
file = FileField()
-class SAMLProviderViewSet(ModelViewSet):
+class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
"""SAMLProvider Viewset"""
queryset = SAMLProvider.objects.all()
@@ -166,7 +167,7 @@ class SAMLPropertyMappingSerializer(PropertyMappingSerializer):
]
-class SAMLPropertyMappingViewSet(ModelViewSet):
+class SAMLPropertyMappingViewSet(UsedByMixin, ModelViewSet):
"""SAMLPropertyMapping Viewset"""
queryset = SAMLPropertyMapping.objects.all()
diff --git a/authentik/sources/ldap/api.py b/authentik/sources/ldap/api.py
index 9196186f3..5113da93b 100644
--- a/authentik/sources/ldap/api.py
+++ b/authentik/sources/ldap/api.py
@@ -10,6 +10,7 @@ from rest_framework.viewsets import ModelViewSet
from authentik.admin.api.tasks import TaskSerializer
from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.sources import SourceSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.events.monitored_tasks import TaskInfo
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
@@ -41,7 +42,7 @@ class LDAPSourceSerializer(SourceSerializer):
extra_kwargs = {"bind_password": {"write_only": True}}
-class LDAPSourceViewSet(ModelViewSet):
+class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
"""LDAP Source Viewset"""
queryset = LDAPSource.objects.all()
@@ -75,7 +76,7 @@ class LDAPPropertyMappingSerializer(PropertyMappingSerializer):
]
-class LDAPPropertyMappingViewSet(ModelViewSet):
+class LDAPPropertyMappingViewSet(UsedByMixin, ModelViewSet):
"""LDAP PropertyMapping Viewset"""
queryset = LDAPPropertyMapping.objects.all()
diff --git a/authentik/sources/oauth/api/source.py b/authentik/sources/oauth/api/source.py
index 8899cfc89..f0af31661 100644
--- a/authentik/sources/oauth/api/source.py
+++ b/authentik/sources/oauth/api/source.py
@@ -9,6 +9,7 @@ from rest_framework.serializers import ValidationError
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import SourceSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.sources.oauth.models import OAuthSource
from authentik.sources.oauth.types.manager import MANAGER
@@ -78,7 +79,7 @@ class OAuthSourceSerializer(SourceSerializer):
extra_kwargs = {"consumer_secret": {"write_only": True}}
-class OAuthSourceViewSet(ModelViewSet):
+class OAuthSourceViewSet(UsedByMixin, ModelViewSet):
"""Source Viewset"""
queryset = OAuthSource.objects.all()
diff --git a/authentik/sources/oauth/api/source_connection.py b/authentik/sources/oauth/api/source_connection.py
index c7e1d036b..8c18b5bea 100644
--- a/authentik/sources/oauth/api/source_connection.py
+++ b/authentik/sources/oauth/api/source_connection.py
@@ -6,6 +6,7 @@ from rest_framework.viewsets import GenericViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
from authentik.core.api.sources import SourceSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.sources.oauth.models import UserOAuthSourceConnection
@@ -26,6 +27,7 @@ class UserOAuthSourceConnectionViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/sources/plex/api.py b/authentik/sources/plex/api.py
index 00200982a..02ce89fd3 100644
--- a/authentik/sources/plex/api.py
+++ b/authentik/sources/plex/api.py
@@ -14,6 +14,7 @@ from structlog.stdlib import get_logger
from authentik.api.decorators import permission_required
from authentik.core.api.sources import SourceSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.flows.challenge import RedirectChallenge
from authentik.flows.views import to_stage_response
@@ -42,7 +43,7 @@ class PlexTokenRedeemSerializer(PassiveSerializer):
plex_token = CharField()
-class PlexSourceViewSet(ModelViewSet):
+class PlexSourceViewSet(UsedByMixin, ModelViewSet):
"""Plex source Viewset"""
queryset = PlexSource.objects.all()
diff --git a/authentik/sources/saml/api.py b/authentik/sources/saml/api.py
index 81cbcf8fb..063970f8c 100644
--- a/authentik/sources/saml/api.py
+++ b/authentik/sources/saml/api.py
@@ -7,6 +7,7 @@ from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import SourceSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.providers.saml.api import SAMLMetadataSerializer
from authentik.sources.saml.models import SAMLSource
from authentik.sources.saml.processors.metadata import MetadataProcessor
@@ -33,7 +34,7 @@ class SAMLSourceSerializer(SourceSerializer):
]
-class SAMLSourceViewSet(ModelViewSet):
+class SAMLSourceViewSet(UsedByMixin, ModelViewSet):
"""SAMLSource Viewset"""
queryset = SAMLSource.objects.all()
diff --git a/authentik/stages/authenticator_duo/api.py b/authentik/stages/authenticator_duo/api.py
index fe69a1ace..4e02f5966 100644
--- a/authentik/stages/authenticator_duo/api.py
+++ b/authentik/stages/authenticator_duo/api.py
@@ -12,6 +12,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
from authentik.stages.authenticator_duo.stage import (
@@ -37,7 +38,7 @@ class AuthenticatorDuoStageSerializer(StageSerializer):
}
-class AuthenticatorDuoStageViewSet(ModelViewSet):
+class AuthenticatorDuoStageViewSet(UsedByMixin, ModelViewSet):
"""AuthenticatorDuoStage Viewset"""
queryset = AuthenticatorDuoStage.objects.all()
@@ -78,6 +79,7 @@ class DuoDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/stages/authenticator_static/api.py b/authentik/stages/authenticator_static/api.py
index d0fdea081..4b6498ea5 100644
--- a/authentik/stages/authenticator_static/api.py
+++ b/authentik/stages/authenticator_static/api.py
@@ -8,6 +8,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_static.models import AuthenticatorStaticStage
@@ -21,7 +22,7 @@ class AuthenticatorStaticStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields + ["configure_flow", "token_count"]
-class AuthenticatorStaticStageViewSet(ModelViewSet):
+class AuthenticatorStaticStageViewSet(UsedByMixin, ModelViewSet):
"""AuthenticatorStaticStage Viewset"""
queryset = AuthenticatorStaticStage.objects.all()
@@ -52,6 +53,7 @@ class StaticDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/stages/authenticator_totp/api.py b/authentik/stages/authenticator_totp/api.py
index 52689de37..3c9a95f7b 100644
--- a/authentik/stages/authenticator_totp/api.py
+++ b/authentik/stages/authenticator_totp/api.py
@@ -8,6 +8,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage
@@ -21,7 +22,7 @@ class AuthenticatorTOTPStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields + ["configure_flow", "digits"]
-class AuthenticatorTOTPStageViewSet(ModelViewSet):
+class AuthenticatorTOTPStageViewSet(UsedByMixin, ModelViewSet):
"""AuthenticatorTOTPStage Viewset"""
queryset = AuthenticatorTOTPStage.objects.all()
@@ -45,6 +46,7 @@ class TOTPDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/stages/authenticator_validate/api.py b/authentik/stages/authenticator_validate/api.py
index 4a51aabb3..32fb88a49 100644
--- a/authentik/stages/authenticator_validate/api.py
+++ b/authentik/stages/authenticator_validate/api.py
@@ -2,6 +2,7 @@
from rest_framework.serializers import ValidationError
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.flows.models import NotConfiguredAction
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
@@ -32,7 +33,7 @@ class AuthenticatorValidateStageSerializer(StageSerializer):
]
-class AuthenticatorValidateStageViewSet(ModelViewSet):
+class AuthenticatorValidateStageViewSet(UsedByMixin, ModelViewSet):
"""AuthenticatorValidateStage Viewset"""
queryset = AuthenticatorValidateStage.objects.all()
diff --git a/authentik/stages/authenticator_webauthn/api.py b/authentik/stages/authenticator_webauthn/api.py
index 9f9314bf8..9f95be3f5 100644
--- a/authentik/stages/authenticator_webauthn/api.py
+++ b/authentik/stages/authenticator_webauthn/api.py
@@ -7,6 +7,7 @@ from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
from authentik.api.authorization import OwnerFilter, OwnerPermissions
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.authenticator_webauthn.models import (
AuthenticateWebAuthnStage,
@@ -23,7 +24,7 @@ class AuthenticateWebAuthnStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields + ["configure_flow"]
-class AuthenticateWebAuthnStageViewSet(ModelViewSet):
+class AuthenticateWebAuthnStageViewSet(UsedByMixin, ModelViewSet):
"""AuthenticateWebAuthnStage Viewset"""
queryset = AuthenticateWebAuthnStage.objects.all()
@@ -44,6 +45,7 @@ class WebAuthnDeviceViewSet(
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/stages/captcha/api.py b/authentik/stages/captcha/api.py
index fb425e42f..5623533ce 100644
--- a/authentik/stages/captcha/api.py
+++ b/authentik/stages/captcha/api.py
@@ -1,6 +1,7 @@
"""CaptchaStage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.captcha.models import CaptchaStage
@@ -15,7 +16,7 @@ class CaptchaStageSerializer(StageSerializer):
extra_kwargs = {"private_key": {"write_only": True}}
-class CaptchaStageViewSet(ModelViewSet):
+class CaptchaStageViewSet(UsedByMixin, ModelViewSet):
"""CaptchaStage Viewset"""
queryset = CaptchaStage.objects.all()
diff --git a/authentik/stages/consent/api.py b/authentik/stages/consent/api.py
index edd067921..609156600 100644
--- a/authentik/stages/consent/api.py
+++ b/authentik/stages/consent/api.py
@@ -6,6 +6,7 @@ from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.core.api.applications import ApplicationSerializer
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.flows.api.stages import StageSerializer
from authentik.stages.consent.models import ConsentStage, UserConsent
@@ -20,7 +21,7 @@ class ConsentStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields + ["mode", "consent_expire_in"]
-class ConsentStageViewSet(ModelViewSet):
+class ConsentStageViewSet(UsedByMixin, ModelViewSet):
"""ConsentStage Viewset"""
queryset = ConsentStage.objects.all()
@@ -42,6 +43,7 @@ class UserConsentSerializer(StageSerializer):
class UserConsentViewSet(
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
+ UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
diff --git a/authentik/stages/deny/api.py b/authentik/stages/deny/api.py
index 89c1d6e08..b6a9fcd20 100644
--- a/authentik/stages/deny/api.py
+++ b/authentik/stages/deny/api.py
@@ -1,6 +1,7 @@
"""deny Stage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.deny.models import DenyStage
@@ -14,7 +15,7 @@ class DenyStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields
-class DenyStageViewSet(ModelViewSet):
+class DenyStageViewSet(UsedByMixin, ModelViewSet):
"""DenyStage Viewset"""
queryset = DenyStage.objects.all()
diff --git a/authentik/stages/dummy/api.py b/authentik/stages/dummy/api.py
index 02e1c9463..4447ec134 100644
--- a/authentik/stages/dummy/api.py
+++ b/authentik/stages/dummy/api.py
@@ -1,6 +1,7 @@
"""DummyStage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.dummy.models import DummyStage
@@ -14,7 +15,7 @@ class DummyStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields
-class DummyStageViewSet(ModelViewSet):
+class DummyStageViewSet(UsedByMixin, ModelViewSet):
"""DummyStage Viewset"""
queryset = DummyStage.objects.all()
diff --git a/authentik/stages/email/api.py b/authentik/stages/email/api.py
index e13d9584f..90dfd2c6d 100644
--- a/authentik/stages/email/api.py
+++ b/authentik/stages/email/api.py
@@ -6,6 +6,7 @@ from rest_framework.response import Response
from rest_framework.serializers import ValidationError
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import TypeCreateSerializer
from authentik.flows.api.stages import StageSerializer
from authentik.stages.email.models import EmailStage, get_template_choices
@@ -46,7 +47,7 @@ class EmailStageSerializer(StageSerializer):
extra_kwargs = {"password": {"write_only": True}}
-class EmailStageViewSet(ModelViewSet):
+class EmailStageViewSet(UsedByMixin, ModelViewSet):
"""EmailStage Viewset"""
queryset = EmailStage.objects.all()
diff --git a/authentik/stages/identification/api.py b/authentik/stages/identification/api.py
index e2b44ce54..54e9bc8ca 100644
--- a/authentik/stages/identification/api.py
+++ b/authentik/stages/identification/api.py
@@ -1,6 +1,7 @@
"""Identification Stage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.identification.models import IdentificationStage
@@ -22,7 +23,7 @@ class IdentificationStageSerializer(StageSerializer):
]
-class IdentificationStageViewSet(ModelViewSet):
+class IdentificationStageViewSet(UsedByMixin, ModelViewSet):
"""IdentificationStage Viewset"""
queryset = IdentificationStage.objects.all()
diff --git a/authentik/stages/invitation/api.py b/authentik/stages/invitation/api.py
index fc5c508d3..ff6a720e2 100644
--- a/authentik/stages/invitation/api.py
+++ b/authentik/stages/invitation/api.py
@@ -3,6 +3,7 @@ from rest_framework.fields import JSONField
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import is_dict
from authentik.flows.api.stages import StageSerializer
@@ -20,7 +21,7 @@ class InvitationStageSerializer(StageSerializer):
]
-class InvitationStageViewSet(ModelViewSet):
+class InvitationStageViewSet(UsedByMixin, ModelViewSet):
"""InvitationStage Viewset"""
queryset = InvitationStage.objects.all()
@@ -45,7 +46,7 @@ class InvitationSerializer(ModelSerializer):
]
-class InvitationViewSet(ModelViewSet):
+class InvitationViewSet(UsedByMixin, ModelViewSet):
"""Invitation Viewset"""
queryset = Invitation.objects.all()
diff --git a/authentik/stages/password/api.py b/authentik/stages/password/api.py
index 48499663e..30a376590 100644
--- a/authentik/stages/password/api.py
+++ b/authentik/stages/password/api.py
@@ -1,6 +1,7 @@
"""PasswordStage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.password.models import PasswordStage
@@ -18,7 +19,7 @@ class PasswordStageSerializer(StageSerializer):
]
-class PasswordStageViewSet(ModelViewSet):
+class PasswordStageViewSet(UsedByMixin, ModelViewSet):
"""PasswordStage Viewset"""
queryset = PasswordStage.objects.all()
diff --git a/authentik/stages/prompt/api.py b/authentik/stages/prompt/api.py
index a318ff646..dc5d3b4e6 100644
--- a/authentik/stages/prompt/api.py
+++ b/authentik/stages/prompt/api.py
@@ -3,6 +3,7 @@ from rest_framework.serializers import CharField, ModelSerializer
from rest_framework.validators import UniqueValidator
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.prompt.models import Prompt, PromptStage
@@ -21,7 +22,7 @@ class PromptStageSerializer(StageSerializer):
]
-class PromptStageViewSet(ModelViewSet):
+class PromptStageViewSet(UsedByMixin, ModelViewSet):
"""PromptStage Viewset"""
queryset = PromptStage.objects.all()
@@ -48,7 +49,7 @@ class PromptSerializer(ModelSerializer):
]
-class PromptViewSet(ModelViewSet):
+class PromptViewSet(UsedByMixin, ModelViewSet):
"""Prompt Viewset"""
queryset = Prompt.objects.all().prefetch_related("promptstage_set")
diff --git a/authentik/stages/user_delete/api.py b/authentik/stages/user_delete/api.py
index 195fdcca7..8ab224b44 100644
--- a/authentik/stages/user_delete/api.py
+++ b/authentik/stages/user_delete/api.py
@@ -1,6 +1,7 @@
"""User Delete Stage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.user_delete.models import UserDeleteStage
@@ -14,7 +15,7 @@ class UserDeleteStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields
-class UserDeleteStageViewSet(ModelViewSet):
+class UserDeleteStageViewSet(UsedByMixin, ModelViewSet):
"""UserDeleteStage Viewset"""
queryset = UserDeleteStage.objects.all()
diff --git a/authentik/stages/user_login/api.py b/authentik/stages/user_login/api.py
index 55ff8a00c..b55f9779c 100644
--- a/authentik/stages/user_login/api.py
+++ b/authentik/stages/user_login/api.py
@@ -1,6 +1,7 @@
"""Login Stage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.user_login.models import UserLoginStage
@@ -16,7 +17,7 @@ class UserLoginStageSerializer(StageSerializer):
]
-class UserLoginStageViewSet(ModelViewSet):
+class UserLoginStageViewSet(UsedByMixin, ModelViewSet):
"""UserLoginStage Viewset"""
queryset = UserLoginStage.objects.all()
diff --git a/authentik/stages/user_logout/api.py b/authentik/stages/user_logout/api.py
index 89017e3b9..d361bcfea 100644
--- a/authentik/stages/user_logout/api.py
+++ b/authentik/stages/user_logout/api.py
@@ -1,6 +1,7 @@
"""Logout Stage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.user_logout.models import UserLogoutStage
@@ -14,7 +15,7 @@ class UserLogoutStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields
-class UserLogoutStageViewSet(ModelViewSet):
+class UserLogoutStageViewSet(UsedByMixin, ModelViewSet):
"""UserLogoutStage Viewset"""
queryset = UserLogoutStage.objects.all()
diff --git a/authentik/stages/user_write/api.py b/authentik/stages/user_write/api.py
index f1dadc769..5acaa6ae1 100644
--- a/authentik/stages/user_write/api.py
+++ b/authentik/stages/user_write/api.py
@@ -1,6 +1,7 @@
"""User Write Stage API Views"""
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.flows.api.stages import StageSerializer
from authentik.stages.user_write.models import UserWriteStage
@@ -14,7 +15,7 @@ class UserWriteStageSerializer(StageSerializer):
fields = StageSerializer.Meta.fields
-class UserWriteStageViewSet(ModelViewSet):
+class UserWriteStageViewSet(UsedByMixin, ModelViewSet):
"""UserWriteStage Viewset"""
queryset = UserWriteStage.objects.all()
diff --git a/authentik/tenants/api.py b/authentik/tenants/api.py
index 4a40453ac..3e85257e5 100644
--- a/authentik/tenants/api.py
+++ b/authentik/tenants/api.py
@@ -8,6 +8,7 @@ from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
+from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.lib.config import CONFIG
from authentik.tenants.models import Tenant
@@ -56,7 +57,7 @@ class CurrentTenantSerializer(PassiveSerializer):
flow_unenrollment = CharField(source="flow_unenrollment.slug", required=False)
-class TenantViewSet(ModelViewSet):
+class TenantViewSet(UsedByMixin, ModelViewSet):
"""Tenant Viewset"""
queryset = Tenant.objects.all()
diff --git a/authentik/tenants/models.py b/authentik/tenants/models.py
index c777ff283..1c1da4e5a 100644
--- a/authentik/tenants/models.py
+++ b/authentik/tenants/models.py
@@ -41,7 +41,9 @@ class Tenant(models.Model):
)
def __str__(self) -> str:
- return self.domain
+ if self.default:
+ return "Default tenant"
+ return f"Tenant {self.domain}"
class Meta:
diff --git a/pyproject.toml b/pyproject.toml
index a4a3056ad..f3601d61d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -9,6 +9,7 @@ force_grid_wrap = 0
use_parentheses = true
line_length = 88
src_paths = ["authentik", "tests", "lifecycle"]
+force_to_top = "*"
[tool.coverage.run]
source = ["authentik"]
diff --git a/schema.yml b/schema.yml
index 8cf6ca3a3..03ff271a0 100644
--- a/schema.yml
+++ b/schema.yml
@@ -664,6 +664,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/authenticators/duo/{id}/used_by/:
+ get:
+ operationId: authenticators_duo_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this Duo Device.
+ required: true
+ tags:
+ - authenticators
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/authenticators/static/:
get:
operationId: authenticators_static_list
@@ -837,6 +866,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/authenticators/static/{id}/used_by/:
+ get:
+ operationId: authenticators_static_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this static device.
+ required: true
+ tags:
+ - authenticators
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/authenticators/totp/:
get:
operationId: authenticators_totp_list
@@ -1010,6 +1068,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/authenticators/totp/{id}/used_by/:
+ get:
+ operationId: authenticators_totp_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this TOTP device.
+ required: true
+ tags:
+ - authenticators
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/authenticators/webauthn/:
get:
operationId: authenticators_webauthn_list
@@ -1183,6 +1270,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/authenticators/webauthn/{id}/used_by/:
+ get:
+ operationId: authenticators_webauthn_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this WebAuthn Device.
+ required: true
+ tags:
+ - authenticators
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/applications/:
get:
operationId: core_applications_list
@@ -1519,6 +1635,35 @@ paths:
description: Bad request
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/applications/{slug}/used_by/:
+ get:
+ operationId: core_applications_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Internal application name, used in URLs.
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/authenticated_sessions/:
get:
operationId: core_authenticated_sessions_list
@@ -1627,6 +1772,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/authenticated_sessions/{uuid}/used_by/:
+ get:
+ operationId: core_authenticated_sessions_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this authenticated session.
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/groups/:
get:
operationId: core_groups_list
@@ -1839,6 +2014,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/groups/{group_uuid}/used_by/:
+ get:
+ operationId: core_groups_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: group_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this group.
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/tenants/:
get:
operationId: core_tenants_list
@@ -2043,6 +2248,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/tenants/{tenant_uuid}/used_by/:
+ get:
+ operationId: core_tenants_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: tenant_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Tenant.
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/tenants/current/:
get:
operationId: core_tenants_current_retrieve
@@ -2280,6 +2515,34 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/tokens/{identifier}/used_by/:
+ get:
+ operationId: core_tokens_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: identifier
+ schema:
+ type: string
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/tokens/{identifier}/view_key/:
get:
operationId: core_tokens_view_key_retrieve
@@ -2411,6 +2674,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/user_consent/{id}/used_by/:
+ get:
+ operationId: core_user_consent_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this User Consent.
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/users/:
get:
operationId: core_users_list
@@ -2692,6 +2984,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/core/users/{id}/used_by/:
+ get:
+ operationId: core_users_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this User.
+ required: true
+ tags:
+ - core
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/core/users/me/:
get:
operationId: core_users_me_retrieve
@@ -2925,6 +3246,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/crypto/certificatekeypairs/{kp_uuid}/used_by/:
+ get:
+ operationId: crypto_certificatekeypairs_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: kp_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Certificate-Key Pair.
+ required: true
+ tags:
+ - crypto
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/crypto/certificatekeypairs/{kp_uuid}/view_certificate/:
get:
operationId: crypto_certificatekeypairs_view_certificate_retrieve
@@ -3419,6 +3770,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/events/notifications/{uuid}/used_by/:
+ get:
+ operationId: events_notifications_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Notification.
+ required: true
+ tags:
+ - events
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/events/rules/:
get:
operationId: events_rules_list
@@ -3623,6 +4004,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/events/rules/{pbm_uuid}/used_by/:
+ get:
+ operationId: events_rules_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: pbm_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Notification Rule.
+ required: true
+ tags:
+ - events
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/events/transports/:
get:
operationId: events_transports_list
@@ -3859,6 +4270,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/events/transports/{uuid}/used_by/:
+ get:
+ operationId: events_transports_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Notification Transport.
+ required: true
+ tags:
+ - events
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/flows/bindings/:
get:
operationId: flows_bindings_list
@@ -4111,6 +4552,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/flows/bindings/{fsb_uuid}/used_by/:
+ get:
+ operationId: flows_bindings_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: fsb_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Flow Stage Binding.
+ required: true
+ tags:
+ - flows
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/flows/executor/{flow_slug}/:
get:
operationId: flows_executor_get
@@ -4563,6 +5034,35 @@ paths:
description: Bad request
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/flows/instances/{slug}/used_by/:
+ get:
+ operationId: flows_instances_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Visible in the URL.
+ required: true
+ tags:
+ - flows
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/flows/instances/cache_clear/:
post:
operationId: flows_instances_cache_clear_create
@@ -4722,6 +5222,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/oauth2/authorization_codes/{id}/used_by/:
+ get:
+ operationId: oauth2_authorization_codes_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this Authorization Code.
+ required: true
+ tags:
+ - oauth2
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/oauth2/refresh_tokens/:
get:
operationId: oauth2_refresh_tokens_list
@@ -4824,6 +5353,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/oauth2/refresh_tokens/{id}/used_by/:
+ get:
+ operationId: oauth2_refresh_tokens_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this OAuth2 Token.
+ required: true
+ tags:
+ - oauth2
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/outposts/instances/:
get:
operationId: outposts_instances_list
@@ -5078,6 +5636,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/outposts/instances/{uuid}/used_by/:
+ get:
+ operationId: outposts_instances_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this outpost.
+ required: true
+ tags:
+ - outposts
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/outposts/instances/default_settings/:
get:
operationId: outposts_instances_default_settings_retrieve
@@ -5370,6 +5958,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/outposts/service_connections/all/{uuid}/used_by/:
+ get:
+ operationId: outposts_service_connections_all_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Outpost Service-Connection.
+ required: true
+ tags:
+ - outposts
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/outposts/service_connections/all/types/:
get:
operationId: outposts_service_connections_all_types_list
@@ -5596,6 +6214,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/outposts/service_connections/docker/{uuid}/used_by/:
+ get:
+ operationId: outposts_service_connections_docker_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Docker Service-Connection.
+ required: true
+ tags:
+ - outposts
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/outposts/service_connections/kubernetes/:
get:
operationId: outposts_service_connections_kubernetes_list
@@ -5800,6 +6448,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/outposts/service_connections/kubernetes/{uuid}/used_by/:
+ get:
+ operationId: outposts_service_connections_kubernetes_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Kubernetes Service-Connection.
+ required: true
+ tags:
+ - outposts
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/all/:
get:
operationId: policies_all_list
@@ -5944,6 +6622,36 @@ paths:
description: Invalid parameters
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/all/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_all_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/all/cache_clear/:
post:
operationId: policies_all_cache_clear_create
@@ -6228,6 +6936,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/bindings/{policy_binding_uuid}/used_by/:
+ get:
+ operationId: policies_bindings_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_binding_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Policy Binding.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/dummy/:
get:
operationId: policies_dummy_list
@@ -6430,6 +7168,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/dummy/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_dummy_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Dummy Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/event_matcher/:
get:
operationId: policies_event_matcher_list
@@ -6632,6 +7400,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/event_matcher/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_event_matcher_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Event Matcher Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/expression/:
get:
operationId: policies_expression_list
@@ -6836,6 +7634,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/expression/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_expression_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Expression Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/haveibeenpwned/:
get:
operationId: policies_haveibeenpwned_list
@@ -7038,6 +7866,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/haveibeenpwned/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_haveibeenpwned_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Have I Been Pwned Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/password/:
get:
operationId: policies_password_list
@@ -7242,6 +8100,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/password/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_password_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Password Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/password_expiry/:
get:
operationId: policies_password_expiry_list
@@ -7446,6 +8334,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/password_expiry/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_password_expiry_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Password Expiry Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/reputation/:
get:
operationId: policies_reputation_list
@@ -7648,6 +8566,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/reputation/{policy_uuid}/used_by/:
+ get:
+ operationId: policies_reputation_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: policy_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Reputation Policy.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/reputation/ips/:
get:
operationId: policies_reputation_ips_list
@@ -7750,6 +8698,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/reputation/ips/{id}/used_by/:
+ get:
+ operationId: policies_reputation_ips_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this ip reputation.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/policies/reputation/users/:
get:
operationId: policies_reputation_users_list
@@ -7852,6 +8829,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/policies/reputation/users/{id}/used_by/:
+ get:
+ operationId: policies_reputation_users_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this user reputation.
+ required: true
+ tags:
+ - policies
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/propertymappings/all/:
get:
operationId: propertymappings_all_list
@@ -7996,6 +9002,36 @@ paths:
description: Invalid parameters
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/propertymappings/all/{pm_uuid}/used_by/:
+ get:
+ operationId: propertymappings_all_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: pm_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Property Mapping.
+ required: true
+ tags:
+ - propertymappings
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/propertymappings/all/types/:
get:
operationId: propertymappings_all_types_list
@@ -8222,6 +9258,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/propertymappings/ldap/{pm_uuid}/used_by/:
+ get:
+ operationId: propertymappings_ldap_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: pm_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this LDAP Property Mapping.
+ required: true
+ tags:
+ - propertymappings
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/propertymappings/saml/:
get:
operationId: propertymappings_saml_list
@@ -8426,6 +9492,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/propertymappings/saml/{pm_uuid}/used_by/:
+ get:
+ operationId: propertymappings_saml_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: pm_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this SAML Property Mapping.
+ required: true
+ tags:
+ - propertymappings
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/propertymappings/scope/:
get:
operationId: propertymappings_scope_list
@@ -8630,6 +9726,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/propertymappings/scope/{pm_uuid}/used_by/:
+ get:
+ operationId: propertymappings_scope_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: pm_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Scope Mapping.
+ required: true
+ tags:
+ - propertymappings
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/providers/all/:
get:
operationId: providers_all_list
@@ -8728,6 +9854,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/providers/all/{id}/used_by/:
+ get:
+ operationId: providers_all_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this provider.
+ required: true
+ tags:
+ - providers
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/providers/all/types/:
get:
operationId: providers_all_types_list
@@ -8950,6 +10105,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/providers/ldap/{id}/used_by/:
+ get:
+ operationId: providers_ldap_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this LDAP Provider.
+ required: true
+ tags:
+ - providers
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/providers/oauth2/:
get:
operationId: providers_oauth2_list
@@ -9179,6 +10363,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/providers/oauth2/{id}/used_by/:
+ get:
+ operationId: providers_oauth2_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this OAuth2/OpenID Provider.
+ required: true
+ tags:
+ - providers
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/providers/proxy/:
get:
operationId: providers_proxy_list
@@ -9379,6 +10592,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/providers/proxy/{id}/used_by/:
+ get:
+ operationId: providers_proxy_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this Proxy Provider.
+ required: true
+ tags:
+ - providers
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/providers/saml/:
get:
operationId: providers_saml_list
@@ -9613,6 +10855,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/providers/saml/{id}/used_by/:
+ get:
+ operationId: providers_saml_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this SAML Provider.
+ required: true
+ tags:
+ - providers
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/providers/saml/import_metadata/:
post:
operationId: providers_saml_import_metadata_create
@@ -9897,6 +11168,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/sources/all/{slug}/used_by/:
+ get:
+ operationId: sources_all_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Internal source name, used in URLs.
+ required: true
+ tags:
+ - sources
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/sources/all/types/:
get:
operationId: sources_all_types_list
@@ -10170,6 +11470,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/sources/ldap/{slug}/used_by/:
+ get:
+ operationId: sources_ldap_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Internal source name, used in URLs.
+ required: true
+ tags:
+ - sources
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/sources/oauth/:
get:
operationId: sources_oauth_list
@@ -10370,6 +11699,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/sources/oauth/{slug}/used_by/:
+ get:
+ operationId: sources_oauth_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Internal source name, used in URLs.
+ required: true
+ tags:
+ - sources
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/sources/oauth/source_types/:
get:
operationId: sources_oauth_source_types_list
@@ -10565,6 +11923,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/sources/oauth_user_connections/{id}/used_by/:
+ get:
+ operationId: sources_oauth_user_connections_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: id
+ schema:
+ type: integer
+ description: A unique integer value identifying this User OAuth Source Connection.
+ required: true
+ tags:
+ - sources
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/sources/plex/:
get:
operationId: sources_plex_list
@@ -10765,6 +12152,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/sources/plex/{slug}/used_by/:
+ get:
+ operationId: sources_plex_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Internal source name, used in URLs.
+ required: true
+ tags:
+ - sources
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/sources/plex/redeem_token/:
post:
operationId: sources_plex_redeem_token_create
@@ -11032,6 +12448,35 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/sources/saml/{slug}/used_by/:
+ get:
+ operationId: sources_saml_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: slug
+ schema:
+ type: string
+ description: Internal source name, used in URLs.
+ required: true
+ tags:
+ - sources
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/all/:
get:
operationId: stages_all_list
@@ -11132,6 +12577,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/all/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_all_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/all/types/:
get:
operationId: stages_all_types_list
@@ -11406,6 +12881,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/authenticator/duo/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_authenticator_duo_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Duo Authenticator Setup Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/authenticator/static/:
get:
operationId: stages_authenticator_static_list
@@ -11610,6 +13115,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/authenticator/static/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_authenticator_static_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Static Authenticator Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/authenticator/totp/:
get:
operationId: stages_authenticator_totp_list
@@ -11814,6 +13349,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/authenticator/totp/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_authenticator_totp_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this TOTP Authenticator Setup Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/authenticator/validate/:
get:
operationId: stages_authenticator_validate_list
@@ -12018,6 +13583,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/authenticator/validate/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_authenticator_validate_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Authenticator Validation Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/authenticator/webauthn/:
get:
operationId: stages_authenticator_webauthn_list
@@ -12222,6 +13817,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/authenticator/webauthn/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_authenticator_webauthn_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this WebAuthn Authenticator Setup Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/captcha/:
get:
operationId: stages_captcha_list
@@ -12426,6 +14051,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/captcha/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_captcha_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Captcha Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/consent/:
get:
operationId: stages_consent_list
@@ -12630,6 +14285,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/consent/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_consent_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Consent Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/deny/:
get:
operationId: stages_deny_list
@@ -12834,6 +14519,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/deny/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_deny_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Deny Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/dummy/:
get:
operationId: stages_dummy_list
@@ -13038,6 +14753,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/dummy/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_dummy_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Dummy Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/email/:
get:
operationId: stages_email_list
@@ -13242,6 +14987,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/email/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_email_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Email Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/email/templates/:
get:
operationId: stages_email_templates_list
@@ -13468,6 +15243,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/identification/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_identification_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Identification Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/invitation/invitations/:
get:
operationId: stages_invitation_invitations_list
@@ -13679,6 +15484,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/invitation/invitations/{invite_uuid}/used_by/:
+ get:
+ operationId: stages_invitation_invitations_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: invite_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Invitation.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/invitation/stages/:
get:
operationId: stages_invitation_stages_list
@@ -13883,6 +15718,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/invitation/stages/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_invitation_stages_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Invitation Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/password/:
get:
operationId: stages_password_list
@@ -14087,6 +15952,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/password/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_password_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Password Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/prompt/prompts/:
get:
operationId: stages_prompt_prompts_list
@@ -14319,6 +16214,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/prompt/prompts/{prompt_uuid}/used_by/:
+ get:
+ operationId: stages_prompt_prompts_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: prompt_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Prompt.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/prompt/stages/:
get:
operationId: stages_prompt_stages_list
@@ -14523,6 +16448,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/prompt/stages/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_prompt_stages_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this Prompt Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/user_delete/:
get:
operationId: stages_user_delete_list
@@ -14727,6 +16682,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/user_delete/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_user_delete_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this User Delete Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/user_login/:
get:
operationId: stages_user_login_list
@@ -14931,6 +16916,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/user_login/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_user_login_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this User Login Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/user_logout/:
get:
operationId: stages_user_logout_list
@@ -15135,6 +17150,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/user_logout/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_user_logout_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this User Logout Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
/api/v2beta/stages/user_write/:
get:
operationId: stages_user_write_list
@@ -15339,6 +17384,36 @@ paths:
$ref: '#/components/schemas/ValidationError'
'403':
$ref: '#/components/schemas/GenericError'
+ /api/v2beta/stages/user_write/{stage_uuid}/used_by/:
+ get:
+ operationId: stages_user_write_used_by_list
+ description: Get a list of all objects that use this object
+ parameters:
+ - in: path
+ name: stage_uuid
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this User Write Stage.
+ required: true
+ tags:
+ - stages
+ security:
+ - authentik: []
+ - cookieAuth: []
+ responses:
+ '200':
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UsedBy'
+ description: ''
+ '400':
+ $ref: '#/components/schemas/ValidationError'
+ '403':
+ $ref: '#/components/schemas/GenericError'
components:
schemas:
AccessDeniedChallenge:
@@ -15362,33 +17437,6 @@ components:
type: string
required:
- type
- ActionEnum:
- enum:
- - login
- - login_failed
- - logout
- - user_write
- - suspicious_request
- - password_set
- - secret_view
- - invitation_used
- - authorize_application
- - source_linked
- - impersonation_started
- - impersonation_ended
- - policy_execution
- - policy_exception
- - property_mapping_exception
- - system_task_execution
- - system_task_exception
- - configuration_error
- - model_created
- - model_updated
- - model_deleted
- - email_sent
- - update_available
- - custom_
- type: string
App:
type: object
description: Serialize Application info
@@ -17076,7 +19124,7 @@ components:
readOnly: true
action:
allOf:
- - $ref: '#/components/schemas/ActionEnum'
+ - $ref: '#/components/schemas/EventMatcherPolicyActionEnum'
description: Match created events with this action type. When left empty,
all action types will be matched.
client_ip:
@@ -17094,6 +19142,33 @@ components:
- pk
- verbose_name
- verbose_name_plural
+ EventMatcherPolicyActionEnum:
+ enum:
+ - login
+ - login_failed
+ - logout
+ - user_write
+ - suspicious_request
+ - password_set
+ - secret_view
+ - invitation_used
+ - authorize_application
+ - source_linked
+ - impersonation_started
+ - impersonation_ended
+ - policy_execution
+ - policy_exception
+ - property_mapping_exception
+ - system_task_execution
+ - system_task_exception
+ - configuration_error
+ - model_created
+ - model_updated
+ - model_deleted
+ - email_sent
+ - update_available
+ - custom_
+ type: string
EventMatcherPolicyRequest:
type: object
description: Event Matcher Policy Serializer
@@ -17107,7 +19182,7 @@ components:
will be logged. By default, only execution errors are logged.
action:
allOf:
- - $ref: '#/components/schemas/ActionEnum'
+ - $ref: '#/components/schemas/EventMatcherPolicyActionEnum'
description: Match created events with this action type. When left empty,
all action types will be matched.
client_ip:
@@ -22199,7 +24274,7 @@ components:
will be logged. By default, only execution errors are logged.
action:
allOf:
- - $ref: '#/components/schemas/ActionEnum'
+ - $ref: '#/components/schemas/EventMatcherPolicyActionEnum'
description: Match created events with this action type. When left empty,
all action types will be matched.
client_ip:
@@ -25448,6 +27523,33 @@ components:
required:
- challenge
- name
+ UsedBy:
+ type: object
+ description: A list of all objects referencing the queried object
+ properties:
+ app:
+ type: string
+ model_name:
+ type: string
+ pk:
+ type: string
+ name:
+ type: string
+ action:
+ $ref: '#/components/schemas/UsedByActionEnum'
+ required:
+ - action
+ - app
+ - model_name
+ - name
+ - pk
+ UsedByActionEnum:
+ enum:
+ - CASCADE
+ - CASCADE_MANY
+ - SET_NULL
+ - SET_DEFAULT
+ type: string
User:
type: object
description: User Serializer
diff --git a/web/src/elements/forms/DeleteForm.ts b/web/src/elements/forms/DeleteForm.ts
index 27c436c14..724070b1b 100644
--- a/web/src/elements/forms/DeleteForm.ts
+++ b/web/src/elements/forms/DeleteForm.ts
@@ -1,20 +1,30 @@
import { t } from "@lingui/macro";
-import { customElement, html, property, TemplateResult } from "lit-element";
+import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
import { EVENT_REFRESH } from "../../constants";
import { ModalButton } from "../buttons/ModalButton";
import { MessageLevel } from "../messages/Message";
import { showMessage } from "../messages/MessageContainer";
import "../buttons/SpinnerButton";
+import { UsedBy, UsedByActionEnum } from "authentik-api";
+import PFList from "@patternfly/patternfly/components/List/list.css";
+import { until } from "lit-html/directives/until";
@customElement("ak-forms-delete")
export class DeleteForm extends ModalButton {
+ static get styles(): CSSResult[] {
+ return super.styles.concat(PFList);
+ }
+
@property({attribute: false})
obj?: Record