From 48dc656d45c543ca4ee074c2765ed3d36a09cdb7 Mon Sep 17 00:00:00 2001
From: Lucas Brandstaetter <lucas@brandstaetter.tech>
Date: Wed, 13 Nov 2024 02:02:02 +0100
Subject: [PATCH] Update conference member retrieval

- Use the new `get_member` method on `ConferenceMember` to retrieve the
  member in the `ConferenceSlugMixin` and `ConferenceRequiredMixin`
  mixins.
---
 src/api/views/mixins.py        |  6 ++----
 src/backoffice/views/mixins.py | 17 +++++------------
 src/core/models/conference.py  | 19 ++++++++++++++++---
 src/core/models/users.py       |  2 +-
 4 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/src/api/views/mixins.py b/src/api/views/mixins.py
index 8cc93edfc..46c930245 100644
--- a/src/api/views/mixins.py
+++ b/src/api/views/mixins.py
@@ -39,10 +39,8 @@ class ConferenceSlugMixin(PermissionRequiredMixin):
     @property
     def conferencemember(self):
         if self._conferencemember is None:
-            try:
-                self._conferencemember = ConferenceMember.objects.get(conference=self.conference, user=self.request.user)
-            except ConferenceMember.DoesNotExist:
-                return None
+            self._conferencemember = ConferenceMember.get_member(conference=self.conference, user=self.request.user)
+            return self._conferencemember if self._conferencemember.is_authenticated else None
         return self._conferencemember
 
 
diff --git a/src/backoffice/views/mixins.py b/src/backoffice/views/mixins.py
index 0b5e6867b..c1acd6327 100644
--- a/src/backoffice/views/mixins.py
+++ b/src/backoffice/views/mixins.py
@@ -52,18 +52,11 @@ class ConferenceRequiredMixin(PermissionRequiredMixin):
     @property
     def conferencemember(self):
         if self._conferencemember is None:
-            if not self.request.user.is_authenticated:
-                return ConferenceMember.get_anonymous_member(self.conference)
-
-            try:
-                self._conferencemember = (
-                    ConferenceMember.objects.select_related('user')
-                    .prefetch_related('user__groups', 'user__user_permissions', 'permission_groups')
-                    .get(conference=self.conference, user=self.request.user)
-                )
-            except ConferenceMember.DoesNotExist:
-                self._conferencemember = ConferenceMember.get_anonymous_member(self.conference)
-
+            self._conferencemember = ConferenceMember.get_member(
+                conference=self.conference,
+                user=self.request.user,
+                prefetch_user=True,
+            )
         return self._conferencemember
 
     @property
diff --git a/src/core/models/conference.py b/src/core/models/conference.py
index 51b231760..8aa080ee9 100644
--- a/src/core/models/conference.py
+++ b/src/core/models/conference.py
@@ -114,8 +114,19 @@ class ConferenceMember(models.Model):
         all_permissions = self.user.get_all_permissions() | self.get_permission_groups_permissions()
         return all_permissions
 
+    @property
+    def is_authenticated(self):
+        return self.user.is_authenticated
+
     @classmethod
-    def get_member(cls, conference: 'Conference', *, user: PlatformUser | None = None, member: 'ConferenceMember | None' = None) -> 'ConferenceMember':
+    def get_member(
+        cls,
+        conference: 'Conference',
+        *,
+        user: PlatformUser | None = None,
+        member: 'ConferenceMember | None' = None,
+        prefetch_user: bool = False,
+    ) -> 'ConferenceMember':
         if member is None and user is None:
             raise ValueError('Either user or member must be given.')
         if member and user and member.user != user:
@@ -127,7 +138,10 @@ class ConferenceMember(models.Model):
         if not user.is_authenticated:
             return cls.get_anonymous_member(conference, user)
         try:
-            return cls.objects.get(conference=conference, user=user)
+            qs = cls.objects.all()
+            if prefetch_user:
+                qs = qs.select_related('user').prefetch_related('user__groups', 'user__user_permissions', 'permission_groups')
+            return qs.get(conference=conference, user=user)
         except cls.DoesNotExist:
             return cls.get_anonymous_member(conference, user)
 
@@ -146,7 +160,6 @@ class ConferenceMember(models.Model):
             def has_perms(self, *perms: str, require_all: bool = True, require_staff: bool = False) -> bool:
                 return False
 
-            is_authenticated = False
             conference = conf
 
             def save(self, *args, **kwargs):
diff --git a/src/core/models/users.py b/src/core/models/users.py
index 169a80bbc..495500edd 100644
--- a/src/core/models/users.py
+++ b/src/core/models/users.py
@@ -230,7 +230,7 @@ class PlatformUser(AbstractUser):
             is_authenticated = False
 
             def save(self, *args, **kwargs):
-                raise Exception
+                raise TypeError('Cannot save an anonymous user.')
 
         return AnonUser()
 
-- 
GitLab