MDL-35556 completion: Improve user completion data permission checking
authorAaron Barnes <aaronb@catalyst.net.nz>
Fri, 21 Sep 2012 01:37:54 +0000 (13:37 +1200)
committerAaron Barnes <aaronb@catalyst.net.nz>
Mon, 5 Nov 2012 06:03:18 +0000 (19:03 +1300)
blocks/completionstatus/details.php
lib/completionlib.php
report/completion/index.php

index bb1b051..3878964 100644 (file)
@@ -46,25 +46,9 @@ if ($userid) {
 
 
 // Check permissions
-require_login($course);
-
-$coursecontext   = context_course::instance($course->id);
-$personalcontext = context_user::instance($user->id);
-
-$can_view = false;
-
-// Can view own report
-if ($USER->id == $user->id) {
-    $can_view = true;
-} else if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)) {
-    $can_view = true;
-} else if (has_capability('report/completion:view', $coursecontext)) {
-    $can_view = true;
-} else if (has_capability('report/completion:view', $personalcontext)) {
-    $can_view = true;
-}
+require_login();
 
-if (!$can_view) {
+if (!completion_can_view_data($user->id, $course)) {
     print_error('cannotviewreport');
 }
 
index 05d24d4..fc841d0 100644 (file)
@@ -146,6 +146,73 @@ define('COMPLETION_AGGREGATION_ALL', 1);
 define('COMPLETION_AGGREGATION_ANY', 2);
 
 
+/**
+ * Utility function for checking if the logged in user can view
+ * another's completion data for a particular course
+ *
+ * @access  public
+ * @param   int         $userid     Completion data's owner
+ * @param   mixed       $course     Course object or Course ID (optional)
+ * @return  boolean
+ */
+function completion_can_view_data($userid, $course = null) {
+    global $USER;
+
+    if (!isloggedin()) {
+        return false;
+    }
+
+    if (!is_object($course)) {
+        $cid = $course;
+        $course = new object();
+        $course->id = $cid;
+    }
+
+    // Check if this is the site course
+    if ($course->id == SITEID) {
+        $course = null;
+    }
+
+    // Check if completion is enabled
+    if ($course) {
+        $cinfo = new completion_info($course);
+        if (!$cinfo->is_enabled()) {
+            return false;
+        }
+    } else {
+        if (!completion_info::is_enabled_for_site()) {
+            return false;
+        }
+    }
+
+    // Is own user's data?
+    if ($USER->id == $userid) {
+        return true;
+    }
+
+    // Check capabilities
+    $personalcontext = context_user::instance($userid);
+
+    if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)) {
+        return true;
+    } elseif (has_capability('report/completion:view', $personalcontext)) {
+        return true;
+    }
+
+    if ($courseid) {
+        $coursecontext = context_course::instance($course->id);
+    } else {
+        $coursecontext = context_system::instance();
+    }
+
+    if (has_capability('report/completion:view', $coursecontext)) {
+        return true;
+    }
+
+    return false;
+}
+
+
 /**
  * Class represents completion information for a course.
  *
index a09a3dc..217383d 100644 (file)
@@ -561,7 +561,12 @@ foreach ($progress as $user) {
     } else {
         print PHP_EOL.'<tr id="user-'.$user->id.'">';
 
-        $userurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
+        if (completion_can_view_data($user->id, $course)) {
+            $userurl = new moodle_url('/blocks/completionstatus/details.php', array('course' => $course->id, 'user' => $user->id));
+        } else {
+            $userurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
+        }
+
         print '<th scope="row"><a href="'.$userurl->out().'">'.fullname($user).'</a></th>';
         foreach ($extrafields as $field) {
             echo '<td>'.s($user->{$field}).'</td>';