Merge branch 'version-2021.5' into next
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> # Conflicts: # authentik/stages/authenticator_static/api.py # swagger.yaml
This commit is contained in:
commit
1a0f72d0a8
|
@ -43,7 +43,7 @@ def token_from_header(raw_header: bytes) -> Optional[Token]:
|
|||
return tokens.first()
|
||||
|
||||
|
||||
class AuthentikTokenAuthentication(BaseAuthentication):
|
||||
class TokenAuthentication(BaseAuthentication):
|
||||
"""Token-based authentication using HTTP Bearer authentication"""
|
||||
|
||||
def authenticate(self, request: Request) -> Union[tuple[User, Any], None]:
|
||||
|
@ -61,7 +61,7 @@ class AuthentikTokenAuthentication(BaseAuthentication):
|
|||
class TokenSchema(OpenApiAuthenticationExtension):
|
||||
"""Auth schema"""
|
||||
|
||||
target_class = AuthentikTokenAuthentication
|
||||
target_class = TokenAuthentication
|
||||
name = "authentik"
|
||||
|
||||
def get_security_definition(self, auto_schema):
|
|
@ -0,0 +1,35 @@
|
|||
"""API Authorization"""
|
||||
from django.db.models import Model
|
||||
from django.db.models.query import QuerySet
|
||||
from rest_framework.filters import BaseFilterBackend
|
||||
from rest_framework.permissions import BasePermission
|
||||
from rest_framework.request import Request
|
||||
|
||||
|
||||
class OwnerFilter(BaseFilterBackend):
|
||||
"""Filter objects by their owner"""
|
||||
|
||||
owner_key = "user"
|
||||
|
||||
def filter_queryset(self, request: Request, queryset: QuerySet, view) -> QuerySet:
|
||||
return queryset.filter(**{self.owner_key: request.user})
|
||||
|
||||
|
||||
class OwnerPermissions(BasePermission):
|
||||
"""Authorize requests by an object's owner matching the requesting user"""
|
||||
|
||||
owner_key = "user"
|
||||
|
||||
def has_permission(self, request: Request, view) -> bool:
|
||||
"""If the user is authenticated, we allow all requests here. For listing, the
|
||||
object-level permissions are done by the filter backend"""
|
||||
return request.user.is_authenticated
|
||||
|
||||
def has_object_permission(self, request: Request, view, obj: Model) -> bool:
|
||||
"""Check if the object's owner matches the currently logged in user"""
|
||||
if not hasattr(obj, self.owner_key):
|
||||
return False
|
||||
owner = getattr(obj, self.owner_key)
|
||||
if owner != request.user:
|
||||
return False
|
||||
return True
|
|
@ -5,7 +5,7 @@ from django.test import TestCase
|
|||
from guardian.shortcuts import get_anonymous_user
|
||||
from rest_framework.exceptions import AuthenticationFailed
|
||||
|
||||
from authentik.api.auth import token_from_header
|
||||
from authentik.api.authentication import token_from_header
|
||||
from authentik.core.models import Token, TokenIntents
|
||||
|
||||
|
||||
|
|
|
@ -161,9 +161,19 @@ router.register("propertymappings/scope", ScopeMappingViewSet)
|
|||
router.register("authenticators/static", StaticDeviceViewSet)
|
||||
router.register("authenticators/totp", TOTPDeviceViewSet)
|
||||
router.register("authenticators/webauthn", WebAuthnDeviceViewSet)
|
||||
router.register("authenticators/admin/static", StaticAdminDeviceViewSet)
|
||||
router.register("authenticators/admin/totp", TOTPAdminDeviceViewSet)
|
||||
router.register("authenticators/admin/webauthn", WebAuthnAdminDeviceViewSet)
|
||||
router.register(
|
||||
"authenticators/admin/static",
|
||||
StaticAdminDeviceViewSet,
|
||||
basename="admin-staticdevice",
|
||||
)
|
||||
router.register(
|
||||
"authenticators/admin/totp", TOTPAdminDeviceViewSet, basename="admin-totpdevice"
|
||||
)
|
||||
router.register(
|
||||
"authenticators/admin/webauthn",
|
||||
WebAuthnAdminDeviceViewSet,
|
||||
basename="admin-webauthndevice",
|
||||
)
|
||||
|
||||
router.register("stages/all", StageViewSet)
|
||||
router.register("stages/authenticator/static", AuthenticatorStaticStageViewSet)
|
||||
|
|
|
@ -78,7 +78,7 @@ class PropertyMappingViewSet(
|
|||
filterset_fields = {"managed": ["isnull"]}
|
||||
ordering = ["name"]
|
||||
|
||||
def get_queryset(self):
|
||||
def get_queryset(self): # pragma: no cover
|
||||
return PropertyMapping.objects.select_subclasses()
|
||||
|
||||
@extend_schema(responses={200: TypeCreateSerializer(many=True)})
|
||||
|
|
|
@ -63,7 +63,7 @@ class ProviderViewSet(
|
|||
"application__name",
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
def get_queryset(self): # pragma: no cover
|
||||
return Provider.objects.select_subclasses()
|
||||
|
||||
@extend_schema(responses={200: TypeCreateSerializer(many=True)})
|
||||
|
|
|
@ -61,7 +61,7 @@ class SourceViewSet(
|
|||
serializer_class = SourceSerializer
|
||||
lookup_field = "slug"
|
||||
|
||||
def get_queryset(self):
|
||||
def get_queryset(self): # pragma: no cover
|
||||
return Source.objects.select_subclasses()
|
||||
|
||||
@extend_schema(responses={200: TypeCreateSerializer(many=True)})
|
||||
|
|
|
@ -139,7 +139,7 @@ class UserViewSet(ModelViewSet):
|
|||
search_fields = ["username", "name", "is_active"]
|
||||
filterset_class = UsersFilter
|
||||
|
||||
def get_queryset(self):
|
||||
def get_queryset(self): # pragma: no cover
|
||||
return User.objects.all().exclude(pk=get_anonymous_user().pk)
|
||||
|
||||
@extend_schema(responses={200: SessionUserSerializer(many=False)})
|
||||
|
|
|
@ -4,7 +4,7 @@ from channels.generic.websocket import JsonWebsocketConsumer
|
|||
from rest_framework.exceptions import AuthenticationFailed
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.api.auth import token_from_header
|
||||
from authentik.api.authentication import token_from_header
|
||||
from authentik.core.models import User
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"""Notification API Views"""
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from guardian.utils import get_anonymous_user
|
||||
from rest_framework import mixins
|
||||
from rest_framework.fields import ReadOnlyField
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||
from authentik.events.api.event import EventSerializer
|
||||
from authentik.events.models import Notification
|
||||
|
||||
|
@ -49,12 +49,5 @@ class NotificationViewSet(
|
|||
"event",
|
||||
"seen",
|
||||
]
|
||||
filter_backends = [
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
SearchFilter,
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
return Notification.objects.filter(user=user.pk)
|
||||
permission_classes = [OwnerPermissions]
|
||||
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
|
||||
|
|
|
@ -65,7 +65,7 @@ class StageViewSet(
|
|||
search_fields = ["name"]
|
||||
filterset_fields = ["name"]
|
||||
|
||||
def get_queryset(self):
|
||||
def get_queryset(self): # pragma: no cover
|
||||
return Stage.objects.select_subclasses()
|
||||
|
||||
@extend_schema(responses={200: TypeCreateSerializer(many=True)})
|
||||
|
|
|
@ -2,28 +2,6 @@
|
|||
from django.http import HttpRequest
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import CreateView
|
||||
from guardian.shortcuts import assign_perm
|
||||
|
||||
|
||||
class CreateAssignPermView(CreateView):
|
||||
"""Assign permissions to object after creation"""
|
||||
|
||||
permissions = [
|
||||
"%s.view_%s",
|
||||
"%s.change_%s",
|
||||
"%s.delete_%s",
|
||||
]
|
||||
|
||||
def form_valid(self, form):
|
||||
response = super().form_valid(form)
|
||||
for permission in self.permissions:
|
||||
full_permission = permission % (
|
||||
self.object._meta.app_label,
|
||||
self.object._meta.model_name,
|
||||
)
|
||||
assign_perm(full_permission, self.request.user, self.object)
|
||||
return response
|
||||
|
||||
|
||||
def bad_request_message(
|
||||
|
|
|
@ -92,7 +92,7 @@ class PolicyViewSet(
|
|||
}
|
||||
search_fields = ["name"]
|
||||
|
||||
def get_queryset(self):
|
||||
def get_queryset(self): # pragma: no cover
|
||||
return Policy.objects.select_subclasses().prefetch_related(
|
||||
"bindings", "promptstage_set"
|
||||
)
|
||||
|
|
|
@ -174,7 +174,7 @@ REST_FRAMEWORK = {
|
|||
"rest_framework.permissions.DjangoObjectPermissions",
|
||||
),
|
||||
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||
"authentik.api.auth.AuthentikTokenAuthentication",
|
||||
"authentik.api.authentication.TokenAuthentication",
|
||||
"rest_framework.authentication.SessionAuthentication",
|
||||
),
|
||||
"DEFAULT_RENDERER_CLASSES": [
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
"""OAuth Source Serializer"""
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from guardian.utils import get_anonymous_user
|
||||
from rest_framework import mixins
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||
from authentik.core.api.sources import SourceSerializer
|
||||
from authentik.sources.oauth.models import UserOAuthSourceConnection
|
||||
|
||||
|
@ -21,20 +22,17 @@ class UserOAuthSourceConnectionSerializer(SourceSerializer):
|
|||
]
|
||||
|
||||
|
||||
class UserOAuthSourceConnectionViewSet(ModelViewSet):
|
||||
class UserOAuthSourceConnectionViewSet(
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = UserOAuthSourceConnection.objects.all()
|
||||
serializer_class = UserOAuthSourceConnectionSerializer
|
||||
filterset_fields = ["source__slug"]
|
||||
filter_backends = [
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
SearchFilter,
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
if user.is_superuser:
|
||||
return super().get_queryset()
|
||||
return super().get_queryset().filter(user=user.pk)
|
||||
permission_classes = [OwnerPermissions]
|
||||
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
"""AuthenticatorStaticStage API Views"""
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
|
||||
from guardian.utils import get_anonymous_user
|
||||
from rest_framework import mixins
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||
|
||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.stages.authenticator_static.models import AuthenticatorStaticStage
|
||||
|
||||
|
@ -47,23 +48,22 @@ class StaticDeviceSerializer(ModelSerializer):
|
|||
fields = ["name", "token_set", "pk"]
|
||||
|
||||
|
||||
class StaticDeviceViewSet(ModelViewSet):
|
||||
class StaticDeviceViewSet(
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
"""Viewset for static authenticator devices"""
|
||||
|
||||
queryset = StaticDevice.objects.none()
|
||||
queryset = StaticDevice.objects.all()
|
||||
serializer_class = StaticDeviceSerializer
|
||||
permission_classes = [OwnerPermissions]
|
||||
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
|
||||
search_fields = ["name"]
|
||||
filterset_fields = ["name"]
|
||||
ordering = ["name"]
|
||||
filter_backends = [
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
SearchFilter,
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
return StaticDevice.objects.filter(user=user.pk)
|
||||
|
||||
|
||||
class StaticAdminDeviceViewSet(ReadOnlyModelViewSet):
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"""Test Static API"""
|
||||
from django.urls import reverse
|
||||
from django_otp.plugins.otp_static.models import StaticDevice
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
|
||||
|
||||
class AuthenticatorStaticStage(APITestCase):
|
||||
"""Test Static API"""
|
||||
|
||||
def test_api_delete(self):
|
||||
"""Test api delete"""
|
||||
user = User.objects.create(username="foo")
|
||||
self.client.force_login(user)
|
||||
dev = StaticDevice.objects.create(user=user)
|
||||
response = self.client.delete(
|
||||
reverse("authentik_api:staticdevice-detail", kwargs={"pk": dev.pk})
|
||||
)
|
||||
self.assertEqual(response.status_code, 204)
|
|
@ -1,12 +1,13 @@
|
|||
"""AuthenticatorTOTPStage API Views"""
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||
from guardian.utils import get_anonymous_user
|
||||
from rest_framework import mixins
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||
|
||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.stages.authenticator_totp.models import AuthenticatorTOTPStage
|
||||
|
||||
|
@ -40,23 +41,22 @@ class TOTPDeviceSerializer(ModelSerializer):
|
|||
depth = 2
|
||||
|
||||
|
||||
class TOTPDeviceViewSet(ModelViewSet):
|
||||
class TOTPDeviceViewSet(
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
"""Viewset for totp authenticator devices"""
|
||||
|
||||
queryset = TOTPDevice.objects.none()
|
||||
queryset = TOTPDevice.objects.all()
|
||||
serializer_class = TOTPDeviceSerializer
|
||||
permission_classes = [OwnerPermissions]
|
||||
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
|
||||
search_fields = ["name"]
|
||||
filterset_fields = ["name"]
|
||||
ordering = ["name"]
|
||||
filter_backends = [
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
SearchFilter,
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
return TOTPDevice.objects.filter(user=user.pk)
|
||||
|
||||
|
||||
class TOTPAdminDeviceViewSet(ReadOnlyModelViewSet):
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"""Test TOTP API"""
|
||||
from django.urls import reverse
|
||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
|
||||
|
||||
class AuthenticatorTOTPStage(APITestCase):
|
||||
"""Test TOTP API"""
|
||||
|
||||
def test_api_delete(self):
|
||||
"""Test api delete"""
|
||||
user = User.objects.create(username="foo")
|
||||
self.client.force_login(user)
|
||||
dev = TOTPDevice.objects.create(user=user)
|
||||
response = self.client.delete(
|
||||
reverse("authentik_api:totpdevice-detail", kwargs={"pk": dev.pk})
|
||||
)
|
||||
self.assertEqual(response.status_code, 204)
|
|
@ -1,11 +1,12 @@
|
|||
"""AuthenticateWebAuthnStage API Views"""
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from guardian.utils import get_anonymous_user
|
||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
from rest_framework import mixins
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ReadOnlyModelViewSet
|
||||
|
||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.stages.authenticator_webauthn.models import (
|
||||
AuthenticateWebAuthnStage,
|
||||
|
@ -39,23 +40,22 @@ class WebAuthnDeviceSerializer(ModelSerializer):
|
|||
depth = 2
|
||||
|
||||
|
||||
class WebAuthnDeviceViewSet(ModelViewSet):
|
||||
class WebAuthnDeviceViewSet(
|
||||
mixins.RetrieveModelMixin,
|
||||
mixins.UpdateModelMixin,
|
||||
mixins.DestroyModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
GenericViewSet,
|
||||
):
|
||||
"""Viewset for WebAuthn authenticator devices"""
|
||||
|
||||
queryset = WebAuthnDevice.objects.none()
|
||||
queryset = WebAuthnDevice.objects.all()
|
||||
serializer_class = WebAuthnDeviceSerializer
|
||||
search_fields = ["name"]
|
||||
filterset_fields = ["name"]
|
||||
ordering = ["name"]
|
||||
filter_backends = [
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
SearchFilter,
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
return WebAuthnDevice.objects.filter(user=user.pk)
|
||||
permission_classes = [OwnerPermissions]
|
||||
filter_backends = [OwnerFilter, DjangoFilterBackend, OrderingFilter, SearchFilter]
|
||||
|
||||
|
||||
class WebAuthnAdminDeviceViewSet(ReadOnlyModelViewSet):
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"""Test WebAuthn API"""
|
||||
from django.urls import reverse
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
|
||||
|
||||
|
||||
class AuthenticatorWebAuthnStage(APITestCase):
|
||||
"""Test WebAuthn API"""
|
||||
|
||||
def test_api_delete(self):
|
||||
"""Test api delete"""
|
||||
user = User.objects.create(username="foo")
|
||||
self.client.force_login(user)
|
||||
dev = WebAuthnDevice.objects.create(user=user)
|
||||
response = self.client.delete(
|
||||
reverse("authentik_api:webauthndevice-detail", kwargs={"pk": dev.pk})
|
||||
)
|
||||
self.assertEqual(response.status_code, 204)
|
|
@ -1,5 +1,5 @@
|
|||
"""dummy tests"""
|
||||
from django.test import Client, TestCase
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
|
@ -14,7 +14,6 @@ class TestDummyStage(TestCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||
self.client = Client()
|
||||
|
||||
self.flow = Flow.objects.create(
|
||||
name="test-dummy",
|
||||
|
|
124
schema.yml
124
schema.yml
|
@ -444,37 +444,6 @@ paths:
|
|||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
post:
|
||||
operationId: authenticators_static_create
|
||||
description: Viewset for static authenticator devices
|
||||
tags:
|
||||
- authenticators
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StaticDeviceRequest'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StaticDeviceRequest'
|
||||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StaticDeviceRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/StaticDevice'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/api/v2beta/authenticators/static/{id}/:
|
||||
get:
|
||||
operationId: authenticators_static_retrieve
|
||||
|
@ -648,37 +617,6 @@ paths:
|
|||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
post:
|
||||
operationId: authenticators_totp_create
|
||||
description: Viewset for totp authenticator devices
|
||||
tags:
|
||||
- authenticators
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TOTPDeviceRequest'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TOTPDeviceRequest'
|
||||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TOTPDeviceRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TOTPDevice'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/api/v2beta/authenticators/totp/{id}/:
|
||||
get:
|
||||
operationId: authenticators_totp_retrieve
|
||||
|
@ -852,37 +790,6 @@ paths:
|
|||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
post:
|
||||
operationId: authenticators_webauthn_create
|
||||
description: Viewset for WebAuthn authenticator devices
|
||||
tags:
|
||||
- authenticators
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WebAuthnDeviceRequest'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WebAuthnDeviceRequest'
|
||||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WebAuthnDeviceRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WebAuthnDevice'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/api/v2beta/authenticators/webauthn/{id}/:
|
||||
get:
|
||||
operationId: authenticators_webauthn_retrieve
|
||||
|
@ -10117,37 +10024,6 @@ paths:
|
|||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
post:
|
||||
operationId: sources_oauth_user_connections_create
|
||||
description: Source Viewset
|
||||
tags:
|
||||
- sources
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserOAuthSourceConnectionRequest'
|
||||
application/x-www-form-urlencoded:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserOAuthSourceConnectionRequest'
|
||||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserOAuthSourceConnectionRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UserOAuthSourceConnection'
|
||||
description: ''
|
||||
'400':
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
'403':
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
/api/v2beta/sources/oauth_user_connections/{id}/:
|
||||
get:
|
||||
operationId: sources_oauth_user_connections_retrieve
|
||||
|
|
Reference in New Issue