authentik.endpoints.models

  1from datetime import UTC, datetime
  2from typing import TYPE_CHECKING, Any
  3from uuid import uuid4
  4
  5from django.core.cache import cache
  6from django.db import models
  7from django.db.models import OuterRef, Subquery
  8from django.utils.timezone import now
  9from django.utils.translation import gettext_lazy as _
 10from model_utils.managers import InheritanceManager
 11from rest_framework.serializers import Serializer
 12from structlog.stdlib import get_logger
 13
 14from authentik.core.models import AttributesMixin, ExpiringModel
 15from authentik.flows.models import Stage
 16from authentik.flows.stage import StageView
 17from authentik.lib.merge import MERGE_LIST_UNIQUE
 18from authentik.lib.models import InheritanceForeignKey, InternallyManagedMixin, SerializerModel
 19from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
 20from authentik.policies.models import PolicyBinding, PolicyBindingModel
 21from authentik.tasks.schedules.common import ScheduleSpec
 22from authentik.tasks.schedules.models import ScheduledModel
 23
 24if TYPE_CHECKING:
 25    from authentik.endpoints.controller import BaseController
 26
 27LOGGER = get_logger()
 28DEVICE_FACTS_CACHE_TIMEOUT = 3600
 29
 30
 31class Device(InternallyManagedMixin, ExpiringModel, AttributesMixin, PolicyBindingModel):
 32    device_uuid = models.UUIDField(default=uuid4, primary_key=True)
 33
 34    name = models.TextField(unique=True)
 35    identifier = models.TextField(unique=True)
 36    connections = models.ManyToManyField("Connector", through="DeviceConnection")
 37    access_group = models.ForeignKey(
 38        "DeviceAccessGroup", null=True, on_delete=models.SET_DEFAULT, default=None
 39    )
 40
 41    @property
 42    def cache_key_facts(self):
 43        return f"goauthentik.io/endpoints/devices/{self.device_uuid}/facts"
 44
 45    @property
 46    def cached_facts(self) -> DeviceFactSnapshot:
 47        if cached := cache.get(self.cache_key_facts):
 48            return cached
 49        facts = self.facts
 50        cache.set(self.cache_key_facts, facts, timeout=DEVICE_FACTS_CACHE_TIMEOUT)
 51        return facts
 52
 53    @property
 54    def facts(self) -> DeviceFactSnapshot:
 55        data = {}
 56        last_updated = datetime.fromtimestamp(0, UTC)
 57        for snapshot_data, snapshort_created in DeviceFactSnapshot.objects.filter(
 58            snapshot_id__in=Subquery(
 59                DeviceFactSnapshot.objects.filter(
 60                    connection__connector=OuterRef("connection__connector"), connection__device=self
 61                )
 62                .order_by("-created")
 63                .values("snapshot_id")[:1]
 64            )
 65        ).values_list("data", "created"):
 66            MERGE_LIST_UNIQUE.merge(data, snapshot_data)
 67            last_updated = max(last_updated, snapshort_created)
 68        return DeviceFactSnapshot(data=data, created=last_updated)
 69
 70    def __str__(self):
 71        return f"Device {self.name} {self.identifier} ({self.pk})"
 72
 73    class Meta(ExpiringModel.Meta):
 74        verbose_name = _("Device")
 75        verbose_name_plural = _("Devices")
 76
 77
 78class DeviceUserBinding(PolicyBinding):
 79    is_primary = models.BooleanField(default=False)
 80    # Used for storing a reference to the connector if this user/group binding was created
 81    # by a connector and not manually
 82    connector = models.ForeignKey("Connector", on_delete=models.CASCADE, null=True)
 83
 84    class Meta(PolicyBinding.Meta):
 85        verbose_name = _("Device User binding")
 86        verbose_name_plural = _("Device User bindings")
 87
 88
 89class DeviceConnection(InternallyManagedMixin, SerializerModel):
 90    device_connection_uuid = models.UUIDField(default=uuid4, primary_key=True)
 91    device = models.ForeignKey("Device", on_delete=models.CASCADE)
 92    connector = models.ForeignKey("Connector", on_delete=models.CASCADE)
 93
 94    def create_snapshot(self, data: dict[str, Any]):
 95        expires = now() + timedelta_from_string(self.connector.snapshot_expiry)
 96        # If this is the first snapshot for this connection, purge the cache
 97        if not DeviceFactSnapshot.objects.filter(connection=self).exists():
 98            LOGGER.debug("Purging facts cache for device", device=self.device)
 99            cache.delete(self.device.cache_key_facts)
