From 84f98c7e2b9d7e9485a837d6be4889da899d4d75 Mon Sep 17 00:00:00 2001
From: Hangzhi Yu <hangzhi@protonmail.com>
Date: Tue, 30 Jan 2024 18:19:41 +0100
Subject: [PATCH] Add permission checks for coursebook

---
 aleksis/apps/alsijil/rules.py                | 27 ++++++++++++++++++++
 aleksis/apps/alsijil/schema/__init__.py      |  6 +++++
 aleksis/apps/alsijil/schema/documentation.py | 14 +++++++++-
 3 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py
index fc4cdfe6e..9e564d72b 100644
--- a/aleksis/apps/alsijil/rules.py
+++ b/aleksis/apps/alsijil/rules.py
@@ -16,9 +16,11 @@ from .util.predicates import (
     has_lesson_group_object_perm,
     has_person_group_object_perm,
     has_personal_note_group_perm,
+    is_course_teacher,
     is_group_member,
     is_group_owner,
     is_group_role_assignment_group_owner,
+    is_lesson_event_teacher,
     is_lesson_original_teacher,
     is_lesson_parent_group_owner,
     is_lesson_participant,
@@ -360,6 +362,31 @@ view_documentation_predicate = has_person & (
 )
 add_perm("alsijil.view_documentation_rule", view_documentation_predicate)
 
+view_documentations_for_course_predicate = has_person & (
+    has_global_perm("alsijil.view_documentation") | is_course_teacher
+)
+add_perm("alsijil.view_documentations_for_course_rule", view_documentations_for_course_predicate)
+
+view_documentations_for_group_predicate = has_person & (
+    has_global_perm("alsijil.view_documentation") | is_group_owner
+)
+add_perm("alsijil.view_documentations_for_group_rule", view_documentations_for_group_predicate)
+
+view_documentations_for_teacher_predicate = has_person & (
+    has_global_perm("alsijil.view_documentation") | is_current_person
+)
+add_perm("alsijil.view_documentations_for_teacher_rule", view_documentations_for_teacher_predicate)
+
+add_documentation_for_course_predicate = has_person & (
+    has_global_perm("alsijil.add_documentation") | is_course_teacher
+)
+add_perm("alsijil.add_documentation_for_course_rule", add_documentation_for_course_predicate)
+
+add_documentation_for_lesson_event_predicate = has_person & (
+    has_global_perm("alsijil.add_documentation") | is_lesson_event_teacher
+)
+add_perm("alsijil.add_documentation_for_lesson_event_rule", add_documentation_for_lesson_event_predicate)
+
 edit_documentation_predicate = has_person & (
     has_global_perm("alsijil.change_documentation") | can_edit_documentation
 )
diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py
index c407a6eff..d1de339ab 100644
--- a/aleksis/apps/alsijil/schema/__init__.py
+++ b/aleksis/apps/alsijil/schema/__init__.py
@@ -1,8 +1,11 @@
 from django.db.models.query_utils import Q
+from django.core.exceptions import PermissionDenied
 
 from datetime import datetime
 import graphene
 
+from aleksis.apps.cursus.models import Course
+from aleksis.core.models import Group, Person
 from aleksis.core.schema.base import FilterOrderList
 
 from ..models import Documentation
@@ -39,6 +42,9 @@ class Query(graphene.ObjectType):
         datetime_start = datetime.combine(date_start, datetime.min.time())
         datetime_end = datetime.combine(date_end, datetime.max.time())
 
+        if (obj_type == "COURSE" and not info.context.user.has_perm("alsijil.view_documentations_for_course_rule", Course.objects.get(id=obj_id))) or (obj_type == "GROUPS" and not info.context.user.has_perm("alsijil.view_documentations_for_group_rule", Group.objects.get(id=obj_id))) or (obj_type == "TEACHER" and not info.context.user.has_perm("alsijil.view_documentations_for_teacher_rule", Person.objects.get(id=obj_id))):
+            raise PermissionsDenied()
+
         return Documentation.get_for_coursebook(obj_type, obj_id, datetime_start, datetime_end, info.context)
 
 
diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py
index 774227c9a..a8d6925e8 100644
--- a/aleksis/apps/alsijil/schema/documentation.py
+++ b/aleksis/apps/alsijil/schema/documentation.py
@@ -8,6 +8,8 @@ from graphene_django_cud.mutations import (
 )
 from guardian.shortcuts import get_objects_for_user
 
+from django.core.exceptions import PermissionDenied
+
 from aleksis.apps.chronos.models import LessonEvent
 from aleksis.core.schema.base import (
     DeleteMutation,
@@ -138,17 +140,27 @@ class DocumentationCreateOrUpdateMutation(graphene.Mutation):
         # Sadly, we can't use the update_or_create method since create_defaults is only introduced in Django 5.0
         if id.startswith("DUMMY"):
             dummy, lesson_event_id, datetime_start, datetime_end = id.split(";")
+            lesson_event = LessonEvent.objects.get(id=lesson_event_id)
+
+            if not info.context.user.has_perm("alsijil.add_documentation_for_lesson_event_rule", lesson_event):
+                raise PermissionDenied()
 
             obj = Documentation.objects.create(
                 datetime_start=datetime.fromisoformat(datetime_start),
                 datetime_end=datetime.fromisoformat(datetime_end),
-                lesson_event=LessonEvent.objects.get(id=lesson_event_id),
+                lesson_event=lesson_event,
+                course=lesson_event.course,
+                subject=lesson_event.subject,
                 topic=input.topic,
                 homework=input.homework,
                 group_note=input.group_note,
             )  # TODO: Add course & subject
         else:
             obj = Documentation.objects.get(id=id)
+
+            if not info.context.user.has_perm("alsijil.edit_documentation_rule", obj):
+                raise PermissionDenied()
+
             obj.topic = input.topic
             obj.homework = input.homework
             obj.group_note = input.group_note
-- 
GitLab