authentik.stages.identification.models

identification stage models

  1"""identification stage models"""
  2
  3from django.contrib.postgres.fields import ArrayField
  4from django.db import models
  5from django.utils.translation import gettext_lazy as _
  6from django.views import View
  7from rest_framework.serializers import BaseSerializer
  8
  9from authentik.core.models import Source
 10from authentik.flows.models import Flow, Stage
 11from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
 12from authentik.stages.captcha.models import CaptchaStage
 13from authentik.stages.password.models import PasswordStage
 14
 15
 16class UserFields(models.TextChoices):
 17    """Fields which the user can identify themselves with"""
 18
 19    E_MAIL = "email"
 20    USERNAME = "username"
 21    UPN = "upn"
 22
 23
 24class IdentificationStage(Stage):
 25    """Identify the user for authentication."""
 26
 27    user_fields = ArrayField(
 28        models.CharField(max_length=100, choices=UserFields.choices),
 29        blank=True,
 30        help_text=_(
 31            "Fields of the user object to match against. (Hold shift to select multiple options)"
 32        ),
 33    )
 34
 35    password_stage = models.ForeignKey(
 36        PasswordStage,
 37        null=True,
 38        default=None,
 39        on_delete=models.SET_NULL,
 40        help_text=_(
 41            (
 42                "When set, shows a password field, instead of showing the "
 43                "password field as separate step."
 44            ),
 45        ),
 46    )
 47
 48    captcha_stage = models.ForeignKey(
 49        CaptchaStage,
 50        null=True,
 51        default=None,
 52        on_delete=models.SET_NULL,
 53        help_text=_(
 54            (
 55                "When set, adds functionality exactly like a Captcha stage, but baked into the "
 56                "Identification stage."
 57            ),
 58        ),
 59    )
 60
 61    webauthn_stage = models.ForeignKey(
 62        AuthenticatorValidateStage,
 63        null=True,
 64        default=None,
 65        on_delete=models.SET_NULL,
 66        help_text=_(
 67            (
 68                "When set, and conditional WebAuthn is available, allow the user to use their "
 69                "passkey as a first factor."
 70            ),
 71        ),
 72    )
 73
 74    case_insensitive_matching = models.BooleanField(
 75        default=True,
 76        help_text=_("When enabled, user fields are matched regardless of their casing."),
 77    )
 78    show_matched_user = models.BooleanField(
 79        default=True,
 80        help_text=_(
 81            "When a valid username/email has been entered, and this option is enabled, "
 82            "the user's username and avatar will be shown. Otherwise, the text that the user "
 83            "entered will be shown"
 84        ),
 85    )
 86    pretend_user_exists = models.BooleanField(
 87        default=True,
 88        help_text=_(
 89            "When enabled, the stage will succeed and continue even when incorrect user info "
 90            "is entered."
 91        ),
 92    )
 93    enable_remember_me = models.BooleanField(
 94        default=False,
 95        help_text=_(
 96            "Show the user the 'Remember me on this device' toggle, allowing repeat "
 97            "users to skip straight to entering their password."
 98        ),
 99    )
100    enrollment_flow = models.ForeignKey(
101        Flow,
102        on_delete=models.SET_DEFAULT,
103        null=True,
104        blank=True,
105        related_name="+",
106        default=None,
107        help_text=_("Optional enrollment flow, which is linked at the bottom of the page."),
108    )
109    recovery_flow = models.ForeignKey(
110        Flow,
111        on_delete=models.SET_DEFAULT,
112        null=True,
113        blank=True,
114        related_name="+",
115        default=None,
116        help_text=_("Optional recovery flow, which is linked at the bottom of the page."),
117    )
118    passwordless_flow = models.ForeignKey(
119        Flow,
120        on_delete=models.SET_DEFAULT,
121        null=True,
122        blank=True,
123        related_name="+",
124        default=None,
125        help_text=_("Optional passwordless flow, which is linked at the bottom of the page."),
126    )
127
128    sources = models.ManyToManyField(
129        Source, default=list, help_text=_("Specify which sources should be shown."), blank=True
130    )
131    show_source_labels = models.BooleanField(default=False)
132
133    @property
134    def serializer(self) -> type[BaseSerializer]:
135        from authentik.stages.identification.api import IdentificationStageSerializer
136
137        return IdentificationStageSerializer
138
139    @property
140    def view(self) -> type[View]:
141        from authentik.stages.identification.stage import IdentificationStageView
142
143        return IdentificationStageView
144
145    @property
146    def component(self) -> str:
147        return "ak-stage-identification-form"
148
149    class Meta:
150        verbose_name = _("Identification Stage")
151        verbose_name_plural = _("Identification Stages")
class UserFields(django.db.models.enums.TextChoices):
17class UserFields(models.TextChoices):
18    """Fields which the user can identify themselves with"""
19
20    E_MAIL = "email"
21    USERNAME = "username"
22    UPN = "upn"

Fields which the user can identify themselves with

