From 3f982d23362a04c1f4c1252cf1b3c93774b5f27e Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Wed, 3 Jul 2024 20:12:06 +0200 Subject: [PATCH] Add permissions for personal notes and extra marks --- aleksis/apps/alsijil/rules.py | 20 ++++++++++ aleksis/apps/alsijil/schema/extra_marks.py | 31 +++++++++++++-- aleksis/apps/alsijil/schema/personal_note.py | 6 +-- aleksis/apps/alsijil/util/predicates.py | 40 ++++++++++++++++++-- 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index 9045598fd..5f85fec80 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -13,9 +13,11 @@ from aleksis.core.util.predicates import ( from .util.predicates import ( can_edit_documentation, can_edit_participation_status, + can_edit_personal_note, can_view_any_documentation, can_view_documentation, can_view_participation_status, + can_view_personal_note, has_lesson_group_object_perm, has_person_group_object_perm, has_personal_note_group_perm, @@ -435,3 +437,21 @@ add_perm( "alsijil.edit_participation_status_for_documentation_rule", edit_participation_status_for_documentation_predicate, ) + +view_personal_note_predicate = has_person & ( + has_global_perm("alsijil.change_newpersonalnote") | can_view_personal_note +) +add_perm( + "alsijil.view_personal_note_rule", + view_personal_note_predicate, +) + +edit_personal_note_predicate = ( + has_person + & (has_global_perm("alsijil.change_newpersonalnote") | can_edit_personal_note) + & is_in_allowed_time_range +) +add_perm( + "alsijil.edit_personal_note_rule", + edit_personal_note_predicate, +) diff --git a/aleksis/apps/alsijil/schema/extra_marks.py b/aleksis/apps/alsijil/schema/extra_marks.py index 90f3e28d2..4eb9f0fe1 100644 --- a/aleksis/apps/alsijil/schema/extra_marks.py +++ b/aleksis/apps/alsijil/schema/extra_marks.py @@ -1,4 +1,7 @@ +from django.core.exceptions import PermissionDenied + from graphene_django import DjangoObjectType +from guardian.shortcuts import get_objects_for_user from aleksis.apps.alsijil.models import ExtraMark from aleksis.core.schema.base import ( @@ -9,6 +12,7 @@ from aleksis.core.schema.base import ( OptimisticResponseTypeMixin, PermissionsTypeMixin, ) +from aleksis.core.util.core_helpers import has_person class ExtraMarkType( @@ -21,23 +25,44 @@ class ExtraMarkType( model = ExtraMark fields = ("id", "short_name", "name", "colour_fg", "colour_bg", "show_in_coursebook") + @classmethod + def get_queryset(cls, queryset, info): + if has_person(info.context.user): + return get_objects_for_user(info.context.user, "alsijil.view_extramark", queryset) + raise PermissionDenied() + class ExtraMarkBatchCreateMutation(BaseBatchCreateMutation): class Meta: model = ExtraMark fields = ("short_name", "name", "colour_fg", "colour_bg", "show_in_coursebook") optional_fields = ("name",) - permissions = ("alsijil.create_extra_mark",) # FIXME + + @classmethod + def check_permissions(cls, root, info, input): # noqa + if info.context.user.has_perm("alsijil.add_extramark_rule"): + return + raise PermissionDenied() class ExtraMarkBatchDeleteMutation(BaseBatchDeleteMutation): class Meta: model = ExtraMark - permissions = ("alsijil.delete_extra_mark",) # FIXME + + @classmethod + def check_permissions(cls, root, info, input): # noqa + if info.context.user.has_perm("alsijil.delete_extramark_rule"): + return + raise PermissionDenied() class ExtraMarkBatchPatchMutation(BaseBatchPatchMutation): class Meta: model = ExtraMark fields = ("id", "short_name", "name", "colour_fg", "colour_bg", "show_in_coursebook") - permissions = ("alsijil.change_extra_mark",) # FIXME + + @classmethod + def check_permissions(cls, root, info, input): # noqa + if info.context.user.has_perm("alsijil.edit_extramark_rule"): + return + raise PermissionDenied() diff --git a/aleksis/apps/alsijil/schema/personal_note.py b/aleksis/apps/alsijil/schema/personal_note.py index 7558378ae..dfe36359d 100644 --- a/aleksis/apps/alsijil/schema/personal_note.py +++ b/aleksis/apps/alsijil/schema/personal_note.py @@ -32,7 +32,7 @@ class PersonalNoteBatchCreateMutation(BaseBatchCreateMutation): type_name = "BatchCreatePersonalNoteInput" return_field_name = "personalNotes" fields = ("note", "extra_mark", "documentation", "person") - permissions = ("alsijil.create_personal_note",) # FIXME + permissions = ("alsijil.edit_personal_note_rule",) class PersonalNoteBatchPatchMutation(BaseBatchPatchMutation): @@ -41,10 +41,10 @@ class PersonalNoteBatchPatchMutation(BaseBatchPatchMutation): type_name = "BatchPatchPersonalNoteInput" return_field_name = "personalNotes" fields = ("id", "note", "extra_mark", "documentation", "person") - permissions = ("alsijil.change_personal_note",) # FIXME + permissions = ("alsijil.edit_personal_note_rule",) class PersonalNoteBatchDeleteMutation(BaseBatchDeleteMutation): class Meta: model = NewPersonalNote - permissions = ("alsijil.delete_personal_note",) # FIXME + permissions = ("alsijil.edit_personal_note_rule",) diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py index 9f06195e2..122442edd 100644 --- a/aleksis/apps/alsijil/util/predicates.py +++ b/aleksis/apps/alsijil/util/predicates.py @@ -12,7 +12,7 @@ from aleksis.core.models import Group, Person from aleksis.core.util.core_helpers import get_site_preferences from aleksis.core.util.predicates import check_object_permission -from ..models import Documentation, PersonalNote +from ..models import Documentation, NewPersonalNote, PersonalNote @predicate @@ -475,8 +475,14 @@ def can_edit_participation_status(user: User, obj: Documentation): @predicate -def is_in_allowed_time_range(user: User, obj: Documentation): - """Predicate which checks if the documentation is in the allowed time range for editing.""" +def is_in_allowed_time_range(user: User, obj: Union[Documentation, NewPersonalNote]): + """Predicate for documentations or new personal notes with linked documentation. + + Predicate which checks if the given documentation or the documentation linked + to the given NewPersonalNote is in the allowed time range for editing. + """ + if isinstance(obj, NewPersonalNote): + obj = obj.documentation if obj and ( get_site_preferences()["alsijil__allow_edit_future_documentations"] == "all" or ( @@ -498,3 +504,31 @@ def is_in_allowed_time_range_for_participation_status(user: User, obj: Documenta if obj and obj.value_start_datetime(obj) <= now(): return True return False + + +@predicate +def can_view_personal_note(user: User, obj: NewPersonalNote): + """Predicate which checks if the user is allowed to view a personal note.""" + if obj.documentation: + if is_documentation_teacher(user, obj.documentation): + return True + if obj.documentation.amends: + return is_lesson_event_teacher( + user, obj.documentation.amends + ) | is_lesson_event_group_owner(user, obj.documentation.amends) + if obj.documentation.course: + return is_course_teacher(user, obj.documentation.course) + return False + + +@predicate +def can_edit_personal_note(user: User, obj: NewPersonalNote): + """Predicate which checks if the user is allowed to edit a personal note.""" + if obj.documentation: + if is_documentation_teacher(user, obj.documentation): + return True + if obj.documentation.amends: + return is_lesson_event_teacher( + user, obj.documentation.amends + ) | is_lesson_event_group_owner(user, obj.documentation.amends) + return False -- GitLab