MDL-37852 repository: Prevent undesired access to repositories settings
authorFrederic Massart <fred@moodle.com>
Wed, 27 Feb 2013 00:43:17 +0000 (08:43 +0800)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 5 Mar 2013 08:56:22 +0000 (09:56 +0100)
repository/lib.php
repository/manage_instances.php
repository/upgrade.txt

index 0a2bf47..69d7db8 100644 (file)
@@ -1498,12 +1498,12 @@ abstract class repository {
         $pluginstr = get_string('plugin', 'repository');
         $settingsstr = get_string('settings');
         $deletestr = get_string('delete');
-        //retrieve list of instances. In administration context we want to display all
-        //instances of a type, even if this type is not visible. In course/user context we
-        //want to display only visible instances, but for every type types. The repository::get_instances()
-        //third parameter displays only visible type.
+        // Retrieve list of instances. In administration context we want to display all
+        // instances of a type, even if this type is not visible. In course/user context we
+        // want to display only visible instances, but for every type types. The repository::get_instances()
+        // third parameter displays only visible type.
         $params = array();
-        $params['context'] = array($context, get_system_context());
+        $params['context'] = array($context);
         $params['currentcontext'] = $context;
         $params['onlyvisible'] = !$admin;
         $params['type']        = $typename;
@@ -1805,6 +1805,41 @@ abstract class repository {
         return false;
     }
 
+    /**
+     * Can the instance be edited by the current user?
+     *
+     * The property $readonly must not be used within this method because
+     * it only controls if the options from self::get_instance_option_names()
+     * can be edited.
+     *
+     * @return bool true if the user can edit the instance.
+     * @since 2.5
+     */
+    public final function can_be_edited_by_user() {
+        global $USER;
+
+        // We need to be able to explore the repository.
+        try {
+            $this->check_capability();
+        } catch (repository_exception $e) {
+            return false;
+        }
+
+        $repocontext = context::instance_by_id($this->instance->contextid);
+        if ($repocontext->contextlevel == CONTEXT_USER && $repocontext->instanceid != $USER->id) {
+            // If the context of this instance is a user context, we need to be this user.
+            return false;
+        } else if ($repocontext->contextlevel == CONTEXT_MODULE && !has_capability('moodle/course:update', $repocontext)) {
+            // We need to have permissions on the course to edit the instance.
+            return false;
+        } else if ($repocontext->contextlevel == CONTEXT_SYSTEM && !has_capability('moodle/site:config', $repocontext)) {
+            // Do not meet the requirements for the context system.
+            return false;
+        }
+
+        return true;
+    }
+
     /**
      * Return the name of this instance, can be overridden.
      *
index 7c719d9..52dd718 100644 (file)
@@ -146,9 +146,12 @@ $return = true;
 if (!empty($edit) || !empty($new)) {
     if (!empty($edit)) {
         $instance = repository::get_instance($edit);
+
         //if you try to edit an instance set as readonly, display an error message
         if ($instance->readonly) {
             throw new repository_exception('readonlyinstance', 'repository');
+        } else if (!$instance->can_be_edited_by_user()) {
+            throw new repository_exception('nopermissiontoaccess', 'repository');
         }
         $instancetype = repository::get_type_by_id($instance->options['typeid']);
         $classname = 'repository_' . $instancetype->get_typename();
index 4728b1f..dee842e 100644 (file)
@@ -13,6 +13,9 @@ http://docs.moodle.org/dev/Repository_API
 
 * get_typename() returns the type of repository: dropbox, googledocs, etc...
 
+* can_be_edited_by_user() encapsulates all the tests to make sure that the current user
+  has the rights to edit the instance of this repository.
+
 === 2.4 ===
 
 * copy_to_area() can receive a new parameter called $areamaxbytes which controls the maximum