Skip to content
Browse files

MDL-36426 repository: Prevent login_as() users to access private repo…

…sitories
  • Loading branch information...
1 parent 4ce7617 commit 31581ae65df05ea64031ac24c8b8f817414f1379 @FMCorz FMCorz committed with stronk7 Feb 4, 2013
View
2 lang/en/repository.php
@@ -158,7 +158,7 @@
$string['nofilesavailable'] = 'No files available';
$string['nomorefiles'] = 'No more attachments allowed';
$string['nopathselected'] = 'No destination path select yet (double click tree node to select)';
-$string['nopermissiontoaccess'] = 'No permission to access this repository';
+$string['nopermissiontoaccess'] = 'No permission to access this repository.';
$string['noresult'] = 'No search result';
$string['norepositoriesavailable'] = 'Sorry, none of your current repositories can return files in the required format.';
$string['norepositoriesexternalavailable'] = 'Sorry, none of your current repositories can return external files.';
View
9 repository/coursefiles/lib.php
@@ -216,4 +216,13 @@ public function get_reference_file_lifetime($ref) {
// this should be realtime
return 0;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/equella/lib.php
@@ -437,4 +437,13 @@ public function get_reference_details($reference, $filestatus = 0) {
return get_string('lostsource', 'repository', '');
}
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/filesystem/lib.php
@@ -333,4 +333,13 @@ public function send_file($storedfile, $lifetime=86400 , $filter=0, $forcedownlo
send_file_not_found();
}
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/flickr_public/lib.php
@@ -550,4 +550,13 @@ public function supported_returntypes() {
public function get_file_source_info($photoid) {
return $this->build_photo_url($photoid);
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
90 repository/lib.php
@@ -487,6 +487,9 @@ public function delete($downloadcontents = false) {
public $returntypes;
/** @var stdClass repository instance database record */
public $instance;
+ /** @var string Type of repository (webdav, google_docs, dropbox, ...). Read from $this->get_typename(). */
+ protected $typename;
+
/**
* Constructor
*
@@ -559,6 +562,24 @@ public static function get_repository_by_id($repositoryid, $context, $options =
}
/**
+ * Returns the type name of the repository.
+ *
+ * @return string type name of the repository.
+ * @since 2.5
+ */
+ public function get_typename() {
+ if (empty($this->typename)) {
+ $matches = array();
+ if (!preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
+ throw new coding_exception('The class name of a repository should be repository_<typeofrepository>, '.
+ 'e.g. repository_dropbox');
+ }
+ $this->typename = $matches[1];
+ }
+ return $this->typename;
+ }
+
+ /**
* Get a repository type object by a given type name.
*
* @static
@@ -620,19 +641,43 @@ public static function get_types($visible=null) {
}
/**
- * Checks if user has a capability to view the current repository in current context
+ * Checks if user has a capability to view the current repository.
*
- * @return bool
+ * @return bool true when the user can, otherwise throws an exception.
+ * @throws repository_exception when the user does not meet the requirements.
*/
public final function check_capability() {
- $capability = false;
- if (preg_match("/^repository_(.*)$/", get_class($this), $matches)) {
- $type = $matches[1];
- $capability = has_capability('repository/'.$type.':view', $this->context);
+ global $USER;
+
+ // Ensure that the user can view the repository in the current context.
+ $can = has_capability('repository/'.$this->get_typename().':view', $this->context);
+
+ // Context in which the repository has been created.
+ $repocontext = context::instance_by_id($this->instance->contextid);
+
+ // Prevent access to private repositories when logged in as.
+ if ($can && session_is_loggedinas()) {
+ if ($this->contains_private_data() || $repocontext->contextlevel == CONTEXT_USER) {
+ $can = false;
+ }
}
- if (!$capability) {
- throw new repository_exception('nopermissiontoaccess', 'repository');
+
+ // Ensure that the user can view the repository in the context of the repository.
+ // We need to perform the check when already disallowed.
+ if ($can) {
+ if ($repocontext->contextlevel == CONTEXT_USER && $repocontext->instanceid != $USER->id) {
+ // Prevent URL hijack to access someone else's repository.
+ $can = false;
+ } else {
+ $can = has_capability('repository/'.$this->get_typename().':view', $repocontext);
+ }
+ }
+
+ if ($can) {
+ return true;
}
+
+ throw new repository_exception('nopermissiontoaccess', 'repository');
}
/**
@@ -1767,14 +1812,37 @@ public function is_visible() {
*/
public function get_name() {
global $DB;
- if ( $name = $this->instance->name ) {
+ if ($name = $this->instance->name) {
return $name;
} else {
- return get_string('pluginname', 'repository_' . $this->options['type']);
+ return get_string('pluginname', 'repository_' . $this->get_typename());
}
}
/**
+ * Is this repository accessing private data?
+ *
+ * This function should return true for the repositories which access external private
+ * data from a user. This is the case for repositories such as Dropbox, Google Docs or Box.net
+ * which authenticate the user and then store the auth token.
+ *
+ * Of course, many repositories store 'private data', but we only want to set
+ * contains_private_data() to repositories which are external to Moodle and shouldn't be accessed
+ * to by the users having the capability to 'login as' someone else. For instance, the repository
+ * 'Private files' is not considered as private because it's part of Moodle.
+ *
+ * You should not set contains_private_data() to true on repositories which allow different types
+ * of instances as the levels other than 'user' are, by definition, not private. Also
+ * the user instances will be protected when they need to.
+ *
+ * @return boolean True when the repository accesses private external data.
+ * @since 2.5
+ */
+ public function contains_private_data() {
+ return true;
+ }
+
+ /**
* What kind of files will be in this repository?
*
* @return array return '*' means this repository support any files, otherwise
@@ -1806,7 +1874,7 @@ public function supported_returntypes() {
$meta = new stdClass();
$meta->id = $this->id;
$meta->name = format_string($this->get_name());
- $meta->type = $this->options['type'];
+ $meta->type = $this->get_typename();
$meta->icon = $OUTPUT->pix_url('icon', 'repository_'.$meta->type)->out(false);
$meta->supported_types = file_get_typegroup('extension', $this->supported_filetypes());
$meta->return_types = $this->supported_returntypes();
View
9 repository/local/lib.php
@@ -262,4 +262,13 @@ private function get_node_path(file_info $fileinfo) {
'name' => $fileinfo->get_visible_name()
);
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/merlot/lib.php
@@ -161,5 +161,14 @@ public function supported_returntypes() {
public function supported_filetypes() {
return array('link');
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/recent/lib.php
@@ -203,4 +203,13 @@ public function file_is_accessible($source) {
public function has_moodle_files() {
return true;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/s3/lib.php
@@ -249,4 +249,13 @@ public static function type_config_form($mform, $classname = 'repository') {
public function supported_returntypes() {
return FILE_INTERNAL;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
5 repository/upgrade.txt
@@ -8,6 +8,11 @@ http://docs.moodle.org/dev/Repository_API
* repository::append_suffix() has been deprecated, use repository::get_unused_filename() if you need
to get a file name which has not yet been used in the draft area.
+* contains_private_data() is a new method to determine if a user 'logged in as' another user
+ can access the content of the repository. The default is to return True (no access).
+
+* get_typename() returns the type of repository: dropbox, googledocs, etc...
+
=== 2.4 ===
* copy_to_area() can receive a new parameter called $areamaxbytes which controls the maximum
View
9 repository/upload/lib.php
@@ -288,4 +288,13 @@ public function get_listing($path = '', $page = '') {
public function supported_returntypes() {
return FILE_INTERNAL;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/url/lib.php
@@ -237,4 +237,13 @@ public function get_file_source_info($url) {
public function supported_filetypes() {
return array('web_image');
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/user/lib.php
@@ -169,4 +169,13 @@ public function get_reference_file_lifetime($ref) {
// this should be realtime
return 0;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
10 repository/webdav/lib.php
@@ -185,4 +185,14 @@ public static function instance_config_form($mform) {
public function supported_returntypes() {
return (FILE_INTERNAL | FILE_EXTERNAL);
}
+
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/wikimedia/lib.php
@@ -189,4 +189,13 @@ public function supported_returntypes() {
public function get_file_source_info($url) {
return $url;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}
View
9 repository/youtube/lib.php
@@ -202,4 +202,13 @@ public function supported_filetypes() {
public function supported_returntypes() {
return FILE_EXTERNAL;
}
+
+ /**
+ * Is this repository accessing private data?
+ *
+ * @return bool
+ */
+ public function contains_private_data() {
+ return false;
+ }
}

0 comments on commit 31581ae

Please sign in to comment.
Something went wrong with that request. Please try again.