authentik.stages.authenticator_static.models
Static Authenticator models
1"""Static Authenticator models""" 2 3from base64 import b32encode 4from os import urandom 5 6from django.core.validators import MaxValueValidator 7from django.db import models 8from django.utils.translation import gettext_lazy as _ 9from django.views import View 10from rest_framework.serializers import BaseSerializer 11 12from authentik.core.types import UserSettingSerializer 13from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage 14from authentik.lib.models import SerializerModel 15from authentik.stages.authenticator.models import Device, ThrottlingMixin 16 17 18class AuthenticatorStaticStage(ConfigurableStage, FriendlyNamedStage, Stage): 19 """Setup static token based authentication for the user.""" 20 21 token_count = models.PositiveIntegerField(default=6) 22 token_length = models.PositiveIntegerField(default=12, validators=[MaxValueValidator(100)]) 23 24 @property 25 def serializer(self) -> type[BaseSerializer]: 26 from authentik.stages.authenticator_static.api import AuthenticatorStaticStageSerializer 27 28 return AuthenticatorStaticStageSerializer 29 30 @property 31 def view(self) -> type[View]: 32 from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView 33 34 return AuthenticatorStaticStageView 35 36 @property 37 def component(self) -> str: 38 return "ak-stage-authenticator-static-form" 39 40 def ui_user_settings(self) -> UserSettingSerializer | None: 41 return UserSettingSerializer( 42 data={ 43 "title": self.friendly_name or str(self._meta.verbose_name), 44 "component": "ak-user-settings-authenticator-static", 45 } 46 ) 47 48 def __str__(self) -> str: 49 return f"Static Authenticator Setup Stage {self.name}" 50 51 class Meta: 52 verbose_name = _("Static Authenticator Setup Stage") 53 verbose_name_plural = _("Static Authenticator Setup Stages") 54 55 56class StaticDevice(SerializerModel, ThrottlingMixin, Device): 57 """ 58 A static :class:`~authentik.stages.authenticator.models.Device` simply consists of random 59 tokens shared by the database and the user. 60 61 These are frequently used as emergency tokens in case a user's normal 62 device is lost or unavailable. They can be consumed in any order; each 63 token will be removed from the database as soon as it is used. 64 65 This model has no fields of its own, but serves as a container for 66 :class:`StaticToken` objects. 67 68 .. attribute:: token_set 69 70 The RelatedManager for our tokens. 71 72 """ 73 74 @property 75 def serializer(self) -> type[BaseSerializer]: 76 from authentik.stages.authenticator_static.api import StaticDeviceSerializer 77 78 return StaticDeviceSerializer 79 80 def verify_token(self, token): 81 verify_allowed, _ = self.verify_is_allowed() 82 if verify_allowed: 83 match = self.token_set.filter(token=token).first() 84 if match is not None: 85 match.delete() 86 self.throttle_reset() 87 else: 88 self.throttle_increment() 89 else: 90 match = None 91 92 return match is not None 93 94 class Meta(Device.Meta): 95 verbose_name = _("Static Device") 96 verbose_name_plural = _("Static Devices") 97 98 99class StaticToken(models.Model): 100 """ 101 A single token belonging to a :class:`StaticDevice`. 102 103 .. attribute:: device 104 105 *ForeignKey*: A foreign key to :class:`StaticDevice`. 106 107 .. attribute:: token 108 109 *CharField*: A random string up to 100 characters. 110 """ 111 112 device = models.ForeignKey(StaticDevice, related_name="token_set", on_delete=models.CASCADE) 113 token = models.CharField(max_length=100, db_index=True) 114 115 class Meta: 116 verbose_name = _("Static Token") 117 verbose_name_plural = _("Static Tokens") 118 119 def __str__(self) -> str: 120 return "Static Token" 121 122 @staticmethod 123 def random_token(): 124 """ 125 Returns a new random string that can be used as a static token. 126 127 :rtype: bytes 128 129 """ 130 return b32encode(urandom(5)).decode("utf-8").lower()
19class AuthenticatorStaticStage(ConfigurableStage, FriendlyNamedStage, Stage): 20 """Setup static token based authentication for the user.""" 21 22 token_count = models.PositiveIntegerField(default=6) 23 token_length = models.PositiveIntegerField(default=12, validators=[MaxValueValidator(100)]) 24 25 @property 26 def serializer(self) -> type[BaseSerializer]: 27 from authentik.stages.authenticator_static.api import AuthenticatorStaticStageSerializer 28 29 return AuthenticatorStaticStageSerializer 30 31 @property 32 def view(self) -> type[View]: 33 from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView 34 35 return AuthenticatorStaticStageView 36 37 @property 38 def component(self) -> str: 39 return "ak-stage-authenticator-static-form" 40 41 def ui_user_settings(self) -> UserSettingSerializer | None: 42 return UserSettingSerializer( 43 data={ 44 "title": self.friendly_name or str(self._meta.verbose_name), 45 "component": "ak-user-settings-authenticator-static", 46 } 47 ) 48 49 def __str__(self) -> str: 50 return f"Static Authenticator Setup Stage {self.name}" 51 52 class Meta: 53 verbose_name = _("Static Authenticator Setup Stage") 54 verbose_name_plural = _("Static Authenticator Setup Stages")
Setup static token based authentication for the user.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
25 @property 26 def serializer(self) -> type[BaseSerializer]: 27 from authentik.stages.authenticator_static.api import AuthenticatorStaticStageSerializer 28 29 return AuthenticatorStaticStageSerializer
Get serializer for this model
31 @property 32 def view(self) -> type[View]: 33 from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView 34 35 return AuthenticatorStaticStageView
Return StageView class that implements logic for this stage
41 def ui_user_settings(self) -> UserSettingSerializer | None: 42 return UserSettingSerializer( 43 data={ 44 "title": self.friendly_name or str(self._meta.verbose_name), 45 "component": "ak-user-settings-authenticator-static", 46 } 47 )
Entrypoint to integrate with User settings. Can either return None if no user settings are available, or a challenge.
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.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
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.
Inherited Members
- authentik.flows.models.Stage
- stage_uuid
- name
- objects
- is_in_memory
- flow_set
- flowstagebinding_set
- emailstage
- endpointstage
- invitationstage
- passwordstage
- promptstage
- authenticatorstaticstage
- authenticatorduostage
- authenticatoremailstage
- authenticatorsmsstage
- authenticatorwebauthnstage
- authenticatorvalidatestage
- captchastage
- identificationstage
- authenticatortotpstage
- consentstage
- denystage
- dummystage
- redirectstage
- userdeletestage
- userloginstage
- userlogoutstage
- userwritestage
- accountlockdownstage
- authenticatorendpointgdtcstage
- mutualtlsstage
- sourcestage
The requested object does not exist
The query returned multiple objects when only one was expected.
57class StaticDevice(SerializerModel, ThrottlingMixin, Device): 58 """ 59 A static :class:`~authentik.stages.authenticator.models.Device` simply consists of random 60 tokens shared by the database and the user. 61 62 These are frequently used as emergency tokens in case a user's normal 63 device is lost or unavailable. They can be consumed in any order; each 64 token will be removed from the database as soon as it is used. 65 66 This model has no fields of its own, but serves as a container for 67 :class:`StaticToken` objects. 68 69 .. attribute:: token_set 70 71 The RelatedManager for our tokens. 72 73 """ 74 75 @property 76 def serializer(self) -> type[BaseSerializer]: 77 from authentik.stages.authenticator_static.api import StaticDeviceSerializer 78 79 return StaticDeviceSerializer 80 81 def verify_token(self, token): 82 verify_allowed, _ = self.verify_is_allowed() 83 if verify_allowed: 84 match = self.token_set.filter(token=token).first() 85 if match is not None: 86 match.delete() 87 self.throttle_reset() 88 else: 89 self.throttle_increment() 90 else: 91 match = None 92 93 return match is not None 94 95 class Meta(Device.Meta): 96 verbose_name = _("Static Device") 97 verbose_name_plural = _("Static Devices")
A static :class:~authentik.stages.authenticator.models.Device simply consists of random
tokens shared by the database and the user.
These are frequently used as emergency tokens in case a user's normal device is lost or unavailable. They can be consumed in any order; each token will be removed from the database as soon as it is used.
This model has no fields of its own, but serves as a container for
:class:StaticToken objects.
.. attribute:: token_set
The RelatedManager for our tokens.
75 @property 76 def serializer(self) -> type[BaseSerializer]: 77 from authentik.stages.authenticator_static.api import StaticDeviceSerializer 78 79 return StaticDeviceSerializer
Get serializer for this model
81 def verify_token(self, token): 82 verify_allowed, _ = self.verify_is_allowed() 83 if verify_allowed: 84 match = self.token_set.filter(token=token).first() 85 if match is not None: 86 match.delete() 87 self.throttle_reset() 88 else: 89 self.throttle_increment() 90 else: 91 match = None 92 93 return match is not None
Verifies a token. As a rule, the token should no longer be valid if
this returns True.
:param str token: The OTP token provided by the user. :rtype: bool
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
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.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
Method descriptor with partial application of the given arguments and keywords.
Supports wrapping existing descriptors and handles non-descriptor callables as instance methods.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
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.
Inherited Members
The requested object does not exist
The query returned multiple objects when only one was expected.
100class StaticToken(models.Model): 101 """ 102 A single token belonging to a :class:`StaticDevice`. 103 104 .. attribute:: device 105 106 *ForeignKey*: A foreign key to :class:`StaticDevice`. 107 108 .. attribute:: token 109 110 *CharField*: A random string up to 100 characters. 111 """ 112 113 device = models.ForeignKey(StaticDevice, related_name="token_set", on_delete=models.CASCADE) 114 token = models.CharField(max_length=100, db_index=True) 115 116 class Meta: 117 verbose_name = _("Static Token") 118 verbose_name_plural = _("Static Tokens") 119 120 def __str__(self) -> str: 121 return "Static Token" 122 123 @staticmethod 124 def random_token(): 125 """ 126 Returns a new random string that can be used as a static token. 127 128 :rtype: bytes 129 130 """ 131 return b32encode(urandom(5)).decode("utf-8").lower()
A single token belonging to a :class:StaticDevice.
.. attribute:: device
*ForeignKey*: A foreign key to :class:`StaticDevice`.
.. attribute:: token
*CharField*: A random string up to 100 characters.
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.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
123 @staticmethod 124 def random_token(): 125 """ 126 Returns a new random string that can be used as a static token. 127 128 :rtype: bytes 129 130 """ 131 return b32encode(urandom(5)).decode("utf-8").lower()
Returns a new random string that can be used as a static token.
:rtype: bytes
The requested object does not exist
The query returned multiple objects when only one was expected.