mirror of
https://github.com/catalyst/moodle-auth_outage.git
synced 2026-05-16 21:41:31 +02:00
Merge pull request #264 from catalyst/issue263
Bypass permissions check when generating a static page to fix #263
This commit is contained in:
@@ -48,6 +48,11 @@ class infopage {
|
||||
*/
|
||||
private $outage;
|
||||
|
||||
/**
|
||||
* @var bool|null Defines if the page is generated for a static outage page.
|
||||
*/
|
||||
private $static;
|
||||
|
||||
/**
|
||||
* infopage_controller constructor.
|
||||
* @param array $params Parameters to use or null to get from Moodle API (request).
|
||||
@@ -62,11 +67,13 @@ class infopage {
|
||||
$params = [
|
||||
'id' => optional_param('id', null, PARAM_INT),
|
||||
'outage' => null,
|
||||
'static' => optional_param('static', false, PARAM_BOOL),
|
||||
];
|
||||
} else {
|
||||
$defaults = [
|
||||
'id' => null,
|
||||
'outage' => null,
|
||||
'static' => false,
|
||||
];
|
||||
$params = array_merge($defaults, $params);
|
||||
}
|
||||
@@ -97,10 +104,14 @@ class infopage {
|
||||
public function output() {
|
||||
global $PAGE, $CFG, $OUTPUT;
|
||||
|
||||
if (is_null($this->outage) || !has_capability('auth/outage:viewinfo', context_system::instance())) {
|
||||
if (is_null($this->outage)) {
|
||||
redirect(new moodle_url('/'));
|
||||
}
|
||||
|
||||
// If it's not static outage page, then check access, then redirect if not allowed.
|
||||
if (!$this->static && !has_capability('auth/outage:viewinfo', context_system::instance())) {
|
||||
redirect(new moodle_url('/'));
|
||||
}
|
||||
$PAGE->set_context(context_system::instance());
|
||||
$PAGE->set_title($this->outage->get_title());
|
||||
$PAGE->set_heading($this->outage->get_title());
|
||||
@@ -143,5 +154,6 @@ class infopage {
|
||||
}
|
||||
|
||||
$this->outage = $params['outage'];
|
||||
$this->static = $params['static'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class maintenance_static_page {
|
||||
$html = '<html></html>';
|
||||
} else {
|
||||
$data = maintenance_static_page_io::file_get_data(
|
||||
$CFG->wwwroot.'/auth/outage/info.php?auth_outage_hide_warning=1&id='.$outage->id);
|
||||
$CFG->wwwroot.'/auth/outage/info.php?auth_outage_hide_warning=1&static=1&id='.$outage->id);
|
||||
$html = $data['contents'];
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
use auth_outage\dml\outagedb;
|
||||
use auth_outage\local\outage;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@@ -65,6 +66,37 @@ abstract class auth_outage_base_testcase extends advanced_testcase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke permission to see info page.
|
||||
*/
|
||||
protected function revoke_info_page_permissions() {
|
||||
global $DB;
|
||||
|
||||
$guestrole = $DB->get_record('role', array('shortname' => 'guest'));
|
||||
role_change_permission($guestrole->id, context_system::instance(), 'auth/outage:viewinfo', CAP_PREVENT);
|
||||
|
||||
$this->setGuestUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an outage object.
|
||||
*
|
||||
* @return \auth_outage\local\outage
|
||||
*/
|
||||
protected function get_dummy_outage() {
|
||||
$now = time();
|
||||
|
||||
return new outage([
|
||||
'id' => 1,
|
||||
'autostart' => false,
|
||||
'warntime' => $now - 100,
|
||||
'starttime' => $now + 100,
|
||||
'stoptime' => $now + 200,
|
||||
'title' => 'Title',
|
||||
'description' => 'Description',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup testcase.
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,8 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
|
||||
* Tests the constructor.
|
||||
*/
|
||||
public function test_constructor() {
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
new infopage();
|
||||
}
|
||||
|
||||
@@ -49,6 +51,8 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
|
||||
* Tests the constructor with given parameters.
|
||||
*/
|
||||
public function test_constructor_withparams() {
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
$_GET = ['id' => 1, 'static' => 'true'];
|
||||
new infopage();
|
||||
}
|
||||
@@ -57,16 +61,10 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
|
||||
* Tests the constructor with different id and outage id.
|
||||
*/
|
||||
public function test_constructor_idmismatch() {
|
||||
$outage = new outage([
|
||||
'id' => 1,
|
||||
'autostart' => false,
|
||||
'warntime' => time() - 60,
|
||||
'starttime' => time(),
|
||||
'stoptime' => time() + 60,
|
||||
'title' => 'Title',
|
||||
'description' => 'Description',
|
||||
]);
|
||||
$this->set_expected_exception('coding_exception');
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
$outage = $this->get_dummy_outage();
|
||||
$this->set_expected_exception('coding_exception', 'Provided id and outage->id do not match. (2/1)');
|
||||
new infopage(['id' => 2, 'outage' => $outage]);
|
||||
}
|
||||
|
||||
@@ -74,43 +72,92 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
|
||||
* Tests the constructor with an invalid outage.
|
||||
*/
|
||||
public function test_constructor_invalidoutage() {
|
||||
$this->set_expected_exception('coding_exception');
|
||||
new infopage(['outage' => 'My outage']);
|
||||
}
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
/**
|
||||
* We should have an exception because CLI cannot redirect.
|
||||
*/
|
||||
public function test_output_nonstatic_nooutage() {
|
||||
$info = new infopage(['static' => false]);
|
||||
$this->set_expected_exception('moodle_exception');
|
||||
$info->output();
|
||||
$this->set_expected_exception('coding_exception', 'Provided outage is not a valid outage object. (My outage)');
|
||||
new infopage(['outage' => 'My outage']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the output of the info page.
|
||||
*/
|
||||
public function test_output() {
|
||||
$now = time();
|
||||
$outage = new outage([
|
||||
'id' => 1,
|
||||
'autostart' => false,
|
||||
'warntime' => $now - 100,
|
||||
'starttime' => $now + 100,
|
||||
'stoptime' => $now + 200,
|
||||
'title' => 'Title',
|
||||
'description' => 'Description',
|
||||
]);
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
$outage = $this->get_dummy_outage();
|
||||
|
||||
$info = new infopage(['outage' => $outage]);
|
||||
$output = $info->get_output();
|
||||
self::assertStringContainsString('auth_outage_info', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the output of the info page.
|
||||
*/
|
||||
public function test_output_without_permission() {
|
||||
$this->revoke_info_page_permissions();
|
||||
$this->assertFalse(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
$outage = $this->get_dummy_outage();
|
||||
$info = new infopage(['outage' => $outage]);
|
||||
|
||||
$this->set_expected_exception('moodle_exception', 'Unsupported redirect detected, script execution terminated');
|
||||
$output = $info->get_output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the output of the info page.
|
||||
*/
|
||||
public function test_output_without_permission_but_static() {
|
||||
$this->revoke_info_page_permissions();
|
||||
$this->assertFalse(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
$outage = $this->get_dummy_outage();
|
||||
$info = new infopage(['outage' => $outage, 'static' => true]);
|
||||
|
||||
$output = $info->get_output();
|
||||
self::assertStringContainsString('auth_outage_info', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the output of the info page.
|
||||
*/
|
||||
public function test_output_with_forcelogin() {
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
set_config('forcelogin', true);
|
||||
|
||||
$outage = $this->get_dummy_outage();
|
||||
$info = new infopage(['outage' => $outage]);
|
||||
|
||||
$this->set_expected_exception('moodle_exception', 'Unsupported redirect detected, script execution terminated');
|
||||
$info->get_output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the output of the info page.
|
||||
*/
|
||||
public function test_output_with_forcelogin_if_static() {
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
set_config('forcelogin', true);
|
||||
|
||||
$outage = $this->get_dummy_outage();
|
||||
|
||||
$info = new infopage(['outage' => $outage, 'static' => true]);
|
||||
|
||||
$output = $info->get_output();
|
||||
self::assertStringContainsString('auth_outage_info', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the constructor enables SVG support.
|
||||
*/
|
||||
public function test_svgicons_is_true() {
|
||||
global $CFG;
|
||||
|
||||
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
|
||||
|
||||
$CFG->svgicons = false;
|
||||
new infopage();
|
||||
self::assertTrue($CFG->svgicons);
|
||||
|
||||
Reference in New Issue
Block a user