diff --git a/repository/nextcloud/classes/issuer_management.php b/repository/nextcloud/classes/issuer_management.php index 3dc20eed7e9..8db9a2b9a2a 100644 --- a/repository/nextcloud/classes/issuer_management.php +++ b/repository/nextcloud/classes/issuer_management.php @@ -77,7 +77,7 @@ class issuer_management { * @return array parseurl [scheme => https/http, host=>'hostname', port=>443, path=>'path'] * @throws configuration_exception if an endpoint is undefined */ - public static function parse_endpoint_url(string $endpointname, \core\oauth2\issuer $issuer): array { + public static function parse_endpoint_url(string $endpointname, \core\oauth2\issuer $issuer) : array { $url = $issuer->get_endpoint_url($endpointname); if (empty($url)) { throw new configuration_exception(get_string('endpointnotdefined', 'repository_nextcloud', $endpointname)); diff --git a/repository/nextcloud/lib.php b/repository/nextcloud/lib.php index 9d543bbcdd8..d643bb2d73f 100755 --- a/repository/nextcloud/lib.php +++ b/repository/nextcloud/lib.php @@ -85,6 +85,7 @@ class repository_nextcloud extends repository { * @var ocs_client */ private $systemocsclient = null; + /** * Name of the folder for controlled links. * @var string @@ -93,6 +94,7 @@ class repository_nextcloud extends repository { /** * repository_nextcloud constructor. + * * @param int $repositoryid * @param bool|int|stdClass $context * @param array $options @@ -145,6 +147,7 @@ class repository_nextcloud extends repository { /** * Get or initialise an oauth client for the system account. + * * @return false|oauth2_client False if initialisation was unsuccessful, otherwise an initialised client. */ private function get_system_oauth_client() { @@ -160,6 +163,7 @@ class repository_nextcloud extends repository { /** * Get or initialise an ocs client for the system account. + * * @return null|ocs_client Null if initialisation was unsuccessful, otherwise an initialised client. */ private function get_system_ocs_client() { @@ -179,6 +183,7 @@ class repository_nextcloud extends repository { /** * Initiates the webdav client. + * * @throws \repository_nextcloud\configuration_exception If configuration is missing (endpoints). */ private function initiate_webdavclient() { @@ -311,31 +316,18 @@ class repository_nextcloud extends repository { } /** - * This method converts the source from the file picker (chosen by the user) into - * information, which will be received by methods that fetch files/references from - * the Nextcloud server. + * This method does not do any translation of the file source. * * @param string $source source of the file, returned by repository as 'source' and received back from user (not cleaned) * @return string file reference, ready to be stored */ public function get_file_reference($source) { - $usefilereference = optional_param('usefilereference', false, PARAM_BOOL); - - // A filereference is requested if an alias/shortcut shall be created, i.e. a FILE_REFERENCE option is selected. - // Therefore, generate and return a public link to the file. - if ($usefilereference) { - $reference = $this->get_link($source); - $filereturn = new stdClass(); - $filereturn->type = 'FILE_REFERENCE'; - $filereturn->link = $reference; - return json_encode($filereturn); - } - - // Otherwise, the simple relative path to the file is enough. + // The simple relative path to the file is enough. return $source; } - /** Called when a file is selected as a "access control link". + /** + * Called when a file is selected as a "access control link". * Invoked at MOODLE/repository/repository_ajax.php * * This is called at the point the reference files are being copied from the draft area to the real area. @@ -428,10 +420,6 @@ class repository_nextcloud extends repository { $repositoryname = $this->get_name(); $reference = json_decode($storedfile->get_reference()); - if ($reference->type == 'FILE_REFERENCE') { - redirect($reference->link); - } - // 1. assure the client and user is logged in. if (empty($this->client) || $this->get_system_oauth_client() === false || $this->get_system_ocs_client() === null) { $details = get_string('contactadminwith', 'repository_nextcloud', @@ -552,6 +540,7 @@ class repository_nextcloud extends repository { /** * Get a cached user authenticated oauth client. + * * @param bool|moodle_url $overrideurl Use this url instead of the repo callback. * @return \core\oauth2\client */ @@ -571,7 +560,6 @@ class repository_nextcloud extends repository { return $this->client; } - /** * Prints a simple Login Button which redirects to an authorization window from Nextcloud. * @@ -618,7 +606,6 @@ class repository_nextcloud extends repository { $client->is_logged_in(); } - /** * Create an instance for this plug-in * @@ -636,7 +623,6 @@ class repository_nextcloud extends repository { return parent::create($type, $userid, $context, $params, $readonly); } - /** * This method adds a select form and additional information to the settings form.. * @@ -728,34 +714,33 @@ class repository_nextcloud extends repository { /** * Method to define which file-types are supported (hardcoded can not be changed in Admin Menu) + * * By default FILE_INTERNAL is supported. In case a system account is connected and an issuer exist, * FILE_CONTROLLED_LINK is supported. + * * FILE_INTERNAL - the file is uploaded/downloaded and stored directly within the Moodle file system. * FILE_CONTROLLED_LINK - creates a copy of the file in Nextcloud from which private shares to permitted users will be * created. The file itself can not be changed any longer by the owner. + * * @return int return type bitmask supported */ public function supported_returntypes() { - // We can only support access controlled links if the system account is connected. - $setting = $this->get_option('supportedreturntypes'); - $sysisconnected = !empty($this->issuer) && $this->issuer->is_system_account_connected(); - if ($setting === 'internal') { + // We can only support references if the system account is connected. + if (!empty($this->issuer) && $this->issuer->is_system_account_connected()) { + $setting = $this->get_option('supportedreturntypes'); + if ($setting === 'internal') { + return FILE_INTERNAL; + } else if ($setting === 'external') { + return FILE_CONTROLLED_LINK; + } else { + return FILE_CONTROLLED_LINK | FILE_INTERNAL; + } + } else { return FILE_INTERNAL; } - if ($setting === 'external') { - if ($sysisconnected) { - return FILE_CONTROLLED_LINK | FILE_REFERENCE | FILE_EXTERNAL; - } - return FILE_REFERENCE | FILE_EXTERNAL; - } - // Otherwise all of them are supported (controlled link only with system account). - if ($sysisconnected) { - return FILE_CONTROLLED_LINK | FILE_INTERNAL | FILE_REFERENCE | FILE_EXTERNAL; - } - return FILE_INTERNAL | FILE_REFERENCE | FILE_EXTERNAL; - } + /** * Take the WebDAV `ls()' output and convert it into a format that Moodle's filepicker understands. * @@ -812,6 +797,7 @@ class repository_nextcloud extends repository { ksort($folders); return array_merge($folders, $files); } + /** * Print the login in a popup. * @@ -836,10 +822,12 @@ class repository_nextcloud extends repository { echo $OUTPUT->footer(); } + /** * Prepare response of get_listing; namely * - defining setting elements, * - filling in the parent path of the currently-viewed directory. + * * @param string $path Relative path * @return array ret array for use as get_listing's $ret */ @@ -876,4 +864,27 @@ class repository_nextcloud extends repository { } return $ret; } -} \ No newline at end of file + + /** + * When a controlled link is clicked in the file picker get the human readable info about this file. + * + * @param string $reference + * @param int $filestatus + * @return string + */ + public function get_reference_details($reference, $filestatus = 0) { + if ($this->disabled) { + throw new repository_exception('cannotdownload', 'repository'); + } + if (empty($reference)) { + return get_string('unknownsource', 'repository'); + } + $source = json_decode($reference); + $path = ''; + if (!empty($source->usesystem) && !empty($source->name)) { + $path = $source->name; + } + + return $path; + } +} diff --git a/repository/nextcloud/tests/lib_test.php b/repository/nextcloud/tests/lib_test.php index 1856e3e5117..c8f3ec36c74 100644 --- a/repository/nextcloud/tests/lib_test.php +++ b/repository/nextcloud/tests/lib_test.php @@ -449,8 +449,8 @@ XML; // Method get_link correctly raises an exception that contains error code and message. $this->expectException(\repository_nextcloud\request_exception::class); - $this->expectExceptionMessage(get_string('request_exception', 'repository_nextcloud', array('instance' => $this->repo->get_name(), - 'errormessage' => sprintf('(%s) %s', '404', 'Msg')))); + $params = array('instance' => $this->repo->get_name(), 'errormessage' => sprintf('(%s) %s', '404', 'Msg')); + $this->expectExceptionMessage(get_string('request_exception', 'repository_nextcloud', $params)); $this->repo->get_link($file); } @@ -491,70 +491,6 @@ JSON; $this->assertEquals('/somefile', $this->repo->get_file_reference('/somefile')); } - /** - * Test get_file reference in case the optional param is set. Therefore has to simulate the get_link method. - */ - public function test_get_file_reference_withoptionalparam() { - $_GET['usefilereference'] = true; - $filename = '/somefile'; - // Calls for get link(). Therefore, mocks for get_link are build. - $mock = $this->getMockBuilder(\repository_nextcloud\ocs_client::class)->disableOriginalConstructor()->disableOriginalClone( - )->getMock(); - $expectedresponse = << - - - ok - 100 - - - - 2 - 3 - admin - admin - 1 - 1502883721 - - - QXbqrJj8DcMaXen - admin - admin - /somefile - file - application/pdf - home::admin - 1 - 6 - 6 - 4 - /somefile - - - - https://www.default.test/somefile - 0 - - -XML; - // Expected Parameters. - $ocsquery = ['path' => $filename, - 'shareType' => \repository_nextcloud\ocs_client::SHARE_TYPE_PUBLIC, - 'publicUpload' => false, - 'permissions' => \repository_nextcloud\ocs_client::SHARE_PERMISSION_READ, - ]; - - // With test whether mock is called with right parameters. - $mock->expects($this->once())->method('call')->with('create_share', $ocsquery)->will($this->returnValue($expectedresponse)); - $this->set_private_property($mock, 'ocsclient'); - - $expected = new \stdClass(); - $expected->type = 'FILE_REFERENCE'; - $expected->link = 'https://www.default.test' . $filename . '/download'; - // Method redirects to get_link() and return the suitable value. - $this->assertEquals(json_encode($expected), $this->repo->get_file_reference($filename)); - } - /** * Test logout. */ @@ -688,11 +624,11 @@ XML; /** * Test supported_returntypes. * FILE_INTERNAL when no system account is connected. - * FILE_INTERNAL | FILE_CONTROLLED_LINK | FILE_EXTERNAL | FILE_REFERENCE when a system account is connected. + * FILE_INTERNAL | FILE_CONTROLLED_LINK when a system account is connected. */ public function test_supported_returntypes() { global $DB; - $this->assertEquals(FILE_INTERNAL | FILE_EXTERNAL | FILE_REFERENCE, $this->repo->supported_returntypes()); + $this->assertEquals(FILE_INTERNAL, $this->repo->supported_returntypes()); $dataobject = new stdClass(); $dataobject->timecreated = time(); $dataobject->timemodified = time(); @@ -705,7 +641,7 @@ XML; $DB->insert_record('oauth2_system_account', $dataobject); // When a system account is registered the file_type FILE_CONTROLLED_LINK is supported. - $this->assertEquals(FILE_INTERNAL | FILE_EXTERNAL | FILE_CONTROLLED_LINK | FILE_REFERENCE, + $this->assertEquals(FILE_INTERNAL | FILE_CONTROLLED_LINK, $this->repo->supported_returntypes()); }