From 454d3e3bb66bd030f708feb9e1e1f644ca3321e7 Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Mon, 4 Nov 2024 22:06:44 +0100 Subject: [PATCH] Add permissions for coursebook statistics --- aleksis/apps/alsijil/preferences.py | 13 +++++++++++++ aleksis/apps/alsijil/rules.py | 19 ++++++++++++++++++ aleksis/apps/alsijil/schema/__init__.py | 26 ++++++++++++++++++++----- aleksis/apps/alsijil/util/predicates.py | 10 ++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) diff --git a/aleksis/apps/alsijil/preferences.py b/aleksis/apps/alsijil/preferences.py index b0d8fbc42..43125d96b 100644 --- a/aleksis/apps/alsijil/preferences.py +++ b/aleksis/apps/alsijil/preferences.py @@ -64,6 +64,19 @@ class GroupTypesRegisterAbsence(ModelMultipleChoicePreference): ) +@site_preferences_registry.register +class GroupTypesViewPersonStatistics(ModelMultipleChoicePreference): + section = alsijil + name = "group_types_view_person_statistics" + required = False + default = [] + model = GroupType + verbose_name = _( + "User is allowed to view coursebook statistics for members " + "of groups the user is an owner of with these group types" + ) + + @site_preferences_registry.register class GroupTypePriorityCoursebook(ModelChoicePreference): section = alsijil diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index 602663b51..71927e400 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -20,6 +20,7 @@ from .util.predicates import ( can_view_documentation, can_view_participation_status, can_view_personal_note, + can_view_statistics_for_person, has_person_group_object_perm, is_course_group_owner, is_course_member, @@ -241,6 +242,24 @@ add_perm( edit_personal_note_predicate, ) +view_group_statistics_predicate = has_person & ( + has_global_perm("alsijil.view_participationstatus") | is_group_owner +) +add_perm( + "alsijil.view_group_statistics_rule", + view_group_statistics_predicate, +) + +view_person_statistics_predicate = has_person & ( + is_current_person + | has_global_perm("alsijil.view_participationstatus") + | can_view_statistics_for_person +) +add_perm( + "alsijil.view_person_statistics_rule", + view_person_statistics_predicate, +) + # View parent menu entry view_menu_predicate = has_person & (view_documentations_menu_predicate | view_extramarks_predicate) add_perm( diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index c7e7e2a23..2e6bb7ad8 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -259,28 +259,44 @@ class Query(graphene.ObjectType): @staticmethod def resolve_statistics_by_person(root, info, person, term): + person = Person.objects.get(pk=person) + if not info.context.user.has_perm("alsijil.view_person_statistics_rule", person): + return None school_term = SchoolTerm.objects.get(id=term) return annotate_person_statistics_for_school_term( - Person.objects.filter(id=person), school_term + Person.objects.filter(id=person.id), school_term ).first() @staticmethod def resolve_participations_of_person(root, info, person, term=None): - # TODO: only current term - return ParticipationStatus.objects.filter(person=person, absence_reason__isnull=False) + person = Person.objects.get(pk=person) + if not info.context.user.has_perm("alsijil.view_person_statistics_rule", person): + return [] + school_term = SchoolTerm.objects.get(id=term) + return ParticipationStatus.objects.filter( + person=person, + absence_reason__isnull=False, + datetime_start__date__gte=school_term.date_start, + datetime_end__date__lte=school_term.date_end, + ) @staticmethod def resolve_personal_notes_for_person(root, info, person, term=None): - # TODO: only current term + person = Person.objects.get(pk=person) + if not info.context.user.has_perm("alsijil.view_person_statistics_rule", person): + return [] return NewPersonalNote.objects.filter(person=person) @staticmethod def resolve_statistics_by_group(root, info, group, term=None): + group = Group.objects.get(pk=group) + if not info.context.user.has_perm("alsijil.view_group_statistics_rule", group): + return [] school_term = ( SchoolTerm.objects.get(id=term) if term is not None else SchoolTerm.get_current() ) - members = Group.objects.get(id=group).members.all() + members = group.members.all() return annotate_person_statistics_for_school_term(members, school_term, group=group) diff --git a/aleksis/apps/alsijil/util/predicates.py b/aleksis/apps/alsijil/util/predicates.py index 2a27bca7e..f44b7677a 100644 --- a/aleksis/apps/alsijil/util/predicates.py +++ b/aleksis/apps/alsijil/util/predicates.py @@ -365,3 +365,13 @@ def can_edit_personal_note(user: User, obj: NewPersonalNote): user, obj.documentation.amends ) | is_lesson_event_group_owner(user, obj.documentation.amends) return False + + +@predicate +def can_view_statistics_for_person(user: User, obj: Person) -> bool: + """Predicate for registering absence for person.""" + group_types = get_site_preferences()["alsijil__group_types_view_person_statistics"] + qs = obj.member_of.filter(owners=user.person) + if not group_types: + return False + return qs.filter(group_type__in=group_types).exists() -- GitLab