diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py index e2a55de885f3e415d9b4e461ab3192f899af2398..9fe3a62812123a8e701ad0ccb2a730470d9ad350 100644 --- a/aleksis/apps/alsijil/preferences.py +++ b/aleksis/apps/alsijil/preferences.py @@ -14,3 +14,11 @@ class BlockPersonalNotesForCancelled(BooleanPreference): name = "block_personal_notes_for_cancelled" default = True verbose_name = _("Block adding personal notes for cancelled lessons") + + +@site_preferences_registry.register +class ViewOwnPersonalNotes(BooleanPreference): + section = alsijil + name = "view_own_personal_notes" + default = True + verbose_name = _("Allow users to view their own personal notes") diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index 63db5927747e2a71b544d3ea2ff4f960fff9fe45..f87447f4283a81a32463a10487b91122674c912a 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -11,12 +11,16 @@ from aleksis.core.util.predicates import ( from .util.predicates import ( has_lesson_group_object_perm, + has_personal_note_group_perm, has_person_group_object_perm, is_group_member, is_group_owner, is_lesson_parent_group_owner, is_lesson_participant, is_lesson_teacher, + is_own_personal_note, + is_personal_note_lesson_parent_group_owner, + is_personal_note_lesson_teacher, is_person_group_owner, ) @@ -33,14 +37,15 @@ add_perm("alsijil.view_lesson", view_lesson_predicate) # View lesson in menu add_perm("alsijil.view_lesson_menu", has_person) -# View lesson personal notes -view_lesson_personal_notes_predicate = has_person & ( +# View personal note +view_personal_note_predicate = has_person & ( has_global_perm("alsijil.view_personalnote") - | has_lesson_group_object_perm("core.view_personalnote_group") - | is_lesson_teacher - | is_lesson_parent_group_owner + | has_personal_note_group_perm("core.view_personalnote_group") + | is_personal_note_lesson_teacher + | is_own_personal_note + | is_personal_note_lesson_parent_group_owner ) -add_perm("alsijil.view_lesson_personalnote", view_lesson_personal_notes_predicate) +add_perm("alsijil.view_personalnote", view_personal_note_predicate) # Edit lesson personal notes edit_lesson_personal_notes_predicate = has_person & ( diff --git a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html index 87941f96725c89a35078c8604923fa01cf569712..130e697e140d78e09788d8179e9b79e41dd68bb9 100644 --- a/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html +++ b/aleksis/apps/alsijil/templates/alsijil/class_register/lesson.html @@ -131,7 +131,10 @@ <th>{{ extra_mark.name }}</th> <td> {% for note in notes %} - <span>{{ note.person }}{% if not forloop.last %},{% endif %}</span> + {% has_perm "alsijil.view_personalnote" user note as can_view_personalnote %} + {% if can_view_personalnote %} + <span>{{ note.person }}{% if not forloop.last %},{% endif %}</span> + {% endif %} {% endfor %} </td> </tr> diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/absences.html b/aleksis/apps/alsijil/templates/alsijil/partials/absences.html index 6deaa3891c480026b22fbad2cfc75a4f2b260110..c72204c556efee0c5308d607947b5cd9670d85c3 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/absences.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/absences.html @@ -1,6 +1,9 @@ -{% load i18n %} +{% load i18n rules %} {% for note in notes %} - <span class="{% if note.excused %}green-text{% else %}red-text{% endif %}">{{ note.person }} - {% if note.excused %}{% if note.excuse_type %}({{ note.excuse_type.short_name }}){% else %}{% trans "(e)" %}{% endif %}{% else %}{% trans "(u)" %}{% endif %}{% if not forloop.last %},{% endif %} - </span> + {% has_perm "alsijil.view_personalnote" user note as can_view_personalnote %} + {% if can_view_personalnote %} + <span class="{% if note.excused %}green-text{% else %}red-text{% endif %}">{{ note.person }} + {% if note.excused %}{% if note.excuse_type %}({{ note.excuse_type.short_name }}){% else %}{% trans "(e)" %}{% endif %}{% else %}{% trans "(u)" %}{% endif %}{% if not forloop.last %},{% endif %} + </span> + {% endif %} {% endfor %} diff --git a/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html b/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html index b3639ea88b779bd746ab551f0a9f2e5d938fd786..3bb86191612f2bdface729be8d048a6fb05edcd5 100644 --- a/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html +++ b/aleksis/apps/alsijil/templates/alsijil/partials/tardinesses.html @@ -1,3 +1,7 @@ +{% load rules %} {% for note in notes %} - <span>{{ note.person }} ({{ note.late }}'){% if not forloop.last %},{% endif %}</span> + {% has_perm "alsijil.view_personalnote" user note as can_view_personalnote %} + {% if can_view_personalnote %} + <span>{{ note.person }} ({{ note.late }}'){% if not forloop.last %},{% endif %}</span> + {% endif %} {% endfor %} diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py index 9fe6949e4cc3b133ee169c614c8e795f2ddc444b..bad3a644cff10f6c4a79b7e4e0ab0a0dd717c9bc 100644 --- a/aleksis/apps/alsijil/util/predicates.py +++ b/aleksis/apps/alsijil/util/predicates.py @@ -6,7 +6,9 @@ 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 +from aleksis.core.util.predicates import check_object_permission, get_site_preferences + +from ..models import PersonalNote @predicate @@ -16,12 +18,7 @@ def is_lesson_teacher(user: User, obj: LessonPeriod) -> bool: Checks whether the person linked to the user is a teacher in the lesson or the substitution linked to the given LessonPeriod. """ - if hasattr(obj, "lesson"): - return ( - user.person in obj.lesson.teachers.all() - or user.person in Person.objects.filter(lesson_substitutions__lesson_period=obj, lesson_substitutions__week=obj._week) - ) - return True + return user.person in Person.objects.filter(lesson_substitutions=obj.get_substitution()) @predicate @@ -122,3 +119,66 @@ def has_lesson_group_object_perm(perm: str): return True return fn + + +def has_personal_note_group_perm(perm: str): + """Predicate builder for permissions on personal notes + + Checks whether a user has a permission on any group of a person of a PersonalNote. + """ + name = f"has_personal_note_person_or_group_perm:{perm}" + + @predicate(name) + def fn(user: User, obj: PersonalNote) -> bool: + if hasattr(obj, "person"): + for group in obj.person.member_of.all(): + if check_object_permission(user, perm, group): + return True + return False + + return fn + + +@predicate +def is_own_personal_note(user: User, obj: PersonalNote): + """Predicate for users referred to in a personal note + + Checks whether the user referred to in a PersonalNote is the active user. + Is configurable via dynamic preferences. + """ + if hasattr(obj, "person"): + if get_site_preferences()["alsijil__view_own_personal_notes"] and obj.person is user.person: + return True + return False + + +@predicate +def is_personal_note_lesson_teacher(user: User, obj: PersonalNote): + """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 + in the lesson or the substitution linked to the LessonPeriod of the given PersonalNote. + """ + if hasattr(obj, "lesson_period"): + if hasattr(obj.lesson_period, "lesson"): + return ( + user.person in obj.lesson_period.lesson.teachers.all() + or user.person in Person.objects.filter(lesson_substitutions=obj.lesson_period.get_substitution()) + ) + return False + return False + + +@predicate +def is_personal_note_lesson_parent_group_owner(user: User, obj: PersonalNote): + """ + Predicate for parent group owners of a lesson referred to in the lesson period of a personal note. + + Checks whether the person linked to the user is the owner of + any parent groups of any groups of the given LessonPeriod lesson of the given PersonalNote. + """ + if hasattr(obj, "lesson_period"): + if hasattr(obj.lesson_period, "lesson"): + return obj.lesson_period.lesson.groups.filter(parent_groups__owners=user.person).exists() + return False + return False