/** * Validate that the given user name is converted to the provided user id. * @dataProvider folder_to_userid_provider * @param string $foldername The name of the ELIS Files folder * @param mixed $expecteduserid The userid the method should return (or false if no valid user exists) * @param string $adminusername The config value to use for the admin username setting */ public function test_method_returns_correct_userid($foldername, $expecteduserid, $adminusername) { $this->resetAfterTest(true); $this->setup_test_data_xml(); // Set up the configured admin username set_config('admin_username', $adminusername, 'elisfiles'); set_config('mnethostid', 1); elis::$config = new elis_config(); // Validate method output $userid = elis_files_folder_to_userid($foldername); $this->assertEquals($expecteduserid, $userid); }
/** * Prepares folder tree structure for JSON encoding to FileManager * * @param array &$output The output array * @param array $folderentry The input folder structure * @param string $path Top-level path folder name (i.e. 'Company Home' or 'ELIS Files') * @param int $puid Optional parent folder's uuid * @param int $uid Optional user id setting * @param int $cid Optional course id setting * @param int $oid Optional userset/cluster id setting * @param bool $shared Optional shared flag setting * @uses $DB */ protected function folder_tree_to_fm(&$output, $folderentry, $path = '', $puuid = '', $uid = 0, $cid = 0, $oid = 0, $shared = false) { global $DB; foreach ($folderentry as $folder) { $_uid = $uid; $_cid = $cid; $_oid = $oid; $_shared = $shared; if (!empty($puuid) && !$uid && !$cid && !$oid && !$shared) { // No flags set check if we need to set them if ($puuid == $this->elis_files->cuuid) { $_cid = $DB->get_field('repository_elisfiles_course', 'courseid', array('uuid' => $folder['uuid'])); } else if ($puuid == $this->elis_files->ouuid) { $_oid = $DB->get_field('repository_elisfiles_userset', 'usersetid', array('uuid' => $folder['uuid'])); } else if ($puuid == $this->elis_files->suuid) { $_shared = true; } else if ($folder['uuid'] == $this->elis_files->uuuid) { $_uid = elis_files_folder_to_userid($folder['name']); } } $entry = array(); $entry['filepath'] = repository_elisfiles::build_encodedpath($folder['uuid'], $_uid, $_cid, $_oid, $_shared); $entry['textpath'] = $path .'/'. $folder['name']; $entry['fullname'] = $folder['name']; $entry['id'] = $folder['uuid']; // TBD $entry['sortorder'] = 0; // TBD $entry['children'] = array(); if (!empty($folder['children'])) { $this->folder_tree_to_fm($entry['children'], $folder['children'], $entry['textpath'], $folder['uuid'], $_uid, $_cid, $_oid, $_shared); } $output[] = $entry; } }
/** * Check for valid permissions given the storage context for a file, also taking * into account the location where the file was included within Moodle. * * @uses $CFG * @uses $USER * @param string $uuid Unique identifier for a node. * @param int $uid The user ID (optional). * @param bool $useurl Check the referring URL for Moodle-based permissions (default: true). * @param object $repo ELIS Files repo object to use (only for unit testing) * @return bool True if the user has permission to access the file, False otherwise. */ function permission_check($uuid, $uid = 0, $useurl = true, $repo = NULL) { global $CFG, $DB, $USER; require_once($CFG->dirroot .'/repository/elisfiles/lib.php'); // error_log("/repository/elisfiles/lib/lib.php::permission_check({$uuid}, {$uid}, {$useurl})"); if (ELIS_FILES_DEBUG_TRACE) mtrace('permission_check(' . $uuid . ', ' . $uid . ', ' . ($useurl === true ? 'true' : 'false') . ')'); if ($repo === NULL) { $repo = new repository_elisfiles('elisfiles', context_system::instance(), array('ajax' => false, 'type' => 'elisfiles')); } $repo->get_parent_path($uuid, $result, 0, 0, 0, 0); if (!empty($this->config->root_folder)) { $moodleroot = $this->config->root_folder; } else { $moodleroot = '/moodle'; } // get the flags for uid, cid, oid and shared $uid = 0; $cid = 0; $oid = 0; $shared = false; $parent_node = $this->get_parent($uuid); $prev_node = $this->get_info($uuid); do { $check_uuid = !empty($parent_node->uuid) ? $parent_node->uuid : 0; $folder_name = !empty($prev_node->title) ? $prev_node->title : ''; if ($check_uuid == $this->cuuid) { $cid = $DB->get_field('repository_elisfiles_course', 'courseid', array('uuid' => $prev_node->uuid)); } else if ($check_uuid == $this->ouuid) { $oid = $DB->get_field('repository_elisfiles_userset', 'usersetid', array('uuid' => $prev_node->uuid)); } else if ($check_uuid == $this->suuid) { $shared = true; } else if (!empty($prev_node->uuid) && $prev_node->uuid == $this->uuuid) { $uid = elis_files_folder_to_userid($folder_name); } $prev_node = $parent_node; } while (!$uid && !$cid && !$oid && !$shared && ($parent_node = $this->get_parent($check_uuid)) && !empty($parent_node->uuid)); if (!empty($cid)) { $cid = $DB->get_field('course', 'id', array('id' => $cid), IGNORE_MULTIPLE); // This is a server file. if ($cid == SITEID) { $context = context_system::instance(); } // This is a course file. if (!empty($cid)) { $context = context_course::instance($cid); } } // This is a shared file. if ($shared) { $context = context_system::instance(); } // This is a user file. if (!empty($uid)) { $info = $this->get_info($this->uuuid); if (isset($info->title)) { $username = str_replace('_AT_', '@', $info->title); //error_log("preg_match('/\/User\sHomes\/([-_a-zA-Z0-9\s]+)\//', {$path}, = {$tmp}) => username = {$username}"); $context = context_system::instance(); } } /// This is a userset file. if (!empty($oid)) { $cluster_context = \local_elisprogram\context\userset::instance($oid); } /// Default to the root of the Alfresco repository (requires system-level repository access). if (!isset($context)) { $context = context_system::instance(); } /// Attempt to determine where the file open request came from to determine if the current user /// has permission to access that file in Moodle (this overrides the current user's Alfresco /// permissions. $referer = $this->get_referer(); if ($useurl && !empty($referer)) { $fromplugin = strpos($referer, $CFG->wwwroot.'/pluginfile.php') !== false; $frommodule = strpos($referer, $CFG->wwwroot . '/mod/') !== false; $fromblock = strpos($referer, $CFG->wwwroot . '/blocks/') !== false; $frommodedit = strpos($referer, '/course/modedit.php') !== false; $fromeditor = strpos($referer, '/lib/editor/htmlarea/blank.html') !== false; $fromcourse = strpos($referer, '/course/view.php') !== false; $fromsite = ($referer == $CFG->wwwroot . '/' || $referer == $CFG->wwwroot || $referer == $CFG->wwwroot . '/index.php'); // error_log("ELIS_files::permissions_check(): fromplugin={$fromplugin}, frommodule={$frommodule}, fromblock={$fromblock}" // .", frommodedit={$frommodedit}, fromeditor={$fromeditor}, fromcourse={$fromcourse}, fromsite={$fromsite}"); /// If this access is coming from something inside of the mod or blocks directory, then allow access. if ($frommodule || $fromblock || $fromeditor) { return true; } if (!empty($referer) && ($frommodedit || $fromcourse || $fromsite || $fromplugin)) { if ($fromsite) { return true; } else if ($frommodedit) { /// Look for the CM ID from editing a module. preg_match('/.+?update=([0-9]+)/', $referer, $matches); if (count($matches) == 2) { $sql = "SELECT cm.*, m.name as modname FROM {$CFG->prefix}course_modules cm INNER JOIN {$CFG->prefix}modules m ON m.id = cm.module WHERE cm.id = " . $matches[1]; if ($cm = $DB->get_record_sql($sql)) { require_login($cm->course, false, $cm, false); } } } else if ($fromcourse) { /// Look for the course ID. preg_match('/.+?id=([0-9]+)/', $referer, $matches); if (count($matches) == 2) { require_login($matches[1], false, false, false); } } else if ($fromplugin) { // Look for module contextid preg_match('/pluginfile.php\/([0-9]+)\/mod/', $referer, $matches); if (count($matches) != 2 && !$CFG->slasharguments) { // Look for 'file' url parameter in referer preg_match('/file=\/([0-9]+)\/mod/', $referer, $matches); } if (count($matches) == 2 && ($instanceid = $DB->get_field('context', 'instanceid', array('id' => $matches[1]))) !== false && ($cm = $DB->get_record('course_modules', array('id' => $instanceid)))) { // error_log("ELIS_files::permissions_check(): pluginfile instanceid = {$instanceid}"); require_login($cm->course, false, $cm, false); } } } /// This file didn't come from somewhere within Moodle that we know about so access has /// to be determined based on the Alfresco capabilities the current user has. } else { // Get the non context based permissions $capabilities = array( 'repository/elisfiles:viewowncontent' => false, 'repository/elisfiles:createowncontent' => false, 'repository/elisfiles:viewsharedcontent' => false, 'repository/elisfiles:createsharedcontent' => false ); $this->get_other_capabilities($USER, $capabilities); // Determine if the user has "site files" permissions $syscontext = context_system::instance(); $allowsitefiles = has_capability('repository/elisfiles:viewsitecontent', $syscontext) || has_capability('repository/elisfiles:createsitecontent', $syscontext); if ($uid) { /// If the current user is not the user who owns this file and we can't access anything in the /// repository, don't allow access. if ($USER->username != $username && !has_capability('repository/elisfiles:viewsitecontent', $context)) { return false; } /// This repository location is not tied to a specific Moodle context, so we need to look for the /// specific capability anywhere within the user's role assignments. $hascap = $allowsitefiles || $capabilities['repository/elisfiles:viewowncontent'] || $capabilities['repository/elisfiles:createowncontent']; if (!$hascap) { return false; } } else if ($cid) { /// This file belongs to a course, make sure the current user can access that course's repository /// content. $hascap = $allowsitefiles || has_capability('repository/elisfiles:viewcoursecontent', $context) || has_capability('repository/elisfiles:createcoursecontent', $context); if (!$hascap) { return false; } } else if ($oid) { /// This file belongs to a course, make sure the current user can access that course's repository /// content. $hascap = $allowsitefiles || has_capability('repository/elisfiles:viewusersetcontent', $cluster_context) || has_capability('repository/elisfiles:createusersetcontent', $cluster_context); if (!$hascap) { return false; } } else if ($shared) { /// This repository location is not tied to a specific Moodle context, so we need to look for the /// specific capability anywhere within the user's role assignments. $hascap = $allowsitefiles || $capabilities['repository/elisfiles:viewsharedcontent'] || $capabilities['repository/elisfiles:createsharedcontent']; if (!$hascap) { return false; } } else { /// This file is not part of a standard Moodle storage area thus requiring full repository access. if (!$allowsitefiles) { return false; } } } return true; }