mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-36426 repository: Prevent login_as() users to access private repositories
This commit is contained in:
parent
4ce761716c
commit
31581ae65d
@ -158,7 +158,7 @@ $string['nofilesattached'] = 'No files attached';
|
||||
$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.';
|
||||
|
@ -216,4 +216,13 @@ class repository_coursefiles extends repository {
|
||||
// this should be realtime
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -437,4 +437,13 @@ class repository_equella extends repository {
|
||||
return get_string('lostsource', 'repository', '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -333,4 +333,13 @@ class repository_filesystem extends repository {
|
||||
send_file_not_found();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -550,4 +550,13 @@ class repository_flickr_public extends repository {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -487,6 +487,9 @@ abstract class repository {
|
||||
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
|
||||
*
|
||||
@ -558,6 +561,24 @@ abstract class repository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -620,19 +641,43 @@ abstract class repository {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,13 +1812,36 @@ abstract class repository {
|
||||
*/
|
||||
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?
|
||||
*
|
||||
@ -1806,7 +1874,7 @@ abstract class repository {
|
||||
$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();
|
||||
|
@ -262,4 +262,13 @@ class repository_local extends repository {
|
||||
'name' => $fileinfo->get_visible_name()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -161,5 +161,14 @@ class repository_merlot extends repository {
|
||||
public function supported_filetypes() {
|
||||
return array('link');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,4 +203,13 @@ class repository_recent extends repository {
|
||||
public function has_moodle_files() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -249,4 +249,13 @@ class repository_s3 extends repository {
|
||||
public function supported_returntypes() {
|
||||
return FILE_INTERNAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -288,4 +288,13 @@ class repository_upload extends repository {
|
||||
public function supported_returntypes() {
|
||||
return FILE_INTERNAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -237,4 +237,13 @@ EOD;
|
||||
public function supported_filetypes() {
|
||||
return array('web_image');
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -169,4 +169,13 @@ class repository_user extends repository {
|
||||
// this should be realtime
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -185,4 +185,14 @@ class repository_webdav extends repository {
|
||||
public function supported_returntypes() {
|
||||
return (FILE_INTERNAL | FILE_EXTERNAL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -189,4 +189,13 @@ EOD;
|
||||
public function get_file_source_info($url) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -202,4 +202,13 @@ class repository_youtube extends repository {
|
||||
public function supported_returntypes() {
|
||||
return FILE_EXTERNAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this repository accessing private data?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function contains_private_data() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user