mirror of
https://github.com/catalyst/moodle-auth_outage.git
synced 2026-05-16 21:41:31 +02:00
Issue #2 - IP Block implementation.
This commit is contained in:
@@ -154,6 +154,21 @@ class behat_auth_outage extends behat_base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Then /^I should see an empty settings text area "([^"]*)"$/
|
||||
* @param string $name
|
||||
*/
|
||||
public function i_should_see_an_empty_settings_text_area($name) {
|
||||
$this->assertSession()->fieldValueEquals('s_auth_outage_'.$name, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @When /^I go to the "Outage Settings" page$/
|
||||
*/
|
||||
public function i_go_to_the_outage_settings_page() {
|
||||
$this->getSession()->visit($this->locate_path('/admin/settings.php?section=authsettingoutage'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts how many times an specific action is visible.
|
||||
* @param string $action Action to check.
|
||||
|
||||
21
tests/behat/ipblock.feature
Normal file
21
tests/behat/ipblock.feature
Normal file
@@ -0,0 +1,21 @@
|
||||
@dev @auth @auth_outage @javascript
|
||||
Feature: IP Blocker
|
||||
In order to allow admins to access the system during an outage
|
||||
As an admin
|
||||
I need to be able to login into Moodle
|
||||
|
||||
Terminology:
|
||||
- An ongoing outage does not block Moodle execution, although it can trigger maintenance mode.
|
||||
- Maintenance mode completely blocks Moodle and can only be deactivated using the CLI.
|
||||
|
||||
|
||||
Background:
|
||||
Given the authentication plugin "outage" is enabled
|
||||
|
||||
|
||||
Scenario: Default IP Whitelist Settings
|
||||
Given I am an administrator
|
||||
And I am on homepage
|
||||
When I navigate to "Settings" node in "Site administration > Plugins > Authentication > Outage manager"
|
||||
Then I should see "Allowed IP list"
|
||||
And I should see an empty settings text area "allowedips"
|
||||
@@ -1,4 +1,4 @@
|
||||
@dev @auth @auth_outage @javascript
|
||||
@auth @auth_outage @javascript
|
||||
Feature: Warning bar
|
||||
In order alert users about an outage
|
||||
As any user
|
||||
|
||||
@@ -257,7 +257,7 @@ class infopagecontroller_test extends auth_outage_base_testcase {
|
||||
* Tests updating the static page when there is no outage.
|
||||
*/
|
||||
public function test_updatestaticpage_nooutage() {
|
||||
infopage::update_static_page();
|
||||
infopage::update_static_page(null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +267,7 @@ class infopagecontroller_test extends auth_outage_base_testcase {
|
||||
$file = infopage::get_defaulttemplatefile();
|
||||
touch($file);
|
||||
self::assertFileExists($file);
|
||||
infopage::update_static_page();
|
||||
infopage::update_static_page(null);
|
||||
self::assertFileNotExists($file);
|
||||
}
|
||||
|
||||
@@ -276,7 +276,15 @@ class infopagecontroller_test extends auth_outage_base_testcase {
|
||||
*/
|
||||
public function test_updatestaticpage_invalidfile() {
|
||||
$this->set_expected_exception('coding_exception');
|
||||
infopage::update_static_page(123);
|
||||
infopage::update_static_page(null, 123);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating the static page with an invalid outage.
|
||||
*/
|
||||
public function test_updatestaticpage_invalidoutage() {
|
||||
$this->set_expected_exception('coding_exception');
|
||||
infopage::update_static_page("foobar");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -339,6 +347,7 @@ class infopagecontroller_test extends auth_outage_base_testcase {
|
||||
* Checks if we can create and execute a task to update outage pages.
|
||||
*/
|
||||
public function test_tasks() {
|
||||
$this->resetAfterTest(true);
|
||||
$task = new update_static_page();
|
||||
self::assertNotEmpty($task->get_name());
|
||||
$task->execute();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
use auth_outage\dml\outagedb;
|
||||
use auth_outage\local\controllers\infopage;
|
||||
use auth_outage\local\outage;
|
||||
use auth_outage\local\outagelib;
|
||||
|
||||
@@ -70,7 +71,7 @@ class outagelib_test extends advanced_testcase {
|
||||
$this->resetAfterTest(true);
|
||||
set_config('maintenance_later', time() + (60 * 60 * 24 * 7)); // In 1 week.
|
||||
self::assertNotEmpty(get_config('moodle', 'maintenance_later'));
|
||||
outagelib::outages_modified();
|
||||
outagelib::prepare_next_outage();
|
||||
self::assertEmpty(get_config('moodle', 'maintenance_later'));
|
||||
}
|
||||
|
||||
@@ -194,6 +195,7 @@ class outagelib_test extends advanced_testcase {
|
||||
'default_duration',
|
||||
'default_title',
|
||||
'default_warning_duration',
|
||||
'allowedips',
|
||||
];
|
||||
// Set config with values.
|
||||
foreach ($keys as $k) {
|
||||
@@ -206,12 +208,33 @@ class outagelib_test extends advanced_testcase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that config has key.
|
||||
*/
|
||||
public function test_config_keys() {
|
||||
$this->resetAfterTest(true);
|
||||
$keys = [
|
||||
'allowedips',
|
||||
'css',
|
||||
'default_autostart',
|
||||
'default_description',
|
||||
'default_duration',
|
||||
'default_title',
|
||||
'default_warning_duration',
|
||||
];
|
||||
$defaults = outagelib::get_config_defaults();
|
||||
foreach ($keys as $k) {
|
||||
self::assertArrayHasKey($k, $defaults);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if get config works getting defaults when needed.
|
||||
*/
|
||||
public function test_get_config_invalid() {
|
||||
$this->resetAfterTest(true);
|
||||
// Set config with invalid values.
|
||||
set_config('allowedips', " \n", 'auth_outage');
|
||||
set_config('css', " \n", 'auth_outage');
|
||||
set_config('default_autostart', " \n", 'auth_outage');
|
||||
set_config('default_description', " \n", 'auth_outage');
|
||||
@@ -221,7 +244,7 @@ class outagelib_test extends advanced_testcase {
|
||||
// Get defaults.
|
||||
$defaults = outagelib::get_config_defaults();
|
||||
$config = outagelib::get_config();
|
||||
// Ensure it is using all defailts.
|
||||
// Ensure it is using all defaults.
|
||||
foreach ($defaults as $k => $v) {
|
||||
self::assertSame($v, $config->$k);
|
||||
}
|
||||
@@ -255,5 +278,165 @@ class outagelib_test extends advanced_testcase {
|
||||
|
||||
self::assertEmpty($CFG->additionalhtmltopofbody);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_createmaintenancephpcode() {
|
||||
$expected = <<<'EOT'
|
||||
<?php
|
||||
if (time() >= 123) {
|
||||
if (!defined('CLI_SCRIPT') || !CLI_SCRIPT) {
|
||||
define('MOODLE_INTERNAL', true);
|
||||
require_once($CFG->dirroot.'/lib/moodlelib.php');
|
||||
if (!remoteip_in_list('heyyou
|
||||
a.b.c.d
|
||||
e.e.e.e/20')) {
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 503 Moodle under maintenance');
|
||||
header('Status: 503 Moodle under maintenance');
|
||||
header('Retry-After: 300');
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
header('X-UA-Compatible: IE=edge');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Accept-Ranges: none');
|
||||
echo '<!-- Blocked by ip, your ip: '.getremoteaddr('n/a').' -->';
|
||||
if (file_exists($CFG->dataroot.'/climaintenance.template.html')) {
|
||||
require($CFG->dataroot.'/climaintenance.template.html');
|
||||
exit(0);
|
||||
}
|
||||
// The file above should always exist, but just in case...
|
||||
die('We are currently under maintentance, please try again later.');
|
||||
}
|
||||
}
|
||||
}
|
||||
$CFG->auth_outage_check = 1;
|
||||
EOT;
|
||||
$found = outagelib::create_climaintenancephp_code(123, 456, "hey'\"you\na.b.c.d\ne.e.e.e/20");
|
||||
self::assertSame($expected, $found);
|
||||
}
|
||||
|
||||
public function test_createmaintenancephpcode_withoutage() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$expected = <<<'EOT'
|
||||
<?php
|
||||
if (time() >= 123) {
|
||||
if (!defined('CLI_SCRIPT') || !CLI_SCRIPT) {
|
||||
define('MOODLE_INTERNAL', true);
|
||||
require_once($CFG->dirroot.'/lib/moodlelib.php');
|
||||
if (!remoteip_in_list('127.0.0.1')) {
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 503 Moodle under maintenance');
|
||||
header('Status: 503 Moodle under maintenance');
|
||||
header('Retry-After: 300');
|
||||
header('Content-type: text/html; charset=utf-8');
|
||||
header('X-UA-Compatible: IE=edge');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Accept-Ranges: none');
|
||||
echo '<!-- Blocked by ip, your ip: '.getremoteaddr('n/a').' -->';
|
||||
if (file_exists($CFG->dataroot.'/climaintenance.template.html')) {
|
||||
require($CFG->dataroot.'/climaintenance.template.html');
|
||||
exit(0);
|
||||
}
|
||||
// The file above should always exist, but just in case...
|
||||
die('We are currently under maintentance, please try again later.');
|
||||
}
|
||||
}
|
||||
}
|
||||
$CFG->auth_outage_check = 1;
|
||||
EOT;
|
||||
$outage = new outage([
|
||||
'starttime' => 123,
|
||||
'stoptime' => 456,
|
||||
]);
|
||||
$file = $CFG->dataroot.'/climaintenance.php';
|
||||
set_config('allowedips', '127.0.0.1', 'auth_outage');
|
||||
|
||||
outagelib::update_climaintenance_code($outage);
|
||||
self::assertFileExists($file);
|
||||
$found = file_get_contents($file);
|
||||
self::assertSame($found, $expected);
|
||||
}
|
||||
|
||||
public function test_createmaintenancephpcode_withoutips() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$outage = new outage([
|
||||
'starttime' => 123,
|
||||
'stoptime' => 456,
|
||||
]);
|
||||
$file = $CFG->dataroot.'/climaintenance.php';
|
||||
set_config('allowedips', '', 'auth_outage');
|
||||
|
||||
touch($file);
|
||||
outagelib::update_climaintenance_code($outage);
|
||||
self::assertFileNotExists($file);
|
||||
}
|
||||
|
||||
public function test_createmaintenancephpcode_withoutoutage() {
|
||||
global $CFG;
|
||||
$file = $CFG->dataroot.'/climaintenance.php';
|
||||
|
||||
touch($file);
|
||||
outagelib::update_climaintenance_code(null);
|
||||
self::assertFileNotExists($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Related to Issue #70: Creating ongoing outage does not trigger maintenance file creation.
|
||||
*/
|
||||
public function test_preparenextoutage_notautostart() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
self::setAdminUser();
|
||||
$now = time();
|
||||
$outage = new outage([
|
||||
'autostart' => false,
|
||||
'warntime' => $now - 200,
|
||||
'starttime' => $now - 100,
|
||||
'stoptime' => $now + 200,
|
||||
'title' => 'Title',
|
||||
'description' => 'Description',
|
||||
]);
|
||||
set_config('allowedips', '127.0.0.1', 'auth_outage');
|
||||
outagedb::save($outage);
|
||||
|
||||
// The method outagelib::prepare_next_outage() should have been called by save().
|
||||
foreach ([infopage::get_defaulttemplatefile(), $CFG->dataroot.'/climaintenance.php'] as $file) {
|
||||
self::assertFileExists($file);
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Related to Issue #72: IP Block still triggers cli maintenance mode even without autostart.
|
||||
*/
|
||||
public function test_preparenextoutage_noautostarttrigger() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
self::setAdminUser();
|
||||
$now = time();
|
||||
$outage = new outage([
|
||||
'autostart' => false,
|
||||
'warntime' => $now - 200,
|
||||
'starttime' => $now - 100,
|
||||
'stoptime' => $now + 200,
|
||||
'title' => 'Title',
|
||||
'description' => 'Description',
|
||||
]);
|
||||
outagedb::save($outage);
|
||||
|
||||
// The method outagelib::prepare_next_outage() should have been called by save().
|
||||
self::assertFalse(get_config('moodle', 'maintenance_later'));
|
||||
// This file should not exist even if the statement above fails as Moodle does not create it immediately but test anyway.
|
||||
self::assertFileNotExists($CFG->dataroot.'/climaintenance.html');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user