Permalink
Browse files

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

  • Loading branch information...
1 parent c3a1ea1 commit ded4050f1bb050770df3bc8e78dcfadf815011ea @FMCorz FMCorz committed with stronk7 Feb 4, 2013
Showing with 44 additions and 9 deletions.
  1. +1 −1 lang/en/repository.php
  2. +43 −8 repository/lib.php
View
@@ -154,7 +154,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
@@ -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, ...). */
+ public $type;
+
/**
* Constructor
*
@@ -519,6 +522,16 @@ public function __construct($repositoryid, $context = SYSCONTEXTID, $options = a
$this->name = $this->get_name();
$this->returntypes = $this->supported_returntypes();
$this->super_called = true;
+
+ // Determining the type of repository if not set.
+ if (empty($this->type)) {
+ $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->type = $matches[1];
+ }
}
/**
@@ -620,19 +633,41 @@ 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->type.':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 (session_is_loggedinas()) {
+ $can = false;
+ }
+
+ // Ensure that the user can view the repository in the context of the repository.
+ // Ne 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->type.':view', $repocontext);
+ }
}
- if (!$capability) {
- throw new repository_exception('nopermissiontoaccess', 'repository');
+
+ if ($can) {
+ return true;
}
+
+ throw new repository_exception('nopermissiontoaccess', 'repository');
}
/**

0 comments on commit ded4050

Please sign in to comment.