Пример #1
0
    /**
     * 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;
        }
    }
Пример #2
0
    /**
    * 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;
    }