From 4e5f6669f73bf87435c1702781c5a15bca2af1a8 Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Wed, 21 Aug 2024 23:21:27 +0200
Subject: [PATCH] Adapt absence overview page for permission checking

---
 .../absences/DocumentationAbsences.vue        |  1 +
 aleksis/apps/alsijil/models.py                | 25 ++++++++++++++-----
 aleksis/apps/alsijil/rules.py                 | 10 +++++++-
 aleksis/apps/alsijil/schema/__init__.py       |  2 ++
 aleksis/apps/alsijil/schema/documentation.py  |  3 ++-
 .../alsijil/schema/participation_status.py    |  3 ++-
 6 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue
index ef97f2ddb..8dbe68847 100644
--- a/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue
+++ b/aleksis/apps/alsijil/frontend/components/coursebook/absences/DocumentationAbsences.vue
@@ -15,6 +15,7 @@
 
       <lesson-notes class="span-2" v-bind="documentationPartProps" />
       <participation-list
+        v-if="documentation.canEditParticipationStatus"
         :include-present="false"
         class="participation-list"
         v-bind="documentationPartProps"
diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py
index ed1da5ee7..5303a40e5 100644
--- a/aleksis/apps/alsijil/models.py
+++ b/aleksis/apps/alsijil/models.py
@@ -535,6 +535,7 @@ class Documentation(CalendarEvent):
         events: list,
         incomplete: Optional[bool] = False,
         absences_exist: Optional[bool] = False,
+        request: Optional[HttpRequest] = None,
     ) -> tuple:
         """Get all the documentations for the events.
         Create dummy documentations if none exist.
@@ -566,11 +567,22 @@ class Documentation(CalendarEvent):
 
             doc = next(existing_documentations_event, None)
             if doc:
-                if (incomplete and doc.topic) or (
-                    absences_exist
-                    and (
-                        not doc.participations.all()
-                        or not [d for d in doc.participations.all() if d.absence_reason]
+                if (
+                    (incomplete and doc.topic)
+                    or (
+                        not request.user.has_perm(
+                            "alsijil.edit_participation_status_for_documentation_rule", doc
+                        )
+                        and not doc.participations.filter(
+                            person__pk=request.user.person.pk, absence_reason__isnull=False
+                        ).exists()
+                    )
+                    or (
+                        absences_exist
+                        and (
+                            not doc.participations.all()
+                            or not [d for d in doc.participations.all() if d.absence_reason]
+                        )
                     )
                 ):
                     continue
@@ -609,6 +621,7 @@ class Documentation(CalendarEvent):
         start: datetime,
         end: datetime,
         incomplete: Optional[bool] = False,
+        request: Optional[HttpRequest] = None,
     ) -> tuple:
         """Get all the documentations for the person from start to end datetime.
         Create dummy documentations if none exist.
@@ -627,7 +640,7 @@ class Documentation(CalendarEvent):
             with_reference_object=True,
         )
 
-        return Documentation.get_documentations_for_events(start, end, events, incomplete)
+        return Documentation.get_documentations_for_events(start, end, events, incomplete, request)
 
     @classmethod
     def parse_dummy(
diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index 8b8e15e7b..171a07657 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -431,11 +431,19 @@ add_perm(
     view_participation_status_for_documentation_predicate,
 )
 
-edit_participation_status_for_documentation_predicate = (
+edit_participation_status_for_documentation_with_time_range_predicate = (
     has_person
     & (has_global_perm("alsijil.change_participationstatus") | can_edit_participation_status)
     & is_in_allowed_time_range_for_participation_status
 )
+add_perm(
+    "alsijil.edit_participation_status_for_documentation_with_time_range_rule",
+    edit_participation_status_for_documentation_with_time_range_predicate,
+)
+
+edit_participation_status_for_documentation_predicate = has_person & (
+    has_global_perm("alsijil.change_participationstatus") | can_edit_participation_status
+)
 add_perm(
     "alsijil.edit_participation_status_for_documentation_rule",
     edit_participation_status_for_documentation_predicate,
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index 97ec4f187..ceb9bbd4b 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -141,6 +141,7 @@ class Query(graphene.ObjectType):
             events,
             incomplete,
             absences_exist,
+            info.context,
         )
         return docs + dummies
 
@@ -218,6 +219,7 @@ class Query(graphene.ObjectType):
                 person,
                 start,
                 end,
+                info.context,
             )
 
             lessons_for_person.append(LessonsForPersonType(id=person, lessons=docs + dummies))
diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py
index 6132340c5..cdb2eaca1 100644
--- a/aleksis/apps/alsijil/schema/documentation.py
+++ b/aleksis/apps/alsijil/schema/documentation.py
@@ -180,7 +180,8 @@ class TouchDocumentationMutation(graphene.Mutation):
         )
 
         if not info.context.user.has_perm(
-            "alsijil.edit_participation_status_for_documentation_rule", documentation
+            "alsijil.edit_participation_status_for_documentation_with_time_range_rule",
+            documentation,
         ):
             raise PermissionDenied()
 
diff --git a/aleksis/apps/alsijil/schema/participation_status.py b/aleksis/apps/alsijil/schema/participation_status.py
index 2b9ebb25f..fcf15df81 100644
--- a/aleksis/apps/alsijil/schema/participation_status.py
+++ b/aleksis/apps/alsijil/schema/participation_status.py
@@ -73,7 +73,8 @@ class ParticipationStatusBatchPatchMutation(BaseBatchPatchMutation):
     @classmethod
     def after_update_obj(cls, root, info, input, obj, full_input):  # noqa: A002
         if not info.context.user.has_perm(
-            "alsijil.edit_participation_status_for_documentation_rule", obj.related_documentation
+            "alsijil.edit_participation_status_for_documentation_with_time_range_rule",
+            obj.related_documentation,
         ):
             raise PermissionDenied()
 
-- 
GitLab