authentik.core.api.devices

Authenticator Devices API Views

 1"""Authenticator Devices API Views"""
 2
 3from drf_spectacular.utils import extend_schema
 4from guardian.shortcuts import get_objects_for_user
 5from rest_framework.fields import (
 6    BooleanField,
 7    CharField,
 8    DateTimeField,
 9    SerializerMethodField,
10)
11from rest_framework.permissions import IsAuthenticated
12from rest_framework.request import Request
13from rest_framework.response import Response
14from rest_framework.viewsets import ViewSet
15
16from authentik.api.validation import validate
17from authentik.core.api.users import ParamUserSerializer
18from authentik.core.api.utils import MetaNameSerializer
19from authentik.stages.authenticator import device_classes, devices_for_user
20from authentik.stages.authenticator.models import Device
21from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
22
23try:
24    from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import EndpointDevice
25except ModuleNotFoundError:
26    EndpointDevice = None
27
28
29class DeviceSerializer(MetaNameSerializer):
30    """Serializer for authenticator devices"""
31
32    pk = CharField()
33    name = CharField()
34    type = SerializerMethodField()
35    confirmed = BooleanField()
36    created = DateTimeField(read_only=True)
37    last_updated = DateTimeField(read_only=True)
38    last_used = DateTimeField(read_only=True, allow_null=True)
39    extra_description = SerializerMethodField()
40    external_id = SerializerMethodField()
41
42    def get_type(self, instance: Device) -> str:
43        """Get type of device"""
44        return instance._meta.label
45
46    def get_extra_description(self, instance: Device) -> str | None:
47        """Get extra description"""
48        if isinstance(instance, WebAuthnDevice):
49            return instance.device_type.description if instance.device_type else None
50        if EndpointDevice and isinstance(instance, EndpointDevice):
51            return instance.data.get("deviceSignals", {}).get("deviceModel")
52        return None
53
54    def get_external_id(self, instance: Device) -> str | None:
55        """Get external Device ID"""
56        if isinstance(instance, WebAuthnDevice):
57            return instance.device_type.aaguid if instance.device_type else None
58        if EndpointDevice and isinstance(instance, EndpointDevice):
59            return instance.data.get("deviceSignals", {}).get("deviceModel")
60        return None
61
62
63class DeviceViewSet(ViewSet):
64    """Viewset for authenticator devices"""
65
66    serializer_class = DeviceSerializer
67    permission_classes = [IsAuthenticated]
68
69    def list(self, request: Request) -> Response:
70        """Get all devices for current user"""
71        devices = devices_for_user(request.user)
72        return Response(DeviceSerializer(devices, many=True).data)
73
74
75class AdminDeviceViewSet(ViewSet):
76    """Viewset for authenticator devices"""
77
78    serializer_class = DeviceSerializer
79    permission_classes = [IsAuthenticated]
80
81    def get_devices(self, **kwargs):
82        """Get all devices in all child classes"""
83        for model in device_classes():
84            device_set = get_objects_for_user(
85                self.request.user, f"{model._meta.app_label}.view_{model._meta.model_name}"
86            ).filter(**kwargs)
87            yield from device_set
88
89    @extend_schema(
90        parameters=[ParamUserSerializer],
91        responses={200: DeviceSerializer(many=True)},
92    )
93    @validate(ParamUserSerializer, "query")
94    def list(self, request: Request, query: ParamUserSerializer) -> Response:
95        """Get all devices for current user"""
96        return Response(DeviceSerializer(self.get_devices(**query.validated_data), many=True).data)
class DeviceSerializer(authentik.core.api.utils.MetaNameSerializer):
30class DeviceSerializer(MetaNameSerializer):
31    """Serializer for authenticator devices"""
32
33    pk = CharField()
34    name = CharField()
35    type = SerializerMethodField()
36    confirmed = BooleanField()
37    created = DateTimeField(read_only=True)
38    last_updated = DateTimeField(read_only=True)
39    last_used = DateTimeField(read_only=True, allow_null=True)
40    extra_description = SerializerMethodField()
41    external_id = SerializerMethodField()
42
43    def get_type(self, instance: Device) -> str:
44        """Get type of device"""
45        return instance._meta.label
46
47    def get_extra_description(self, instance: Device) -> str | None:
48        """Get extra description"""
49        if isinstance(instance, WebAuthnDevice):
50            return instance.device_type.description if instance.device_type else None
51        if EndpointDevice and isinstance(instance, EndpointDevice):
52            return instance.data.get("deviceSignals", {}).get("deviceModel")
53        return None
54
55    def get_external_id(self, instance: Device) -> str | None:
56        """Get external Device ID"""
57        if isinstance(instance, WebAuthnDevice):
58            return instance.device_type.aaguid if instance.device_type else None
59        if EndpointDevice and isinstance(instance, EndpointDevice):
60            return instance.data.get("deviceSignals", {}).get("deviceModel")
61        return None

