Permalink
Browse files

MDL-35381 limit teachers to do permissions checks of enrolled users only

  • Loading branch information...
1 parent b733b0a commit 89fbf2e874d01c4912e624bc69895fff9282ef81 @skodak skodak committed with stronk7 Sep 15, 2012
Showing with 133 additions and 10 deletions.
  1. +5 −10 admin/roles/check.php
  2. +128 −0 admin/roles/lib.php
View
@@ -59,16 +59,11 @@
$contextname = print_context_name($context);
// Get the user_selector we will need.
-// Teachers within a course just get to see the same list of people they can
-// assign roles to. Admins (people with moodle/role:manage) can run this report for any user.
-$options = array('context' => $context, 'roleid' => 0);
-if (has_capability('moodle/role:manage', $context)) {
- $userselector = new potential_assignees_course_and_above('reportuser', $options);
-} else {
- $userselector = roles_get_potential_user_selector($context, 'reportuser', $options);
-}
-$userselector->set_multiselect(false);
-$userselector->set_rows(10);
+// Teachers within a course just get to see the same list of enrolled users.
+// Admins (people with moodle/role:manage) can run this report for any user.
+$options = array('accesscontext' => $context);
+$userselector = new role_check_users_selector('reportuser', $options);
+$userselector->set_rows(20);
// Work out an appropriate page title.
$title = get_string('checkpermissionsin', 'role', $contextname);
View
@@ -1076,6 +1076,134 @@ public function find_users($search) {
}
}
+/**
+ * User selector subclass for the selection of users in the check permissions page.
+ *
+ * @copyright 2012 Petr Skoda {@link http://skodak.org}
+ */
+class role_check_users_selector extends user_selector_base {
+ const MAX_ENROLLED_PER_PAGE = 100;
+ const MAX_POTENTIAL_PER_PAGE = 100;
+
+ /** @var bool limit listing of users to enrolled only */
+ var $onlyenrolled;
+
+ /**
+ * Constructor.
+ *
+ * @param string $name the control name/id for use in the HTML.
+ * @param array $options other options needed to construct this selector.
+ * You must be able to clone a userselector by doing new get_class($us)($us->get_name(), $us->get_options());
+ */
+ public function __construct($name, $options) {
+ if (!isset($options['multiselect'])) {
+ $options['multiselect'] = false;
+ }
+ parent::__construct($name, $options);
+
+ $coursecontext = $this->accesscontext->get_course_context(false);
+ if ($coursecontext and $coursecontext->id != SITEID and !has_capability('moodle/role:manage', $coursecontext)) {
+ // Prevent normal teachers from looking up all users.
+ $this->onlyenrolled = true;
+ } else {
+ $this->onlyenrolled = false;
+ }
+ }
+
+ public function find_users($search) {
+ global $DB;
+
+ list($wherecondition, $params) = $this->search_sql($search, 'u');
+
+ $fields = 'SELECT ' . $this->required_fields_sql('u');
+ $countfields = 'SELECT COUNT(1)';
+
+ $coursecontext = $this->accesscontext->get_course_context(false);
+
+ if ($coursecontext and $coursecontext != SITEID) {
+ $sql1 = " FROM {user} u
+ JOIN {user_enrolments} ue ON (ue.userid = u.id)
+ JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid1)
+ WHERE $wherecondition";
+ $params['courseid1'] = $coursecontext->instanceid;
+
+ if ($this->onlyenrolled) {
+ $sql2 = null;
+ } else {
+ $sql2 = " FROM {user} u
+ LEFT JOIN ({user_enrolments} ue
+ JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid2)) ON (ue.userid = u.id)
+ WHERE $wherecondition
+ AND ue.id IS NULL";
+ $params['courseid2'] = $coursecontext->instanceid;
+ }
+
+ } else {
+ if ($this->onlyenrolled) {
+ // Bad luck, current user may not view only enrolled users.
+ return array();
+ }
+ $sql1 = null;
+ $sql2 = " FROM {user} u
+ WHERE $wherecondition";
+ }
+
+ $order = " ORDER BY lastname ASC, firstname ASC";
+
+ $params['contextid'] = $this->accesscontext->id;
+
+ $result = array();
+
+ if ($search) {
+ $groupname1 = get_string('enrolledusersmatching', 'enrol', $search);
+ $groupname2 = get_string('potusersmatching', 'role', $search);
+ } else {
+ $groupname1 = get_string('enrolledusers', 'enrol');
+ $groupname2 = get_string('potusers', 'role');
+ }
+
+ if ($sql1) {
+ $enrolleduserscount = $DB->count_records_sql($countfields . $sql1, $params);
+ if (!$this->is_validating() and $enrolleduserscount > $this::MAX_ENROLLED_PER_PAGE) {
+ $result[$groupname1] = array();
+ $toomany = $this->too_many_results($search, $enrolleduserscount);
+ $result[implode(' - ', array_keys($toomany))] = array();
+
+ } else {
+ $enrolledusers = $DB->get_records_sql($fields . $sql1 . $order, $params);
+ if ($enrolledusers) {
+ $result[$groupname1] = $enrolledusers;
+ }
+ }
+ if ($sql2) {
+ $result[''] = array();
+ }
+ }
+ if ($sql2) {
+ $otheruserscount = $DB->count_records_sql($countfields . $sql2, $params);
+ if (!$this->is_validating() and $otheruserscount > $this::MAX_POTENTIAL_PER_PAGE) {
+ $result[$groupname2] = array();
+ $toomany = $this->too_many_results($search, $otheruserscount);
+ $result[implode(' - ', array_keys($toomany))] = array();
+ } else {
+ $otherusers = $DB->get_records_sql($fields . $sql2 . $order, $params);
+ if ($otherusers) {
+ $result[$groupname2] = $otherusers;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ protected function get_options() {
+ global $CFG;
+ $options = parent::get_options();
+ $options['file'] = $CFG->admin . '/roles/lib.php';
+ return $options;
+ }
+}
+
/**
* User selector subclass for the list of potential users on the assign roles page,
* when we are assigning in a context at or above the course level. In this case we

0 comments on commit 89fbf2e

Please sign in to comment.