100        return DeviceFactSnapshot.objects.create(
101            connection=self,
102            data=data,
103            expiring=True,
104            expires=expires,
105        )
106
107    @property
108    def serializer(self) -> type[Serializer]:
109        from authentik.endpoints.api.device_connections import DeviceConnectionSerializer
110
111        return DeviceConnectionSerializer
112
113    class Meta:
114        verbose_name = _("Device connection")
115        verbose_name_plural = _("Device connections")
116
117
118class DeviceFactSnapshot(InternallyManagedMixin, ExpiringModel, SerializerModel):
119    snapshot_id = models.UUIDField(primary_key=True, default=uuid4)
120    connection = models.ForeignKey(DeviceConnection, on_delete=models.CASCADE)
121    data = models.JSONField(default=dict)
122    created = models.DateTimeField(auto_now_add=True)
123
124    def __str__(self):
125        return f"Device fact snapshot {self.snapshot_id} from {self.created}"
126
127    @property
128    def serializer(self) -> type[Serializer]:
129        from authentik.endpoints.api.device_fact_snapshots import DeviceFactSnapshotSerializer
130
131        return DeviceFactSnapshotSerializer
132
133    class Meta(ExpiringModel.Meta):
134        verbose_name = _("Device fact snapshot")
135        verbose_name_plural = _("Device fact snapshots")
136
137
138class Connector(ScheduledModel, SerializerModel):
139    connector_uuid = models.UUIDField(default=uuid4, primary_key=True)
140
141    name = models.TextField()
142    enabled = models.BooleanField(default=True)
143
144    snapshot_expiry = models.TextField(
145        default="hours=24",
146        validators=[timedelta_string_validator],
147    )
148
149    objects = InheritanceManager()
150
151    @property
152    def stage(self) -> type[StageView] | None:
153        return None
154
155    @property
156    def component(self) -> str:
157        raise NotImplementedError
158
159    @property
160    def controller(self) -> type[BaseController[Connector]]:
161        raise NotImplementedError
162
163    @property
164    def schedule_specs(self) -> list[ScheduleSpec]:
165        from authentik.endpoints.controller import Capabilities
166        from authentik.endpoints.tasks import endpoints_sync
167
168        if Capabilities.ENROLL_AUTOMATIC_API not in self.controller(self).capabilities():
169            return []
170        return [
171            ScheduleSpec(
172                actor=endpoints_sync,
173                uid=self.name,
174                args=(self.pk,),
175                crontab="3-59/15 * * * *",
176                send_on_save=True,
177            ),
178        ]
179
180
181class DeviceAccessGroup(AttributesMixin, SerializerModel, PolicyBindingModel):
182
183    name = models.TextField(unique=True)
184
185    @property
186    def serializer(self) -> type[Serializer]:
187        from authentik.endpoints.api.device_access_group import DeviceAccessGroupSerializer
188
189        return DeviceAccessGroupSerializer
190
191    class Meta:
192        verbose_name = _("Device access group")
193        verbose_name_plural = _("Device access groups")
194
195
196class StageMode(models.TextChoices):
197    """Modes the Stage can operate in"""
198
199    OPTIONAL = "optional"
200    REQUIRED = "required"
201
202
203class EndpointStage(Stage):
204    """Stage which associates the currently used device with the current session."""
205
206    connector = InheritanceForeignKey(Connector, on_delete=models.CASCADE)
207
208    mode = models.TextField(choices=StageMode.choices, default=StageMode.OPTIONAL)
209
210    @property
211    def view(self) -> type[StageView]:
212        from authentik.endpoints.stage import EndpointStageView
213
214        return EndpointStageView
215
216    @property
217    def serializer(self) -> type[Serializer]:
218        from authentik.endpoints.api.stages import EndpointStageSerializer
219
220        return EndpointStageSerializer
221
222    @property
223    def component(self) -> str:
224        return "ak-endpoints-stage-form"
225
226    class Meta(PolicyBinding.Meta):
227        verbose_name = _("Endpoint Stage")
228        verbose_name_plural = _("Endpoint Stages")
LOGGER = <BoundLoggerLazyProxy(logger=None, wrapper_class=None, processors=None, context_class=None, initial_values={}, logger_factory_args=())>
DEVICE_FACTS_CACHE_TIMEOUT = 3600
32class Device(InternallyManagedMixin, ExpiringModel, AttributesMixin, PolicyBindingModel):
33    device_uuid = models.UUIDField(default=uuid4, primary_key=True)
34
35    name = models.TextField(unique=True)
36    identifier = models.TextField(unique=True)
37    connections = models.ManyToManyField("Connector", through="DeviceConnection")
38    access_group = models.ForeignKey(
39        "DeviceAccessGroup", null=True, on_delete=models.SET_DEFAULT, default=None
40    )
41
42    @property
43    def cache_key_facts(self):
44        return f"goauthentik.io/endpoints/devices/{self.device_uuid}/facts"
45
46    @property
47    def cached_facts(self) -> DeviceFactSnapshot:
48        if cached := cache.get(self.cache_key_facts):
49            return cached
50        facts = self.facts
51        cache.set(self.cache_key_facts, facts, timeout=DEVICE_FACTS_CACHE_TIMEOUT)
52        return facts
53
54    @property
55    def facts(self) -> DeviceFactSnapshot:
56        data = {}
57        last_updated = datetime.fromtimestamp(0, UTC)
58        for snapshot_data, snapshort_created in DeviceFactSnapshot.objects.filter(
59            snapshot_id__in=Subquery(
60                DeviceFactSnapshot.objects.filter(
61                    connection__connector=OuterRef("connection__connector"), connection__device=self
62                )
63                .order_by("-created")
64                .values("snapshot_id")[:1]
65            )
66        ).values_list("data", "created"):
67            MERGE_LIST_UNIQUE.merge(data, snapshot_data)
68            last_updated = max(last_updated, snapshort_created)
69        return DeviceFactSnapshot(data=data, created=last_updated)
70
71    def __str__(self):
72        return f"Device {self.name} {self.identifier} ({self.pk})"
73
74    class Meta(ExpiringModel.Meta):
75        verbose_name = _("Device")
76        verbose_name_plural = _("Devices")

