diff --git a/lib/filelib.php b/lib/filelib.php index a80f3a8ecb7..01b360c8430 100644 --- a/lib/filelib.php +++ b/lib/filelib.php @@ -455,30 +455,41 @@ function file_prepare_draft_area(&$draftitemid, $contextid, $component, $fileare * Passing a new option reverse = true in the $options var will make the function to convert actual URLs in $text to encoded URLs * in the @@PLUGINFILE@@ form. * - * @category files - * @global stdClass $CFG - * @param string $text The content that may contain ULRs in need of rewriting. - * @param string $file The script that should be used to serve these files. pluginfile.php, draftfile.php, etc. - * @param int $contextid This parameter and the next two identify the file area to use. - * @param string $component - * @param string $filearea helps identify the file area. - * @param int $itemid helps identify the file area. - * @param array $options text and file options ('forcehttps'=>false), use reverse = true to reverse the behaviour of the function. - * @return string the processed text. + * @param string $text The content that may contain ULRs in need of rewriting. + * @param string $file The script that should be used to serve these files. pluginfile.php, draftfile.php, etc. + * @param int $contextid This parameter and the next two identify the file area to use. + * @param string $component + * @param string $filearea helps identify the file area. + * @param int $itemid helps identify the file area. + * @param array $options + * bool $options.forcehttps Force the user of https + * bool $options.reverse Reverse the behaviour of the function + * bool $options.includetoken Use a token for authentication + * string The processed text. */ function file_rewrite_pluginfile_urls($text, $file, $contextid, $component, $filearea, $itemid, array $options=null) { - global $CFG; + global $CFG, $USER; $options = (array)$options; if (!isset($options['forcehttps'])) { $options['forcehttps'] = false; } - if (!$CFG->slasharguments) { - $file = $file . '?file='; + $baseurl = "{$CFG->wwwroot}/{$file}"; + if (!empty($options['includetoken'])) { + $token = get_user_key('core_files', $USER->id); + $finalfile = basename($file); + $tokenfile = "token{$finalfile}"; + $file = substr($file, 0, strlen($file) - strlen($finalfile)) . $tokenfile; + + if (!$CFG->slasharguments) { + $baseurl .= "?token={$token}&file="; + } else { + $baseurl .= "/{$token}"; + } } - $baseurl = "$CFG->wwwroot/$file/$contextid/$component/$filearea/"; + $baseurl .= "/{$contextid}/{$component}/{$filearea}/"; if ($itemid !== null) { $baseurl .= "$itemid/"; diff --git a/lib/tests/filelib_test.php b/lib/tests/filelib_test.php index 6931a597b29..d417ad382f6 100644 --- a/lib/tests/filelib_test.php +++ b/lib/tests/filelib_test.php @@ -1052,6 +1052,79 @@ EOF; $this->assertEquals($originaltext, $finaltext); } + /** + * Test file_rewrite_pluginfile_urls with includetoken. + */ + public function test_file_rewrite_pluginfile_urls_includetoken() { + global $USER, $CFG; + + $CFG->slasharguments = true; + + $this->resetAfterTest(); + + $syscontext = context_system::instance(); + $originaltext = 'Fake test with an image '; + $options = ['includetoken' => true]; + + // Rewrite the content. This will generate a new token. + $finaltext = file_rewrite_pluginfile_urls( + $originaltext, 'pluginfile.php', $syscontext->id, 'user', 'private', 0, $options); + + $token = get_user_key('core_files', $USER->id); + $expectedurl = new \moodle_url("/tokenpluginfile.php/{$token}/{$syscontext->id}/user/private/0/image.png"); + $expectedtext = "Fake test with an image "; + $this->assertEquals($expectedtext, $finaltext); + + // Do it again - the second time will use an existing token. + $finaltext = file_rewrite_pluginfile_urls( + $originaltext, 'pluginfile.php', $syscontext->id, 'user', 'private', 0, $options); + $this->assertEquals($expectedtext, $finaltext); + + // Now undo. + $options['reverse'] = true; + $finaltext = file_rewrite_pluginfile_urls($finaltext, 'pluginfile.php', $syscontext->id, 'user', 'private', 0, $options); + + // Compare the final text is the same that the original. + $this->assertEquals($originaltext, $finaltext); + } + + /** + * Test file_rewrite_pluginfile_urls with includetoken with slasharguments disabled.. + */ + public function test_file_rewrite_pluginfile_urls_includetoken_no_slashargs() { + global $USER, $CFG; + + $CFG->slasharguments = false; + + $this->resetAfterTest(); + + $syscontext = context_system::instance(); + $originaltext = 'Fake test with an image '; + $options = ['includetoken' => true]; + + // Rewrite the content. This will generate a new token. + $finaltext = file_rewrite_pluginfile_urls( + $originaltext, 'pluginfile.php', $syscontext->id, 'user', 'private', 0, $options); + + $token = get_user_key('core_files', $USER->id); + $expectedurl = new \moodle_url("/tokenpluginfile.php"); + $expectedurl .= "?token={$token}&file=/{$syscontext->id}/user/private/0/image.png"; + $expectedtext = "Fake test with an image "; + $this->assertEquals($expectedtext, $finaltext); + + // Do it again - the second time will use an existing token. + $finaltext = file_rewrite_pluginfile_urls( + $originaltext, 'pluginfile.php', $syscontext->id, 'user', 'private', 0, $options); + $this->assertEquals($expectedtext, $finaltext); + + // Now undo. + $options['reverse'] = true; + $finaltext = file_rewrite_pluginfile_urls($finaltext, 'pluginfile.php', $syscontext->id, 'user', 'private', 0, $options); + + // Compare the final text is the same that the original. + $this->assertEquals($originaltext, $finaltext); + } + /** * Helpter function to create draft files *