From f2151ca24547d09a48645882f9648b77cffec7f0 Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Fri, 14 Aug 2020 15:36:25 +0200
Subject: [PATCH] Remove usage of has_any_object and change to custom queries

---
 aleksis/apps/alsijil/rules.py           |  6 +++---
 aleksis/apps/alsijil/util/predicates.py | 21 +++++++++++++++++----
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index 43c24f1fd..79ea32519 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -1,8 +1,6 @@
 from rules import add_perm
 
-from aleksis.core.models import Person
 from aleksis.core.util.predicates import (
-    has_any_object,
     has_global_perm,
     has_object_perm,
     has_person,
@@ -10,6 +8,7 @@ from aleksis.core.util.predicates import (
 )
 
 from .util.predicates import (
+    has_any_object_absence,
     has_lesson_group_object_perm,
     has_personal_note_group_perm,
     has_person_group_object_perm,
@@ -96,7 +95,8 @@ add_perm("alsijil.view_week_personalnote", view_week_personal_notes_predicate)
 
 # View register absence page
 view_register_absence_predicate = has_person & (
-    has_any_object("alsijil.register_absence", Person)
+    has_global_perm("alsijil.register_absence")
+    | has_any_object_absence
 )
 add_perm("alsijil.view_register_absence", view_register_absence_predicate)
 
diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py
index bad3a644c..3c53c4b29 100644
--- a/aleksis/apps/alsijil/util/predicates.py
+++ b/aleksis/apps/alsijil/util/predicates.py
@@ -2,11 +2,13 @@ from typing import Union
 
 from django.contrib.auth.models import User
 
+from guardian.shortcuts import get_objects_for_user
 from rules import predicate
 
 from aleksis.apps.chronos.models import LessonPeriod
 from aleksis.core.models import Group, Person
-from aleksis.core.util.predicates import check_object_permission, get_site_preferences
+from aleksis.core.util.predicates import check_object_permission
+from aleksis.core.util.core_helpers import get_site_preferences
 
 from ..models import PersonalNote
 
@@ -140,7 +142,7 @@ def has_personal_note_group_perm(perm: str):
 
 
 @predicate
-def is_own_personal_note(user: User, obj: PersonalNote):
+def is_own_personal_note(user: User, obj: PersonalNote) -> bool:
     """Predicate for users referred to in a personal note
 
     Checks whether the user referred to in a PersonalNote is the active user.
@@ -153,7 +155,7 @@ def is_own_personal_note(user: User, obj: PersonalNote):
 
 
 @predicate
-def is_personal_note_lesson_teacher(user: User, obj: PersonalNote):
+def is_personal_note_lesson_teacher(user: User, obj: PersonalNote) -> bool:
     """Predicate for teachers of a lesson referred to in the lesson period of a personal note.
 
     Checks whether the person linked to the user is a teacher
@@ -170,7 +172,7 @@ def is_personal_note_lesson_teacher(user: User, obj: PersonalNote):
 
 
 @predicate
-def is_personal_note_lesson_parent_group_owner(user: User, obj: PersonalNote):
+def is_personal_note_lesson_parent_group_owner(user: User, obj: PersonalNote) -> bool:
     """
     Predicate for parent group owners of a lesson referred to in the lesson period of a personal note.
 
@@ -182,3 +184,14 @@ def is_personal_note_lesson_parent_group_owner(user: User, obj: PersonalNote):
             return obj.lesson_period.lesson.groups.filter(parent_groups__owners=user.person).exists()
         return False
     return False
+
+
+@predicate
+def has_any_object_absence(user: User) -> bool:
+    """
+    Predicate which builds a query with all the persons the given users is allowed to register an absence for.
+    """
+    return get_objects_for_user(user, "core.register_absence_person", Person)\
+        .union(Person.objects.filter(member_of__owners=user))\
+        .union(Person.objects.filter(member_of__in=get_objects_for_user(user, "core.register_absence_group", Group)))\
+        .exists()
-- 
GitLab