diff --git a/authentik/core/models.py b/authentik/core/models.py index 5b1e4076c7..413fa09c95 100644 --- a/authentik/core/models.py +++ b/authentik/core/models.py @@ -632,7 +632,7 @@ class UserSourceConnection(SerializerModel, CreatedUpdatedModel): raise NotImplementedError def __str__(self) -> str: - return f"User-source connection (user={self.user.username}, source={self.source.slug})" + return f"User-source connection (user={self.user_id}, source={self.source_id})" class Meta: unique_together = (("user", "source"),) diff --git a/authentik/enterprise/providers/rac/models.py b/authentik/enterprise/providers/rac/models.py index 5c6e835c61..c74790de3d 100644 --- a/authentik/enterprise/providers/rac/models.py +++ b/authentik/enterprise/providers/rac/models.py @@ -201,10 +201,7 @@ class ConnectionToken(ExpiringModel): return settings def __str__(self): - return ( - f"RAC Connection token {self.session.user} to " - f"{self.endpoint.provider.name}/{self.endpoint.name}" - ) + return f"RAC Connection token {self.session_id} to {self.provider_id}/{self.endpoint_id}" class Meta: verbose_name = _("RAC Connection token") diff --git a/authentik/events/models.py b/authentik/events/models.py index bea93dccd3..92d934c55b 100644 --- a/authentik/events/models.py +++ b/authentik/events/models.py @@ -556,7 +556,7 @@ class Notification(SerializerModel): if len(self.body) > NOTIFICATION_SUMMARY_LENGTH else self.body ) - return f"Notification for user {self.user}: {body_trunc}" + return f"Notification for user {self.user_id}: {body_trunc}" class Meta: verbose_name = _("Notification") diff --git a/authentik/events/tests/test_models.py b/authentik/events/tests/test_models.py new file mode 100644 index 0000000000..9be7b8b392 --- /dev/null +++ b/authentik/events/tests/test_models.py @@ -0,0 +1,35 @@ +"""authentik event models tests""" + +from collections.abc import Callable + +from django.db.models import Model +from django.test import TestCase + +from authentik.core.models import default_token_key +from authentik.lib.utils.reflection import get_apps + + +class TestModels(TestCase): + """Test Models""" + + +def model_tester_factory(test_model: type[Model]) -> Callable: + """Test models' __str__ and __repr__""" + + def tester(self: TestModels): + allowed = 0 + # Token-like objects need to lookup the current tenant to get the default token length + for field in test_model._meta.fields: + if field.default == default_token_key: + allowed += 1 + with self.assertNumQueries(allowed): + str(test_model()) + with self.assertNumQueries(allowed): + repr(test_model()) + + return tester + + +for app in get_apps(): + for model in app.get_models(): + setattr(TestModels, f"test_{app.label}_{model.__name__}", model_tester_factory(model)) diff --git a/authentik/providers/oauth2/models.py b/authentik/providers/oauth2/models.py index 3e7f00bcf7..d9029e1158 100644 --- a/authentik/providers/oauth2/models.py +++ b/authentik/providers/oauth2/models.py @@ -326,7 +326,7 @@ class AuthorizationCode(SerializerModel, ExpiringModel, BaseGrantModel): verbose_name_plural = _("Authorization Codes") def __str__(self): - return f"Authorization code for {self.provider} for user {self.user}" + return f"Authorization code for {self.provider_id} for user {self.user_id}" @property def serializer(self) -> Serializer: @@ -356,7 +356,7 @@ class AccessToken(SerializerModel, ExpiringModel, BaseGrantModel): verbose_name_plural = _("OAuth2 Access Tokens") def __str__(self): - return f"Access Token for {self.provider} for user {self.user}" + return f"Access Token for {self.provider_id} for user {self.user_id}" @property def id_token(self) -> IDToken: @@ -399,7 +399,7 @@ class RefreshToken(SerializerModel, ExpiringModel, BaseGrantModel): verbose_name_plural = _("OAuth2 Refresh Tokens") def __str__(self): - return f"Refresh Token for {self.provider} for user {self.user}" + return f"Refresh Token for {self.provider_id} for user {self.user_id}" @property def id_token(self) -> IDToken: @@ -443,4 +443,4 @@ class DeviceToken(ExpiringModel): verbose_name_plural = _("Device Tokens") def __str__(self): - return f"Device Token for {self.provider}" + return f"Device Token for {self.provider_id}" diff --git a/authentik/providers/scim/models.py b/authentik/providers/scim/models.py index e078eead4c..e85d796a79 100644 --- a/authentik/providers/scim/models.py +++ b/authentik/providers/scim/models.py @@ -105,7 +105,7 @@ class SCIMUser(models.Model): unique_together = (("id", "user", "provider"),) def __str__(self) -> str: - return f"SCIM User {self.user.username} to {self.provider.name}" + return f"SCIM User {self.user_id} to {self.provider_id}" class SCIMGroup(models.Model): @@ -119,4 +119,4 @@ class SCIMGroup(models.Model): unique_together = (("id", "group", "provider"),) def __str__(self) -> str: - return f"SCIM Group {self.group.name} to {self.provider.name}" + return f"SCIM Group {self.group_id} to {self.provider_id}" diff --git a/authentik/sources/scim/models.py b/authentik/sources/scim/models.py index 6669b46004..4684c4dfa8 100644 --- a/authentik/sources/scim/models.py +++ b/authentik/sources/scim/models.py @@ -60,7 +60,7 @@ class SCIMSourceUser(SerializerModel): unique_together = (("id", "user", "source"),) def __str__(self) -> str: - return f"SCIM User {self.user.username} to {self.source.name}" + return f"SCIM User {self.user_id} to {self.source_id}" class SCIMSourceGroup(SerializerModel): @@ -81,4 +81,4 @@ class SCIMSourceGroup(SerializerModel): unique_together = (("id", "group", "source"),) def __str__(self) -> str: - return f"SCIM Group {self.group.name} to {self.source.name}" + return f"SCIM Group {self.group_id} to {self.source_id}" diff --git a/authentik/stages/authenticator_duo/models.py b/authentik/stages/authenticator_duo/models.py index 37e2f6714c..f9726021d4 100644 --- a/authentik/stages/authenticator_duo/models.py +++ b/authentik/stages/authenticator_duo/models.py @@ -96,7 +96,7 @@ class DuoDevice(SerializerModel, Device): return DuoDeviceSerializer def __str__(self): - return str(self.name) or str(self.user) + return str(self.name) or str(self.user_id) class Meta: verbose_name = _("Duo Device") diff --git a/authentik/stages/authenticator_sms/models.py b/authentik/stages/authenticator_sms/models.py index 36b3dd5370..82ad6f61ee 100644 --- a/authentik/stages/authenticator_sms/models.py +++ b/authentik/stages/authenticator_sms/models.py @@ -221,7 +221,7 @@ class SMSDevice(SerializerModel, SideChannelDevice): return valid def __str__(self): - return str(self.name) or str(self.user) + return str(self.name) or str(self.user_id) class Meta: verbose_name = _("SMS Device") diff --git a/authentik/stages/authenticator_webauthn/models.py b/authentik/stages/authenticator_webauthn/models.py index 5a45b34316..fc0e7f6867 100644 --- a/authentik/stages/authenticator_webauthn/models.py +++ b/authentik/stages/authenticator_webauthn/models.py @@ -155,7 +155,7 @@ class WebAuthnDevice(SerializerModel, Device): return WebAuthnDeviceSerializer def __str__(self): - return str(self.name) or str(self.user) + return str(self.name) or str(self.user_id) class Meta: verbose_name = _("WebAuthn Device") diff --git a/authentik/stages/consent/models.py b/authentik/stages/consent/models.py index 385aaf8921..b180082e60 100644 --- a/authentik/stages/consent/models.py +++ b/authentik/stages/consent/models.py @@ -65,7 +65,7 @@ class UserConsent(SerializerModel, ExpiringModel): return UserConsentSerializer def __str__(self): - return f"User Consent {self.application} by {self.user}" + return f"User Consent {self.application_id} by {self.user_id}" class Meta: unique_together = (("user", "application", "permissions"),) diff --git a/authentik/stages/invitation/models.py b/authentik/stages/invitation/models.py index 831effcedc..b1ead478f5 100644 --- a/authentik/stages/invitation/models.py +++ b/authentik/stages/invitation/models.py @@ -79,7 +79,7 @@ class Invitation(SerializerModel, ExpiringModel): return InvitationSerializer def __str__(self): - return f"Invitation {str(self.invite_uuid)} created by {self.created_by}" + return f"Invitation {str(self.invite_uuid)} created by {self.created_by_id}" class Meta: verbose_name = _("Invitation")