From f04f6e74560367b33daf6c1b88ec4d7f4a983721 Mon Sep 17 00:00:00 2001 From: Moritz Strohm <strohm@data-quest.de> Date: Mon, 18 Mar 2024 10:28:46 +0000 Subject: [PATCH] Fixed permissions for course participants in course calendar, fixes #3824 Closes #3824 Merge request studip/studip!2690 --- app/controllers/calendar/date.php | 33 ++++++++++++++++------ app/views/calendar/date/index.php | 2 +- lib/models/calendar/CalendarDate.class.php | 17 +++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/app/controllers/calendar/date.php b/app/controllers/calendar/date.php index 3c16fa61bb2..8c542b8ed0a 100644 --- a/app/controllers/calendar/date.php +++ b/app/controllers/calendar/date.php @@ -122,7 +122,7 @@ class Calendar_DateController extends AuthenticatedController if ($this->date->repetition_type) { $this->selected_date = Request::get('selected_date'); } - $this->calendar_assignments = CalendarDateAssignment::findBySql( + $this->user_calendar_assignments = CalendarDateAssignment::findBySql( "INNER JOIN `auth_user_md5` ON `calendar_date_assignments`.`range_id` = `auth_user_md5`.`user_id` WHERE @@ -132,14 +132,14 @@ class Calendar_DateController extends AuthenticatedController $this->participation_message = null; $this->user_participation_status = ''; $this->all_assignments_writable = false; - $this->is_group_date = count($this->calendar_assignments) > 1; + $this->is_group_date = count($this->user_calendar_assignments) > 1; - if ($this->calendar_assignments) { + if ($this->user_calendar_assignments) { $writable_assignment_c = 0; - $more_than_one_assignment = count($this->calendar_assignments) > 1; + $more_than_one_assignment = count($this->user_calendar_assignments) > 1; //Find the calendar assignment of the user and set the participation message //according to the participation status. - foreach ($this->calendar_assignments as $index => $assignment) { + foreach ($this->user_calendar_assignments as $index => $assignment) { if ($assignment->range_id === $GLOBALS['user']->id && $this->is_group_date) { $this->user_participation_status = $assignment->participation; if ($assignment->participation === 'ACCEPTED') { @@ -156,7 +156,7 @@ class Calendar_DateController extends AuthenticatedController } else { //We don't need the users own assignment in the list of assignments //when there is only one assignment to the users own calendar. - unset($this->calendar_assignments[$index]); + unset($this->user_calendar_assignments[$index]); } } else { @@ -166,10 +166,10 @@ class Calendar_DateController extends AuthenticatedController } } - $this->all_assignments_writable = $writable_assignment_c === count($this->calendar_assignments); + $this->all_assignments_writable = $writable_assignment_c === count($this->user_calendar_assignments); //Order all calendar assignments by type and name: - uasort($this->calendar_assignments, function ($a, $b) { + uasort($this->user_calendar_assignments, function ($a, $b) { $compare_name = ($a->course instanceof Course && $b->course instanceof Course) || ($a->user instanceof User && $b->user instanceof User); if ($compare_name) { @@ -203,6 +203,20 @@ class Calendar_DateController extends AuthenticatedController } } }); + } else { + //Check for other calendar assignments (course calendar): + $writable_assignment_c = 0; + $other_assignment_c = 0; + foreach ($this->date->calendars as $assignment) { + if (Course::exists($assignment->range_id)) { + //It is a course assignment: + $other_assignment_c++; + if ($assignment->isWritable($GLOBALS['user']->id)) { + $writable_assignment_c++; + } + } + } + $this->all_assignments_writable = $writable_assignment_c == $other_assignment_c; } } @@ -500,6 +514,9 @@ class Calendar_DateController extends AuthenticatedController if (($owner instanceof Course)) { //Set the course as calendar: $allowed_calendar_ids = [$owner->id]; + } elseif (Context::isCourse()) { + //Set the course as allowed calendar: + $allowed_calendar_ids = [Context::getId()]; } else { //Assign the date to the calendars of all the selected users: $allowed_calendar_ids = [$GLOBALS['user']->id]; diff --git a/app/views/calendar/date/index.php b/app/views/calendar/date/index.php index faec7c76cb7..f898f3b60f0 100644 --- a/app/views/calendar/date/index.php +++ b/app/views/calendar/date/index.php @@ -102,7 +102,7 @@ <section> <table class="default"> <body> - <? foreach ($calendar_assignments as $assignment) : ?> + <? foreach ($user_calendar_assignments as $assignment) : ?> <tr> <td><?= htmlReady($assignment->getRangeName()) ?></td> <td><?= htmlReady($assignment->getParticipationAsString()) ?></td> diff --git a/lib/models/calendar/CalendarDate.class.php b/lib/models/calendar/CalendarDate.class.php index d5b96270f35..167efd1ee47 100644 --- a/lib/models/calendar/CalendarDate.class.php +++ b/lib/models/calendar/CalendarDate.class.php @@ -210,6 +210,23 @@ class CalendarDate extends SimpleORMap implements PrivacyObject //may change the date. return true; } + //In case $range_id is a User-ID, a check has to be made if the calendar + //date is bound to a course and the user has at least "tutor" permissions + //in the course. + if (User::exists($range_id)) { + $writable_via_course = false; + $assignments = CalendarDateAssignment::findByCalendar_date_id($this->id); + foreach ($assignments as $assignment) { + if (Course::exists($assignment->range_id) + && $GLOBALS['perm']->have_studip_perm('tutor', $assignment->range_id, $range_id)) { + $writable_via_course = true; + break; + } + } + if ($writable_via_course) { + return true; + } + } //Check contacts: Has the contact of the user that is represented by //$range_id write permissions to all the calendars of all the users that -- GitLab