Skip to content
Snippets Groups Projects
Commit 9512647f authored by Hangzhi Yu's avatar Hangzhi Yu
Browse files

Add backend permission checks for supervisions

parent 5b0f48c3
No related branches found
No related tags found
1 merge request!369Resolve "Permissions for timetables are not checked properly"
Pipeline #193628 failed
......@@ -12,6 +12,6 @@ class Migration(migrations.Migration):
operations = [
migrations.AlterModelOptions(
name='chronosglobalpermissions',
options={'managed': False, 'permissions': (('view_all_room_timetables', 'Can view all room timetables'), ('view_all_group_timetables', 'Can view all group timetables'), ('view_all_person_timetables', 'Can view all person timetables'), ('view_all_course_timetables', 'Can view all course timetables'), ('view_timetable_overview', 'Can view timetable overview'), ('view_lessons_day', 'Can view all lessons per day'), ('view_supervisions_day', 'Can view all supervisions per day'))},
options={'managed': False, 'permissions': (('view_all_room_timetables', 'Can view all room timetables'), ('view_all_group_timetables', 'Can view all group timetables'), ('view_all_person_timetables', 'Can view all person timetables'), ('view_all_course_timetables', 'Can view all course timetables'), ('view_timetable_overview', 'Can view timetable overview'), ('view_substitutions', 'Can view substitutions table'), ('view_all_room_supervisions', 'Can view all room supervisions'), ('view_all_group_supervisions', 'Can view all group supervisions'), ('view_all_person_supervisions', 'Can view all person supervisions'))},
),
]
from django.utils.translation import gettext_lazy as _
from aleksis.apps.cursus.models import Course
from aleksis.core.models import Group, Person
from aleksis.core.models import Group, Person, Room
# Dynamically add extra permissions to Group and Person models in core and Course model in cursus
# Dynamically add extra permissions to Group, Person and Room models in core and Course model in cursus
# Note: requires migrate afterwards
Group.add_permission(
"view_group_timetable",
......@@ -13,6 +13,18 @@ Person.add_permission(
"view_person_timetable",
_("Can view person timetable"),
)
Group.add_permission(
"view_group_supervisions",
_("Can view group supervisions"),
)
Person.add_permission(
"view_person_supervisions",
_("Can view person supervisions"),
)
Room.add_permission(
"view_room_supervisions",
_("Can view room supervisions"),
)
Course.add_permission(
"view_course_timetable",
_("Can view course timetable"),
......
......@@ -150,6 +150,9 @@ class ChronosGlobalPermissions(GlobalPermissionModel):
("view_all_course_timetables", _("Can view all course timetables")),
("view_timetable_overview", _("Can view timetable overview")),
("view_substitutions", _("Can view substitutions table")),
("view_all_room_supervisions", _("Can view all room supervisions")),
("view_all_group_supervisions", _("Can view all group supervisions")),
("view_all_person_supervisions", _("Can view all person supervisions")),
)
......@@ -558,6 +561,32 @@ class SupervisionEvent(LessonEvent):
q = q & SupervisionEventQuerySet.amending_q()
if type_ and obj_id:
if request and not (
(
type_ == "GROUP"
and check_global_permission(
request.user, "chronos.view_all_group_supervisions"
)
)
or (
type_ == "TEACHER"
and check_global_permission(
request.user, "chronos.view_all_person_supervisions"
)
)
or (
type_ == "ROOM"
and check_global_permission(
request.user, "chronos.view_all_room_supervisions"
)
)
):
# inline import needed to avoid circular import
from aleksis.apps.chronos.util.chronos_helpers import get_el_by_pk
obj = get_el_by_pk(request, type_.lower(), obj_id)
if not request.user.has_perm("chronos.view_supervisions_rule", obj):
raise PermissionDenied()
if type_ == "TEACHER":
q = q & SupervisionEventQuerySet.for_teacher_q(obj_id)
elif type_ == "GROUP":
......
......@@ -6,7 +6,7 @@ from aleksis.core.util.predicates import (
has_person,
)
from .util.predicates import has_any_timetable_object, has_timetable_perm
from .util.predicates import has_any_timetable_object, has_supervisions_perm, has_timetable_perm
# View timetable overview
view_timetable_overview_predicate = has_person & (
......@@ -18,6 +18,9 @@ add_perm("chronos.view_timetable_overview_rule", view_timetable_overview_predica
view_timetable_predicate = has_person & has_timetable_perm
add_perm("chronos.view_timetable_rule", view_timetable_predicate)
# View supervisions for group, person or room
view_supervisions_predicate = has_person & has_supervisions_perm
add_perm("chronos.view_supervisions_rule", view_supervisions_predicate)
# Edit substition
edit_substitution_predicate = has_person & (
......
......@@ -93,6 +93,70 @@ def has_course_timetable_perm(user: User, obj: Course) -> bool:
)
@predicate
def has_supervisions_perm(user: User, obj: Model) -> bool:
"""
Check if can access supervisions of object.
Predicate which checks whether the user is allowed
to access the requested supervisions of the given
group, person or room.
"""
if isinstance(obj, Group):
return has_group_supervisions_perm(user, obj)
elif isinstance(obj, Person):
return has_person_supervisions_perm(user, obj)
elif isinstance(obj, Room):
return has_room_supervisions_perm(user, obj)
else:
return False
@predicate
def has_group_supervisions_perm(user: User, obj: Group) -> bool:
"""
Check if can access group supervisions.
Predicate which checks whether the user is allowed
to access the requested group supervisions.
"""
return (
obj in user.person.member_of.all()
or user.person.primary_group == obj
or obj in user.person.owner_of.all()
or has_global_perm("chronos.view_all_group_supervisions")(user)
or has_object_perm("core.view_group_supervisions")(user, obj)
)
@predicate
def has_person_supervisions_perm(user: User, obj: Person) -> bool:
"""
Check if can access person supervisions.
Predicate which checks whether the user is allowed
to access the requested person supervisions.
"""
return (
user.person == obj
or has_global_perm("chronos.view_all_person_supervisions")(user)
or has_object_perm("core.view_person_supervisions")(user, obj)
)
@predicate
def has_room_supervisions_perm(user: User, obj: Room) -> bool:
"""
Check if can access room supervisions.
Predicate which checks whether the user is allowed
to access the requested room supervisions.
"""
return has_global_perm("chronos.view_all_room_supervisions")(user) or has_object_perm(
"core.view_room_supervisions"
)(user, obj)
@predicate
def has_any_timetable_object(user: User) -> bool:
"""Predicate which checks whether there are any timetables the user is allowed to access."""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment