Merge branch 'master' into next
This commit is contained in:
commit
9f7c941426
17
Pipfile.lock
generated
17
Pipfile.lock
generated
|
@ -116,18 +116,17 @@
|
||||||
},
|
},
|
||||||
"boto3": {
|
"boto3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2ade860f66fa6b9a9886d7ff2e5118e5efebc4807b863ef735d358ef730234ed",
|
"sha256:4cfab400cd9ca9b27b7dffb43f5675525ea5d36c81223d64d15542fdb16cdf7e",
|
||||||
"sha256:bbf727d770a9844834bfbf3f811db1d3438320897f67cfb21cdca5bb8fc23c13"
|
"sha256:b0808a58c54c595b6cc6271cbc14a09bb89f0951ca9e8b105d1e94bef3ed24a0"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.17.90"
|
"version": "==1.17.91"
|
||||||
},
|
},
|
||||||
"botocore": {
|
"botocore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:6ae4ff3405cc4fc69ff3673a8dd234bf869aa556ae1e0da050d7f2aa3c3edab6",
|
"sha256:462e75419e6537efb2709b7eb5b8c7ade007d30209416f0476bd7c51a2ddc78d"
|
||||||
"sha256:b301810c4bd6cab1b6eaf6bfd9f25abb27959b586c2e1689bbce035b3fb8ae66"
|
|
||||||
],
|
],
|
||||||
"version": "==1.20.90"
|
"version": "==1.20.91"
|
||||||
},
|
},
|
||||||
"cachetools": {
|
"cachetools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
@ -1167,10 +1166,10 @@
|
||||||
},
|
},
|
||||||
"websocket-client": {
|
"websocket-client": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:3e2bf58191d4619b161389a95bdce84ce9e0b24eb8107e7e590db682c2d0ca81",
|
"sha256:b68e4959d704768fa20e35c9d508c8dc2bbc041fd8d267c0d7345cffe2824568",
|
||||||
"sha256:abf306dc6351dcef07f4d40453037e51cc5d9da2ef60d0fc5d0fe3bcda255372"
|
"sha256:e5c333bfa9fa739538b652b6f8c8fc2559f1d364243c8a689d7c0e1d41c2e611"
|
||||||
],
|
],
|
||||||
"version": "==1.0.1"
|
"version": "==1.1.0"
|
||||||
},
|
},
|
||||||
"websockets": {
|
"websockets": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|
|
@ -29,6 +29,7 @@ from structlog.stdlib import get_logger
|
||||||
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
|
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
from authentik.core.api.providers import ProviderSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.models import Application, User
|
from authentik.core.models import Application, User
|
||||||
from authentik.events.models import EventAction
|
from authentik.events.models import EventAction
|
||||||
from authentik.policies.api.exec import PolicyTestResultSerializer
|
from authentik.policies.api.exec import PolicyTestResultSerializer
|
||||||
|
@ -73,7 +74,7 @@ class ApplicationSerializer(ModelSerializer):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ApplicationViewSet(ModelViewSet):
|
class ApplicationViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Application Viewset"""
|
"""Application Viewset"""
|
||||||
|
|
||||||
queryset = Application.objects.all()
|
queryset = Application.objects.all()
|
||||||
|
|
|
@ -11,6 +11,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
from ua_parser import user_agent_parser
|
from ua_parser import user_agent_parser
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.models import AuthenticatedSession
|
from authentik.core.models import AuthenticatedSession
|
||||||
from authentik.events.geo import GEOIP_READER, GeoIPDict
|
from authentik.events.geo import GEOIP_READER, GeoIPDict
|
||||||
|
|
||||||
|
@ -92,6 +93,7 @@ class AuthenticatedSessionSerializer(ModelSerializer):
|
||||||
class AuthenticatedSessionViewSet(
|
class AuthenticatedSessionViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -5,6 +5,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
from rest_framework_guardian.filters import ObjectPermissionsFilter
|
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.api.utils import is_dict
|
||||||
from authentik.core.models import Group
|
from authentik.core.models import Group
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ class GroupSerializer(ModelSerializer):
|
||||||
fields = ["pk", "name", "is_superuser", "parent", "users", "attributes"]
|
fields = ["pk", "name", "is_superuser", "parent", "users", "attributes"]
|
||||||
|
|
||||||
|
|
||||||
class GroupViewSet(ModelViewSet):
|
class GroupViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Group Viewset"""
|
"""Group Viewset"""
|
||||||
|
|
||||||
queryset = Group.objects.all()
|
queryset = Group.objects.all()
|
||||||
|
|
|
@ -14,6 +14,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import (
|
from authentik.core.api.utils import (
|
||||||
MetaNameSerializer,
|
MetaNameSerializer,
|
||||||
PassiveSerializer,
|
PassiveSerializer,
|
||||||
|
@ -65,6 +66,7 @@ class PropertyMappingSerializer(ManagedSerializer, ModelSerializer, MetaNameSeri
|
||||||
class PropertyMappingViewSet(
|
class PropertyMappingViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -9,6 +9,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||||
from rest_framework.viewsets import GenericViewSet
|
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.api.utils import MetaNameSerializer, TypeCreateSerializer
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
from authentik.lib.utils.reflection import all_subclasses
|
from authentik.lib.utils.reflection import all_subclasses
|
||||||
|
@ -48,6 +49,7 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer):
|
||||||
class ProviderViewSet(
|
class ProviderViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -10,6 +10,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
from structlog.stdlib import get_logger
|
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.api.utils import MetaNameSerializer, TypeCreateSerializer
|
||||||
from authentik.core.models import Source
|
from authentik.core.models import Source
|
||||||
from authentik.core.types import UserSettingSerializer
|
from authentik.core.types import UserSettingSerializer
|
||||||
|
@ -52,6 +53,7 @@ class SourceSerializer(ModelSerializer, MetaNameSerializer):
|
||||||
class SourceViewSet(
|
class SourceViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -9,6 +9,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
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.users import UserSerializer
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.core.models import Token, TokenIntents
|
from authentik.core.models import Token, TokenIntents
|
||||||
|
@ -43,7 +44,7 @@ class TokenViewSerializer(PassiveSerializer):
|
||||||
key = CharField(read_only=True)
|
key = CharField(read_only=True)
|
||||||
|
|
||||||
|
|
||||||
class TokenViewSet(ModelViewSet):
|
class TokenViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Token Viewset"""
|
"""Token Viewset"""
|
||||||
|
|
||||||
lookup_field = "identifier"
|
lookup_field = "identifier"
|
||||||
|
|
102
authentik/core/api/used_by.py
Normal file
102
authentik/core/api/used_by.py
Normal file
|
@ -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)
|
|
@ -25,6 +25,7 @@ from rest_framework_guardian.filters import ObjectPermissionsFilter
|
||||||
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
|
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.groups import GroupSerializer
|
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.api.utils import LinkSerializer, PassiveSerializer, is_dict
|
||||||
from authentik.core.middleware import (
|
from authentik.core.middleware import (
|
||||||
SESSION_IMPERSONATE_ORIGINAL_USER,
|
SESSION_IMPERSONATE_ORIGINAL_USER,
|
||||||
|
@ -131,7 +132,7 @@ class UsersFilter(FilterSet):
|
||||||
fields = ["username", "name", "is_active", "is_superuser", "attributes"]
|
fields = ["username", "name", "is_active", "is_superuser", "attributes"]
|
||||||
|
|
||||||
|
|
||||||
class UserViewSet(ModelViewSet):
|
class UserViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""User Viewset"""
|
"""User Viewset"""
|
||||||
|
|
||||||
queryset = User.objects.none()
|
queryset = User.objects.none()
|
||||||
|
|
|
@ -5,6 +5,7 @@ from typing import Any, Optional, Type
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
|
import django.db.models.options as options
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.contrib.auth.models import UserManager as DjangoUserManager
|
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")
|
DEFAULT_AVATAR = static("dist/assets/images/user_default.png")
|
||||||
|
|
||||||
|
|
||||||
|
options.DEFAULT_NAMES = options.DEFAULT_NAMES + ("authentik_used_by_shadows",)
|
||||||
|
|
||||||
|
|
||||||
def default_token_duration():
|
def default_token_duration():
|
||||||
"""Default duration a Token is valid"""
|
"""Default duration a Token is valid"""
|
||||||
return now() + timedelta(minutes=30)
|
return now() + timedelta(minutes=30)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
"""Crypto API Views"""
|
"""Crypto API Views"""
|
||||||
import django_filters
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||||
from cryptography.x509 import load_pem_x509_certificate
|
from cryptography.x509 import load_pem_x509_certificate
|
||||||
from django.http.response import HttpResponse
|
from django.http.response import HttpResponse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django_filters import FilterSet
|
||||||
|
from django_filters.filters import BooleanFilter
|
||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
@ -20,6 +21,7 @@ from rest_framework.serializers import ModelSerializer, ValidationError
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.crypto.builder import CertificateBuilder
|
from authentik.crypto.builder import CertificateBuilder
|
||||||
from authentik.crypto.models import CertificateKeyPair
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
|
@ -100,10 +102,10 @@ class CertificateGenerationSerializer(PassiveSerializer):
|
||||||
validity_days = IntegerField(initial=365)
|
validity_days = IntegerField(initial=365)
|
||||||
|
|
||||||
|
|
||||||
class CertificateKeyPairFilter(django_filters.FilterSet):
|
class CertificateKeyPairFilter(FilterSet):
|
||||||
"""Filter for certificates"""
|
"""Filter for certificates"""
|
||||||
|
|
||||||
has_key = django_filters.BooleanFilter(
|
has_key = BooleanFilter(
|
||||||
label="Only return certificate-key pairs with keys", method="filter_has_key"
|
label="Only return certificate-key pairs with keys", method="filter_has_key"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -117,7 +119,7 @@ class CertificateKeyPairFilter(django_filters.FilterSet):
|
||||||
fields = ["name"]
|
fields = ["name"]
|
||||||
|
|
||||||
|
|
||||||
class CertificateKeyPairViewSet(ModelViewSet):
|
class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""CertificateKeyPair Viewset"""
|
"""CertificateKeyPair Viewset"""
|
||||||
|
|
||||||
queryset = CertificateKeyPair.objects.all()
|
queryset = CertificateKeyPair.objects.all()
|
||||||
|
|
|
@ -4,10 +4,14 @@ import datetime
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import DeleteAction
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.crypto.api import CertificateKeyPairSerializer
|
from authentik.crypto.api import CertificateKeyPairSerializer
|
||||||
from authentik.crypto.builder import CertificateBuilder
|
from authentik.crypto.builder import CertificateBuilder
|
||||||
from authentik.crypto.models import CertificateKeyPair
|
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):
|
class TestCrypto(TestCase):
|
||||||
|
@ -91,3 +95,35 @@ class TestCrypto(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(200, response.status_code)
|
self.assertEqual(200, response.status_code)
|
||||||
self.assertIn("Content-Disposition", response)
|
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,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
|
@ -7,6 +7,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
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.api.event import EventSerializer
|
||||||
from authentik.events.models import Notification
|
from authentik.events.models import Notification
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ class NotificationViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.UpdateModelMixin,
|
mixins.UpdateModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -3,6 +3,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.groups import GroupSerializer
|
from authentik.core.api.groups import GroupSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.events.models import NotificationRule
|
from authentik.events.models import NotificationRule
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ class NotificationRuleSerializer(ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class NotificationRuleViewSet(ModelViewSet):
|
class NotificationRuleViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""NotificationRule Viewset"""
|
"""NotificationRule Viewset"""
|
||||||
|
|
||||||
queryset = NotificationRule.objects.all()
|
queryset = NotificationRule.objects.all()
|
||||||
|
|
|
@ -9,6 +9,7 @@ from rest_framework.serializers import ModelSerializer, Serializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.events.models import (
|
from authentik.events.models import (
|
||||||
Notification,
|
Notification,
|
||||||
NotificationSeverity,
|
NotificationSeverity,
|
||||||
|
@ -52,7 +53,7 @@ class NotificationTransportTestSerializer(Serializer):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class NotificationTransportViewSet(ModelViewSet):
|
class NotificationTransportViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""NotificationTransport Viewset"""
|
"""NotificationTransport Viewset"""
|
||||||
|
|
||||||
queryset = NotificationTransport.objects.all()
|
queryset = NotificationTransport.objects.all()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.flows.models import FlowStageBinding
|
from authentik.flows.models import FlowStageBinding
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ class FlowStageBindingSerializer(ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class FlowStageBindingViewSet(ModelViewSet):
|
class FlowStageBindingViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""FlowStageBinding Viewset"""
|
"""FlowStageBinding Viewset"""
|
||||||
|
|
||||||
queryset = FlowStageBinding.objects.all()
|
queryset = FlowStageBinding.objects.all()
|
||||||
|
|
|
@ -24,6 +24,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
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.core.api.utils import CacheSerializer, LinkSerializer
|
||||||
from authentik.flows.exceptions import FlowNonApplicableException
|
from authentik.flows.exceptions import FlowNonApplicableException
|
||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
|
@ -94,7 +95,7 @@ class DiagramElement:
|
||||||
return f"{self.identifier}=>{self.type}: {self.rest}"
|
return f"{self.identifier}=>{self.type}: {self.rest}"
|
||||||
|
|
||||||
|
|
||||||
class FlowViewSet(ModelViewSet):
|
class FlowViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Flow Viewset"""
|
"""Flow Viewset"""
|
||||||
|
|
||||||
queryset = Flow.objects.all()
|
queryset = Flow.objects.all()
|
||||||
|
|
|
@ -11,6 +11,7 @@ from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
from structlog.stdlib import get_logger
|
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.api.utils import MetaNameSerializer, TypeCreateSerializer
|
||||||
from authentik.core.types import UserSettingSerializer
|
from authentik.core.types import UserSettingSerializer
|
||||||
from authentik.flows.api.flows import FlowSerializer
|
from authentik.flows.api.flows import FlowSerializer
|
||||||
|
@ -49,6 +50,7 @@ class StageSerializer(ModelSerializer, MetaNameSerializer):
|
||||||
class StageViewSet(
|
class StageViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -72,7 +72,7 @@ class Stage(SerializerModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if hasattr(self, "__in_memory_type"):
|
if hasattr(self, "__in_memory_type"):
|
||||||
return f"In-memory Stage {getattr(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:
|
def in_memory_stage(view: Type["StageView"]) -> Stage:
|
||||||
|
@ -212,7 +212,7 @@ class FlowStageBinding(SerializerModel, PolicyBindingModel):
|
||||||
return FlowStageBindingSerializer
|
return FlowStageBindingSerializer
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"{self.target} #{self.order}"
|
return f"Flow-stage binding #{self.order} to {self.target}"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ from rest_framework.serializers import JSONField, ModelSerializer, ValidationErr
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
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.api.utils import PassiveSerializer, is_dict
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
|
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
|
||||||
|
@ -95,7 +96,7 @@ class OutpostHealthSerializer(PassiveSerializer):
|
||||||
version_outdated = BooleanField(read_only=True)
|
version_outdated = BooleanField(read_only=True)
|
||||||
|
|
||||||
|
|
||||||
class OutpostViewSet(ModelViewSet):
|
class OutpostViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Outpost Viewset"""
|
"""Outpost Viewset"""
|
||||||
|
|
||||||
queryset = Outpost.objects.all()
|
queryset = Outpost.objects.all()
|
||||||
|
|
|
@ -14,6 +14,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import (
|
from authentik.core.api.utils import (
|
||||||
MetaNameSerializer,
|
MetaNameSerializer,
|
||||||
PassiveSerializer,
|
PassiveSerializer,
|
||||||
|
@ -55,6 +56,7 @@ class ServiceConnectionStateSerializer(PassiveSerializer):
|
||||||
class ServiceConnectionViewSet(
|
class ServiceConnectionViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
@ -105,7 +107,7 @@ class DockerServiceConnectionSerializer(ServiceConnectionSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class DockerServiceConnectionViewSet(ModelViewSet):
|
class DockerServiceConnectionViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""DockerServiceConnection Viewset"""
|
"""DockerServiceConnection Viewset"""
|
||||||
|
|
||||||
queryset = DockerServiceConnection.objects.all()
|
queryset = DockerServiceConnection.objects.all()
|
||||||
|
@ -139,7 +141,7 @@ class KubernetesServiceConnectionSerializer(ServiceConnectionSerializer):
|
||||||
fields = ServiceConnectionSerializer.Meta.fields + ["kubeconfig"]
|
fields = ServiceConnectionSerializer.Meta.fields + ["kubeconfig"]
|
||||||
|
|
||||||
|
|
||||||
class KubernetesServiceConnectionViewSet(ModelViewSet):
|
class KubernetesServiceConnectionViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""KubernetesServiceConnection Viewset"""
|
"""KubernetesServiceConnection Viewset"""
|
||||||
|
|
||||||
queryset = KubernetesServiceConnection.objects.all()
|
queryset = KubernetesServiceConnection.objects.all()
|
||||||
|
|
|
@ -11,6 +11,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||||
from structlog.stdlib import get_logger
|
from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.core.api.groups import GroupSerializer
|
from authentik.core.api.groups import GroupSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.users import UserSerializer
|
from authentik.core.api.users import UserSerializer
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.models import PolicyBinding, PolicyBindingModel
|
from authentik.policies.models import PolicyBinding, PolicyBindingModel
|
||||||
|
@ -99,7 +100,7 @@ class PolicyBindingSerializer(ModelSerializer):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
class PolicyBindingViewSet(ModelViewSet):
|
class PolicyBindingViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""PolicyBinding Viewset"""
|
"""PolicyBinding Viewset"""
|
||||||
|
|
||||||
queryset = (
|
queryset = (
|
||||||
|
|
|
@ -14,6 +14,7 @@ from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.applications import user_app_cache_key
|
from authentik.core.api.applications import user_app_cache_key
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import (
|
from authentik.core.api.utils import (
|
||||||
CacheSerializer,
|
CacheSerializer,
|
||||||
MetaNameSerializer,
|
MetaNameSerializer,
|
||||||
|
@ -79,6 +80,7 @@ class PolicySerializer(ModelSerializer, MetaNameSerializer):
|
||||||
class PolicyViewSet(
|
class PolicyViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Dummy Policy API Views"""
|
"""Dummy Policy API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.dummy.models import DummyPolicy
|
from authentik.policies.dummy.models import DummyPolicy
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ class DummyPolicySerializer(PolicySerializer):
|
||||||
fields = PolicySerializer.Meta.fields + ["result", "wait_min", "wait_max"]
|
fields = PolicySerializer.Meta.fields + ["result", "wait_min", "wait_max"]
|
||||||
|
|
||||||
|
|
||||||
class DummyPolicyViewSet(ModelViewSet):
|
class DummyPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Dummy Viewset"""
|
"""Dummy Viewset"""
|
||||||
|
|
||||||
queryset = DummyPolicy.objects.all()
|
queryset = DummyPolicy.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Event Matcher Policy API"""
|
"""Event Matcher Policy API"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.event_matcher.models import EventMatcherPolicy
|
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"""
|
"""Event Matcher Policy Viewset"""
|
||||||
|
|
||||||
queryset = EventMatcherPolicy.objects.all()
|
queryset = EventMatcherPolicy.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Password Expiry Policy API Views"""
|
"""Password Expiry Policy API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.expiry.models import PasswordExpiryPolicy
|
from authentik.policies.expiry.models import PasswordExpiryPolicy
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ class PasswordExpiryPolicySerializer(PolicySerializer):
|
||||||
fields = PolicySerializer.Meta.fields + ["days", "deny_only"]
|
fields = PolicySerializer.Meta.fields + ["days", "deny_only"]
|
||||||
|
|
||||||
|
|
||||||
class PasswordExpiryPolicyViewSet(ModelViewSet):
|
class PasswordExpiryPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Password Expiry Viewset"""
|
"""Password Expiry Viewset"""
|
||||||
|
|
||||||
queryset = PasswordExpiryPolicy.objects.all()
|
queryset = PasswordExpiryPolicy.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Expression Policy API"""
|
"""Expression Policy API"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.expression.evaluator import PolicyEvaluator
|
from authentik.policies.expression.evaluator import PolicyEvaluator
|
||||||
from authentik.policies.expression.models import ExpressionPolicy
|
from authentik.policies.expression.models import ExpressionPolicy
|
||||||
|
@ -20,7 +21,7 @@ class ExpressionPolicySerializer(PolicySerializer):
|
||||||
fields = PolicySerializer.Meta.fields + ["expression"]
|
fields = PolicySerializer.Meta.fields + ["expression"]
|
||||||
|
|
||||||
|
|
||||||
class ExpressionPolicyViewSet(ModelViewSet):
|
class ExpressionPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Source Viewset"""
|
"""Source Viewset"""
|
||||||
|
|
||||||
queryset = ExpressionPolicy.objects.all()
|
queryset = ExpressionPolicy.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Source API Views"""
|
"""Source API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.hibp.models import HaveIBeenPwendPolicy
|
from authentik.policies.hibp.models import HaveIBeenPwendPolicy
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ class HaveIBeenPwendPolicySerializer(PolicySerializer):
|
||||||
fields = PolicySerializer.Meta.fields + ["password_field", "allowed_count"]
|
fields = PolicySerializer.Meta.fields + ["password_field", "allowed_count"]
|
||||||
|
|
||||||
|
|
||||||
class HaveIBeenPwendPolicyViewSet(ModelViewSet):
|
class HaveIBeenPwendPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Source Viewset"""
|
"""Source Viewset"""
|
||||||
|
|
||||||
queryset = HaveIBeenPwendPolicy.objects.all()
|
queryset = HaveIBeenPwendPolicy.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Password Policy API Views"""
|
"""Password Policy API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.policies.api.policies import PolicySerializer
|
from authentik.policies.api.policies import PolicySerializer
|
||||||
from authentik.policies.password.models import PasswordPolicy
|
from authentik.policies.password.models import PasswordPolicy
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class PasswordPolicySerializer(PolicySerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class PasswordPolicyViewSet(ModelViewSet):
|
class PasswordPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Password Policy Viewset"""
|
"""Password Policy Viewset"""
|
||||||
|
|
||||||
queryset = PasswordPolicy.objects.all()
|
queryset = PasswordPolicy.objects.all()
|
||||||
|
|
|
@ -3,6 +3,7 @@ from rest_framework import mixins
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
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.api.policies import PolicySerializer
|
||||||
from authentik.policies.reputation.models import (
|
from authentik.policies.reputation.models import (
|
||||||
IPReputation,
|
IPReputation,
|
||||||
|
@ -23,7 +24,7 @@ class ReputationPolicySerializer(PolicySerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ReputationPolicyViewSet(ModelViewSet):
|
class ReputationPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Reputation Policy Viewset"""
|
"""Reputation Policy Viewset"""
|
||||||
|
|
||||||
queryset = ReputationPolicy.objects.all()
|
queryset = ReputationPolicy.objects.all()
|
||||||
|
@ -46,6 +47,7 @@ class IPReputationSerializer(ModelSerializer):
|
||||||
class IPReputationViewSet(
|
class IPReputationViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
@ -74,6 +76,7 @@ class UserReputationSerializer(ModelSerializer):
|
||||||
class UserReputationViewSet(
|
class UserReputationViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -4,6 +4,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
from authentik.core.api.providers import ProviderSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.providers.ldap.models import LDAPProvider
|
from authentik.providers.ldap.models import LDAPProvider
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ class LDAPProviderSerializer(ProviderSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class LDAPProviderViewSet(ModelViewSet):
|
class LDAPProviderViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""LDAPProvider Viewset"""
|
"""LDAPProvider Viewset"""
|
||||||
|
|
||||||
queryset = LDAPProvider.objects.all()
|
queryset = LDAPProvider.objects.all()
|
||||||
|
|
|
@ -11,6 +11,7 @@ from rest_framework.serializers import ValidationError
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
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.api.utils import PassiveSerializer
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
|
from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
|
||||||
|
@ -61,7 +62,7 @@ class OAuth2ProviderSetupURLs(PassiveSerializer):
|
||||||
logout = ReadOnlyField()
|
logout = ReadOnlyField()
|
||||||
|
|
||||||
|
|
||||||
class OAuth2ProviderViewSet(ModelViewSet):
|
class OAuth2ProviderViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""OAuth2Provider Viewset"""
|
"""OAuth2Provider Viewset"""
|
||||||
|
|
||||||
queryset = OAuth2Provider.objects.all()
|
queryset = OAuth2Provider.objects.all()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.propertymappings import PropertyMappingSerializer
|
from authentik.core.api.propertymappings import PropertyMappingSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.providers.oauth2.models import ScopeMapping
|
from authentik.providers.oauth2.models import ScopeMapping
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ class ScopeMappingSerializer(PropertyMappingSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ScopeMappingViewSet(ModelViewSet):
|
class ScopeMappingViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""ScopeMapping Viewset"""
|
"""ScopeMapping Viewset"""
|
||||||
|
|
||||||
queryset = ScopeMapping.objects.all()
|
queryset = ScopeMapping.objects.all()
|
||||||
|
|
|
@ -10,6 +10,7 @@ from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet
|
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.users import UserSerializer
|
||||||
from authentik.core.api.utils import MetaNameSerializer
|
from authentik.core.api.utils import MetaNameSerializer
|
||||||
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
|
from authentik.providers.oauth2.api.provider import OAuth2ProviderSerializer
|
||||||
|
@ -57,6 +58,7 @@ class RefreshTokenModelSerializer(ExpiringBaseGrantModelSerializer):
|
||||||
class AuthorizationCodeViewSet(
|
class AuthorizationCodeViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
@ -82,6 +84,7 @@ class AuthorizationCodeViewSet(
|
||||||
class RefreshTokenViewSet(
|
class RefreshTokenViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -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",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -215,8 +215,7 @@ class OAuth2Provider(Provider):
|
||||||
rsa_key = models.ForeignKey(
|
rsa_key = models.ForeignKey(
|
||||||
CertificateKeyPair,
|
CertificateKeyPair,
|
||||||
verbose_name=_("RSA Key"),
|
verbose_name=_("RSA Key"),
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.SET_NULL,
|
||||||
blank=True,
|
|
||||||
null=True,
|
null=True,
|
||||||
help_text=_(
|
help_text=_(
|
||||||
"Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
|
"Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
|
||||||
|
|
|
@ -8,6 +8,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
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.api.utils import PassiveSerializer
|
||||||
from authentik.providers.oauth2.views.provider import ProviderInfoView
|
from authentik.providers.oauth2.views.provider import ProviderInfoView
|
||||||
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
|
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
|
||||||
|
@ -76,7 +77,7 @@ class ProxyProviderSerializer(ProviderSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class ProxyProviderViewSet(ModelViewSet):
|
class ProxyProviderViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""ProxyProvider Viewset"""
|
"""ProxyProvider Viewset"""
|
||||||
|
|
||||||
queryset = ProxyProvider.objects.all()
|
queryset = ProxyProvider.objects.all()
|
||||||
|
|
|
@ -167,3 +167,4 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
|
||||||
|
|
||||||
verbose_name = _("Proxy Provider")
|
verbose_name = _("Proxy Provider")
|
||||||
verbose_name_plural = _("Proxy Providers")
|
verbose_name_plural = _("Proxy Providers")
|
||||||
|
authentik_used_by_shadows = ["authentik_providers_oauth2.oauth2provider"]
|
||||||
|
|
|
@ -21,6 +21,7 @@ from structlog.stdlib import get_logger
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.propertymappings import PropertyMappingSerializer
|
from authentik.core.api.propertymappings import PropertyMappingSerializer
|
||||||
from authentik.core.api.providers import ProviderSerializer
|
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.api.utils import PassiveSerializer
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
from authentik.flows.models import Flow, FlowDesignation
|
from authentik.flows.models import Flow, FlowDesignation
|
||||||
|
@ -75,7 +76,7 @@ class SAMLProviderImportSerializer(PassiveSerializer):
|
||||||
file = FileField()
|
file = FileField()
|
||||||
|
|
||||||
|
|
||||||
class SAMLProviderViewSet(ModelViewSet):
|
class SAMLProviderViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""SAMLProvider Viewset"""
|
"""SAMLProvider Viewset"""
|
||||||
|
|
||||||
queryset = SAMLProvider.objects.all()
|
queryset = SAMLProvider.objects.all()
|
||||||
|
@ -166,7 +167,7 @@ class SAMLPropertyMappingSerializer(PropertyMappingSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SAMLPropertyMappingViewSet(ModelViewSet):
|
class SAMLPropertyMappingViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""SAMLPropertyMapping Viewset"""
|
"""SAMLPropertyMapping Viewset"""
|
||||||
|
|
||||||
queryset = SAMLPropertyMapping.objects.all()
|
queryset = SAMLPropertyMapping.objects.all()
|
||||||
|
|
|
@ -10,6 +10,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||||
from authentik.admin.api.tasks import TaskSerializer
|
from authentik.admin.api.tasks import TaskSerializer
|
||||||
from authentik.core.api.propertymappings import PropertyMappingSerializer
|
from authentik.core.api.propertymappings import PropertyMappingSerializer
|
||||||
from authentik.core.api.sources import SourceSerializer
|
from authentik.core.api.sources import SourceSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.events.monitored_tasks import TaskInfo
|
from authentik.events.monitored_tasks import TaskInfo
|
||||||
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
|
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ class LDAPSourceSerializer(SourceSerializer):
|
||||||
extra_kwargs = {"bind_password": {"write_only": True}}
|
extra_kwargs = {"bind_password": {"write_only": True}}
|
||||||
|
|
||||||
|
|
||||||
class LDAPSourceViewSet(ModelViewSet):
|
class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""LDAP Source Viewset"""
|
"""LDAP Source Viewset"""
|
||||||
|
|
||||||
queryset = LDAPSource.objects.all()
|
queryset = LDAPSource.objects.all()
|
||||||
|
@ -75,7 +76,7 @@ class LDAPPropertyMappingSerializer(PropertyMappingSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class LDAPPropertyMappingViewSet(ModelViewSet):
|
class LDAPPropertyMappingViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""LDAP PropertyMapping Viewset"""
|
"""LDAP PropertyMapping Viewset"""
|
||||||
|
|
||||||
queryset = LDAPPropertyMapping.objects.all()
|
queryset = LDAPPropertyMapping.objects.all()
|
||||||
|
|
|
@ -9,6 +9,7 @@ from rest_framework.serializers import ValidationError
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.sources import SourceSerializer
|
from authentik.core.api.sources import SourceSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.sources.oauth.models import OAuthSource
|
from authentik.sources.oauth.models import OAuthSource
|
||||||
from authentik.sources.oauth.types.manager import MANAGER
|
from authentik.sources.oauth.types.manager import MANAGER
|
||||||
|
@ -78,7 +79,7 @@ class OAuthSourceSerializer(SourceSerializer):
|
||||||
extra_kwargs = {"consumer_secret": {"write_only": True}}
|
extra_kwargs = {"consumer_secret": {"write_only": True}}
|
||||||
|
|
||||||
|
|
||||||
class OAuthSourceViewSet(ModelViewSet):
|
class OAuthSourceViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Source Viewset"""
|
"""Source Viewset"""
|
||||||
|
|
||||||
queryset = OAuthSource.objects.all()
|
queryset = OAuthSource.objects.all()
|
||||||
|
|
|
@ -6,6 +6,7 @@ from rest_framework.viewsets import GenericViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
from authentik.core.api.sources import SourceSerializer
|
from authentik.core.api.sources import SourceSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.sources.oauth.models import UserOAuthSourceConnection
|
from authentik.sources.oauth.models import UserOAuthSourceConnection
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ class UserOAuthSourceConnectionViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.UpdateModelMixin,
|
mixins.UpdateModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -14,6 +14,7 @@ from structlog.stdlib import get_logger
|
||||||
|
|
||||||
from authentik.api.decorators import permission_required
|
from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.sources import SourceSerializer
|
from authentik.core.api.sources import SourceSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.flows.challenge import RedirectChallenge
|
from authentik.flows.challenge import RedirectChallenge
|
||||||
from authentik.flows.views import to_stage_response
|
from authentik.flows.views import to_stage_response
|
||||||
|
@ -42,7 +43,7 @@ class PlexTokenRedeemSerializer(PassiveSerializer):
|
||||||
plex_token = CharField()
|
plex_token = CharField()
|
||||||
|
|
||||||
|
|
||||||
class PlexSourceViewSet(ModelViewSet):
|
class PlexSourceViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Plex source Viewset"""
|
"""Plex source Viewset"""
|
||||||
|
|
||||||
queryset = PlexSource.objects.all()
|
queryset = PlexSource.objects.all()
|
||||||
|
|
|
@ -7,6 +7,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.sources import SourceSerializer
|
from authentik.core.api.sources import SourceSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.providers.saml.api import SAMLMetadataSerializer
|
from authentik.providers.saml.api import SAMLMetadataSerializer
|
||||||
from authentik.sources.saml.models import SAMLSource
|
from authentik.sources.saml.models import SAMLSource
|
||||||
from authentik.sources.saml.processors.metadata import MetadataProcessor
|
from authentik.sources.saml.processors.metadata import MetadataProcessor
|
||||||
|
@ -33,7 +34,7 @@ class SAMLSourceSerializer(SourceSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SAMLSourceViewSet(ModelViewSet):
|
class SAMLSourceViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""SAMLSource Viewset"""
|
"""SAMLSource Viewset"""
|
||||||
|
|
||||||
queryset = SAMLSource.objects.all()
|
queryset = SAMLSource.objects.all()
|
||||||
|
|
|
@ -12,6 +12,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||||
from authentik.stages.authenticator_duo.stage import (
|
from authentik.stages.authenticator_duo.stage import (
|
||||||
|
@ -37,7 +38,7 @@ class AuthenticatorDuoStageSerializer(StageSerializer):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorDuoStageViewSet(ModelViewSet):
|
class AuthenticatorDuoStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""AuthenticatorDuoStage Viewset"""
|
"""AuthenticatorDuoStage Viewset"""
|
||||||
|
|
||||||
queryset = AuthenticatorDuoStage.objects.all()
|
queryset = AuthenticatorDuoStage.objects.all()
|
||||||
|
@ -78,6 +79,7 @@ class DuoDeviceViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.UpdateModelMixin,
|
mixins.UpdateModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -8,6 +8,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.authenticator_static.models import AuthenticatorStaticStage
|
from authentik.stages.authenticator_static.models import AuthenticatorStaticStage
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class AuthenticatorStaticStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields + ["configure_flow", "token_count"]
|
fields = StageSerializer.Meta.fields + ["configure_flow", "token_count"]
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorStaticStageViewSet(ModelViewSet):
|
class AuthenticatorStaticStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""AuthenticatorStaticStage Viewset"""
|
"""AuthenticatorStaticStage Viewset"""
|
||||||
|
|
||||||
queryset = AuthenticatorStaticStage.objects.all()
|
queryset = AuthenticatorStaticStage.objects.all()
|
||||||
|
@ -52,6 +53,7 @@ class StaticDeviceViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.UpdateModelMixin,
|
mixins.UpdateModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -8,6 +8,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage
|
from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class AuthenticatorTOTPStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields + ["configure_flow", "digits"]
|
fields = StageSerializer.Meta.fields + ["configure_flow", "digits"]
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorTOTPStageViewSet(ModelViewSet):
|
class AuthenticatorTOTPStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""AuthenticatorTOTPStage Viewset"""
|
"""AuthenticatorTOTPStage Viewset"""
|
||||||
|
|
||||||
queryset = AuthenticatorTOTPStage.objects.all()
|
queryset = AuthenticatorTOTPStage.objects.all()
|
||||||
|
@ -45,6 +46,7 @@ class TOTPDeviceViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.UpdateModelMixin,
|
mixins.UpdateModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
from rest_framework.serializers import ValidationError
|
from rest_framework.serializers import ValidationError
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.flows.models import NotConfiguredAction
|
from authentik.flows.models import NotConfiguredAction
|
||||||
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
|
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
|
||||||
|
@ -32,7 +33,7 @@ class AuthenticatorValidateStageSerializer(StageSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorValidateStageViewSet(ModelViewSet):
|
class AuthenticatorValidateStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""AuthenticatorValidateStage Viewset"""
|
"""AuthenticatorValidateStage Viewset"""
|
||||||
|
|
||||||
queryset = AuthenticatorValidateStage.objects.all()
|
queryset = AuthenticatorValidateStage.objects.all()
|
||||||
|
|
|
@ -7,6 +7,7 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.authenticator_webauthn.models import (
|
from authentik.stages.authenticator_webauthn.models import (
|
||||||
AuthenticateWebAuthnStage,
|
AuthenticateWebAuthnStage,
|
||||||
|
@ -23,7 +24,7 @@ class AuthenticateWebAuthnStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields + ["configure_flow"]
|
fields = StageSerializer.Meta.fields + ["configure_flow"]
|
||||||
|
|
||||||
|
|
||||||
class AuthenticateWebAuthnStageViewSet(ModelViewSet):
|
class AuthenticateWebAuthnStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""AuthenticateWebAuthnStage Viewset"""
|
"""AuthenticateWebAuthnStage Viewset"""
|
||||||
|
|
||||||
queryset = AuthenticateWebAuthnStage.objects.all()
|
queryset = AuthenticateWebAuthnStage.objects.all()
|
||||||
|
@ -44,6 +45,7 @@ class WebAuthnDeviceViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.UpdateModelMixin,
|
mixins.UpdateModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""CaptchaStage API Views"""
|
"""CaptchaStage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.captcha.models import CaptchaStage
|
from authentik.stages.captcha.models import CaptchaStage
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ class CaptchaStageSerializer(StageSerializer):
|
||||||
extra_kwargs = {"private_key": {"write_only": True}}
|
extra_kwargs = {"private_key": {"write_only": True}}
|
||||||
|
|
||||||
|
|
||||||
class CaptchaStageViewSet(ModelViewSet):
|
class CaptchaStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""CaptchaStage Viewset"""
|
"""CaptchaStage Viewset"""
|
||||||
|
|
||||||
queryset = CaptchaStage.objects.all()
|
queryset = CaptchaStage.objects.all()
|
||||||
|
|
|
@ -6,6 +6,7 @@ from rest_framework.filters import OrderingFilter, SearchFilter
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.applications import ApplicationSerializer
|
from authentik.core.api.applications import ApplicationSerializer
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.users import UserSerializer
|
from authentik.core.api.users import UserSerializer
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.consent.models import ConsentStage, UserConsent
|
from authentik.stages.consent.models import ConsentStage, UserConsent
|
||||||
|
@ -20,7 +21,7 @@ class ConsentStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields + ["mode", "consent_expire_in"]
|
fields = StageSerializer.Meta.fields + ["mode", "consent_expire_in"]
|
||||||
|
|
||||||
|
|
||||||
class ConsentStageViewSet(ModelViewSet):
|
class ConsentStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""ConsentStage Viewset"""
|
"""ConsentStage Viewset"""
|
||||||
|
|
||||||
queryset = ConsentStage.objects.all()
|
queryset = ConsentStage.objects.all()
|
||||||
|
@ -42,6 +43,7 @@ class UserConsentSerializer(StageSerializer):
|
||||||
class UserConsentViewSet(
|
class UserConsentViewSet(
|
||||||
mixins.RetrieveModelMixin,
|
mixins.RetrieveModelMixin,
|
||||||
mixins.DestroyModelMixin,
|
mixins.DestroyModelMixin,
|
||||||
|
UsedByMixin,
|
||||||
mixins.ListModelMixin,
|
mixins.ListModelMixin,
|
||||||
GenericViewSet,
|
GenericViewSet,
|
||||||
):
|
):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""deny Stage API Views"""
|
"""deny Stage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.deny.models import DenyStage
|
from authentik.stages.deny.models import DenyStage
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class DenyStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields
|
fields = StageSerializer.Meta.fields
|
||||||
|
|
||||||
|
|
||||||
class DenyStageViewSet(ModelViewSet):
|
class DenyStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""DenyStage Viewset"""
|
"""DenyStage Viewset"""
|
||||||
|
|
||||||
queryset = DenyStage.objects.all()
|
queryset = DenyStage.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""DummyStage API Views"""
|
"""DummyStage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.dummy.models import DummyStage
|
from authentik.stages.dummy.models import DummyStage
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class DummyStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields
|
fields = StageSerializer.Meta.fields
|
||||||
|
|
||||||
|
|
||||||
class DummyStageViewSet(ModelViewSet):
|
class DummyStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""DummyStage Viewset"""
|
"""DummyStage Viewset"""
|
||||||
|
|
||||||
queryset = DummyStage.objects.all()
|
queryset = DummyStage.objects.all()
|
||||||
|
|
|
@ -6,6 +6,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ValidationError
|
from rest_framework.serializers import ValidationError
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import TypeCreateSerializer
|
from authentik.core.api.utils import TypeCreateSerializer
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.email.models import EmailStage, get_template_choices
|
from authentik.stages.email.models import EmailStage, get_template_choices
|
||||||
|
@ -46,7 +47,7 @@ class EmailStageSerializer(StageSerializer):
|
||||||
extra_kwargs = {"password": {"write_only": True}}
|
extra_kwargs = {"password": {"write_only": True}}
|
||||||
|
|
||||||
|
|
||||||
class EmailStageViewSet(ModelViewSet):
|
class EmailStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""EmailStage Viewset"""
|
"""EmailStage Viewset"""
|
||||||
|
|
||||||
queryset = EmailStage.objects.all()
|
queryset = EmailStage.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Identification Stage API Views"""
|
"""Identification Stage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.identification.models import IdentificationStage
|
from authentik.stages.identification.models import IdentificationStage
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ class IdentificationStageSerializer(StageSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class IdentificationStageViewSet(ModelViewSet):
|
class IdentificationStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""IdentificationStage Viewset"""
|
"""IdentificationStage Viewset"""
|
||||||
|
|
||||||
queryset = IdentificationStage.objects.all()
|
queryset = IdentificationStage.objects.all()
|
||||||
|
|
|
@ -3,6 +3,7 @@ from rest_framework.fields import JSONField
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
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.users import UserSerializer
|
||||||
from authentik.core.api.utils import is_dict
|
from authentik.core.api.utils import is_dict
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
|
@ -20,7 +21,7 @@ class InvitationStageSerializer(StageSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class InvitationStageViewSet(ModelViewSet):
|
class InvitationStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""InvitationStage Viewset"""
|
"""InvitationStage Viewset"""
|
||||||
|
|
||||||
queryset = InvitationStage.objects.all()
|
queryset = InvitationStage.objects.all()
|
||||||
|
@ -45,7 +46,7 @@ class InvitationSerializer(ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class InvitationViewSet(ModelViewSet):
|
class InvitationViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Invitation Viewset"""
|
"""Invitation Viewset"""
|
||||||
|
|
||||||
queryset = Invitation.objects.all()
|
queryset = Invitation.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""PasswordStage API Views"""
|
"""PasswordStage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.password.models import PasswordStage
|
from authentik.stages.password.models import PasswordStage
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ class PasswordStageSerializer(StageSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class PasswordStageViewSet(ModelViewSet):
|
class PasswordStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""PasswordStage Viewset"""
|
"""PasswordStage Viewset"""
|
||||||
|
|
||||||
queryset = PasswordStage.objects.all()
|
queryset = PasswordStage.objects.all()
|
||||||
|
|
|
@ -3,6 +3,7 @@ from rest_framework.serializers import CharField, ModelSerializer
|
||||||
from rest_framework.validators import UniqueValidator
|
from rest_framework.validators import UniqueValidator
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.prompt.models import Prompt, PromptStage
|
from authentik.stages.prompt.models import Prompt, PromptStage
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class PromptStageSerializer(StageSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class PromptStageViewSet(ModelViewSet):
|
class PromptStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""PromptStage Viewset"""
|
"""PromptStage Viewset"""
|
||||||
|
|
||||||
queryset = PromptStage.objects.all()
|
queryset = PromptStage.objects.all()
|
||||||
|
@ -48,7 +49,7 @@ class PromptSerializer(ModelSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class PromptViewSet(ModelViewSet):
|
class PromptViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Prompt Viewset"""
|
"""Prompt Viewset"""
|
||||||
|
|
||||||
queryset = Prompt.objects.all().prefetch_related("promptstage_set")
|
queryset = Prompt.objects.all().prefetch_related("promptstage_set")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""User Delete Stage API Views"""
|
"""User Delete Stage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.user_delete.models import UserDeleteStage
|
from authentik.stages.user_delete.models import UserDeleteStage
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class UserDeleteStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields
|
fields = StageSerializer.Meta.fields
|
||||||
|
|
||||||
|
|
||||||
class UserDeleteStageViewSet(ModelViewSet):
|
class UserDeleteStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""UserDeleteStage Viewset"""
|
"""UserDeleteStage Viewset"""
|
||||||
|
|
||||||
queryset = UserDeleteStage.objects.all()
|
queryset = UserDeleteStage.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Login Stage API Views"""
|
"""Login Stage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.user_login.models import UserLoginStage
|
from authentik.stages.user_login.models import UserLoginStage
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ class UserLoginStageSerializer(StageSerializer):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class UserLoginStageViewSet(ModelViewSet):
|
class UserLoginStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""UserLoginStage Viewset"""
|
"""UserLoginStage Viewset"""
|
||||||
|
|
||||||
queryset = UserLoginStage.objects.all()
|
queryset = UserLoginStage.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""Logout Stage API Views"""
|
"""Logout Stage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.user_logout.models import UserLogoutStage
|
from authentik.stages.user_logout.models import UserLogoutStage
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class UserLogoutStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields
|
fields = StageSerializer.Meta.fields
|
||||||
|
|
||||||
|
|
||||||
class UserLogoutStageViewSet(ModelViewSet):
|
class UserLogoutStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""UserLogoutStage Viewset"""
|
"""UserLogoutStage Viewset"""
|
||||||
|
|
||||||
queryset = UserLogoutStage.objects.all()
|
queryset = UserLogoutStage.objects.all()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""User Write Stage API Views"""
|
"""User Write Stage API Views"""
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.flows.api.stages import StageSerializer
|
from authentik.flows.api.stages import StageSerializer
|
||||||
from authentik.stages.user_write.models import UserWriteStage
|
from authentik.stages.user_write.models import UserWriteStage
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class UserWriteStageSerializer(StageSerializer):
|
||||||
fields = StageSerializer.Meta.fields
|
fields = StageSerializer.Meta.fields
|
||||||
|
|
||||||
|
|
||||||
class UserWriteStageViewSet(ModelViewSet):
|
class UserWriteStageViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""UserWriteStage Viewset"""
|
"""UserWriteStage Viewset"""
|
||||||
|
|
||||||
queryset = UserWriteStage.objects.all()
|
queryset = UserWriteStage.objects.all()
|
||||||
|
|
|
@ -8,6 +8,7 @@ from rest_framework.response import Response
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
from authentik.tenants.models import Tenant
|
from authentik.tenants.models import Tenant
|
||||||
|
@ -56,7 +57,7 @@ class CurrentTenantSerializer(PassiveSerializer):
|
||||||
flow_unenrollment = CharField(source="flow_unenrollment.slug", required=False)
|
flow_unenrollment = CharField(source="flow_unenrollment.slug", required=False)
|
||||||
|
|
||||||
|
|
||||||
class TenantViewSet(ModelViewSet):
|
class TenantViewSet(UsedByMixin, ModelViewSet):
|
||||||
"""Tenant Viewset"""
|
"""Tenant Viewset"""
|
||||||
|
|
||||||
queryset = Tenant.objects.all()
|
queryset = Tenant.objects.all()
|
||||||
|
|
|
@ -41,7 +41,9 @@ class Tenant(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.domain
|
if self.default:
|
||||||
|
return "Default tenant"
|
||||||
|
return f"Tenant {self.domain}"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ force_grid_wrap = 0
|
||||||
use_parentheses = true
|
use_parentheses = true
|
||||||
line_length = 88
|
line_length = 88
|
||||||
src_paths = ["authentik", "tests", "lifecycle"]
|
src_paths = ["authentik", "tests", "lifecycle"]
|
||||||
|
force_to_top = "*"
|
||||||
|
|
||||||
[tool.coverage.run]
|
[tool.coverage.run]
|
||||||
source = ["authentik"]
|
source = ["authentik"]
|
||||||
|
|
2162
schema.yml
2162
schema.yml
File diff suppressed because it is too large
Load diff
2718
web/package-lock.json
generated
2718
web/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -38,11 +38,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.14.3",
|
"@babel/core": "^7.14.5",
|
||||||
"@babel/plugin-proposal-decorators": "^7.14.2",
|
"@babel/plugin-proposal-decorators": "^7.14.5",
|
||||||
"@babel/plugin-transform-runtime": "^7.14.3",
|
"@babel/plugin-transform-runtime": "^7.14.5",
|
||||||
"@babel/preset-env": "^7.14.4",
|
"@babel/preset-env": "^7.14.5",
|
||||||
"@babel/preset-typescript": "^7.13.0",
|
"@babel/preset-typescript": "^7.14.5",
|
||||||
"@fortawesome/fontawesome-free": "^5.15.3",
|
"@fortawesome/fontawesome-free": "^5.15.3",
|
||||||
"@lingui/cli": "^3.10.2",
|
"@lingui/cli": "^3.10.2",
|
||||||
"@lingui/core": "^3.10.2",
|
"@lingui/core": "^3.10.2",
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
"eslint": "^7.28.0",
|
"eslint": "^7.28.0",
|
||||||
"eslint-config-google": "^0.14.0",
|
"eslint-config-google": "^0.14.0",
|
||||||
"eslint-plugin-custom-elements": "0.0.2",
|
"eslint-plugin-custom-elements": "0.0.2",
|
||||||
"eslint-plugin-lit": "^1.5.0",
|
"eslint-plugin-lit": "^1.5.1",
|
||||||
"flowchart.js": "^1.15.0",
|
"flowchart.js": "^1.15.0",
|
||||||
"lit-element": "^2.5.1",
|
"lit-element": "^2.5.1",
|
||||||
"lit-html": "^1.4.1",
|
"lit-html": "^1.4.1",
|
||||||
|
|
|
@ -1,20 +1,30 @@
|
||||||
import { t } from "@lingui/macro";
|
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 { EVENT_REFRESH } from "../../constants";
|
||||||
import { ModalButton } from "../buttons/ModalButton";
|
import { ModalButton } from "../buttons/ModalButton";
|
||||||
import { MessageLevel } from "../messages/Message";
|
import { MessageLevel } from "../messages/Message";
|
||||||
import { showMessage } from "../messages/MessageContainer";
|
import { showMessage } from "../messages/MessageContainer";
|
||||||
import "../buttons/SpinnerButton";
|
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")
|
@customElement("ak-forms-delete")
|
||||||
export class DeleteForm extends ModalButton {
|
export class DeleteForm extends ModalButton {
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return super.styles.concat(PFList);
|
||||||
|
}
|
||||||
|
|
||||||
@property({attribute: false})
|
@property({attribute: false})
|
||||||
obj?: Record<string, unknown>;
|
obj?: Record<string, unknown>;
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
objectLabel?: string;
|
objectLabel?: string;
|
||||||
|
|
||||||
|
@property({attribute: false})
|
||||||
|
usedBy?: () => Promise<UsedBy[]>;
|
||||||
|
|
||||||
@property({attribute: false})
|
@property({attribute: false})
|
||||||
delete!: () => Promise<unknown>;
|
delete!: () => Promise<unknown>;
|
||||||
|
|
||||||
|
@ -69,6 +79,40 @@ export class DeleteForm extends ModalButton {
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
${this.usedBy ? until(this.usedBy().then(usedBy => {
|
||||||
|
if (usedBy.length < 1) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<section class="pf-c-page__main-section">
|
||||||
|
<form class="pf-c-form pf-m-horizontal">
|
||||||
|
<p>
|
||||||
|
${t`The following objects use ${objName} `}
|
||||||
|
</p>
|
||||||
|
<ul class="pf-c-list">
|
||||||
|
${usedBy.map(ub => {
|
||||||
|
let consequence = "";
|
||||||
|
switch (ub.action) {
|
||||||
|
case UsedByActionEnum.Cascade:
|
||||||
|
consequence = t`object will be DELETED`;
|
||||||
|
break;
|
||||||
|
case UsedByActionEnum.CascadeMany:
|
||||||
|
consequence = t`connecting object will be deleted`;
|
||||||
|
break;
|
||||||
|
case UsedByActionEnum.SetDefault:
|
||||||
|
consequence = t`reference will be reset to default value`;
|
||||||
|
break;
|
||||||
|
case UsedByActionEnum.SetNull:
|
||||||
|
consequence = t`reference will be set to an empty value`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return html`<li>${t`${ub.name} (${consequence})`}</li>`;
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
`;
|
||||||
|
})) : html``}
|
||||||
<footer class="pf-c-modal-box__footer">
|
<footer class="pf-c-modal-box__footer">
|
||||||
<ak-spinner-button
|
<ak-spinner-button
|
||||||
.callAction=${() => {
|
.callAction=${() => {
|
||||||
|
|
|
@ -44,9 +44,14 @@ export class UserOAuthCodeList extends Table<ExpiringBaseGrantModel> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Authorization Code`}
|
objectLabel=${t`Authorization Code`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2AuthorizationCodesUsedByList({
|
||||||
|
id: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new Oauth2Api(DEFAULT_CONFIG).oauth2AuthorizationCodesDestroy({
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2AuthorizationCodesDestroy({
|
||||||
id: item.pk || 0,
|
id: item.pk,
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -68,9 +68,14 @@ export class UserOAuthRefreshList extends Table<RefreshTokenModel> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Refresh Code`}
|
objectLabel=${t`Refresh Code`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensUsedByList({
|
||||||
|
id: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensDestroy({
|
return new Oauth2Api(DEFAULT_CONFIG).oauth2RefreshTokensDestroy({
|
||||||
id: item.pk || 0,
|
id: item.pk,
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -45,6 +45,11 @@ export class AuthenticatedSessionList extends Table<AuthenticatedSession> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Session`}
|
objectLabel=${t`Session`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsUsedByList({
|
||||||
|
uuid: item.uuid || "",
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsDestroy({
|
return new CoreApi(DEFAULT_CONFIG).coreAuthenticatedSessionsDestroy({
|
||||||
uuid: item.uuid || "",
|
uuid: item.uuid || "",
|
||||||
|
|
|
@ -40,9 +40,14 @@ export class UserConsentList extends Table<UserConsent> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Consent`}
|
objectLabel=${t`Consent`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CoreApi(DEFAULT_CONFIG).coreUserConsentUsedByList({
|
||||||
|
id: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreUserConsentDestroy({
|
return new CoreApi(DEFAULT_CONFIG).coreUserConsentDestroy({
|
||||||
id: item.pk || 0,
|
id: item.pk,
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -1144,6 +1144,9 @@ msgid "Disable"
|
||||||
msgstr "Disable"
|
msgstr "Disable"
|
||||||
|
|
||||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||||
|
msgid "Disable Duo authenticator"
|
||||||
|
msgstr "Disable Duo authenticator"
|
||||||
|
|
||||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||||
msgid "Disable Static Tokens"
|
msgid "Disable Static Tokens"
|
||||||
msgstr "Disable Static Tokens"
|
msgstr "Disable Static Tokens"
|
||||||
|
@ -1293,11 +1296,14 @@ msgstr "Email: Text field with Email type."
|
||||||
msgid "Enable"
|
msgid "Enable"
|
||||||
msgstr "Enable"
|
msgstr "Enable"
|
||||||
|
|
||||||
|
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||||
|
msgid "Enable Duo authenticator"
|
||||||
|
msgstr "Enable Duo authenticator"
|
||||||
|
|
||||||
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
#: src/pages/sources/ldap/LDAPSourceForm.ts
|
||||||
msgid "Enable StartTLS"
|
msgid "Enable StartTLS"
|
||||||
msgstr "Enable StartTLS"
|
msgstr "Enable StartTLS"
|
||||||
|
|
||||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
|
||||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||||
msgid "Enable Static Tokens"
|
msgid "Enable Static Tokens"
|
||||||
msgstr "Enable Static Tokens"
|
msgstr "Enable Static Tokens"
|
||||||
|
@ -2148,6 +2154,10 @@ msgstr "Matches Event's Client IP (strict matching, for network matching use an
|
||||||
msgid "Matches an event against a set of criteria. If any of the configured values match, the policy passes."
|
msgid "Matches an event against a set of criteria. If any of the configured values match, the policy passes."
|
||||||
msgstr "Matches an event against a set of criteria. If any of the configured values match, the policy passes."
|
msgstr "Matches an event against a set of criteria. If any of the configured values match, the policy passes."
|
||||||
|
|
||||||
|
#: src/pages/tenants/TenantForm.ts
|
||||||
|
msgid "Matching is done based on domain suffix, so if you enter domain.tld, foo.domain.tld will still match."
|
||||||
|
msgstr "Matching is done based on domain suffix, so if you enter domain.tld, foo.domain.tld will still match."
|
||||||
|
|
||||||
#: src/pages/policies/expiry/ExpiryPolicyForm.ts
|
#: src/pages/policies/expiry/ExpiryPolicyForm.ts
|
||||||
msgid "Maximum age (in days)"
|
msgid "Maximum age (in days)"
|
||||||
msgstr "Maximum age (in days)"
|
msgstr "Maximum age (in days)"
|
||||||
|
@ -3805,6 +3815,10 @@ msgstr "The external URL you'll access the application at. Include any non-stand
|
||||||
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
|
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
|
||||||
msgstr "The external URL you'll authenticate at. Can be the same domain as authentik."
|
msgstr "The external URL you'll authenticate at. Can be the same domain as authentik."
|
||||||
|
|
||||||
|
#: src/elements/forms/DeleteForm.ts
|
||||||
|
msgid "The following objects use {objName}"
|
||||||
|
msgstr "The following objects use {objName}"
|
||||||
|
|
||||||
#: src/pages/policies/dummy/DummyPolicyForm.ts
|
#: src/pages/policies/dummy/DummyPolicyForm.ts
|
||||||
msgid "The policy takes a random time to execute. This controls the minimum time it will take."
|
msgid "The policy takes a random time to execute. This controls the minimum time it will take."
|
||||||
msgstr "The policy takes a random time to execute. This controls the minimum time it will take."
|
msgstr "The policy takes a random time to execute. This controls the minimum time it will take."
|
||||||
|
@ -4519,6 +4533,18 @@ msgstr "authentik LDAP Backend"
|
||||||
msgid "no tabs defined"
|
msgid "no tabs defined"
|
||||||
msgstr "no tabs defined"
|
msgstr "no tabs defined"
|
||||||
|
|
||||||
|
#: src/elements/forms/DeleteForm.ts
|
||||||
|
msgid "object will be DELETED"
|
||||||
|
msgstr "object will be DELETED"
|
||||||
|
|
||||||
|
#: src/elements/forms/DeleteForm.ts
|
||||||
|
msgid "reference will be reset to default value"
|
||||||
|
msgstr "reference will be reset to default value"
|
||||||
|
|
||||||
|
#: src/elements/forms/DeleteForm.ts
|
||||||
|
msgid "reference will be set to an empty value"
|
||||||
|
msgstr "reference will be set to an empty value"
|
||||||
|
|
||||||
#: src/elements/Expand.ts
|
#: src/elements/Expand.ts
|
||||||
#: src/elements/Expand.ts
|
#: src/elements/Expand.ts
|
||||||
msgid "{0}"
|
msgid "{0}"
|
||||||
|
@ -4532,6 +4558,10 @@ msgstr "{0} (\"{1}\", of type {2})"
|
||||||
msgid "{0} ({1})"
|
msgid "{0} ({1})"
|
||||||
msgstr "{0} ({1})"
|
msgstr "{0} ({1})"
|
||||||
|
|
||||||
|
#: src/elements/forms/DeleteForm.ts
|
||||||
|
msgid "{0} ({consequence})"
|
||||||
|
msgstr "{0} ({consequence})"
|
||||||
|
|
||||||
#: src/elements/table/TablePagination.ts
|
#: src/elements/table/TablePagination.ts
|
||||||
msgid "{0} - {1} of {2}"
|
msgid "{0} - {1} of {2}"
|
||||||
msgstr "{0} - {1} of {2}"
|
msgstr "{0} - {1} of {2}"
|
||||||
|
|
|
@ -1136,6 +1136,9 @@ msgid "Disable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
|
msgid "Disable Duo authenticator"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
msgid "Disable Static Tokens"
|
msgid "Disable Static Tokens"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -1286,10 +1289,13 @@ msgid "Enable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
msgid "Enable StartTLS"
|
msgid "Enable Duo authenticator"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
|
msgid "Enable StartTLS"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
msgid "Enable Static Tokens"
|
msgid "Enable Static Tokens"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -2140,6 +2146,10 @@ msgstr ""
|
||||||
msgid "Matches an event against a set of criteria. If any of the configured values match, the policy passes."
|
msgid "Matches an event against a set of criteria. If any of the configured values match, the policy passes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
msgid "Matching is done based on domain suffix, so if you enter domain.tld, foo.domain.tld will still match."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
msgid "Maximum age (in days)"
|
msgid "Maximum age (in days)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -3797,6 +3807,10 @@ msgstr ""
|
||||||
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
|
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
msgid "The following objects use {objName}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
msgid "The policy takes a random time to execute. This controls the minimum time it will take."
|
msgid "The policy takes a random time to execute. This controls the minimum time it will take."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -4505,6 +4519,18 @@ msgstr ""
|
||||||
msgid "no tabs defined"
|
msgid "no tabs defined"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
msgid "object will be DELETED"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
msgid "reference will be reset to default value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
msgid "reference will be set to an empty value"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
#:
|
#:
|
||||||
msgid "{0}"
|
msgid "{0}"
|
||||||
|
@ -4518,6 +4544,10 @@ msgstr ""
|
||||||
msgid "{0} ({1})"
|
msgid "{0} ({1})"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
msgid "{0} ({consequence})"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#:
|
#:
|
||||||
msgid "{0} - {1} of {2}"
|
msgid "{0} - {1} of {2}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -103,9 +103,14 @@ export class ApplicationListPage extends TablePage<Application> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Application`}
|
objectLabel=${t`Application`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CoreApi(DEFAULT_CONFIG).coreApplicationsUsedByList({
|
||||||
|
slug: item.slug
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreApplicationsDestroy({
|
return new CoreApi(DEFAULT_CONFIG).coreApplicationsDestroy({
|
||||||
slug: item.slug || ""
|
slug: item.slug
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -79,9 +79,14 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Certificate-Key Pair`}
|
objectLabel=${t`Certificate-Key Pair`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsUsedByList({
|
||||||
|
kpUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsDestroy({
|
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsDestroy({
|
||||||
kpUuid: item.pk || ""
|
kpUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { t } from "@lingui/macro";
|
import { t } from "@lingui/macro";
|
||||||
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
||||||
import { until } from "lit-html/directives/until";
|
import { until } from "lit-html/directives/until";
|
||||||
import { ActionEnum, FlowsApi } from "authentik-api";
|
import { EventMatcherPolicyActionEnum, FlowsApi } from "authentik-api";
|
||||||
import "../../elements/Spinner";
|
import "../../elements/Spinner";
|
||||||
import "../../elements/Expand";
|
import "../../elements/Expand";
|
||||||
import { PFSize } from "../../elements/Spinner";
|
import { PFSize } from "../../elements/Spinner";
|
||||||
|
@ -142,14 +142,14 @@ export class EventInfo extends LitElement {
|
||||||
return html`<ak-spinner size=${PFSize.Medium}></ak-spinner>`;
|
return html`<ak-spinner size=${PFSize.Medium}></ak-spinner>`;
|
||||||
}
|
}
|
||||||
switch (this.event?.action) {
|
switch (this.event?.action) {
|
||||||
case ActionEnum.ModelCreated:
|
case EventMatcherPolicyActionEnum.ModelCreated:
|
||||||
case ActionEnum.ModelUpdated:
|
case EventMatcherPolicyActionEnum.ModelUpdated:
|
||||||
case ActionEnum.ModelDeleted:
|
case EventMatcherPolicyActionEnum.ModelDeleted:
|
||||||
return html`
|
return html`
|
||||||
<h3>${t`Affected model:`}</h3>
|
<h3>${t`Affected model:`}</h3>
|
||||||
${this.getModelInfo(this.event.context?.model as EventContext)}
|
${this.getModelInfo(this.event.context?.model as EventContext)}
|
||||||
`;
|
`;
|
||||||
case ActionEnum.AuthorizeApplication:
|
case EventMatcherPolicyActionEnum.AuthorizeApplication:
|
||||||
return html`<div class="pf-l-flex">
|
return html`<div class="pf-l-flex">
|
||||||
<div class="pf-l-flex__item">
|
<div class="pf-l-flex__item">
|
||||||
<h3>${t`Authorized application:`}</h3>
|
<h3>${t`Authorized application:`}</h3>
|
||||||
|
@ -166,17 +166,17 @@ export class EventInfo extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||||
case ActionEnum.EmailSent:
|
case EventMatcherPolicyActionEnum.EmailSent:
|
||||||
return html`<h3>${t`Email info:`}</h3>
|
return html`<h3>${t`Email info:`}</h3>
|
||||||
${this.getEmailInfo(this.event.context)}
|
${this.getEmailInfo(this.event.context)}
|
||||||
<ak-expand>
|
<ak-expand>
|
||||||
<iframe srcdoc=${this.event.context.body}></iframe>
|
<iframe srcdoc=${this.event.context.body}></iframe>
|
||||||
</ak-expand>`;
|
</ak-expand>`;
|
||||||
case ActionEnum.SecretView:
|
case EventMatcherPolicyActionEnum.SecretView:
|
||||||
return html`
|
return html`
|
||||||
<h3>${t`Secret:`}</h3>
|
<h3>${t`Secret:`}</h3>
|
||||||
${this.getModelInfo(this.event.context.secret as EventContext)}`;
|
${this.getModelInfo(this.event.context.secret as EventContext)}`;
|
||||||
case ActionEnum.PropertyMappingException:
|
case EventMatcherPolicyActionEnum.PropertyMappingException:
|
||||||
return html`<div class="pf-l-flex">
|
return html`<div class="pf-l-flex">
|
||||||
<div class="pf-l-flex__item">
|
<div class="pf-l-flex__item">
|
||||||
<h3>${t`Exception`}</h3>
|
<h3>${t`Exception`}</h3>
|
||||||
|
@ -188,7 +188,7 @@ export class EventInfo extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||||
case ActionEnum.PolicyException:
|
case EventMatcherPolicyActionEnum.PolicyException:
|
||||||
return html`<div class="pf-l-flex">
|
return html`<div class="pf-l-flex">
|
||||||
<div class="pf-l-flex__item">
|
<div class="pf-l-flex__item">
|
||||||
<h3>${t`Binding`}</h3>
|
<h3>${t`Binding`}</h3>
|
||||||
|
@ -207,7 +207,7 @@ export class EventInfo extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||||
case ActionEnum.PolicyExecution:
|
case EventMatcherPolicyActionEnum.PolicyExecution:
|
||||||
return html`<div class="pf-l-flex">
|
return html`<div class="pf-l-flex">
|
||||||
<div class="pf-l-flex__item">
|
<div class="pf-l-flex__item">
|
||||||
<h3>${t`Binding`}</h3>
|
<h3>${t`Binding`}</h3>
|
||||||
|
@ -235,10 +235,10 @@ export class EventInfo extends LitElement {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||||
case ActionEnum.ConfigurationError:
|
case EventMatcherPolicyActionEnum.ConfigurationError:
|
||||||
return html`<h3>${this.event.context.message}</h3>
|
return html`<h3>${this.event.context.message}</h3>
|
||||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||||
case ActionEnum.UpdateAvailable:
|
case EventMatcherPolicyActionEnum.UpdateAvailable:
|
||||||
return html`<h3>${t`New version available!`}</h3>
|
return html`<h3>${t`New version available!`}</h3>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@ -247,7 +247,7 @@ export class EventInfo extends LitElement {
|
||||||
</a>`;
|
</a>`;
|
||||||
// Action types which typically don't record any extra context.
|
// Action types which typically don't record any extra context.
|
||||||
// If context is not empty, we fall to the default response.
|
// If context is not empty, we fall to the default response.
|
||||||
case ActionEnum.Login:
|
case EventMatcherPolicyActionEnum.Login:
|
||||||
if ("using_source" in this.event.context) {
|
if ("using_source" in this.event.context) {
|
||||||
return html`<div class="pf-l-flex">
|
return html`<div class="pf-l-flex">
|
||||||
<div class="pf-l-flex__item">
|
<div class="pf-l-flex__item">
|
||||||
|
@ -257,11 +257,11 @@ export class EventInfo extends LitElement {
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
return this.defaultResponse();
|
return this.defaultResponse();
|
||||||
case ActionEnum.LoginFailed:
|
case EventMatcherPolicyActionEnum.LoginFailed:
|
||||||
return html`
|
return html`
|
||||||
<h3>${t`Attempted to log in as ${this.event.context.username}`}</h3>
|
<h3>${t`Attempted to log in as ${this.event.context.username}`}</h3>
|
||||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||||
case ActionEnum.Logout:
|
case EventMatcherPolicyActionEnum.Logout:
|
||||||
if (this.event.context === {}) {
|
if (this.event.context === {}) {
|
||||||
return html`<span>${t`No additional data available.`}</span>`;
|
return html`<span>${t`No additional data available.`}</span>`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,9 +73,14 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Notification rule`}
|
objectLabel=${t`Notification rule`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new EventsApi(DEFAULT_CONFIG).eventsRulesUsedByList({
|
||||||
|
pbmUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new EventsApi(DEFAULT_CONFIG).eventsRulesDestroy({
|
return new EventsApi(DEFAULT_CONFIG).eventsRulesDestroy({
|
||||||
pbmUuid: item.pk || ""
|
pbmUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -77,9 +77,14 @@ export class TransportListPage extends TablePage<NotificationTransport> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Notifications Transport`}
|
objectLabel=${t`Notifications Transport`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new EventsApi(DEFAULT_CONFIG).eventsTransportsUsedByList({
|
||||||
|
uuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new EventsApi(DEFAULT_CONFIG).eventsTransportsDestroy({
|
return new EventsApi(DEFAULT_CONFIG).eventsTransportsDestroy({
|
||||||
uuid: item.pk || ""
|
uuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -82,9 +82,14 @@ export class BoundStagesList extends Table<FlowStageBinding> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Stage binding`}
|
objectLabel=${t`Stage binding`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsUsedByList({
|
||||||
|
fsbUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsDestroy({
|
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsDestroy({
|
||||||
fsbUuid: item.pk || "",
|
fsbUuid: item.pk,
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -78,6 +78,11 @@ export class FlowListPage extends TablePage<Flow> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Flow`}
|
objectLabel=${t`Flow`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesUsedByList({
|
||||||
|
slug: item.slug
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesDestroy({
|
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesDestroy({
|
||||||
slug: item.slug
|
slug: item.slug
|
||||||
|
|
|
@ -72,9 +72,14 @@ export class GroupListPage extends TablePage<Group> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Group`}
|
objectLabel=${t`Group`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CoreApi(DEFAULT_CONFIG).coreGroupsUsedByList({
|
||||||
|
groupUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreGroupsDestroy({
|
return new CoreApi(DEFAULT_CONFIG).coreGroupsDestroy({
|
||||||
groupUuid: item.pk || ""
|
groupUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -77,9 +77,14 @@ export class OutpostListPage extends TablePage<Outpost> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Outpost`}
|
objectLabel=${t`Outpost`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new OutpostsApi(DEFAULT_CONFIG).outpostsInstancesUsedByList({
|
||||||
|
uuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new OutpostsApi(DEFAULT_CONFIG).outpostsInstancesDestroy({
|
return new OutpostsApi(DEFAULT_CONFIG).outpostsInstancesDestroy({
|
||||||
uuid: item.pk || ""
|
uuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -93,9 +93,14 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Outpost Service-connection`}
|
objectLabel=${t`Outpost Service-connection`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsAllUsedByList({
|
||||||
|
uuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsAllDestroy({
|
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsAllDestroy({
|
||||||
uuid: item.pk || ""
|
uuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -137,9 +137,14 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Policy binding`}
|
objectLabel=${t`Policy binding`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsUsedByList({
|
||||||
|
policyBindingUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsDestroy({
|
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsDestroy({
|
||||||
policyBindingUuid: item.pk || "",
|
policyBindingUuid: item.pk,
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -107,9 +107,14 @@ export class PolicyListPage extends TablePage<Policy> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Policy`}
|
objectLabel=${t`Policy`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new PoliciesApi(DEFAULT_CONFIG).policiesAllUsedByList({
|
||||||
|
policyUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new PoliciesApi(DEFAULT_CONFIG).policiesAllDestroy({
|
return new PoliciesApi(DEFAULT_CONFIG).policiesAllDestroy({
|
||||||
policyUuid: item.pk || ""
|
policyUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -55,6 +55,11 @@ export class IPReputationListPage extends TablePage<IPReputation> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`IP Reputation`}
|
objectLabel=${t`IP Reputation`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationIpsUsedByList({
|
||||||
|
id: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationIpsDestroy({
|
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationIpsDestroy({
|
||||||
id: item.pk,
|
id: item.pk,
|
||||||
|
|
|
@ -55,6 +55,11 @@ export class UserReputationListPage extends TablePage<UserReputation> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`User Reputation`}
|
objectLabel=${t`User Reputation`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationUsersUsedByList({
|
||||||
|
id: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationUsersDestroy({
|
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationUsersDestroy({
|
||||||
id: item.pk,
|
id: item.pk,
|
||||||
|
|
|
@ -97,9 +97,14 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Property Mapping`}
|
objectLabel=${t`Property Mapping`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsAllUsedByList({
|
||||||
|
pmUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsAllDestroy({
|
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsAllDestroy({
|
||||||
pmUuid: item.pk || ""
|
pmUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -90,9 +90,14 @@ export class ProviderListPage extends TablePage<Provider> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Provider`}
|
objectLabel=${t`Provider`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new ProvidersApi(DEFAULT_CONFIG).providersAllUsedByList({
|
||||||
|
id: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new ProvidersApi(DEFAULT_CONFIG).providersAllDestroy({
|
return new ProvidersApi(DEFAULT_CONFIG).providersAllDestroy({
|
||||||
id: item.pk || 0
|
id: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -86,9 +86,14 @@ export class SourceListPage extends TablePage<Source> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Source`}
|
objectLabel=${t`Source`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new SourcesApi(DEFAULT_CONFIG).sourcesAllUsedByList({
|
||||||
|
slug: item.slug
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new SourcesApi(DEFAULT_CONFIG).sourcesAllDestroy({
|
return new SourcesApi(DEFAULT_CONFIG).sourcesAllDestroy({
|
||||||
slug: item.slug || ""
|
slug: item.slug
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -102,9 +102,14 @@ export class StageListPage extends TablePage<Stage> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${item.verboseName || ""}
|
objectLabel=${item.verboseName || ""}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new StagesApi(DEFAULT_CONFIG).stagesAllUsedByList({
|
||||||
|
stageUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new StagesApi(DEFAULT_CONFIG).stagesAllDestroy({
|
return new StagesApi(DEFAULT_CONFIG).stagesAllDestroy({
|
||||||
stageUuid: item.pk || ""
|
stageUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -58,9 +58,14 @@ export class InvitationListPage extends TablePage<Invitation> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Invitation`}
|
objectLabel=${t`Invitation`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsUsedByList({
|
||||||
|
inviteUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsDestroy({
|
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsDestroy({
|
||||||
inviteUuid: item.pk || ""
|
inviteUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -77,9 +77,14 @@ export class PromptListPage extends TablePage<Prompt> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Prompt`}
|
objectLabel=${t`Prompt`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new StagesApi(DEFAULT_CONFIG).stagesPromptPromptsUsedByList({
|
||||||
|
promptUuid: item.pk
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new StagesApi(DEFAULT_CONFIG).stagesPromptPromptsDestroy({
|
return new StagesApi(DEFAULT_CONFIG).stagesPromptPromptsDestroy({
|
||||||
promptUuid: item.pk || ""
|
promptUuid: item.pk
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
<button slot="trigger" class="pf-c-button pf-m-danger">
|
<button slot="trigger" class="pf-c-button pf-m-danger">
|
||||||
|
|
|
@ -47,6 +47,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
|
||||||
?required=${true}
|
?required=${true}
|
||||||
name="domain">
|
name="domain">
|
||||||
<input type="text" value="${first(this.instance?.domain, window.location.host)}" class="pf-c-form-control" required>
|
<input type="text" value="${first(this.instance?.domain, window.location.host)}" class="pf-c-form-control" required>
|
||||||
|
<p class="pf-c-form__helper-text">${t`Matching is done based on domain suffix, so if you enter domain.tld, foo.domain.tld will still match.`}</p>
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal name="default">
|
<ak-form-element-horizontal name="default">
|
||||||
<div class="pf-c-check">
|
<div class="pf-c-check">
|
||||||
|
|
|
@ -68,6 +68,11 @@ export class TenantListPage extends TablePage<Tenant> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Tenant`}
|
objectLabel=${t`Tenant`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CoreApi(DEFAULT_CONFIG).coreTenantsUsedByList({
|
||||||
|
tenantUuid: item.tenantUuid
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreTenantsDestroy({
|
return new CoreApi(DEFAULT_CONFIG).coreTenantsDestroy({
|
||||||
tenantUuid: item.tenantUuid
|
tenantUuid: item.tenantUuid
|
||||||
|
|
|
@ -58,6 +58,11 @@ export class TokenListPage extends TablePage<Token> {
|
||||||
<ak-forms-delete
|
<ak-forms-delete
|
||||||
.obj=${item}
|
.obj=${item}
|
||||||
objectLabel=${t`Token`}
|
objectLabel=${t`Token`}
|
||||||
|
.usedBy=${() => {
|
||||||
|
return new CoreApi(DEFAULT_CONFIG).coreTokensUsedByList({
|
||||||
|
identifier: item.identifier
|
||||||
|
});
|
||||||
|
}}
|
||||||
.delete=${() => {
|
.delete=${() => {
|
||||||
return new CoreApi(DEFAULT_CONFIG).coreTokensDestroy({
|
return new CoreApi(DEFAULT_CONFIG).coreTokensDestroy({
|
||||||
identifier: item.identifier
|
identifier: item.identifier
|
||||||
|
|
|
@ -31,7 +31,7 @@ export class UserSettingsAuthenticatorDuo extends BaseUserSettings {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}}>
|
}}>
|
||||||
${t`Disable Static Tokens`}
|
${t`Disable Duo authenticator`}
|
||||||
</button>
|
</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ export class UserSettingsAuthenticatorDuo extends BaseUserSettings {
|
||||||
<div class="pf-c-card__footer">
|
<div class="pf-c-card__footer">
|
||||||
${this.configureUrl ?
|
${this.configureUrl ?
|
||||||
html`<a href="${this.configureUrl}?next=/%23%2Fuser"
|
html`<a href="${this.configureUrl}?next=/%23%2Fuser"
|
||||||
class="pf-c-button pf-m-primary">${t`Enable Static Tokens`}
|
class="pf-c-button pf-m-primary">${t`Enable Duo authenticator`}
|
||||||
</a>`: html``}
|
</a>`: html``}
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue