From 3eb8d333a922166a35d80399c3bd539b407d8aee Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Wed, 7 Dec 2016 15:45:10 +1300 Subject: [PATCH] MDL-57027 fix get_users_by_capability() Change-Id: I98dc88784dfa0293f88a19c3d36e7a46a3f52672 --- lib/accesslib.php | 10 +++++----- lib/tests/accesslib_test.php | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/accesslib.php b/lib/accesslib.php index 0e449c9ca54..21d9ff84098 100644 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -3983,11 +3983,11 @@ function get_users_by_capability(context $context, $capability, $fields = '', $s AND roleid IN (".implode(',', array_keys($prohibited[$cap])) ."))"; } else { - $unions[] = "SELECT userid - FROM {role_assignments} - WHERE contextid IN ($ctxids) - AND roleid IN (".implode(',', array_keys($needed[$cap])) .") - AND roleid NOT IN (".implode(',', array_keys($prohibited[$cap])) .")"; + $unions[] = "SELECT ra.userid + FROM {role_assignments} ra + LEFT JOIN {role_assignments} rap ON (rap.userid = ra.userid AND rap.contextid IN ($ctxids) AND rap.roleid IN (".implode(',', array_keys($prohibited[$cap])) .")) + WHERE ra.contextid IN ($ctxids) AND ra.roleid IN (".implode(',', array_keys($needed[$cap])) .") + AND rap.id IS NULL"; } } } diff --git a/lib/tests/accesslib_test.php b/lib/tests/accesslib_test.php index 4534dde1fd6..91c326a7bf8 100644 --- a/lib/tests/accesslib_test.php +++ b/lib/tests/accesslib_test.php @@ -2483,6 +2483,12 @@ class core_accesslib_testcase extends advanced_testcase { assign_capability('mod/page:view', CAP_PREVENT, $allroles['guest'], $systemcontext, true); + // Prepare for prohibit test. + role_assign($allroles['editingteacher'], $testusers[19], context_system::instance()); + role_assign($allroles['teacher'], $testusers[19], context_course::instance($testcourses[17])); + role_assign($allroles['editingteacher'], $testusers[19], context_course::instance($testcourses[17])); + assign_capability('moodle/course:update', CAP_PROHIBIT, $allroles['teacher'], context_course::instance($testcourses[17]), true); + accesslib_clear_all_caches_for_unit_testing(); /// Must be done after assign_capability(). // Extra tests for guests and not-logged-in users because they can not be verified by cross checking @@ -2506,6 +2512,14 @@ class core_accesslib_testcase extends advanced_testcase { $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[19]), $testusers[9])); $this->assertFalse(has_capability('moodle/course:update', $systemcontext, $testusers[9])); + // Test prohibits. + $this->assertTrue(has_capability('moodle/course:update', context_system::instance(), $testusers[19])); + $ids = get_users_by_capability(context_system::instance(), 'moodle/course:update', 'u.id'); + $this->assertArrayHasKey($testusers[19], $ids); + $this->assertFalse(has_capability('moodle/course:update', context_course::instance($testcourses[17]), $testusers[19])); + $ids = get_users_by_capability(context_course::instance($testcourses[17]), 'moodle/course:update', 'u.id'); + $this->assertArrayNotHasKey($testusers[19], $ids); + // Test the list of enrolled users. $coursecontext = context_course::instance($course1->id); $enrolled = get_enrolled_users($coursecontext); -- 2.11.0