authentik.stages.authenticator_static.models
Static Authenticator models
1"""Static Authenticator models""" 2 3from base64 import b32encode 4from os import urandom 5 6from django.conf import settings 7from django.core.validators import MaxValueValidator 8from django.db import models 9from django.utils.translation import gettext_lazy as _ 10from django.views import View 11from rest_framework.serializers import BaseSerializer 12 13from authentik.core.types import UserSettingSerializer 14from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage 15from authentik.lib.models import SerializerModel 16from authentik.stages.authenticator.models import Device, ThrottlingMixin 17 18 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") 55 56 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 get_throttle_factor(self): 82 return getattr(settings, "OTP_STATIC_THROTTLE_FACTOR", 1) 83 84 def verify_token(self, token): 85 verify_allowed, _ = self.verify_is_allowed() 86 if verify_allowed: 87 match = self.token_set.filter(token=token).first() 88 if match is not None: 89 match.delete() 90 self.throttle_reset() 91 else: 92 self.throttle_increment() 93 else: 94 match = None 95 96 return match is not None 97 98 class Meta(Device.Meta): 99 verbose_name = _("Static Device") 100 verbose_name_plural = _("Static Devices") 101 102 103class StaticToken(models.Model): 104 """ 105 A single token belonging to a :class:`StaticDevice`. 106 107 .. attribute:: device 108 109 *ForeignKey*: A foreign key to :class:`StaticDevice`. 110 111 .. attribute:: token 112 113 *CharField*: A random string up to 100 characters. 114 """ 115 116 device = models.ForeignKey(StaticDevice, related_name="token_set", on_delete=models.CASCADE) 117 token = models.CharField(max_length=100, db_index=True) 118 119 class Meta: 120 verbose_name = _("Static Token") 121 verbose_name_plural = _("Static Tokens") 122 123 def __str__(self) -> str: 124 return "Static Token" 125 126 @staticmethod 127 def random_token(): 128 """ 129 Returns a new random string that can be used as a static token. 130 131 :rtype: bytes 132 133 """ 134 return b32encode(urandom(5)).decode("utf-8").lower()
20class AuthenticatorStaticStage(ConfigurableStage, FriendlyNamedStage, Stage): 21 """Setup static token based authentication for the user.""" 22 23 token_count = models.PositiveIntegerField(default=6) 24 token_length = models.PositiveIntegerField(default=12, validators=[MaxValueValidator(100)]) 25 26 @property 27 def serializer(self) -> type[BaseSerializer]: 28 from authentik.stages.authenticator_static.api import AuthenticatorStaticStageSerializer 29 30 return AuthenticatorStaticStageSerializer 31 32 @property 33 def view(self) -> type[View]: 34 from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView 35 36 return AuthenticatorStaticStageView 37 38 @property 39 def component(self) -> str: 40 return "ak-stage-authenticator-static-form" 41 42 def ui_user_settings(self) -> UserSettingSerializer | None: 43 return UserSettingSerializer( 44 data={ 45 "title": self.friendly_name or str(self._meta.verbose_name), 46 "component": "ak-user-settings-authenticator-static", 47 } 48 ) 49 50 def __str__(self) -> str: 51 return f"Static Authenticator Setup Stage {self.name}" 52 53 class Meta: 54 verbose_name = _("Static Authenticator Setup Stage") 55 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.
26 @property 27 def serializer(self) -> type[BaseSerializer]: 28 from authentik.stages.authenticator_static.api import AuthenticatorStaticStageSerializer 29 30 return AuthenticatorStaticStageSerializer
Get serializer for this model
32 @property 33 def view(self) -> type[View]: 34 from authentik.stages.authenticator_static.stage import AuthenticatorStaticStageView 35 36 return AuthenticatorStaticStageView
Return StageView class that implements logic for this stage
42 def ui_user_settings(self) -> UserSettingSerializer | None: 43 return UserSettingSerializer( 44 data={ 45 "title": self.friendly_name or str(self._meta.verbose_name), 46 "component": "ak-user-settings-authenticator-static", 47 } 48 )
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
- authenticatorendpointgdtcstage
- mutualtlsstage
- sourcestage
The requested object does not exist
The query returned multiple objects when only one was expected.
58class StaticDevice(SerializerModel, ThrottlingMixin, Device): 59 """ 60 A static :class:`~authentik.stages.authenticator.models.Device` simply consists of random 61 tokens shared by the database and the user. 62 63 These are frequently used as emergency tokens in case a user's normal 64 device is lost or unavailable. They can be consumed in any order; each 65 token will be removed from the database as soon as it is used. 66 67 This model has no fields of its own, but serves as a container for 68 :class:`StaticToken` objects. 69 70 .. attribute:: token_set 71 72 The RelatedManager for our tokens. 73 74 """ 75 76 @property 77 def serializer(self) -> type[BaseSerializer]: 78 from authentik.stages.authenticator_static.api import StaticDeviceSerializer 79 80 return StaticDeviceSerializer 81 82 def get_throttle_factor(self): 83 return getattr(settings, "OTP_STATIC_THROTTLE_FACTOR", 1) 84 85 def verify_token(self, token): 86 verify_allowed, _ = self.verify_is_allowed() 87 if verify_allowed: 88 match = self.token_set.filter(token=token).first() 89 if match is not None: 90 match.delete() 91 self.throttle_reset() 92 else: 93 self.throttle_increment() 94 else: 95 match = None 96 97 return match is not None 98 99 class Meta(Device.Meta): 100 verbose_name = _("Static Device") 101 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.
76 @property 77 def serializer(self) -> type[BaseSerializer]: 78 from authentik.stages.authenticator_static.api import StaticDeviceSerializer 79 80 return StaticDeviceSerializer
Get serializer for this model
This must be implemented to return the throttle factor.
The number of seconds required between verification attempts will be
:math:c2^{n-1} where c is this factor and n is the number of
previous failures. A factor of 1 translates to delays of 1, 2, 4, 8,
etc. seconds. A factor of 0 disables the throttling.
Normally this is just a wrapper for a plugin-specific setting like
:setting:OTP_EMAIL_THROTTLE_FACTOR.
85 def verify_token(self, token): 86 verify_allowed, _ = self.verify_is_allowed() 87 if verify_allowed: 88 match = self.token_set.filter(token=token).first() 89 if match is not None: 90 match.delete() 91 self.throttle_reset() 92 else: 93 self.throttle_increment() 94 else: 95 match = None 96 97 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.
104class StaticToken(models.Model): 105 """ 106 A single token belonging to a :class:`StaticDevice`. 107 108 .. attribute:: device 109 110 *ForeignKey*: A foreign key to :class:`StaticDevice`. 111 112 .. attribute:: token 113 114 *CharField*: A random string up to 100 characters. 115 """ 116 117 device = models.ForeignKey(StaticDevice, related_name="token_set", on_delete=models.CASCADE) 118 token = models.CharField(max_length=100, db_index=True) 119 120 class Meta: 121 verbose_name = _("Static Token") 122 verbose_name_plural = _("Static Tokens") 123 124 def __str__(self) -> str: 125 return "Static Token" 126 127 @staticmethod 128 def random_token(): 129 """ 130 Returns a new random string that can be used as a static token. 131 132 :rtype: bytes 133 134 """ 135 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.
127 @staticmethod 128 def random_token(): 129 """ 130 Returns a new random string that can be used as a static token. 131 132 :rtype: bytes 133 134 """ 135 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.