MDL-50039 tool_monitor: Additional checks for subscription.
authorAdrian Greeve <adrian@moodle.com>
Fri, 1 May 2015 04:34:27 +0000 (12:34 +0800)
committerDavid Monllao <davidm@moodle.com>
Thu, 7 May 2015 05:13:04 +0000 (13:13 +0800)
Additional capability checks are now in place to stop unauthorised
users from accessing the event monitor subscription page.

Thanks to Eloy Lafuente for creating a gist with ideas of tackling
No site level capability to the rule subscription.

admin/tool/monitor/classes/output/managesubs/rules.php
admin/tool/monitor/index.php
admin/tool/monitor/lib.php

index b298abf..0e519ec 100644 (file)
@@ -203,27 +203,24 @@ class rules extends \table_sql implements \renderable {
     /**
      * Gets a list of courses where the current user can subscribe to rules as a dropdown.
      *
+     * @param bool $choose A flag for whether to show the 'choose...' option in the select box.
      * @return \single_select|bool returns the list of courses, or false if the select box
      *      should not be displayed.
      */
-    public function get_user_courses_select() {
-        global $DB;
-
-        // If the number of courses on the site exceed the maximum drop down limit do not display the select box.
-        $numcourses = $DB->count_records('course');
-        if ($numcourses > COURSE_MAX_COURSES_PER_DROPDOWN) {
+    public function get_user_courses_select($choose = false) {
+        $options = tool_monitor_get_user_courses();
+        // If we have no options then don't create a select element.
+        if (!$options) {
             return false;
         }
-        $orderby = 'visible DESC, sortorder ASC';
-        $options = array(0 => get_string('site'));
-        if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname', $orderby)) {
-            foreach ($courses as $course) {
-                $options[$course->id] = format_string($course->fullname, true,
-                    array('context' => \context_course::instance($course->id)));
-            }
+        $selected = $this->courseid;
+        $nothing = array();
+        if ($choose) {
+            $selected = null;
+            $nothing = array('choosedots');
         }
         $url = new \moodle_url('/admin/tool/monitor/index.php');
-        $select = new \single_select($url, 'courseid', $options, $this->courseid);
+        $select = new \single_select($url, 'courseid', $options, $selected, $nothing);
         $select->set_label(get_string('selectacourse', 'tool_monitor'));
         return $select;
     }
index 84f1ea6..1065bd1 100644 (file)
@@ -24,6 +24,7 @@
 
 require_once(__DIR__ . '/../../../config.php');
 require_once($CFG->libdir.'/adminlib.php');
+require_once($CFG->dirroot . '/admin/tool/monitor/lib.php');
 
 $courseid = optional_param('courseid', 0, PARAM_INT);
 $action = optional_param('action', '', PARAM_ALPHA);
@@ -32,10 +33,22 @@ $ruleid = optional_param('ruleid', 0, PARAM_INT);
 $subscriptionid = optional_param('subscriptionid', 0, PARAM_INT);
 $confirm = optional_param('confirm', false, PARAM_BOOL);
 
+$choose = false;
 // Validate course id.
 if (empty($courseid)) {
     require_login();
     $context = context_system::instance();
+    // check system level capability.
+    if (!has_capability('tool/monitor:subscribe', $context)) {
+        // If not system level then check to see if they have access to any course level rules.
+        if (tool_monitor_get_user_courses()){
+            // Make them choose a course.
+            $choose = true;
+        } else {
+            // return error.
+            print_error('rulenopermission', 'tool_monitor');
+        }
+    }
 } else {
     // They might want to see rules for this course.
     $course = get_course($courseid);
@@ -59,7 +72,10 @@ $PAGE->set_url($indexurl);
 $PAGE->set_pagelayout('report');
 $PAGE->set_title(get_string('managesubscriptions', 'tool_monitor'));
 $PAGE->set_heading(fullname($USER));
-$settingsnode = $PAGE->settingsnav->find('monitor', null)->make_active();
+$settingsnode = $PAGE->settingsnav->find('monitor', null);
+if ($settingsnode) {
+    $settingsnode->make_active();
+}
 
 // Create/delete subscription if needed.
 if (!empty($action)) {
@@ -108,17 +124,13 @@ $renderer = $PAGE->get_renderer('tool_monitor', 'managesubs');
 $totalrules = \tool_monitor\rule_manager::count_rules_by_courseid($courseid);
 $rules = new \tool_monitor\output\managesubs\rules('toolmonitorrules', $indexurl, $courseid);
 
-$usercourses = $rules->get_user_courses_select();
-if (!empty($usercourses)) {
-    echo $renderer->render($usercourses);
-} else {
-    // Nothing to show at all. Show a notification.
-    echo $OUTPUT->notification(get_string('rulenopermission', 'tool_monitor'), 'notifyproblem');
-}
+$usercourses = $rules->get_user_courses_select($choose);
+// There must be user courses otherwise we wouldn't make it this far.
+echo $renderer->render($usercourses);
 
 // Render the current subscriptions list.
 $totalsubs = \tool_monitor\subscription_manager::count_user_subscriptions();
-if (!empty($totalsubs)) {
+if (!empty($totalsubs) && !$choose) {
     // Show the subscriptions section only if there are subscriptions.
     $subs = new \tool_monitor\output\managesubs\subs('toolmonitorsubs', $indexurl, $courseid);
     echo $OUTPUT->heading(get_string('currentsubscriptions', 'tool_monitor'), 3);
@@ -126,8 +138,10 @@ if (!empty($totalsubs)) {
 }
 
 // Render the potential rules list.
-echo $OUTPUT->heading(get_string('rulescansubscribe', 'tool_monitor'), 3);
-echo $renderer->render($rules);
+if (!$choose) {
+    echo $OUTPUT->heading(get_string('rulescansubscribe', 'tool_monitor'), 3);
+    echo $renderer->render($rules);
+}
 
 // Check if the user can manage the course rules we are viewing.
 $canmanagerules = has_capability('tool/monitor:managerules', $context);
index cbce856..7e91f0b 100644 (file)
@@ -79,12 +79,40 @@ function tool_monitor_extend_navigation_user_settings($navigation, $user, $userc
 
     // Don't show the setting if the event monitor isn't turned on. No access to other peoples subscriptions.
     if (get_config('tool_monitor', 'enablemonitor') && $USER->id == $user->id) {
-        $url = new moodle_url('/admin/tool/monitor/index.php');
-        $subsnode = navigation_node::create(get_string('managesubscriptions', 'tool_monitor'), $url,
-                navigation_node::TYPE_SETTING, null, 'monitor', new pix_icon('i/settings', ''));
+        // Now let's check to see if the user has any courses / site rules that they can subscribe to.
+        if ($courses = tool_monitor_get_user_courses()) {
+            $url = new moodle_url('/admin/tool/monitor/index.php');
+            $subsnode = navigation_node::create(get_string('managesubscriptions', 'tool_monitor'), $url,
+                    navigation_node::TYPE_SETTING, null, 'monitor', new pix_icon('i/settings', ''));
 
-        if (isset($subsnode) && !empty($navigation)) {
-            $navigation->add_node($subsnode);
+            if (isset($subsnode) && !empty($navigation)) {
+                $navigation->add_node($subsnode);
+            }
         }
     }
 }
+
+/**
+ * Get a list of courses and also include 'Site' for site wide rules.
+ *
+ * @return array|bool Returns an array of courses or false if the user has no permission to subscribe to rules.
+ */
+function tool_monitor_get_user_courses() {
+    $orderby = 'visible DESC, sortorder ASC';
+    $options = array();
+    if (has_capability('tool/monitor:subscribe', context_system::instance())) {
+        $options[0] = get_string('site');
+    }
+    if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname', $orderby)) {
+        foreach ($courses as $course) {
+            $options[$course->id] = format_string($course->fullname, true,
+                array('context' => context_course::instance($course->id)));
+        }
+    }
+    // If there are no courses and there is no site permission then return false.
+    if (count($options) < 1) {
+        return false;
+    } else {
+        return $options;
+    }
+}