diff --git a/calendar/externallib.php b/calendar/externallib.php index b2c94b546b0..620c20bad3b 100644 --- a/calendar/externallib.php +++ b/calendar/externallib.php @@ -448,6 +448,10 @@ class core_calendar_external extends external_api { $context = \context_user::instance($user->id); self::validate_context($context); + if ($params['userid'] && $USER->id !== $params['userid'] && !has_capability('moodle/calendar:manageentries', $context)) { + throw new \required_capability_exception($context, 'moodle/calendar:manageentries', 'nopermission', ''); + } + if (empty($params['aftereventid'])) { $params['aftereventid'] = null; } diff --git a/calendar/tests/externallib_test.php b/calendar/tests/externallib_test.php index bc33c032785..0d05cd0ad41 100644 --- a/calendar/tests/externallib_test.php +++ b/calendar/tests/externallib_test.php @@ -1035,6 +1035,54 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase { $this->assertEquals('Lesson 1 closes', $result->events[0]->name); } + /** + * Check that it is possible to get other user's events without the permission. + */ + public function test_get_calendar_action_events_by_timesort_for_other_users() { + $this->resetAfterTest(); + // Create test users. + $user1 = $this->getDataGenerator()->create_user(['email' => 'student1@localhost.com']); + $user2 = $this->getDataGenerator()->create_user(['email' => 'student2@localhost.com']); + // Create test course. + $course = $this->getDataGenerator()->create_course(); + $this->setAdminUser(); + // Create test activity and make it available only for student2. + $lesson = $this->getDataGenerator()->create_module('lesson', [ + 'name' => 'Lesson 1', + 'course' => $course->id, + 'available' => time(), + 'deadline' => (time() + (60 * 60 * 24 * 5)), + 'availability' => '{"op":"&","c":[{"type":"profile","sf":"email","op":"isequalto","v":"student2@localhost.com"}],"showc":[true]}' + ] + ); + // Enrol. + $this->getDataGenerator()->enrol_user($user1->id, $course->id); + $this->getDataGenerator()->enrol_user($user2->id, $course->id); + + // Student2 can see the event. + $this->setUser($user2); + $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true); + $this->assertCount(1, $result->events); + $this->assertEquals('Lesson 1 closes', $result->events[0]->name); + + // Student1 cannot see the event. + $this->setUser($user1); + $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true); + $this->assertEmpty($result->events); + + // Admin, Manager, Teacher can view student2's data. + $this->setAdminUser(); + $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true, $user2->id); + $this->assertCount(1, $result->events); + $this->assertEquals('Lesson 1 closes', $result->events[0]->name); + + // Student1 will see an exception if he/she trying to view student2's data. + $this->setUser($user1); + $this->expectException(required_capability_exception::class); + $this->expectExceptionMessage('error/nopermission'); + $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true, $user2->id); + } + /** * Requesting calendar events from a given course and time should return all * events with a sort time at or after the requested time. All events prior