From 9a24025b8099b0879f6bff72e4e251aac5ba6cc2 Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Thu, 10 Sep 2020 17:20:44 +0200
Subject: [PATCH] Add cached content type getter

---
 aleksis/core/util/core_helpers.py | 12 ++++++++++++
 aleksis/core/util/predicates.py   | 10 ++--------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index 6428e293c..aeffad13f 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -361,6 +361,18 @@ def handle_uploaded_file(f, filename: str):
             destination.write(chunk)
 
 
+@cache_memoize(3600)
+def get_content_type_by_perm(perm: str) -> Union["ContentType", None]:
+    from django.contrib.contenttypes.models import ContentType  # noqa
+
+    try:
+        return ContentType.objects.get(
+            app_label=perm.split(".", 1)[0], permission__codename=perm.split(".", 1)[1]
+        )
+    except ContentType.DoesNotExist:
+        return None
+
+
 @cache_memoize(3600)
 def queryset_rules_filter(
     obj: Union[HttpRequest, Model], queryset: QuerySet, perm: str
diff --git a/aleksis/core/util/predicates.py b/aleksis/core/util/predicates.py
index 46fe98c73..d107b425b 100644
--- a/aleksis/core/util/predicates.py
+++ b/aleksis/core/util/predicates.py
@@ -1,6 +1,5 @@
 from django.contrib.auth.backends import ModelBackend
 from django.contrib.auth.models import User
-from django.contrib.contenttypes.models import ContentType
 from django.db.models import Model
 from django.http import HttpRequest
 
@@ -9,7 +8,7 @@ from guardian.shortcuts import get_objects_for_user
 from rules import predicate
 
 from ..models import Group
-from .core_helpers import get_site_preferences
+from .core_helpers import get_content_type_by_perm, get_site_preferences
 from .core_helpers import has_person as has_person_helper
 from .core_helpers import queryset_rules_filter
 
@@ -65,12 +64,7 @@ def has_any_object(perm: str, klass):
 
     @predicate(name)
     def fn(user: User) -> bool:
-        try:
-            ct_perm = ContentType.objects.get(
-                app_label=perm.split(".", 1)[0], permission__codename=perm.split(".", 1)[1]
-            )
-        except ContentType.DoesNotExist:
-            ct_perm = None
+        ct_perm = get_content_type_by_perm(perm)
         if ct_perm and ct_perm.model_class() == klass:
             return get_objects_for_user(user, perm, klass).exists()
         else:
-- 
GitLab