From 7c0a44c836aaa57f00d5d9934f50a07b41a1e64e Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Thu, 11 Mar 2021 10:34:27 +0100
Subject: [PATCH] Ensure that original teachers only can view substituted
 lessons

---
 aleksis/apps/alsijil/rules.py           |  8 +++++-
 aleksis/apps/alsijil/util/predicates.py | 38 ++++++++++++++++++++++---
 2 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index f36db7aa5..4037bb6df 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -15,6 +15,7 @@ from .util.predicates import (
     is_group_member,
     is_group_owner,
     is_group_role_assignment_group_owner,
+    is_lesson_original_teacher,
     is_lesson_parent_group_owner,
     is_lesson_participant,
     is_lesson_teacher,
@@ -23,6 +24,7 @@ from .util.predicates import (
     is_owner_of_any_group,
     is_person_group_owner,
     is_person_primary_group_owner,
+    is_personal_note_lesson_original_teacher,
     is_personal_note_lesson_parent_group_owner,
     is_personal_note_lesson_teacher,
     is_teacher,
@@ -32,6 +34,7 @@ from .util.predicates import (
 view_register_object_predicate = has_person & (
     is_none  # View is opened as "Current lesson"
     | is_lesson_teacher
+    | is_lesson_original_teacher
     | is_lesson_participant
     | is_lesson_parent_group_owner
     | has_global_perm("alsijil.view_lesson")
@@ -46,6 +49,7 @@ add_perm("alsijil.view_lesson_menu", has_person)
 view_lesson_personal_notes_predicate = view_register_object_predicate & (
     ~is_lesson_participant
     | is_lesson_teacher
+    | is_lesson_original_teacher
     | has_global_perm("alsijil.view_personalnote")
     | has_lesson_group_object_perm("core.view_personalnote_group")
 )
@@ -63,6 +67,7 @@ add_perm("alsijil.edit_register_object_personalnote", edit_lesson_personal_note_
 view_personal_note_predicate = has_person & (
     (is_own_personal_note & is_site_preference_set("alsijil", "view_own_personal_notes"))
     | is_personal_note_lesson_teacher
+    | is_personal_note_lesson_original_teacher
     | is_personal_note_lesson_parent_group_owner
     | has_global_perm("alsijil.view_personalnote")
     | has_personal_note_group_perm("core.view_personalnote_group")
@@ -71,7 +76,7 @@ add_perm("alsijil.view_personalnote", view_personal_note_predicate)
 
 # Edit personal note
 edit_personal_note_predicate = view_personal_note_predicate & (
-    ~is_own_personal_note
+    ~is_own_personal_note & ~is_personal_note_lesson_original_teacher
     | has_global_perm("alsijil.view_personalnote")
     | has_personal_note_group_perm("core.edit_personalnote_group")
 )
@@ -242,6 +247,7 @@ add_perm("alsijil.delete_grouprole", delete_group_role_predicate)
 view_assigned_group_roles_predicate = (
     is_group_owner
     | is_lesson_teacher
+    | is_lesson_original_teacher
     | is_lesson_parent_group_owner
     | has_global_perm("alsjil.assign_grouprole")
     | has_object_perm("alsijil.assign_grouprole")
diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py
index 8b59bb5dc..8ef58e204 100644
--- a/aleksis/apps/alsijil/util/predicates.py
+++ b/aleksis/apps/alsijil/util/predicates.py
@@ -22,8 +22,22 @@ def is_none(user: User, obj: Any) -> bool:
 def is_lesson_teacher(user: User, obj: Union[LessonPeriod, Event, ExtraLesson]) -> bool:
     """Predicate for teachers of a lesson.
 
-    Checks whether the person linked to the user is a teacher
-    in the lesson or the substitution linked to the given LessonPeriod.
+    Checks whether the person linked to the user is a teacher in the register object.
+    If the register object is a lesson period and has a substitution linked,
+    this will **only** check if the person is one of the substitution teachers.
+    """
+    if obj:
+        return user.person in obj.get_teachers().all()
+    return False
+
+
+@predicate
+def is_lesson_original_teacher(user: User, obj: Union[LessonPeriod, Event, ExtraLesson]) -> bool:
+    """Predicate for teachers of a lesson.
+
+    Checks whether the person linked to the user is a teacher in the register object.
+    If the register object is a lesson period and has a substitution linked,
+    this will **also** check if the person is one of the substitution teachers.
     """
     if obj:
         if isinstance(obj, LessonPeriod) and user.person in obj.lesson.teachers.all():
@@ -205,10 +219,26 @@ def is_own_personal_note(user: User, obj: PersonalNote) -> bool:
 
 @predicate
 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.
+    """Predicate for teachers of a register object linked to a personal note.
+
+    Checks whether the person linked to the user is a teacher
+    in the register object linked to the personal note.
+    If the register object is a lesson period and has a substitution linked,
+    this will **only** check if the person is one of the substitution teachers.
+    """
+    if hasattr(obj, "register_object"):
+        return user.person in obj.register_object.get_teachers().all()
+    return False
+
+
+@predicate
+def is_personal_note_lesson_original_teacher(user: User, obj: PersonalNote) -> bool:
+    """Predicate for teachers of a register object linked to a personal note.
 
     Checks whether the person linked to the user is a teacher
-    in the lesson or the substitution linked to the LessonPeriod of the given PersonalNote.
+    in the register object linked to the personal note.
+    If the register object is a lesson period and has a substitution linked,
+    this will **also** check if the person is one of the substitution teachers.
     """
     if hasattr(obj, "register_object"):
         if (
-- 
GitLab