From ad65d9c6fcf0e858eb4cf671e1cb4084c1dc89cf Mon Sep 17 00:00:00 2001 From: Jonathan Weth <git@jonathanweth.de> Date: Mon, 7 Aug 2023 13:57:08 +0200 Subject: [PATCH] Move LessonEvent queries to own queryset and drop dangerous attributes --- aleksis/apps/chronos/managers.py | 34 +++++++++++++++++++- aleksis/apps/chronos/models.py | 53 ++++++++------------------------ 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/aleksis/apps/chronos/managers.py b/aleksis/apps/chronos/managers.py index 80563bcd..d537dd45 100644 --- a/aleksis/apps/chronos/managers.py +++ b/aleksis/apps/chronos/managers.py @@ -12,7 +12,7 @@ from calendarweek import CalendarWeek from aleksis.apps.chronos.util.date import week_weekday_from_date, week_weekday_to_date from aleksis.core.managers import DateRangeQuerySetMixin, SchoolTermRelatedQuerySet -from aleksis.core.models import Group, Person +from aleksis.core.models import Group, Person, Room from aleksis.core.util.core_helpers import get_site_preferences @@ -859,3 +859,35 @@ class RoomPropertiesMixin: @property def room_short_names(self, sep: str = ", ") -> str: return sep.join([room.short_name for room in self.get_rooms()]) + + +class LessonEventQuerySet(QuerySet): + """Queryset with special query methods for lesson events.""" + + def for_teacher(self, teacher: Union[int, Person]): + amended = objs.filter(Q(amended_by__isnull=False) & (Q(teachers=teacher))).values_list( + "amended_by__pk", flat=True + ) + return objs.filter(Q(teachers=teacher) | Q(pk__in=amended)).distinct() + + def for_group(self, group: Union[int, Group]): + amended = self.filter( + Q(amended_by__isnull=False) & (Q(groups=group) | Q(groups__parent_groups=group)) + ).values_list("amended_by__pk", flat=True) + return self.filter( + Q(groups=group) | Q(groups__parent_groups=group) | Q(pk__in=amended) + ).distinct() + + def for_room(self, room: Union[int, Room]): + amended = self.filter(Q(amended_by__isnull=False) & (Q(rooms=room))).values_list( + "amended_by__pk", flat=True + ) + return self.filter(Q(rooms=room) | Q(pk__in=amended)).distinct() + + def for_person(self, person: Union[int, Person]): + amended = self.filter( + Q(amended_by__isnull=False) & (Q(teachers=person) | Q(groups__members=person)) + ).values_list("amended_by__pk", flat=True) + return self.filter( + Q(teachers=person) | Q(groups__members=person) | Q(pk__in=amended) + ).distinct() diff --git a/aleksis/apps/chronos/models.py b/aleksis/apps/chronos/models.py index 7cc450ef..ae323ccc 100644 --- a/aleksis/apps/chronos/models.py +++ b/aleksis/apps/chronos/models.py @@ -42,6 +42,7 @@ from aleksis.apps.chronos.managers import ( ExtraLessonQuerySet, GroupPropertiesMixin, HolidayQuerySet, + LessonEventQuerySet, LessonPeriodManager, LessonPeriodQuerySet, LessonSubstitutionManager, @@ -63,7 +64,10 @@ from aleksis.apps.chronos.util.format import format_m2m from aleksis.apps.cursus import models as cursus_models from aleksis.apps.cursus.models import Course from aleksis.apps.resint.models import LiveDocument -from aleksis.core.managers import CurrentSiteManagerWithoutMigrations +from aleksis.core.managers import ( + AlekSISBaseManagerWithoutMigrations, + CurrentSiteManagerWithoutMigrations, +) from aleksis.core.mixins import ( ExtensibleModel, GlobalPermissionModel, @@ -1370,6 +1374,8 @@ class LessonEvent(CalendarEvent): name = "lesson" verbose_name = _("Lessons") + objects = AlekSISBaseManagerWithoutMigrations.from_queryset(LessonEventQuerySet)() + title = models.CharField(verbose_name=_("Name"), max_length=255, blank=True) course = models.ForeignKey( @@ -1513,19 +1519,10 @@ class LessonEvent(CalendarEvent): return reference_object.real_amends.subject.colour_bg return super().value_color(reference_object, request) - @classmethod - def value_organizer(cls, reference_object: "LessonEvent", request) -> str: - """Get the organizer of the event.""" - # TODO: Do not use the teachers as organizer, because only one organizer is allowed - return [t.get_vcal_address(role="CHAIR") for t in reference_object.teachers.all()] - @classmethod def value_attendee(cls, reference_object: "LessonEvent", request) -> str: """Get the attendees of the event.""" - # FIXME: Permissions - attendees = [t.get_vcal_address(role="CHAIR") for t in reference_object.teachers.all()] + [ - g.get_vcal_address(role="REQ-PARTICIPANT") for g in reference_object.all_members - ] + attendees = [t.get_vcal_address(role="CHAIR") for t in reference_object.teachers.all()] return [a for a in attendees if a] @classmethod @@ -1585,44 +1582,18 @@ class LessonEvent(CalendarEvent): def get_objects(cls, request, params=None) -> Iterable: """Return all objects that should be included in the calendar.""" objs = super().get_objects(request, params) - print(params) if params: obj_id = int(params.get("id", 0)) type = params.get("type", None) - print(obj_id, type) if type and obj_id: if type == "TEACHER": - amended = objs.filter( - Q(amended_by__isnull=False) & (Q(teachers=obj_id)) - ).values_list("amended_by__pk", flat=True) - return objs.filter(Q(teachers=obj_id) | Q(pk__in=amended)).distinct() + return objs.for_teacher(obj_id) elif type == "GROUP": - amended = objs.filter( - Q(amended_by__isnull=False) & (Q(groups=obj_id)) - ).values_list("amended_by__pk", flat=True) - print( - objs.filter( - Q(groups=obj_id) | Q(groups__parent_groups=obj_id) | Q(pk__in=amended) - ).distinct() - ) - return objs.filter( - Q(groups=obj_id) | Q(groups__parent_groups=obj_id) | Q(pk__in=amended) - ).distinct() + return objs.for_group(obj_id) elif type == "ROOM": - amended = objs.filter( - Q(amended_by__isnull=False) & (Q(roms=obj_id)) - ).values_list("amended_by__pk", flat=True) - return objs.filter(Q(rooms=obj_id) | Q(pk__in=amended)).distinct() - amended = objs.filter( - Q(amended_by__isnull=False) - & (Q(teachers=request.user.person) | Q(groups__members=request.user.person)) - ).values_list("amended_by__pk", flat=True) - return objs.filter( - Q(teachers=request.user.person) - | Q(groups__members=request.user.person) - | Q(pk__in=amended) - ).distinct() + return objs.for_room(obj_id) + return objs.for_person(request.user.person) class Meta: verbose_name = _("Lesson Event") -- GitLab