events: ensure all models' __str__ can be called without any further lookups (#9480)
* events: ensure all models' __str__ can be called without any further lookups Signed-off-by: Jens Langhammer <jens@goauthentik.io> * allow for additional queries for models using default_token_key Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
		@ -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"),)
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										35
									
								
								authentik/events/tests/test_models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								authentik/events/tests/test_models.py
									
									
									
									
									
										Normal file
									
								
							@ -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))
 | 
			
		||||
@ -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}"
 | 
			
		||||
 | 
			
		||||
@ -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}"
 | 
			
		||||
 | 
			
		||||
@ -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}"
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -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"),)
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user