USERNAME = UserFields.USERNAME
class IdentificationStage(authentik.flows.models.Stage):
 25class IdentificationStage(Stage):
 26    """Identify the user for authentication."""
 27
 28    user_fields = ArrayField(
 29        models.CharField(max_length=100, choices=UserFields.choices),
 30        blank=True,
 31        help_text=_(
 32            "Fields of the user object to match against. (Hold shift to select multiple options)"
 33        ),
 34    )
 35
 36    password_stage = models.ForeignKey(
 37        PasswordStage,
 38        null=True,
 39        default=None,
 40        on_delete=models.SET_NULL,
 41        help_text=_(
 42            (
 43                "When set, shows a password field, instead of showing the "
 44                "password field as separate step."
 45            ),
 46        ),
 47    )
 48
 49    captcha_stage = models.ForeignKey(
 50        CaptchaStage,
 51        null=True,
 52        default=None,
 53        on_delete=models.SET_NULL,
 54        help_text=_(
 55            (
 56                "When set, adds functionality exactly like a Captcha stage, but baked into the "
 57                "Identification stage."
 58            ),
 59        ),
 60    )
 61
 62    webauthn_stage = models.ForeignKey(
 63        AuthenticatorValidateStage,
 64        null=True,
 65        default=None,
 66        on_delete=models.SET_NULL,
 67        help_text=_(
 68            (
 69                "When set, and conditional WebAuthn is available, allow the user to use their "
 70                "passkey as a first factor."
 71            ),
 72        ),
 73    )
 74
 75    case_insensitive_matching = models.BooleanField(
 76        default=True,
 77        help_text=_("When enabled, user fields are matched regardless of their casing."),
 78    )
 79    show_matched_user = models.BooleanField(
 80        default=True,
 81        help_text=_(
 82            "When a valid username/email has been entered, and this option is enabled, "
 83            "the user's username and avatar will be shown. Otherwise, the text that the user "
 84            "entered will be shown"
 85        ),
 86    )
 87    pretend_user_exists = models.BooleanField(
 88        default=True,
 89        help_text=_(
 90            "When enabled, the stage will succeed and continue even when incorrect user info "
 91            "is entered."
 92        ),
 93    )
 94    enable_remember_me = models.BooleanField(
 95        default=False,
 96        help_text=_(
 97            "Show the user the 'Remember me on this device' toggle, allowing repeat "
 98            "users to skip straight to entering their password."
 99        ),
100    )
101    enrollment_flow = models.ForeignKey(
102        Flow,
103        on_delete=models.SET_DEFAULT,
104        null=True,
105        blank=True,
106        related_name="+",
107        default=None,
108        help_text=_("Optional enrollment flow, which is linked at the bottom of the page."),
109    )
110    recovery_flow = models.ForeignKey(
111        Flow,
112        on_delete=models.SET_DEFAULT,
113        null=True,
114        blank=True,
115        related_name="+",
116        default=None,
117        help_text=_("Optional recovery flow, which is linked at the bottom of the page."),
118    )
119    passwordless_flow = models.ForeignKey(
120        Flow,
121        on_delete=models.SET_DEFAULT,
122        null=True,
123        blank=True,
124        related_name="+",
125        default=None,
126        help_text=_("Optional passwordless flow, which is linked at the bottom of the page."),
127    )
128
129    sources = models.ManyToManyField(
130        Source, default=list, help_text=_("Specify which sources should be shown."), blank=True
131    )
132    show_source_labels = models.BooleanField(default=False)
133
134    @property
135    def serializer(self) -> type[BaseSerializer]:
136        from authentik.stages.identification.api import IdentificationStageSerializer
137
138        return IdentificationStageSerializer
139
140    @property
141    def view(self) -> type[View]:
142        from authentik.stages.identification.stage import IdentificationStageView
143
144        return IdentificationStageView
145
146    @property
147    def component(self) -> str:
148        return "ak-stage-identification-form"
149
150    class Meta:
151        verbose_name = _("Identification Stage")
152        verbose_name_plural = _("Identification Stages")

Identify the user for authentication.

def user_fields(unknown):

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

password_stage

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.

captcha_stage

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.

webauthn_stage

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 case_insensitive_matching(unknown):

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

def show_matched_user(unknown):

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

def pretend_user_exists(unknown):

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

def enable_remember_me(unknown):

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

enrollment_flow

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.

recovery_flow

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.

passwordless_flow

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.

sources

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.

def show_source_labels(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.BaseSerializer]
134    @property
135    def serializer(self) -> type[BaseSerializer]:
136        from authentik.stages.identification.api import IdentificationStageSerializer
137
138        return IdentificationStageSerializer

Get serializer for this model

view: type[django.views.generic.base.View]
140    @property
141    def view(self) -> type[View]:
142        from authentik.stages.identification.stage import IdentificationStageView
143
144        return IdentificationStageView

Return StageView class that implements logic for this stage

component: str
146    @property
147    def component(self) -> str:
148        return "ak-stage-identification-form"

Return component used to edit this object

password_stage_id
captcha_stage_id
webauthn_stage_id
enrollment_flow_id
recovery_flow_id
passwordless_flow_id
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 IdentificationStage.DoesNotExist(authentik.flows.models.Stage.DoesNotExist):

The requested object does not exist

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

The query returned multiple objects when only one was expected.