Serializer for authenticator devices

pk
name
type
confirmed
created
last_updated
last_used
extra_description
external_id
def get_type(self, instance: authentik.stages.authenticator.models.Device) -> str:
43    def get_type(self, instance: Device) -> str:
44        """Get type of device"""
45        return instance._meta.label

Get type of device

def get_extra_description( self, instance: authentik.stages.authenticator.models.Device) -> str | None:
47    def get_extra_description(self, instance: Device) -> str | None:
48        """Get extra description"""
49        if isinstance(instance, WebAuthnDevice):
50            return instance.device_type.description if instance.device_type else None
51        if EndpointDevice and isinstance(instance, EndpointDevice):
52            return instance.data.get("deviceSignals", {}).get("deviceModel")
53        return None

Get extra description

def get_external_id( self, instance: authentik.stages.authenticator.models.Device) -> str | None:
55    def get_external_id(self, instance: Device) -> str | None:
56        """Get external Device ID"""
57        if isinstance(instance, WebAuthnDevice):
58            return instance.device_type.aaguid if instance.device_type else None
59        if EndpointDevice and isinstance(instance, EndpointDevice):
60            return instance.data.get("deviceSignals", {}).get("deviceModel")
61        return None

Get external Device ID

class DeviceViewSet(rest_framework.viewsets.ViewSet):
64class DeviceViewSet(ViewSet):
65    """Viewset for authenticator devices"""
66
67    serializer_class = DeviceSerializer
68    permission_classes = [IsAuthenticated]
69
70    def list(self, request: Request) -> Response:
71        """Get all devices for current user"""
72        devices = devices_for_user(request.user)
73        return Response(DeviceSerializer(devices, many=True).data)

Viewset for authenticator devices

serializer_class = <class 'DeviceSerializer'>
permission_classes = [<class 'rest_framework.permissions.IsAuthenticated'>]
def list( self, request: rest_framework.request.Request) -> rest_framework.response.Response:
70    def list(self, request: Request) -> Response:
71        """Get all devices for current user"""
72        devices = devices_for_user(request.user)
73        return Response(DeviceSerializer(devices, many=True).data)

Get all devices for current user

name = None
description = None
suffix = None
detail = None
basename = None
class AdminDeviceViewSet(rest_framework.viewsets.ViewSet):
76class AdminDeviceViewSet(ViewSet):
77    """Viewset for authenticator devices"""
78
79    serializer_class = DeviceSerializer
80    permission_classes = [IsAuthenticated]
81
82    def get_devices(self, **kwargs):
83        """Get all devices in all child classes"""
84        for model in device_classes():
85            device_set = get_objects_for_user(
86                self.request.user, f"{model._meta.app_label}.view_{model._meta.model_name}"
87            ).filter(**kwargs)
88            yield from device_set
89
90    @extend_schema(
91        parameters=[ParamUserSerializer],
92        responses={200: DeviceSerializer(many=True)},
93    )
94    @validate(ParamUserSerializer, "query")
95    def list(self, request: Request, query: ParamUserSerializer) -> Response:
96        """Get all devices for current user"""
97        return Response(DeviceSerializer(self.get_devices(**query.validated_data), many=True).data)

Viewset for authenticator devices

serializer_class = <class 'DeviceSerializer'>
permission_classes = [<class 'rest_framework.permissions.IsAuthenticated'>]
def get_devices(self, **kwargs):
82    def get_devices(self, **kwargs):
83        """Get all devices in all child classes"""
84        for model in device_classes():
85            device_set = get_objects_for_user(
86                self.request.user, f"{model._meta.app_label}.view_{model._meta.model_name}"
87            ).filter(**kwargs)
88            yield from device_set

Get all devices in all child classes

@extend_schema(parameters=[ParamUserSerializer], responses={200: DeviceSerializer(many=True)})
@validate(ParamUserSerializer, 'query')
def list( self, request: rest_framework.request.Request, query: authentik.core.api.users.ParamUserSerializer) -> rest_framework.response.Response:
90    @extend_schema(
91        parameters=[ParamUserSerializer],
92        responses={200: DeviceSerializer(many=True)},
93    )
94    @validate(ParamUserSerializer, "query")
95    def list(self, request: Request, query: ParamUserSerializer) -> Response:
96        """Get all devices for current user"""
97        return Response(DeviceSerializer(self.get_devices(**query.validated_data), many=True).data)

Get all devices for current user

name = None
description = None
suffix = None
detail = None
basename = None