authentik.stages.authenticator_webauthn.models
WebAuthn stage
1"""WebAuthn stage""" 2 3from cryptography.x509 import Certificate, load_pem_x509_certificate 4from django.contrib.auth import get_user_model 5from django.contrib.postgres.fields.array import ArrayField 6from django.db import models 7from django.utils.timezone import now 8from django.utils.translation import gettext_lazy as _ 9from django.views import View 10from rest_framework.serializers import BaseSerializer, Serializer 11from webauthn.helpers.base64url_to_bytes import base64url_to_bytes 12from webauthn.helpers.structs import PublicKeyCredentialDescriptor 13 14from authentik.core.types import UserSettingSerializer 15from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage 16from authentik.lib.models import InternallyManagedMixin, SerializerModel 17from authentik.stages.authenticator.models import Device 18 19UNKNOWN_DEVICE_TYPE_AAGUID = "00000000-0000-0000-0000-000000000000" 20 21 22class UserVerification(models.TextChoices): 23 """The degree to which the Relying Party wishes to verify a user's identity. 24 25 Members: 26 `REQUIRED`: User verification must occur 27 `PREFERRED`: User verification would be great, but if not that's okay too 28 `DISCOURAGED`: User verification should not occur, but it's okay if it does 29 30 https://www.w3.org/TR/webauthn-2/#enumdef-userverificationrequirement 31 """ 32 33 REQUIRED = "required" 34 PREFERRED = "preferred" 35 DISCOURAGED = "discouraged" 36 37 38class ResidentKeyRequirement(models.TextChoices): 39 """The Relying Party's preference for the authenticator to create a dedicated "client-side" 40 credential for it. Requiring an authenticator to store a dedicated credential should not be 41 done lightly due to the limited storage capacity of some types of authenticators. 42 43 Members: 44 `DISCOURAGED`: The authenticator should not create a dedicated credential 45 `PREFERRED`: The authenticator can create and store a dedicated credential, but if it 46 doesn't that's alright too 47 `REQUIRED`: The authenticator MUST create a dedicated credential. If it cannot, the RP 48 is prepared for an error to occur. 49 50 https://www.w3.org/TR/webauthn-2/#enum-residentKeyRequirement 51 """ 52 53 DISCOURAGED = "discouraged" 54 PREFERRED = "preferred" 55 REQUIRED = "required" 56 57 58class AuthenticatorAttachment(models.TextChoices): 59 """How an authenticator is connected to the client/browser. 60 61 Members: 62 `PLATFORM`: A non-removable authenticator, like TouchID or Windows Hello 63 `CROSS_PLATFORM`: A "roaming" authenticator, like a YubiKey 64 65 https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment 66 """ 67 68 PLATFORM = "platform" 69 CROSS_PLATFORM = "cross-platform" 70 71 72class WebAuthnHint(models.TextChoices): 73 """Hints to guide the browser in prioritizing the preferred authenticator during 74 WebAuthn registration and authentication. Unlike authenticatorAttachment, hints are 75 advisory and browsers may ignore them. 76 77 Members: 78 `SECURITY_KEY`: A portable FIDO2 authenticator, like a YubiKey 79 `CLIENT_DEVICE`: The device WebAuthn is being called on, like TouchID or Windows Hello 80 `HYBRID`: A platform authenticator on a mobile device, accessed via QR code 81 82 https://w3c.github.io/webauthn/#enumdef-publickeycredentialhint 83 """ 84 85 SECURITY_KEY = "security-key" 86 CLIENT_DEVICE = "client-device" 87 HYBRID = "hybrid" 88 89 90class AuthenticatorWebAuthnStage(ConfigurableStage, FriendlyNamedStage, Stage): 91 """Setup WebAuthn-based authentication for the user.""" 92 93 user_verification = models.TextField( 94 choices=UserVerification.choices, 95 default=UserVerification.PREFERRED, 96 ) 97 resident_key_requirement = models.TextField( 98 choices=ResidentKeyRequirement.choices, 99 default=ResidentKeyRequirement.PREFERRED, 100 ) 101 authenticator_attachment = models.TextField( # noqa: DJ001 102 choices=AuthenticatorAttachment.choices, default=None, null=True 103 ) 104 105 prevent_duplicate_devices = models.BooleanField( 106 default=True, help_text=_("When enabled, a given device can only be registered once.") 107 ) 108 hints = ArrayField( 109 models.TextField(choices=WebAuthnHint.choices), 110 default=list, 111 blank=True, 112 ) 113 114 device_type_restrictions = models.ManyToManyField("WebAuthnDeviceType", blank=True) 115 116 max_attempts = models.PositiveIntegerField(default=0) 117 118 @property 119 def serializer(self) -> type[BaseSerializer]: 120 from authentik.stages.authenticator_webauthn.api.stages import ( 121 AuthenticatorWebAuthnStageSerializer, 122 ) 123 124 return AuthenticatorWebAuthnStageSerializer 125 126 @property 127 def view(self) -> type[View]: 128 from authentik.stages.authenticator_webauthn.stage import AuthenticatorWebAuthnStageView 129 130 return AuthenticatorWebAuthnStageView 131 132 @property 133 def component(self) -> str: 134 return "ak-stage-authenticator-webauthn-form" 135 136 def ui_user_settings(self) -> UserSettingSerializer | None: 137 return UserSettingSerializer( 138 data={ 139 "title": self.friendly_name or str(self._meta.verbose_name), 140 "component": "ak-user-settings-authenticator-webauthn", 141 } 142 ) 143 144 def __str__(self) -> str: 145 return f"WebAuthn Authenticator Setup Stage {self.name}" 146 147 class Meta: 148 verbose_name = _("WebAuthn Authenticator Setup Stage") 149 verbose_name_plural = _("WebAuthn Authenticator Setup Stages") 150 151 152class WebAuthnDevice(SerializerModel, Device): 153 """WebAuthn Device for a single user""" 154 155 user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 156 157 name = models.TextField(max_length=200) 158 credential_id = models.TextField(unique=True) 159 public_key = models.TextField() 160 sign_count = models.IntegerField(default=0) 161 rp_id = models.CharField(max_length=253) 162 163 created_on = models.DateTimeField(auto_now_add=True) 164 last_t = models.DateTimeField(default=now) 165 166 attestation_certificate_pem = models.TextField(null=True, default=None) 167 attestation_certificate_fingerprint = models.TextField(null=True, default=None) 168 aaguid = models.TextField(default=UNKNOWN_DEVICE_TYPE_AAGUID) 169 device_type = models.ForeignKey( 170 "WebAuthnDeviceType", on_delete=models.SET_DEFAULT, null=True, default=None 171 ) 172 173 @property 174 def descriptor(self) -> PublicKeyCredentialDescriptor: 175 """Get a publickeydescriptor for this device""" 176 return PublicKeyCredentialDescriptor(id=base64url_to_bytes(self.credential_id)) 177 178 @property 179 def attestation_certificate(self) -> Certificate | None: 180 if not self.attestation_certificate_pem: 181 return None 182 return load_pem_x509_certificate(self.attestation_certificate_pem.encode()) 183 184 def set_sign_count(self, sign_count: int) -> None: 185 """Set the sign_count and update the last_t datetime.""" 186 self.sign_count = sign_count 187 self.last_t = now() 188 self.save() 189 190 @property 191 def serializer(self) -> Serializer: 192 from authentik.stages.authenticator_webauthn.api.devices import WebAuthnDeviceSerializer 193 194 return WebAuthnDeviceSerializer 195 196 def __str__(self): 197 return str(self.name) or str(self.user_id) 198 199 class Meta: 200 verbose_name = _("WebAuthn Device") 201 verbose_name_plural = _("WebAuthn Devices") 202 203 204class WebAuthnDeviceType(InternallyManagedMixin, SerializerModel): 205 """WebAuthn device type, used to restrict which device types are allowed""" 206 207 aaguid = models.UUIDField(primary_key=True, unique=True) 208 209 description = models.TextField() 210 icon = models.TextField(null=True) 211 212 @property 213 def serializer(self) -> Serializer: 214 from authentik.stages.authenticator_webauthn.api.device_types import ( 215 WebAuthnDeviceTypeSerializer, 216 ) 217 218 return WebAuthnDeviceTypeSerializer 219 220 class Meta: 221 verbose_name = _("WebAuthn Device type") 222 verbose_name_plural = _("WebAuthn Device types") 223 224 def __str__(self) -> str: 225 return f"WebAuthn device type {self.description} ({self.aaguid})"
23class UserVerification(models.TextChoices): 24 """The degree to which the Relying Party wishes to verify a user's identity. 25 26 Members: 27 `REQUIRED`: User verification must occur 28 `PREFERRED`: User verification would be great, but if not that's okay too 29 `DISCOURAGED`: User verification should not occur, but it's okay if it does 30 31 https://www.w3.org/TR/webauthn-2/#enumdef-userverificationrequirement 32 """ 33 34 REQUIRED = "required" 35 PREFERRED = "preferred" 36 DISCOURAGED = "discouraged"
The degree to which the Relying Party wishes to verify a user's identity.
Members:
REQUIRED: User verification must occur
PREFERRED: User verification would be great, but if not that's okay too
DISCOURAGED: User verification should not occur, but it's okay if it does
https://www.w3.org/TR/webauthn-2/#enumdef-userverificationrequirement
39class ResidentKeyRequirement(models.TextChoices): 40 """The Relying Party's preference for the authenticator to create a dedicated "client-side" 41 credential for it. Requiring an authenticator to store a dedicated credential should not be 42 done lightly due to the limited storage capacity of some types of authenticators. 43 44 Members: 45 `DISCOURAGED`: The authenticator should not create a dedicated credential 46 `PREFERRED`: The authenticator can create and store a dedicated credential, but if it 47 doesn't that's alright too 48 `REQUIRED`: The authenticator MUST create a dedicated credential. If it cannot, the RP 49 is prepared for an error to occur. 50 51 https://www.w3.org/TR/webauthn-2/#enum-residentKeyRequirement 52 """ 53 54 DISCOURAGED = "discouraged" 55 PREFERRED = "preferred" 56 REQUIRED = "required"
The Relying Party's preference for the authenticator to create a dedicated "client-side" credential for it. Requiring an authenticator to store a dedicated credential should not be done lightly due to the limited storage capacity of some types of authenticators.
Members:
DISCOURAGED: The authenticator should not create a dedicated credential
PREFERRED: The authenticator can create and store a dedicated credential, but if it
doesn't that's alright too
REQUIRED: The authenticator MUST create a dedicated credential. If it cannot, the RP
is prepared for an error to occur.
https://www.w3.org/TR/webauthn-2/#enum-residentKeyRequirement
59class AuthenticatorAttachment(models.TextChoices): 60 """How an authenticator is connected to the client/browser. 61 62 Members: 63 `PLATFORM`: A non-removable authenticator, like TouchID or Windows Hello 64 `CROSS_PLATFORM`: A "roaming" authenticator, like a YubiKey 65 66 https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment 67 """ 68 69 PLATFORM = "platform" 70 CROSS_PLATFORM = "cross-platform"
How an authenticator is connected to the client/browser.
Members:
PLATFORM: A non-removable authenticator, like TouchID or Windows Hello
CROSS_PLATFORM: A "roaming" authenticator, like a YubiKey
https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment
73class WebAuthnHint(models.TextChoices): 74 """Hints to guide the browser in prioritizing the preferred authenticator during 75 WebAuthn registration and authentication. Unlike authenticatorAttachment, hints are 76 advisory and browsers may ignore them. 77 78 Members: 79 `SECURITY_KEY`: A portable FIDO2 authenticator, like a YubiKey 80 `CLIENT_DEVICE`: The device WebAuthn is being called on, like TouchID or Windows Hello 81 `HYBRID`: A platform authenticator on a mobile device, accessed via QR code 82 83 https://w3c.github.io/webauthn/#enumdef-publickeycredentialhint 84 """ 85 86 SECURITY_KEY = "security-key" 87 CLIENT_DEVICE = "client-device" 88 HYBRID = "hybrid"
Hints to guide the browser in prioritizing the preferred authenticator during WebAuthn registration and authentication. Unlike authenticatorAttachment, hints are advisory and browsers may ignore them.
Members:
SECURITY_KEY: A portable FIDO2 authenticator, like a YubiKey
CLIENT_DEVICE: The device WebAuthn is being called on, like TouchID or Windows Hello
HYBRID: A platform authenticator on a mobile device, accessed via QR code
https://w3c.github.io/webauthn/#enumdef-publickeycredentialhint
91class AuthenticatorWebAuthnStage(ConfigurableStage, FriendlyNamedStage, Stage): 92 """Setup WebAuthn-based authentication for the user.""" 93 94 user_verification = models.TextField( 95 choices=UserVerification.choices, 96 default=UserVerification.PREFERRED, 97 ) 98 resident_key_requirement = models.TextField( 99 choices=ResidentKeyRequirement.choices, 100 default=ResidentKeyRequirement.PREFERRED, 101 ) 102 authenticator_attachment = models.TextField( # noqa: DJ001 103 choices=AuthenticatorAttachment.choices, default=None, null=True 104 ) 105 106 prevent_duplicate_devices = models.BooleanField( 107 default=True, help_text=_("When enabled, a given device can only be registered once.") 108 ) 109 hints = ArrayField( 110 models.TextField(choices=WebAuthnHint.choices), 111 default=list, 112 blank=True, 113 ) 114 115 device_type_restrictions = models.ManyToManyField("WebAuthnDeviceType", blank=True) 116 117 max_attempts = models.PositiveIntegerField(default=0) 118 119 @property 120 def serializer(self) -> type[BaseSerializer]: 121 from authentik.stages.authenticator_webauthn.api.stages import ( 122 AuthenticatorWebAuthnStageSerializer, 123 ) 124 125 return AuthenticatorWebAuthnStageSerializer 126 127 @property 128 def view(self) -> type[View]: 129 from authentik.stages.authenticator_webauthn.stage import AuthenticatorWebAuthnStageView 130 131 return AuthenticatorWebAuthnStageView 132 133 @property 134 def component(self) -> str: 135 return "ak-stage-authenticator-webauthn-form" 136 137 def ui_user_settings(self) -> UserSettingSerializer | None: 138 return UserSettingSerializer( 139 data={ 140 "title": self.friendly_name or str(self._meta.verbose_name), 141 "component": "ak-user-settings-authenticator-webauthn", 142 } 143 ) 144 145 def __str__(self) -> str: 146 return f"WebAuthn Authenticator Setup Stage {self.name}" 147 148 class Meta: 149 verbose_name = _("WebAuthn Authenticator Setup Stage") 150 verbose_name_plural = _("WebAuthn Authenticator Setup Stages")
Setup WebAuthn-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.
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.
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.
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
119 @property 120 def serializer(self) -> type[BaseSerializer]: 121 from authentik.stages.authenticator_webauthn.api.stages import ( 122 AuthenticatorWebAuthnStageSerializer, 123 ) 124 125 return AuthenticatorWebAuthnStageSerializer
Get serializer for this model
127 @property 128 def view(self) -> type[View]: 129 from authentik.stages.authenticator_webauthn.stage import AuthenticatorWebAuthnStageView 130 131 return AuthenticatorWebAuthnStageView
Return StageView class that implements logic for this stage
137 def ui_user_settings(self) -> UserSettingSerializer | None: 138 return UserSettingSerializer( 139 data={ 140 "title": self.friendly_name or str(self._meta.verbose_name), 141 "component": "ak-user-settings-authenticator-webauthn", 142 } 143 )
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.
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.
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.
153class WebAuthnDevice(SerializerModel, Device): 154 """WebAuthn Device for a single user""" 155 156 user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 157 158 name = models.TextField(max_length=200) 159 credential_id = models.TextField(unique=True) 160 public_key = models.TextField() 161 sign_count = models.IntegerField(default=0) 162 rp_id = models.CharField(max_length=253) 163 164 created_on = models.DateTimeField(auto_now_add=True) 165 last_t = models.DateTimeField(default=now) 166 167 attestation_certificate_pem = models.TextField(null=True, default=None) 168 attestation_certificate_fingerprint = models.TextField(null=True, default=None) 169 aaguid = models.TextField(default=UNKNOWN_DEVICE_TYPE_AAGUID) 170 device_type = models.ForeignKey( 171 "WebAuthnDeviceType", on_delete=models.SET_DEFAULT, null=True, default=None 172 ) 173 174 @property 175 def descriptor(self) -> PublicKeyCredentialDescriptor: 176 """Get a publickeydescriptor for this device""" 177 return PublicKeyCredentialDescriptor(id=base64url_to_bytes(self.credential_id)) 178 179 @property 180 def attestation_certificate(self) -> Certificate | None: 181 if not self.attestation_certificate_pem: 182 return None 183 return load_pem_x509_certificate(self.attestation_certificate_pem.encode()) 184 185 def set_sign_count(self, sign_count: int) -> None: 186 """Set the sign_count and update the last_t datetime.""" 187 self.sign_count = sign_count 188 self.last_t = now() 189 self.save() 190 191 @property 192 def serializer(self) -> Serializer: 193 from authentik.stages.authenticator_webauthn.api.devices import WebAuthnDeviceSerializer 194 195 return WebAuthnDeviceSerializer 196 197 def __str__(self): 198 return str(self.name) or str(self.user_id) 199 200 class Meta: 201 verbose_name = _("WebAuthn Device") 202 verbose_name_plural = _("WebAuthn Devices")
WebAuthn Device for a single user
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.
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.
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.
174 @property 175 def descriptor(self) -> PublicKeyCredentialDescriptor: 176 """Get a publickeydescriptor for this device""" 177 return PublicKeyCredentialDescriptor(id=base64url_to_bytes(self.credential_id))
Get a publickeydescriptor for this device
185 def set_sign_count(self, sign_count: int) -> None: 186 """Set the sign_count and update the last_t datetime.""" 187 self.sign_count = sign_count 188 self.last_t = now() 189 self.save()
Set the sign_count and update the last_t datetime.
191 @property 192 def serializer(self) -> Serializer: 193 from authentik.stages.authenticator_webauthn.api.devices import WebAuthnDeviceSerializer 194 195 return WebAuthnDeviceSerializer
Get serializer for this model
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.
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.
The requested object does not exist
The query returned multiple objects when only one was expected.
205class WebAuthnDeviceType(InternallyManagedMixin, SerializerModel): 206 """WebAuthn device type, used to restrict which device types are allowed""" 207 208 aaguid = models.UUIDField(primary_key=True, unique=True) 209 210 description = models.TextField() 211 icon = models.TextField(null=True) 212 213 @property 214 def serializer(self) -> Serializer: 215 from authentik.stages.authenticator_webauthn.api.device_types import ( 216 WebAuthnDeviceTypeSerializer, 217 ) 218 219 return WebAuthnDeviceTypeSerializer 220 221 class Meta: 222 verbose_name = _("WebAuthn Device type") 223 verbose_name_plural = _("WebAuthn Device types") 224 225 def __str__(self) -> str: 226 return f"WebAuthn device type {self.description} ({self.aaguid})"
WebAuthn device type, used to restrict which device types are allowed
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.
213 @property 214 def serializer(self) -> Serializer: 215 from authentik.stages.authenticator_webauthn.api.device_types import ( 216 WebAuthnDeviceTypeSerializer, 217 ) 218 219 return WebAuthnDeviceTypeSerializer
Get serializer for this model
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.
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.
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.
Inherited Members
The requested object does not exist
The query returned multiple objects when only one was expected.