From 520707ef714f5a03d3973e102175fe1db62da9d5 Mon Sep 17 00:00:00 2001 From: Huong Nguyen Date: Fri, 25 Oct 2024 11:15:37 +0700 Subject: [PATCH] MDL-83341 repository_onedrive: Fix download and create controlled link Onedrive direct download URL does not accept authorization headers, it will just return the `unauthenticated` content with 401 HTTP Code We switched to a safer way. We fetch the item information and use a new curl instance (without authorization headers) to fetch the content via direct download URL --- repository/onedrive/lib.php | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/repository/onedrive/lib.php b/repository/onedrive/lib.php index 417783e938a..a3afd17e823 100644 --- a/repository/onedrive/lib.php +++ b/repository/onedrive/lib.php @@ -453,13 +453,21 @@ class repository_onedrive extends repository { $base = 'https://graph.microsoft.com/v1.0/'; - $sourceurl = new moodle_url($base . 'me/drive/items/' . $sourceinfo->id . '/content'); - $source = $sourceurl->out(false); + // Fetch the item info. + $infourl = (new moodle_url($base . 'me/drive/items/' . $sourceinfo->id))->out(false); + $response = $client->get($infourl); + if (!$response) { + throw new repository_exception('cannotdownload', 'repository'); + } + $response = json_decode($response, true); + $downloadurl = $response['@microsoft.graph.downloadUrl']; // We use download_one and not the rest API because it has special timeouts etc. $path = $this->prepare_file($filename); $options = ['filepath' => $path, 'timeout' => 15, 'followlocation' => true, 'maxredirs' => 5]; - $result = $client->download_one($source, null, $options); + // We cannot send authorization headers in the direct download request, it will fail. + $c = new curl(); + $result = $c->download_one($downloadurl, null, $options); if ($result) { @chmod($path, $CFG->filepermissions); @@ -881,16 +889,25 @@ class repository_onedrive extends repository { $systemservice = new repository_onedrive\rest($systemauth); + $base = 'https://graph.microsoft.com/v1.0/'; + + // Fetch the item info. + $infourl = (new moodle_url($base . 'me/drive/items/' . $source->id))->out(false); + $response = $userauth->get($infourl); + if (!$response) { + throw new repository_exception('cannotdownload', 'repository'); + } + $response = json_decode($response, true); + $downloadurl = $response['@microsoft.graph.downloadUrl']; + // Download the file. $tmpfilename = clean_param($source->id, PARAM_PATH); $temppath = make_request_directory() . $tmpfilename; + // We cannot send authorization headers in the direct download request, it will fail. + $c = new curl(); $options = ['filepath' => $temppath, 'timeout' => 60, 'followlocation' => true, 'maxredirs' => 5]; - $base = 'https://graph.microsoft.com/v1.0/'; - $sourceurl = new moodle_url($base . 'me/drive/items/' . $source->id . '/content'); - $sourceurl = $sourceurl->out(false); - - $result = $userauth->download_one($sourceurl, null, $options); + $result = $c->download_one($downloadurl, null, $options); if (!$result) { throw new repository_exception('cannotdownload', 'repository');