From 47da79bae9289103d02f2a3ff3e69f34d6f8888f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Dagef=C3=B6rde?= Date: Fri, 1 Mar 2019 18:21:42 +0100 Subject: [PATCH] MDL-64243 nextcloud: Add support for offline download for Moodle Mobile --- .../access_controlled_link_manager.php | 21 ++++++++++++++++++ repository/nextcloud/lib.php | 22 +++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/repository/nextcloud/classes/access_controlled_link_manager.php b/repository/nextcloud/classes/access_controlled_link_manager.php index f80f1ccc4d8..f9abc6f722b 100644 --- a/repository/nextcloud/classes/access_controlled_link_manager.php +++ b/repository/nextcloud/classes/access_controlled_link_manager.php @@ -26,6 +26,7 @@ namespace repository_nextcloud; use context; use \core\oauth2\api; use \core\notification; +use repository_exception; defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir . '/webdavlib.php'); @@ -453,4 +454,24 @@ class access_controlled_link_manager{ 'filetarget' => (string) $validfile->file_target ]; } + + /** + * Download a file from the system account for the purpose of offline usage. + * @param string $srcpath Name of a file owned by the system account + * @param string $targetpath Temporary filename in Moodle + * @throws repository_exception The download was unsuccessful, maybe the file does not exist. + */ + public function download_for_offline_usage(string $srcpath, string $targetpath): void { + $this->systemwebdavclient->open(); + $webdavendpoint = issuer_management::parse_endpoint_url('webdav', $this->issuer); + $srcpath = ltrim($srcpath, '/'); + $sourcepath = $webdavendpoint['path'] . $srcpath; + + // Write file into temp location. + if (!$this->systemwebdavclient->get_file($sourcepath, $targetpath)) { + $this->systemwebdavclient->close(); + throw new repository_exception('cannotdownload', 'repository'); + } + $this->systemwebdavclient->close(); + } } diff --git a/repository/nextcloud/lib.php b/repository/nextcloud/lib.php index faae5fc5dab..e2ad61f27c7 100644 --- a/repository/nextcloud/lib.php +++ b/repository/nextcloud/lib.php @@ -427,11 +427,25 @@ class repository_nextcloud extends repository { throw new \repository_nextcloud\request_exception(array('instance' => $repositoryname, 'errormessage' => $details)); } + // Download for offline usage. This is strictly read-only, so the file need not be shared. + if (!empty($options['offline'])) { + // Download from system account and provide the file to the user. + $linkmanager = new \repository_nextcloud\access_controlled_link_manager($this->ocsclient, + $this->get_system_oauth_client(), $this->get_system_ocs_client(), $this->issuer, $repositoryname); + + // Create temp path, then download into it. + $filename = basename($reference->link); + $tmppath = make_request_directory() . '/' . $filename; + $linkmanager->download_for_offline_usage($reference->link, $tmppath); + + // Output the obtained file to the user and remove it from disk. + send_temp_file($tmppath, $filename); + + // That's all. + return; + } + if (!$this->client->is_logged_in()) { - if (!empty($options['offline'])) { - // Right now, we can't download referenced files for offline if the client is not authenticated. - send_file_not_found(); // Use this function because it enforces a 404 error. - } $this->print_login_popup(['style' => 'margin-top: 250px'], $options['embed']); return; }