/** * Test times for get_parent using recursive get_parent alfresco calls * @uses $CFG, $DB */ public function test_get_parent_path_tree() { global $CFG, $DB; $this->resetAfterTest(true); $this->setup_test_data_xml(); $options = array( 'ajax' => false, 'name' => 'elis files phpunit test', 'type' => 'elisfiles' ); $repo = new repository_elisfiles('elisfiles', context_system::instance(), $options); // Make sure we connected to the repository successfully. if (empty($repo->elis_files)) { $this->markTestSkipped('Repository not configured or enabled'); } // set up the storage for the full path of the path's UUIDs to validate against $expectedpath = array(); // create folder, get uuid, get path via get_parent_path and elis_files_folder structure // for first folder, create under moodle, then create under the previous folder... $parentfolderuuid = $repo->elis_files->get_root()->uuid; $times = array(); for ($i = 1; $i <= 20; $i++) { $currentfolder = FOLDER_NAME_PREFIX.$i; $currentfolderuuid = $repo->elis_files->create_dir($currentfolder, $parentfolderuuid, '', true); // add the parent folder to our expected sequence of UUIDs $expectedpath[] = repository_elisfiles::build_encodedpath($parentfolderuuid); // elis_files_folder_structure get_parent_path test $starttime = microtime(); $folders = elis_files_folder_structure(); $altrecursivepath = array(); $repo->get_parent_path($currentfolderuuid, $altrecursivepath, 0, 0, 0, 0, 'tree'); $endtime = time(); $structuretime = microtime_diff($starttime, microtime()); // validate the count $this->assertEquals($i, count($altrecursivepath)); // validate the encoded folder UUIDs // look over the expected path parts foreach ($expectedpath as $pathindex => $expectedpart) { // obtain the matching part from the actual return value $resultpart = $altrecursivepath[$pathindex]; $this->assertEquals($expectedpart, $resultpart['path']); } // NOTE: add this back in if we are testing performance $times[] = $times[] = "Folder: $currentfolder and time: $structuretime"; // or nested folders $parentfolderuuid = $currentfolderuuid; } }
/** * 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; }