MDL-87546 tool_mfa: support wildcard theme pluginfile exemptions

This commit is contained in:
Huong Nguyen
2026-03-12 11:30:03 +07:00
parent a834b7b935
commit b2e19ee5bb
2 changed files with 53 additions and 2 deletions
+45 -2
View File
@@ -51,8 +51,49 @@ class manager {
'tool_mfa' => [
'guidance',
],
'theme_*' => [
'loginbackgroundimage',
],
];
/**
* Returns allowed fileareas for a component.
*
* Supports exact component matches and wildcard suffix matches such as `theme_*`.
*
* @param string $component the component to check.
* @return array|null the allowed fileareas, or null if the component is not allowed.
*/
protected static function get_allowed_fileareas_for_component(string $component): ?array {
if (array_key_exists($component, static::ALLOWED_COMPONENTS)) {
return static::ALLOWED_COMPONENTS[$component];
}
foreach (static::ALLOWED_COMPONENTS as $pattern => $fileareas) {
if (!str_ends_with($pattern, '*')) {
continue;
}
$prefix = substr($pattern, 0, -1);
if ($prefix !== '' && str_starts_with($component, $prefix)) {
return $fileareas;
}
}
return null;
}
/**
* Checks whether a filearea is allowed.
*
* @param string $filearea the filearea to check.
* @param array $allowedfileareas the allowed fileareas for the component, where '*' allows all fileareas.
* @return bool
*/
protected static function is_allowed_filearea(string $filearea, array $allowedfileareas): bool {
return in_array('*', $allowedfileareas) || in_array($filearea, $allowedfileareas);
}
/**
* Displays a debug table with current factor information.
*
@@ -469,13 +510,15 @@ class manager {
$component = clean_param(array_shift($args), PARAM_COMPONENT);
$filearea = clean_param(array_shift($args), PARAM_AREA);
$allowedfileareas = static::get_allowed_fileareas_for_component($component);
// Check allowed components.
if (!array_key_exists($component, static::ALLOWED_COMPONENTS)) {
if ($allowedfileareas === null) {
return self::REDIRECT;
}
// Check allowed fileareas.
if (!in_array($filearea, static::ALLOWED_COMPONENTS[$component])) {
if (!static::is_allowed_filearea($filearea, $allowedfileareas)) {
return self::REDIRECT;
}
@@ -277,6 +277,14 @@ final class manager_test extends \advanced_testcase {
$guideurl = new \moodle_url('/pluginfile.php/1/tool_mfa/guidance/0/capybara.png');
$this->assertEquals(\tool_mfa\manager::NO_REDIRECT, \tool_mfa\manager::should_require_mfa($guideurl, false));
// Access the allowed theme pluginfile area via wildcard component rules.
$themeurl = new \moodle_url('/pluginfile.php/1/theme_boost/loginbackgroundimage/0/background.jpg');
$this->assertEquals(\tool_mfa\manager::NO_REDIRECT, \tool_mfa\manager::should_require_mfa($themeurl, false));
// Access a different theme pluginfile area which is not explicitly allowed.
$themeurl = new \moodle_url('/pluginfile.php/1/theme_classic/customfield/0/example.txt');
$this->assertEquals(\tool_mfa\manager::REDIRECT, \tool_mfa\manager::should_require_mfa($themeurl, false));
// Access private area.
$user3 = $this->getDataGenerator()->create_user();
$privateurl = new \moodle_url("/pluginfile.php/{$user3->id}/user/private/privatefile.png");