From 405f8491e56df608ba658851fea8dd0e35782506 Mon Sep 17 00:00:00 2001 From: Ryan Wyllie Date: Mon, 1 May 2017 07:56:34 +0000 Subject: [PATCH] MDL-58518 calendar: ignore events from courses user not enrolled in --- calendar/classes/local/event/container.php | 11 ++++- calendar/tests/container_test.php | 52 ++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/calendar/classes/local/event/container.php b/calendar/classes/local/event/container.php index bb88a5ca6dc..083b19c5ed5 100644 --- a/calendar/classes/local/event/container.php +++ b/calendar/classes/local/event/container.php @@ -147,7 +147,16 @@ class container { $cm = $instances[$dbrow->modulename][$dbrow->instance]; // If the module is not visible to the current user, we should ignore it. - if (!$cm->uservisible) { + // We have to check enrolment here as well because the uservisible check + // looks for the "view" capability however some activities (such as Lesson) + // have that capability set on the "Authenticated User" role rather than + // on "Student" role, which means uservisible returns true even when the user + // is no longer enrolled in the course. + $modulecontext = \context_module::instance($cm->id); + // A user with the 'moodle/course:view' capability is able to see courses + // that they are not a participant in. + $canseecourse = (has_capability('moodle/course:view', $modulecontext) || is_enrolled($modulecontext)); + if (!$cm->uservisible || !$canseecourse) { return true; } diff --git a/calendar/tests/container_test.php b/calendar/tests/container_test.php index 8f4f5a7f47f..f1622387121 100644 --- a/calendar/tests/container_test.php +++ b/calendar/tests/container_test.php @@ -233,6 +233,58 @@ class core_calendar_container_testcase extends advanced_testcase { $this->assertNull($factory->create_instance($event)); } + /** + * Test that the event factory only returns an event if the logged in user + * is enrolled in the course. + */ + public function test_event_factory_unenrolled_user() { + $user = $this->getDataGenerator()->create_user(); + // Create the course we will be using. + $course = $this->getDataGenerator()->create_course(); + + // Add the assignment. + $generator = $this->getDataGenerator()->get_plugin_generator('mod_lesson'); + $lesson = $generator->create_instance(array('course' => $course->id)); + + // Create a user override event for the lesson. + $event = new \stdClass(); + $event->name = 'An event'; + $event->description = 'Event description'; + $event->format = FORMAT_HTML; + $event->eventtype = 'close'; + $event->userid = $user->id; + $event->modulename = 'lesson'; + $event->instance = $lesson->id; + $event->courseid = $course->id; + $event->groupid = 0; + $event->timestart = time(); + $event->timesort = time(); + $event->timemodified = time(); + $event->timeduration = 0; + $event->subscriptionid = null; + $event->repeatid = 0; + $legacyevent = $this->create_event($event); + + // Update the id of the event that was created. + $event->id = $legacyevent->id; + + // Set the logged in user to the one we created. + $this->setUser($user); + + // Create the factory we are going to be testing the behaviour of. + $factory = \core_calendar\local\event\container::get_event_factory(); + + // The result should be null since the user is not enrolled in the + // course the event is for. + $this->assertNull($factory->create_instance($event)); + + // Now enrol the user in the course. + $this->getDataGenerator()->enrol_user($user->id, $course->id); + + // Check that we get the correct instance. + $this->assertInstanceOf(event_interface::class, $factory->create_instance($event)); + } + /** * Test getting the event mapper. */ -- 2.36.1