Device(pbm_uuid, policy_engine_mode, policybindingmodel_ptr, attributes, expires, expiring, device_uuid, name, identifier, access_group)

def device_uuid(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def identifier(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

connections

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

access_group

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

cache_key_facts
42    @property
43    def cache_key_facts(self):
44        return f"goauthentik.io/endpoints/devices/{self.device_uuid}/facts"
cached_facts: DeviceFactSnapshot
46    @property
47    def cached_facts(self) -> DeviceFactSnapshot:
48        if cached := cache.get(self.cache_key_facts):
49            return cached
50        facts = self.facts
51        cache.set(self.cache_key_facts, facts, timeout=DEVICE_FACTS_CACHE_TIMEOUT)
52        return facts
facts: DeviceFactSnapshot
54    @property
55    def facts(self) -> DeviceFactSnapshot:
56        data = {}
57        last_updated = datetime.fromtimestamp(0, UTC)
58        for snapshot_data, snapshort_created in DeviceFactSnapshot.objects.filter(
59            snapshot_id__in=Subquery(
60                DeviceFactSnapshot.objects.filter(
61                    connection__connector=OuterRef("connection__connector"), connection__device=self
62                )
63                .order_by("-created")
64                .values("snapshot_id")[:1]
65            )
66        ).values_list("data", "created"):
67            MERGE_LIST_UNIQUE.merge(data, snapshot_data)
68            last_updated = max(last_updated, snapshort_created)
69        return DeviceFactSnapshot(data=data, created=last_updated)
def expires(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def expiring(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def attributes(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

access_group_id
policybindingmodel_ptr_id
policybindingmodel_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

deviceconnection_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

deviceauthenticationtoken_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

The requested object does not exist

The query returned multiple objects when only one was expected.

class DeviceUserBinding(authentik.policies.models.PolicyBinding):
79class DeviceUserBinding(PolicyBinding):
80    is_primary = models.BooleanField(default=False)
81    # Used for storing a reference to the connector if this user/group binding was created
82    # by a connector and not manually
83    connector = models.ForeignKey("Connector", on_delete=models.CASCADE, null=True)
84
85    class Meta(PolicyBinding.Meta):
86        verbose_name = _("Device User binding")
87        verbose_name_plural = _("Device User bindings")

DeviceUserBinding(policy_binding_uuid, enabled, policy, group, user, target, negate, timeout, failure_result, order, policybinding_ptr, is_primary, connector)

def is_primary(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

connector

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

connector_id
policybinding_ptr_id
policybinding_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

agentdeviceuserbinding

Accessor to the related object on the reverse side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

class DeviceUserBinding.DoesNotExist(authentik.policies.models.PolicyBinding.DoesNotExist):

The requested object does not exist

class DeviceUserBinding.MultipleObjectsReturned(authentik.policies.models.PolicyBinding.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

 90class DeviceConnection(InternallyManagedMixin, SerializerModel):
 91    device_connection_uuid = models.UUIDField(default=uuid4, primary_key=True)
 92    device = models.ForeignKey("Device", on_delete=models.CASCADE)
 93    connector = models.ForeignKey("Connector", on_delete=models.CASCADE)
 94
 95    def create_snapshot(self, data: dict[str, Any]):
 96        expires = now() + timedelta_from_string(self.connector.snapshot_expiry)
 97        # If this is the first snapshot for this connection, purge the cache
 98        if not DeviceFactSnapshot.objects.filter(connection=self).exists():
 99            LOGGER.debug("Purging facts cache for device", device=self.device)
100            cache.delete(self.device.cache_key_facts)
101        return DeviceFactSnapshot.objects.create(
102            connection=self,
103            data=data,
104            expiring=True,
105            expires=expires,
106        )
107
108    @property
109    def serializer(self) -> type[Serializer]:
110        from authentik.endpoints.api.device_connections import DeviceConnectionSerializer
111
112        return DeviceConnectionSerializer
113
114    class Meta:
115        verbose_name = _("Device connection")
116        verbose_name_plural = _("Device connections")

DeviceConnection(device_connection_uuid, device, connector)

def device_connection_uuid(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

device

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

connector

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

def create_snapshot(self, data: dict[str, typing.Any]):
 95    def create_snapshot(self, data: dict[str, Any]):
 96        expires = now() + timedelta_from_string(self.connector.snapshot_expiry)
 97        # If this is the first snapshot for this connection, purge the cache
 98        if not DeviceFactSnapshot.objects.filter(connection=self).exists():
 99            LOGGER.debug("Purging facts cache for device", device=self.device)
100            cache.delete(self.device.cache_key_facts)
101        return DeviceFactSnapshot.objects.create(
102            connection=self,
103            data=data,
104            expiring=True,
105            expires=expires,
106        )
serializer: type[rest_framework.serializers.Serializer]
108    @property
109    def serializer(self) -> type[Serializer]:
110        from authentik.endpoints.api.device_connections import DeviceConnectionSerializer
111
112        return DeviceConnectionSerializer

Get serializer for this model

device_id
connector_id
def objects(unknown):

The type of the None singleton.

devicefactsnapshot_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

agentdeviceconnection

Accessor to the related object on the reverse side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

class DeviceConnection.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class DeviceConnection.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

119class DeviceFactSnapshot(InternallyManagedMixin, ExpiringModel, SerializerModel):
120    snapshot_id = models.UUIDField(primary_key=True, default=uuid4)
121    connection = models.ForeignKey(DeviceConnection, on_delete=models.CASCADE)
122    data = models.JSONField(default=dict)
123    created = models.DateTimeField(auto_now_add=True)
124
125    def __str__(self):
126        return f"Device fact snapshot {self.snapshot_id} from {self.created}"
127
128    @property
129    def serializer(self) -> type[Serializer]:
130        from authentik.endpoints.api.device_fact_snapshots import DeviceFactSnapshotSerializer
131
132        return DeviceFactSnapshotSerializer
133
134    class Meta(ExpiringModel.Meta):
135        verbose_name = _("Device fact snapshot")
136        verbose_name_plural = _("Device fact snapshots")

DeviceFactSnapshot(expires, expiring, snapshot_id, connection, data, created)

def snapshot_id(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

connection

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

def data(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def created(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

serializer: type[rest_framework.serializers.Serializer]
128    @property
129    def serializer(self) -> type[Serializer]:
130        from authentik.endpoints.api.device_fact_snapshots import DeviceFactSnapshotSerializer
131
132        return DeviceFactSnapshotSerializer

Get serializer for this model

def expires(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def expiring(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

connection_id
def get_next_by_created(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

def get_previous_by_created(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

class DeviceFactSnapshot.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class DeviceFactSnapshot.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

139class Connector(ScheduledModel, SerializerModel):
140    connector_uuid = models.UUIDField(default=uuid4, primary_key=True)
141
142    name = models.TextField()
143    enabled = models.BooleanField(default=True)
144
145    snapshot_expiry = models.TextField(
146        default="hours=24",
147        validators=[timedelta_string_validator],
148    )
149
150    objects = InheritanceManager()
151
152    @property
153    def stage(self) -> type[StageView] | None:
154        return None
155
156    @property
157    def component(self) -> str:
158        raise NotImplementedError
159
160    @property
161    def controller(self) -> type[BaseController[Connector]]:
162        raise NotImplementedError
163
164    @property
165    def schedule_specs(self) -> list[ScheduleSpec]:
166        from authentik.endpoints.controller import Capabilities
167        from authentik.endpoints.tasks import endpoints_sync
168
169        if Capabilities.ENROLL_AUTOMATIC_API not in self.controller(self).capabilities():
170            return []
171        return [
172            ScheduleSpec(
173                actor=endpoints_sync,
174                uid=self.name,
175                args=(self.pk,),
176                crontab="3-59/15 * * * *",
177                send_on_save=True,
178            ),
179        ]

Connector(connector_uuid, name, enabled, snapshot_expiry)

def connector_uuid(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def enabled(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def snapshot_expiry(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

def objects(unknown):

The type of the None singleton.

stage: type[authentik.flows.stage.StageView] | None
152    @property
153    def stage(self) -> type[StageView] | None:
154        return None
component: str
156    @property
157    def component(self) -> str:
158        raise NotImplementedError
controller
160    @property
161    def controller(self) -> type[BaseController[Connector]]:
162        raise NotImplementedError
schedule_specs: list[authentik.tasks.schedules.common.ScheduleSpec]
164    @property
165    def schedule_specs(self) -> list[ScheduleSpec]:
166        from authentik.endpoints.controller import Capabilities
167        from authentik.endpoints.tasks import endpoints_sync
168
169        if Capabilities.ENROLL_AUTOMATIC_API not in self.controller(self).capabilities():
170            return []
171        return [
172            ScheduleSpec(
173                actor=endpoints_sync,
174                uid=self.name,
175                args=(self.pk,),
176                crontab="3-59/15 * * * *",
177                send_on_save=True,
178            ),
179        ]
schedules

Accessor to the related objects manager on the one-to-many relation created by GenericRelation.

In the example::

class Post(Model):
    comments = GenericRelation(Comment)

post.comments is a ReverseGenericManyToOneDescriptor instance.

tasks

Accessor to the related objects manager on the one-to-many relation created by GenericRelation.

In the example::

class Post(Model):
    comments = GenericRelation(Comment)

post.comments is a ReverseGenericManyToOneDescriptor instance.

device_set

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example::

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

deviceuserbinding_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

deviceconnection_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

endpointstage_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

agentconnector

Accessor to the related object on the reverse side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

fleetconnector

Accessor to the related object on the reverse side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

googlechromeconnector

Accessor to the related object on the reverse side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Place.restaurant is a ReverseOneToOneDescriptor instance.

class Connector.DoesNotExist(django.core.exceptions.ObjectDoesNotExist):

The requested object does not exist

class Connector.MultipleObjectsReturned(django.core.exceptions.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

182class DeviceAccessGroup(AttributesMixin, SerializerModel, PolicyBindingModel):
183
184    name = models.TextField(unique=True)
185
186    @property
187    def serializer(self) -> type[Serializer]:
188        from authentik.endpoints.api.device_access_group import DeviceAccessGroupSerializer
189
190        return DeviceAccessGroupSerializer
191
192    class Meta:
193        verbose_name = _("Device access group")
194        verbose_name_plural = _("Device access groups")

DeviceAccessGroup(pbm_uuid, policy_engine_mode, policybindingmodel_ptr, attributes, name)

def name(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

serializer: type[rest_framework.serializers.Serializer]
186    @property
187    def serializer(self) -> type[Serializer]:
188        from authentik.endpoints.api.device_access_group import DeviceAccessGroupSerializer
189
190        return DeviceAccessGroupSerializer

Get serializer for this model

def attributes(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

policybindingmodel_ptr_id
policybindingmodel_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

device_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

enrollmenttoken_set

Accessor to the related objects manager on the reverse side of a many-to-one relation.

In the example::

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Parent.children is a ReverseManyToOneDescriptor instance.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

class DeviceAccessGroup.DoesNotExist(authentik.policies.models.PolicyBindingModel.DoesNotExist):

The requested object does not exist

class DeviceAccessGroup.MultipleObjectsReturned(authentik.policies.models.PolicyBindingModel.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.

class StageMode(django.db.models.enums.TextChoices):
197class StageMode(models.TextChoices):
198    """Modes the Stage can operate in"""
199
200    OPTIONAL = "optional"
201    REQUIRED = "required"

Modes the Stage can operate in

OPTIONAL = StageMode.OPTIONAL
REQUIRED = StageMode.REQUIRED
class EndpointStage(authentik.flows.models.Stage):
204class EndpointStage(Stage):
205    """Stage which associates the currently used device with the current session."""
206
207    connector = InheritanceForeignKey(Connector, on_delete=models.CASCADE)
208
209    mode = models.TextField(choices=StageMode.choices, default=StageMode.OPTIONAL)
210
211    @property
212    def view(self) -> type[StageView]:
213        from authentik.endpoints.stage import EndpointStageView
214
215        return EndpointStageView
216
217    @property
218    def serializer(self) -> type[Serializer]:
219        from authentik.endpoints.api.stages import EndpointStageSerializer
220
221        return EndpointStageSerializer
222
223    @property
224    def component(self) -> str:
225        return "ak-endpoints-stage-form"
226
227    class Meta(PolicyBinding.Meta):
228        verbose_name = _("Endpoint Stage")
229        verbose_name_plural = _("Endpoint Stages")

Stage which associates the currently used device with the current session.

connector

Forward ManyToOne Descriptor that selects subclass. Requires InheritanceAutoManager.

def mode(unknown):

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

view: type[authentik.flows.stage.StageView]
211    @property
212    def view(self) -> type[StageView]:
213        from authentik.endpoints.stage import EndpointStageView
214
215        return EndpointStageView

Return StageView class that implements logic for this stage

serializer: type[rest_framework.serializers.Serializer]
217    @property
218    def serializer(self) -> type[Serializer]:
219        from authentik.endpoints.api.stages import EndpointStageSerializer
220
221        return EndpointStageSerializer

Get serializer for this model

component: str
223    @property
224    def component(self) -> str:
225        return "ak-endpoints-stage-form"

Return component used to edit this object

connector_id
def get_mode_display(unknown):

Method descriptor with partial application of the given arguments and keywords.

Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.

stage_ptr_id
stage_ptr

Accessor to the related object on the forward side of a one-to-one relation.

In the example::

class Restaurant(Model):
    place = OneToOneField(Place, related_name='restaurant')

Restaurant.place is a ForwardOneToOneDescriptor instance.

class EndpointStage.DoesNotExist(authentik.flows.models.Stage.DoesNotExist):

The requested object does not exist

class EndpointStage.MultipleObjectsReturned(authentik.flows.models.Stage.MultipleObjectsReturned):

The query returned multiple objects when only one was expected.