diff --git a/aleksis/apps/alsijil/migrations/0026_add_global_permissions.py b/aleksis/apps/alsijil/migrations/0026_add_global_permissions.py new file mode 100644 index 0000000000000000000000000000000000000000..ffee911dadb7d20aa96eb241f2c4f8532ca6e6a5 --- /dev/null +++ b/aleksis/apps/alsijil/migrations/0026_add_global_permissions.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.4 on 2025-01-10 17:52 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('alsijil', '0025_remove_old_models'), + ] + + operations = [ + migrations.AlterModelOptions( + name='alsijilglobalpermissions', + options={'managed': False, 'permissions': (('view_lesson', 'Can view lesson overview'), ('view_week', 'Can view week overview'), ('view_full_register', 'Can view full register'), ('view_all_coursebooks', 'Can view all coursebooks including all related information (e. g. personal notes)'), ('manage_all_coursebooks', 'Can manage all coursebooks including all related information (e. g. personal notes)'), ('register_absence', 'Can register absence'), ('list_personal_note_filters', 'Can list all personal note filters'))}, + ), + ] diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index 6e8465376fad8816f65ab28204d60e367a97221b..d843d6172a07985ae7fe9e176c0615b4f0e945cb 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -659,6 +659,14 @@ class AlsijilGlobalPermissions(GlobalPermissionModel): ("view_lesson", _("Can view lesson overview")), ("view_week", _("Can view week overview")), ("view_full_register", _("Can view full register")), + ( + "view_all_coursebooks", + _("Can view all coursebooks including all related information"), + ), + ( + "manage_all_coursebooks", + _("Can manage all coursebooks including all related information"), + ), ("register_absence", _("Can register absence")), ("list_personal_note_filters", _("Can list all personal note filters")), ) diff --git a/aleksis/apps/alsijil/rules.py b/aleksis/apps/alsijil/rules.py index c0a697b1c8248413e96d339279d7a278852f4b20..93db2dd87f8415f997200104337d248807a1713d 100644 --- a/aleksis/apps/alsijil/rules.py +++ b/aleksis/apps/alsijil/rules.py @@ -52,19 +52,6 @@ register_absence_predicate = has_person & ( ) add_perm("alsijil.register_absence_rule", register_absence_predicate) -# View full register for group -view_full_register_predicate = has_person & ( - is_group_owner - | ( - is_parent_group_owner - & is_site_preference_set("alsijil", "inherit_privileges_from_parent_group") - ) - | has_global_perm("alsijil.view_full_register") - | has_object_perm("core.view_full_register_group") -) -add_perm("alsijil.view_full_register_rule", view_full_register_predicate) - - # View extra mark list view_extramarks_predicate = has_person & has_global_perm("alsijil.view_extramark") add_perm("alsijil.view_extramarks_rule", view_extramarks_predicate) @@ -147,12 +134,15 @@ view_register_objects_list_predicate = has_person & ( add_perm("alsijil.view_register_objects_list_rule", view_register_objects_list_predicate) view_documentation_predicate = has_person & ( - has_global_perm("alsijil.view_documentation") | can_view_documentation + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.view_documentation") + | can_view_documentation ) add_perm("alsijil.view_documentation_rule", view_documentation_predicate) view_documentations_for_course_predicate = has_person & ( - has_global_perm("alsijil.view_documentation") + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.view_documentation") | is_course_teacher | is_course_member | is_course_group_owner @@ -160,28 +150,46 @@ view_documentations_for_course_predicate = has_person & ( 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") + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.view_documentation") | is_group_owner | is_group_member | is_parent_group_owner ) add_perm("alsijil.view_documentations_for_group_rule", view_documentations_for_group_predicate) +print_documentations_for_group_predicate = has_person & ( + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.view_full_register") + | is_group_owner + | ( + is_parent_group_owner + & is_site_preference_set("alsijil", "inherit_privileges_from_parent_group") + ) + | has_object_perm("core.view_full_register_group") +) +add_perm("alsijil.print_documentations_for_group_rule", print_documentations_for_group_predicate) + view_documentations_menu_predicate = has_person add_perm("alsijil.view_documentations_menu_rule", view_documentations_menu_predicate) view_documentations_for_teacher_predicate = has_person & ( - has_global_perm("alsijil.view_documentation") | is_current_person + has_global_perm("alsijil.view_all_coursebooks") + | 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 + has_global_perm("alsijil.manage_all_coursebooks") + | 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") + has_global_perm("alsijil.manage_all_coursebooks") + | has_global_perm("alsijil.add_documentation") | is_lesson_event_teacher | is_lesson_event_group_owner ) @@ -191,14 +199,19 @@ add_perm( edit_documentation_predicate = ( has_person - & (has_global_perm("alsijil.change_documentation") | can_edit_documentation) + & ( + has_global_perm("alsijil.manage_all_coursebooks") + | has_global_perm("alsijil.change_documentation") + | can_edit_documentation + ) & is_in_allowed_time_range ) add_perm("alsijil.edit_documentation_rule", edit_documentation_predicate) add_perm("alsijil.delete_documentation_rule", edit_documentation_predicate) view_participation_status_for_documentation_predicate = has_person & ( - has_global_perm("alsijil.change_participationstatus") + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.change_participationstatus") | can_view_participation_status_for_documentation ) add_perm( @@ -209,7 +222,8 @@ add_perm( edit_participation_status_for_documentation_with_time_range_predicate = ( has_person & ( - has_global_perm("alsijil.change_participationstatus") + has_global_perm("alsijil.manage_all_coursebooks") + | has_global_perm("alsijil.change_participationstatus") | can_edit_participation_status_for_documentation ) & is_in_allowed_time_range_for_participation_status @@ -220,7 +234,8 @@ add_perm( ) edit_participation_status_for_documentation_predicate = has_person & ( - has_global_perm("alsijil.change_participationstatus") + has_global_perm("alsijil.manage_all_coursebooks") + | has_global_perm("alsijil.change_participationstatus") | can_edit_participation_status_for_documentation ) add_perm( @@ -245,7 +260,9 @@ add_perm( ) view_personal_note_predicate = has_person & ( - has_global_perm("alsijil.change_newpersonalnote") | can_view_personal_note + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.change_newpersonalnote") + | can_view_personal_note ) add_perm( "alsijil.view_personal_note_rule", @@ -254,7 +271,11 @@ add_perm( edit_personal_note_predicate = ( has_person - & (has_global_perm("alsijil.change_newpersonalnote") | can_edit_personal_note) + & ( + has_global_perm("alsijil.manage_all_coursebooks") + | has_global_perm("alsijil.change_newpersonalnote") + | can_edit_personal_note + ) & is_in_allowed_time_range ) add_perm( @@ -263,7 +284,9 @@ add_perm( ) view_group_statistics_predicate = has_person & ( - has_global_perm("alsijil.view_participationstatus") | is_group_owner + has_global_perm("alsijil.view_all_coursebooks") + | has_global_perm("alsijil.view_participationstatus") + | is_group_owner ) add_perm( "alsijil.view_group_statistics_rule", @@ -272,6 +295,7 @@ add_perm( view_person_statistics_predicate = has_person & ( is_current_person + | has_global_perm("alsijil.view_all_coursebooks") | has_global_perm("alsijil.view_participationstatus") | can_view_statistics_for_person ) diff --git a/aleksis/apps/alsijil/schema/__init__.py b/aleksis/apps/alsijil/schema/__init__.py index f337be4f836c8f73383e952c88f79e229613e02a..545173b3130b268cb105788d51f325db5da07c76 100644 --- a/aleksis/apps/alsijil/schema/__init__.py +++ b/aleksis/apps/alsijil/schema/__init__.py @@ -150,6 +150,7 @@ class Query(graphene.ObjectType): event_params = { "own": own, } + if obj_type is not None and obj_id is not None: event_params.update( { @@ -168,6 +169,9 @@ class Query(graphene.ObjectType): info.context, event_params, with_reference_object=True, + bypass_permission_and_person_filters=info.context.user.has_perm( + "alsijil.view_all_coursebooks" + ), ) # Lookup or create documentations and return them all. @@ -193,9 +197,10 @@ class Query(graphene.ObjectType): school_term = get_active_school_term(info.context) - return ( - Group.objects.for_school_term(school_term) - .filter( + if info.context.user.has_perm("alsijil.view_all_coursebooks"): + qs = Group.objects.for_school_term(school_term) + else: + qs = Group.objects.for_school_term(school_term).filter( pk__in=Group.objects.filter(members=person) .values_list("id", flat=True) .union(Group.objects.filter(owners=person).values_list("id", flat=True)) @@ -203,14 +208,13 @@ class Query(graphene.ObjectType): Group.objects.filter(parent_groups__owners=person).values_list("id", flat=True) ) ) - .annotate( - is_priority=ExpressionWrapper( - Q(group_type=get_site_preferences()["alsijil__group_type_priority_coursebook"]), - output_field=BooleanField(), - ) + + return qs.annotate( + is_priority=ExpressionWrapper( + Q(group_type=get_site_preferences()["alsijil__group_type_priority_coursebook"]), + output_field=BooleanField(), ) - .order_by("is_priority") - ) + ).order_by("is_priority") @staticmethod def resolve_courses_of_person(root, info, person=None): @@ -225,19 +229,28 @@ class Query(graphene.ObjectType): school_term = get_active_school_term(info.context) - return Course.objects.filter( - pk__in=( - Course.objects.filter(teachers=person) - .values_list("id", flat=True) - .union(Course.objects.filter(groups__members=person).values_list("id", flat=True)) - .union(Course.objects.filter(groups__owners=person).values_list("id", flat=True)) - .union( - Course.objects.filter(groups__parent_groups__owners=person).values_list( - "id", flat=True + if info.context.user.has_perm("alsijil.view_all_coursebooks"): + qs = Course.objects.all() + else: + qs = Course.objects.filter( + pk__in=( + Course.objects.filter(teachers=person) + .values_list("id", flat=True) + .union( + Course.objects.filter(groups__members=person).values_list("id", flat=True) + ) + .union( + Course.objects.filter(groups__owners=person).values_list("id", flat=True) + ) + .union( + Course.objects.filter(groups__parent_groups__owners=person).values_list( + "id", flat=True + ) ) ) ) - ).filter(groups__in=Group.objects.for_school_term(school_term)) + + return qs.filter(groups__in=Group.objects.for_school_term(school_term)) @staticmethod def resolve_absence_creation_persons(root, info, **kwargs): diff --git a/aleksis/apps/alsijil/schema/documentation.py b/aleksis/apps/alsijil/schema/documentation.py index ad88b2de383217984eb4cb8e2e2704daf68c84e9..2f21846461fe5dbca38c98ff864babe3a0e705fe 100644 --- a/aleksis/apps/alsijil/schema/documentation.py +++ b/aleksis/apps/alsijil/schema/documentation.py @@ -7,7 +7,6 @@ from reversion import create_revision, set_comment, set_user from aleksis.apps.alsijil.util.predicates import ( can_edit_documentation, - can_edit_participation_status_for_documentation, is_in_allowed_time_range, is_in_allowed_time_range_for_participation_status, ) @@ -96,7 +95,9 @@ class DocumentationType(PermissionsTypeMixin, DjangoFilterMixin, DjangoObjectTyp @staticmethod def resolve_can_edit_participation_status(root: Documentation, info, **kwargs): """Shows whether the user can edit all participation statuses of the documentation""" - return can_edit_participation_status_for_documentation(info.context.user, root) + return info.context.user.has_perm( + "alsijil.edit_participation_status_for_documentation_rule", root + ) @staticmethod def resolve_can_view_participation_status(root: Documentation, info, **kwargs): diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 71b4cbdd6ee85c3eb280c9f15549e31736b060ab..8cf6f512ae28c69418c35b6dc6da039ea040cbb9 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -54,7 +54,7 @@ def full_register_for_group(request: HttpRequest, ids: str) -> HttpResponse: groups = [] for id_ in ids: group = get_object_or_404(Group, pk=id_) - if not request.user.has_perm("alsijil.view_full_register_rule", group): + if not request.user.has_perm("alsijil.print_documentations_for_group_rule", group): raise PermissionDenied() groups.append(group)