Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MDL-70822 enrol: respect capability to view other users profile.
When retrieving courses of another user via web services, we should
respect the capability to view that users profile in a given course.
  • Loading branch information
paulholden authored and Jenkins committed Mar 2, 2021
1 parent acfb9ef commit c13f7f9
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
8 changes: 6 additions & 2 deletions enrol/externallib.php
Expand Up @@ -295,11 +295,15 @@ public static function get_users_courses($userid) {
global $CFG, $USER, $DB;

require_once($CFG->dirroot . '/course/lib.php');
require_once($CFG->dirroot . '/user/lib.php');

// Do basic automatic PARAM checks on incoming data, using params description
// If any problems are found then exceptions are thrown with helpful error messages
$params = self::validate_parameters(self::get_users_courses_parameters(), array('userid'=>$userid));
$userid = $params['userid'];

// Get user data including last access to courses.
$user = get_complete_user_data('id', $userid);
$sameuser = $USER->id == $userid;

$courses = enrol_get_users_courses($params['userid'], true, 'id, shortname, fullname, idnumber, visible,
Expand All @@ -315,8 +319,8 @@ public static function get_users_courses($userid) {
continue;
}

if (!$sameuser and !course_can_view_participants($context)) {
// we need capability to view participants
// If viewing details of another user, then we must be able to view participants as well as profile of that user.
if (!$sameuser && (!course_can_view_participants($context) || !user_can_view_profile($user, $course))) {
continue;
}

Expand Down
75 changes: 75 additions & 0 deletions enrol/tests/externallib_test.php
Expand Up @@ -464,6 +464,81 @@ public function test_get_users_courses() {
$this->assertEquals(null, $enrolledincourses[0]['progress']); // I can't see this, private.
}

/**
* Test that get_users_courses respects the capability to view participants when viewing courses of other user
*/
public function test_get_users_courses_can_view_participants() {
global $DB;

$this->resetAfterTest();

$course = $this->getDataGenerator()->create_course();
$context = context_course::instance($course->id);

$user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');

$this->setUser($user1);

$courses = core_enrol_external::clean_returnvalue(
core_enrol_external::get_users_courses_returns(),
core_enrol_external::get_users_courses($user2->id, false)
);

$this->assertCount(1, $courses);
$this->assertEquals($course->id, reset($courses)['id']);

// Prohibit the capability for viewing course participants.
$studentrole = $DB->get_field('role', 'id', ['shortname' => 'student']);
assign_capability('moodle/course:viewparticipants', CAP_PROHIBIT, $studentrole, $context->id);

$courses = core_enrol_external::clean_returnvalue(
core_enrol_external::get_users_courses_returns(),
core_enrol_external::get_users_courses($user2->id, false)
);
$this->assertEmpty($courses);
}

/*
* Test that get_users_courses respects the capability to view a users profile when viewing courses of other user
*/
public function test_get_users_courses_can_view_profile() {
$this->resetAfterTest();

$course = $this->getDataGenerator()->create_course([
'groupmode' => VISIBLEGROUPS,
]);

$user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');

// Create separate groups for each of our students.
$group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
groups_add_member($group1, $user1);
$group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
groups_add_member($group2, $user2);

$this->setUser($user1);

$courses = core_enrol_external::clean_returnvalue(
core_enrol_external::get_users_courses_returns(),
core_enrol_external::get_users_courses($user2->id, false)
);

$this->assertCount(1, $courses);
$this->assertEquals($course->id, reset($courses)['id']);

// Change to separate groups mode, so students can't view information about each other in different groups.
$course->groupmode = SEPARATEGROUPS;
update_course($course);

$courses = core_enrol_external::clean_returnvalue(
core_enrol_external::get_users_courses_returns(),
core_enrol_external::get_users_courses($user2->id, false)
);
$this->assertEmpty($courses);
}

/**
* Test get_course_enrolment_methods
*/
Expand Down

0 comments on commit c13f7f9

Please sign in to comment.