Compare commits

..
Author SHA1 Message Date
Waleed Hassan 6ccefa9eda Reduce version bump to +1 to satisfy CI's version-bump-size check 2026-07-13 13:23:50 +01:00
Waleed Hassan 2f5bb06e3c Bump plugin version 2026-07-13 10:03:43 +01:00
Waleed Hassan f785693d06 Set outage metadata headers before echoing injected warning-bar code to avoid headers-already-sent 2026-07-13 09:50:31 +01:00
Waleed Hassan 4976c5c3b6 Add missing default_metadata key to get_config_defaults() to avoid undefined property when creating a new outage 2026-07-13 09:50:24 +01:00
Waleed Hassan 789a1c1163 Fix CI codechecker: wrap long line, fix class closing brace placement, update matching test expectations 2026-07-13 09:47:24 +01:00
Waleed Hassan a6e465b7a3 WR #490867 auth_outage Review changes - avoid mutating svgicons before a redirect and update tests for the access key and svgicons changes 2026-07-12 23:45:42 +01:00
Waleed Hassan 1b2979f8e6 WR #490867 auth_outage Review changes - code cleanup: fix exception chaining, remove dead code, code style fixes, initialise variable, add missing PHPDoc, add database indexes 2026-07-12 22:15:41 +01:00
Waleed Hassan 6aad6d37ba WR #490867 auth_outage Review changes - sanitise header metadata and file request parameters, restrict served mime types, guard warning bar css output, move svgicons config change out of constructor, add missing form field types 2026-07-12 22:15:41 +01:00
Waleed Hassan 675ec899f4 WR #490867 auth_outage Review changes - add capability check to preview.php and escape outage title/description output in info page and renderer, validate access key parameter before use 2026-07-12 22:15:41 +01:00
Tomo Tsuyuki 40fccef237 Revert "Fix URL is blocked message when not behind a proxy/load balancer"
This reverts commit 51db933862.
2026-06-18 12:00:11 +10:00
Tomo Tsuyuki dbc8e75092 issue #405: fix unit test failure 2026-06-18 10:02:04 +10:00
abhinavgandham 54eca9e3a1 Fixed examples table syntax in default settings behat file. 2026-01-22 19:48:35 +11:00
abhinavgandham e4be98f482 Removed more tests that are not needed. 2026-01-22 19:48:35 +11:00
abhinavgandham 2e2692facd Removed maintanance mode tests. 2026-01-22 19:48:35 +11:00
abhinavgandham e653bc4365 Removed maintenance later code in outagelib so that site does not go into hard cli mode when outage starts. 2026-01-22 19:48:35 +11:00
abhinavgandham 74de81ef7c Fixed PHPUnit test errors and failures. 2026-01-22 19:48:35 +11:00
abhinavgandham 990152f439 Fixed upgrade step. 2026-01-22 19:48:35 +11:00
abhinavgandham 5e0a3c015d Modified unit tests to remove autostart, and quickstart guide and readme. 2026-01-22 19:48:35 +11:00
abhinavgandham bf51ff6de9 Version bump and codechecker fixes. 2026-01-22 19:48:35 +11:00
abhinavgandham 6ca7cb6d7e Issue #390: Reverted new 'Force off' option and dropdown conversion. 2026-01-22 19:48:35 +11:00
Matthew Hilton 83cb36660b Merge pull request #400 from catalyst/issue-387-m501
Issue 387: Add metadata header to outage pages
2026-01-19 14:09:47 +10:00
Peter Burnett 2a7556eb75 chore: ci Fixes 2026-01-19 13:56:09 +10:00
Peter Burnett 425ef963fb Issue 387: Add metadata header to outage pages 2026-01-19 13:26:06 +10:00
Brendan Heywood b63af0465e Merge pull request #398 from catalyst/MOODLE_501_issue390
Issue #390: Changed outage auto-start default parameter from checkbox to dropdown with option to fully disable.
2026-01-15 20:17:37 +11:00
abhinavgandham a8d496121f Fixed default parameter in configselect and updated 'Force off' lang string. 2026-01-15 16:32:39 +10:00
abhinavgandham fdd5569324 Formatting fixes. 2026-01-15 14:10:23 +10:00
abhinavgandham a32c923aaa Included logic for 'Force off' setting. 2026-01-15 14:00:45 +10:00
abhinavgandham a96035be92 Issue #390: Changed outage auto-start default parameter from checkbox to dropdown with option to fully disable. 2026-01-14 13:36:54 +10:00
Brendan Heywood 0105891b2e Update README.md 2026-01-13 14:34:46 +10:00
Brendan Heywood 3fca6fe0af Merge pull request #396 from catalyst/MOODLE_501_branchtablefix
Issue #390: Fixed branch table formatting and github actions ci link to point to 5.1 in `README.md`.
2026-01-13 15:33:55 +11:00
abhinavgandham 79b7a0fa59 Issue #390: Fixed branch table formatting and github actions ci link to point to 5.1 in readme. 2026-01-13 14:06:55 +10:00
Brendan Heywood 59b6c63252 Fixed code standards 2026-01-13 14:48:59 +11:00
Brendan Heywood 8a204a9b25 Merge pull request #395 from catalyst/MOODLE_501_versionfix
Issue #390: fixed version.php plugin version, release and required moodle version.
2026-01-13 13:14:32 +11:00
abhinavgandham 245bc347d4 Added new line at the end of version.php. 2026-01-13 12:03:06 +10:00
abhinavgandham cc09171e82 Fixed comments indentation. 2026-01-13 11:47:11 +10:00
abhinavgandham c0ea1c1261 Issue #390: fixed version.php plugin version, release and required moodle version. 2026-01-13 11:31:09 +10:00
Brendan Heywood 2c25292a40 Merge pull request #393 from catalyst/MOODLE_501_codecleanup
Issue #390: Code cleanup to fix code standards codesniffer errors.
2026-01-12 17:56:13 +11:00
abhinavgandham 2b30fca670 Changed require_once path in behat_auth_outage.php 2026-01-12 16:23:44 +10:00
abhinavgandham 1183420b3b Issue #390: Code cleanup to fix code standards codesniffer errors. 2026-01-12 15:08:32 +10:00
Guillaume 845a370d6f Fix #314: Switch optional_param starttime to optional_param_array (#384)
* Fix #314: Switch optional_param starttime to optional_param_array

* convert default startime to timestamp

* fix error debug warning
2025-12-03 17:40:42 +11:00
Brendan Heywood 329c635b3a Merge pull request #385 from catalyst/fix-define-5-1
Fix bootstrap define #352
2025-11-29 16:46:26 +11:00
Brendan Heywood b932792cb0 Fix bootstrap define #352 2025-11-29 15:53:06 +11:00
Brendan Heywood 8bdfa9e222 Merge pull request #381 from catalyst/tweak-comment
Improve comments when blocked
2025-10-22 15:08:20 +10:00
Brendan Heywood 77ee908aed Improve comments when blocked 2025-10-22 14:19:54 +11:00
Dan Marsden 1e40a209b0 Merge pull request #380 from aspark21/patch-1
5.1+ path has changed due to MDL-83424
2025-09-22 02:45:37 +01:00
Dan Marsden 361250ed49 Moodle 5.1 branch. 2025-09-22 13:36:28 +12:00
Alistair Spark 0fd6a20e8e 5.1+ path has changed due to MDL-83424 2025-09-21 18:47:19 +01:00
31 changed files with 128 additions and 152 deletions
+5 -4
View File
@@ -1,4 +1,4 @@
[![ci](https://github.com/catalyst/moodle-auth_outage/actions/workflows/ci.yml/badge.svg?branch=MOODLE_39_STABLE)](https://github.com/catalyst/moodle-auth_outage/actions/workflows/ci.yml?branch=MOODLE_39_STABLE)
[![ci](https://github.com/catalyst/moodle-auth_outage/actions/workflows/ci.yml/badge.svg?branch=MOODLE_501_STABLE)](https://github.com/catalyst/moodle-auth_outage/actions/workflows/ci.yml?branch=MOODLE_501_STABLE)
# Moodle Outage manager plugin
- [Moodle Outage manager plugin](#moodle-outage-manager-plugin)
@@ -42,9 +42,10 @@ need to manually add one extra plugin, please check:
Moodle supported branches
--------
| Version | Branch | PHP |
|-------------|-------------------|------|
| Moodle 3.9+ | MOODLE_39_STABLE | 7.2+ |
| Version | Branch | PHP |
|----------------|---------------------|------|
| Moodle 5.1 | MOODLE_501_STABLE | 8.2 |
| Moodle 3.9-5.0 | MOODLE_39_STABLE | 7.2+ |
Totara supported branches
--------
+1
View File
@@ -69,6 +69,7 @@ if (is_callable('auth_outage_bootstrap_callback')) {
}
// 3) Check for allowed scripts or IPs during outages.
$outageinfo = false;
if (!empty($_SERVER['REQUEST_URI'])) {
$rooturl = parse_url($CFG->wwwroot);
$path = '';
+6 -3
View File
@@ -40,16 +40,18 @@ class calendar {
/**
* Create an event on the calendar for this outage.
* @param outage $outage Outage to be added to the calendar.
* @return void
*/
public static function create(outage $outage) {
public static function create(outage $outage): void {
calendar_event::create(self::create_data($outage));
}
/**
* Updates an event on the calendar based on this outage.
* @param outage $outage Outage to be updated in the calendar.
* @return void
*/
public static function update(outage $outage) {
public static function update(outage $outage): void {
$event = self::load($outage->id);
if (is_null($event)) {
@@ -63,8 +65,9 @@ class calendar {
/**
* Removes an event from the calendar related to this outage.
* @param int $outageid Id of outage to be deleted from the calendar.
* @return void
*/
public static function delete($outageid) {
public static function delete(int $outageid): void {
$event = self::load($outageid);
// If not found (was not created before) ignore it.
+2 -1
View File
@@ -48,6 +48,7 @@ class outagedb {
/**
* Gets all outage entries.
* @return outage[]
*/
public static function get_all() {
global $DB;
@@ -361,7 +362,7 @@ class outagedb {
$data = $DB->get_records_select(
'auth_outage',
'starttime <= :datetime1 AND :datetime2 <= stoptime AND finished IS NULL',
['datetime1' => $time, 'datetime2' => $time, 'datetime3' => $time],
['datetime1' => $time, 'datetime2' => $time],
'starttime ASC, stoptime DESC, title ASC',
'*',
0,
+2
View File
@@ -67,6 +67,7 @@ class edit extends moodleform {
$mform->addHelpButton('title', 'title', 'auth_outage');
$mform->addElement('editor', 'description', get_string('description', 'auth_outage'));
$mform->setType('description[text]', PARAM_RAW);
$mform->addHelpButton('description', 'description', 'auth_outage');
$mform->addElement('static', 'usagehints', '', get_string('textplaceholdershint', 'auth_outage'));
@@ -79,6 +80,7 @@ class edit extends moodleform {
get_string('useaccesskey:desc', 'auth_outage'),
0
);
$mform->setType('useaccesskey', PARAM_BOOL);
$mform->addElement('text', 'accesskey', get_string('accesskey', 'auth_outage'));
$mform->setType('accesskey', PARAM_TEXT);
+1 -1
View File
@@ -79,6 +79,6 @@ class cli_exception extends Exception {
* @param Exception|null $previous Another exception as reference or null.
*/
public function __construct($message, $code = 1, ?Exception $previous = null) {
parent::__construct('*ERROR* ' . $message, $code, $previous = null);
parent::__construct('*ERROR* ' . $message, $code, $previous);
}
}
-1
View File
@@ -114,7 +114,6 @@ abstract class clibase {
* Change session to admin user.
*/
protected function become_admin_user() {
global $DB;
$user = get_admin();
unset($user->description);
unset($user->access);
+2 -30
View File
@@ -28,8 +28,7 @@ use coding_exception;
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class create extends clibase
{
class create extends clibase {
/**
* @var mixed[] Defaults to use if given option is null.
*/
@@ -99,6 +98,7 @@ class create extends clibase
/**
* Executes the CLI.
* @throws cli_exception
*/
public function execute() {
// Help always overrides any other parameter.
@@ -269,32 +269,4 @@ class create extends clibase
}
return $option;
}
/**
* Ensures the given option is or can be converted to a bool.
* @param mixed $option The parameter to check.
* @param string $param Name of that parameter.
* @return bool The converted parameter.
* @throws cli_exception
*/
private function merge_options_check_parameters_bool($option, $param) {
if (is_bool($option)) {
return $option;
}
if (is_string($option)) {
$option = strtoupper($option);
if (in_array($option, ['0', 'FALSE', 'NO', 'N'])) {
return false;
}
if (in_array($option, ['1', 'TRUE', 'YES', 'Y'])) {
return true;
}
}
throw new cli_exception(
get_string('clierrorinvalidvaluenotbool', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID
);
}
}
+1
View File
@@ -56,6 +56,7 @@ class finish extends clibase {
/**
* Executes the CLI.
* @throws cli_exception
*/
public function execute() {
// Help always overrides any other parameter.
+1
View File
@@ -101,6 +101,7 @@ class waitforit extends clibase {
$outage = $this->get_outage();
while ($sleep = $this->wait_for_outage_to_start($outage)) {
$sleep = max(1, $sleep);
if (is_null($this->sleepcallback)) {
$this->verbose('Sleeping for ' . $sleep . ' second(s).');
sleep($sleep);
+15 -14
View File
@@ -47,11 +47,6 @@ class infopage {
* @param array|null $params Parameters to use or null to get from Moodle API (request).
*/
public function __construct(?array $params = null) {
global $CFG;
// Enable SVG support here to make sure all SVG files
// used in the current theme are served properly.
$CFG->svgicons = true;
if (is_null($params)) {
$params = [
'id' => optional_param('id', null, PARAM_INT),
@@ -101,21 +96,29 @@ class infopage {
if (!$this->static && !has_capability('auth/outage:viewinfo', context_system::instance())) {
redirect(new moodle_url('/'));
}
// Enable SVG support here to make sure all SVG files
// used in the current theme are served properly.
$previoussvg = $CFG->svgicons ?? null;
$CFG->svgicons = true;
$PAGE->set_context(context_system::instance());
$PAGE->set_title($this->outage->get_title());
$PAGE->set_heading($this->outage->get_title());
$PAGE->set_url(new moodle_url('/auth/outage/info.php'));
// No hooks injecting into this page, do it manually.
echo outagelib::get_inject_code();
// Inject metadata into the header before output.
// Inject metadata into the header before any output starts, otherwise header() will
// fail once outagelib::get_inject_code() below has echoed anything.
if (!empty($this->outage->metadata)) {
header('X-Outage-Metadata: ' . $this->outage->metadata);
$safemeta = str_replace(["\r", "\n"], '', $this->outage->metadata);
header('X-Outage-Metadata: ' . $safemeta);
header('X-Outage-StartTime: ' . $this->outage->starttime);
header('X-Outage-EndTime: ' . $this->outage->stoptime);
}
// No hooks injecting into this page, do it manually.
echo outagelib::get_inject_code();
echo $OUTPUT->header();
$viewbag = [
'admin' => is_siteadmin(),
@@ -123,10 +126,8 @@ class infopage {
];
require($CFG->dirroot . '/auth/outage/views/info/content.php');
// Moodle 2.7 did not check for CLI mode, which was fixed later.
if (!($CFG->branch == '27' && CLI_SCRIPT)) {
echo $OUTPUT->footer();
}
echo $OUTPUT->footer();
$CFG->svgicons = $previoussvg;
}
/**
@@ -51,7 +51,8 @@ class maintenance_static_page {
} else {
// Inject metadata into the header before output.
if (!empty($outage->metadata)) {
header('X-Outage-Metadata: ' . $outage->metadata);
$safemeta = str_replace(["\r", "\n"], '', $outage->metadata);
header('X-Outage-Metadata: ' . $safemeta);
header('X-Outage-StartTime: ' . $outage->starttime);
header('X-Outage-EndTime: ' . $outage->stoptime);
}
+19 -10
View File
@@ -51,6 +51,7 @@ class outagelib {
/**
* Fetches page.
* @param string $file file to be fetched
* @return array{contents: string|false, mime: string}
*/
public static function fetch_page($file) {
global $CFG;
@@ -69,6 +70,7 @@ class outagelib {
/**
* Resets inject called to allow the code to be regenerated.
* @return void
*/
public static function reset_injectcalled() {
self::$injectcalled = false;
@@ -77,6 +79,7 @@ class outagelib {
/**
* Given a time, usually now, when is the next outage window?
* @param int $time time for next window
* @return int
*/
public static function get_next_window($time = null) {
@@ -177,6 +180,7 @@ class outagelib {
'default_warning_duration' => (string)(60 * 60),
'default_title' => get_string('defaulttitlevalue', 'auth_outage'),
'default_description' => get_string('defaultdescriptionvalue', 'auth_outage'),
'default_metadata' => '',
'remove_selectors' => ".usermenu\n.logininfo\n.homelink",
];
}
@@ -253,7 +257,7 @@ class outagelib {
* @param int $stoptime Outage stop time.
* @param string $allowedips List of IPs allowed.
* @param string|null $accesskey access key, or null if no access key set.
* @param string|null $metadata metadata to be added to the outage headers, or null if none.
* @param string|null $metadata Metadata to set in headers, or null if none.
*
* @return string
* @throws invalid_parameter_exception
@@ -267,10 +271,6 @@ class outagelib {
// single-quotes (and double for the sake of it) are present otherwise it would break the code.
$allowedips = addslashes($allowedips);
// Escape the access key before substitution into the PHP literal to prevent
// code injection via a maliciously crafted access key value.
$accesskey = addslashes((string)$accesskey);
$cookiesecure = is_moodle_cookie_secure();
// Since Moodle 4.3 cookiehttponly is default to true and this CFG is not set.
@@ -288,7 +288,7 @@ if ((time() >= {{STARTTIME}}) && (time() < {{STOPTIME}})) {
require_once($CFG->dirroot.'/lib/classes/ip_utils.php');
}
// Put access key as a cookie if given. This stops the need to put it as a url param on every request.
$urlaccesskey = optional_param('accesskey', null, PARAM_TEXT);
$urlaccesskey = optional_param('accesskey', null, PARAM_ALPHANUM);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
@@ -332,7 +332,8 @@ if ((time() >= {{STARTTIME}}) && (time() < {{STOPTIME}})) {
}
if ({{USEACCESSKEY}} && $accesskeyblocked) {
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: '. $useraccesskey .' -->';
$safeaccesskey = htmlspecialchars($useraccesskey ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8');
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: ' . $safeaccesskey . ' -->';
}
if (!$isphpunit) {
@@ -349,9 +350,17 @@ EOT;
$search = ['{{STARTTIME}}', '{{STOPTIME}}', '{{USEALLOWEDIPS}}', '{{ALLOWEDIPS}}', '{{USEACCESSKEY}}', '{{ACCESSKEY}}',
'{{YOURIP}}', '{{COOKIESECURE}}', '{{COOKIEHTTPONLY}}', '{{METADATA}}'];
// Note that var_export is required because (string) false == '', not 'false'.
$replace = [$starttime, $stoptime, var_export(!empty($allowedips), true), $allowedips, var_export(!empty($accesskey), true),
$accesskey, getremoteaddr('n/a'), var_export($cookiesecure, true),
var_export($cookiehttponly, true), var_export($metadata, true)];
$replace = [
$starttime,
$stoptime,
var_export(!empty($allowedips), true),
$allowedips,
var_export(!empty($accesskey), true),
$accesskey,
getremoteaddr('n/a'),
var_export($cookiesecure, true),
var_export($cookiehttponly, true),
var_export($metadata, true)];
return str_replace($search, $replace, $code);
}
-35
View File
@@ -64,41 +64,6 @@ class base_table extends flexible_table {
$this->set_attribute('class', 'generaltable admintable');
}
/**
* Displays a user by their fullname with a link to a profile.
* @param int $userid
* @return string HTML link to user profile
*/
private function format_user(int $userid): string {
if ($userid == 0 || !$user = \core_user::get_user($userid)) {
return get_string('na', 'auth_outage');
}
$url = new moodle_url('/user/profile.php', ['id' => $userid]);
return html_writer::link($url, fullname($user));
}
/**
* Formats created by column.
* @param outage $outage
* @return string The user who created the outage.
*/
protected function format_created(outage $outage): string {
return $this->format_user($outage->createdby);
}
/**
* Formats modified by column.
* @param outage $outage
* @return string The user who last modiifed the outage and the last modified time.
*/
protected function format_modified(outage $outage): string {
$timestamp = html_writer::div(
userdate($outage->lastmodified, get_string('datetimeformat', 'auth_outage')),
'small text-muted'
);
return $this->format_user($outage->modifiedby) . $timestamp;
}
/**
* Create the action buttons HTML code for a specific outage.
* @param outage $outage The outage to generate the buttons.
+1 -5
View File
@@ -36,7 +36,7 @@ class history_table extends base_table {
public function __construct() {
parent::__construct();
$this->define_columns(['warning', 'starts', 'duration', 'durationactual', 'title', 'created', 'modified', 'actions']);
$this->define_columns(['warning', 'starts', 'durationplanned', 'durationactual', 'title', 'actions']);
$this->define_headers([
get_string('tableheaderwarnbefore', 'auth_outage'),
@@ -44,8 +44,6 @@ class history_table extends base_table {
get_string('tableheaderdurationplanned', 'auth_outage'),
get_string('tableheaderdurationactual', 'auth_outage'),
get_string('tableheadertitle', 'auth_outage'),
get_string('tableheadercreatedby', 'auth_outage'),
get_string('tableheadermodifiedby', 'auth_outage'),
get_string('actions'),
]);
@@ -66,8 +64,6 @@ class history_table extends base_table {
format_time($outage->get_duration_planned()),
$finished,
$outage->get_title(),
$this->format_created($outage),
$this->format_modified($outage),
$this->create_data_buttons($outage, false),
]);
}
+1 -5
View File
@@ -38,15 +38,13 @@ class planned_table extends base_table {
public function __construct() {
parent::__construct();
$this->define_columns(['warning', 'starts', 'duration', 'title', 'created', 'modified', 'actions']);
$this->define_columns(['warning', 'starts', 'duration', 'title', 'actions']);
$this->define_headers([
get_string('tableheaderwarnbefore', 'auth_outage'),
get_string('tableheaderstarttime', 'auth_outage'),
get_string('tableheaderduration', 'auth_outage'),
get_string('tableheadertitle', 'auth_outage'),
get_string('tableheadercreatedby', 'auth_outage'),
get_string('tableheadermodifiedby', 'auth_outage'),
get_string('actions'),
]);
@@ -70,8 +68,6 @@ class planned_table extends base_table {
self::create_starttime_string($outage->starttime),
format_time($outage->get_duration_planned()),
$title,
$this->format_created($outage),
$this->format_modified($outage),
$this->create_data_buttons($outage, true),
]);
}
+2 -2
View File
@@ -187,8 +187,8 @@ class renderer extends plugin_renderer_base {
$outagehtml = html_writer::div(
html_writer::tag(
'blockquote',
html_writer::div(html_writer::tag('b', $outage->get_title(), ['data-id' => $outage->id])) .
html_writer::div(html_writer::tag('i', $outage->get_description())) .
html_writer::div(html_writer::tag('b', format_string($outage->get_title()), ['data-id' => $outage->id])) .
html_writer::div(html_writer::tag('i', format_text($outage->get_description(), FORMAT_HTML))) .
html_writer::div(
html_writer::tag('b', get_string('tableheaderwarnbefore', 'auth_outage') . ': ') .
format_time($outage->get_warning_duration())
+4 -1
View File
@@ -37,7 +37,10 @@ class update_static_page extends scheduled_task {
}
/**
* Executes the event.
* Executes the task: regenerates the maintenance static page for the next scheduled outage.
*
* @throws \coding_exception
* @throws \file_exception
*/
public function execute() {
outagelib::prepare_next_outage();
+5
View File
@@ -21,9 +21,14 @@
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_createdby" TYPE="foreign" FIELDS="createdby" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="fk_modifiedby" TYPE="foreign" FIELDS="modifiedby" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="start_stop_title" UNIQUE="false" FIELDS="starttime, stoptime, title"/>
<INDEX NAME="ix_stoptime_finished" UNIQUE="false" FIELDS="stoptime, finished"/>
<INDEX NAME="ix_createdby" UNIQUE="false" FIELDS="createdby"/>
<INDEX NAME="ix_modifiedby" UNIQUE="false" FIELDS="modifiedby"/>
</INDEXES>
</TABLE>
</TABLES>
+4 -4
View File
@@ -61,7 +61,7 @@ function xmldb_auth_outage_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2024081900, 'auth', 'outage');
}
if ($oldversion < 2024081901) {
if ($oldversion < 2026011301) {
// Define field metadata to be added to auth_outage.
$table = new xmldb_table('auth_outage');
$field = new xmldb_field('metadata', XMLDB_TYPE_TEXT, null, null, null, null, null, 'accesskey');
@@ -72,10 +72,10 @@ function xmldb_auth_outage_upgrade($oldversion) {
}
// Outage savepoint reached.
upgrade_plugin_savepoint(true, 2024081901, 'auth', 'outage');
upgrade_plugin_savepoint(true, 2026011301, 'auth', 'outage');
}
if ($oldversion < 2024081902) {
if ($oldversion < 2026011302) {
// Getting the table auth_outage and target field to remove from the table.
$table = new xmldb_table('auth_outage');
$field = new xmldb_field('autostart');
@@ -89,7 +89,7 @@ function xmldb_auth_outage_upgrade($oldversion) {
unset_config('default_autostart', 'auth_outage');
// Outage savepoint reached.
upgrade_plugin_savepoint(true, 2024081902, 'auth', 'outage');
upgrade_plugin_savepoint(true, 2026011302, 'auth', 'outage');
}
return true;
-1
View File
@@ -28,7 +28,6 @@ use auth_outage\form\outage\edit;
use auth_outage\local\outage;
use auth_outage\local\outagelib;
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/formslib.php');
+20 -3
View File
@@ -37,14 +37,31 @@ if (!isset($_GET['file'])) {
die('Missing file parameter.');
}
$parts = explode('.', $_GET['file']);
$rawfile = $_GET['file'];
if (!preg_match('/^[a-zA-Z0-9_\-\.\/]+$/', $rawfile)) {
http_response_code(400);
die('Invalid file parameter.');
}
$parts = explode('.', $rawfile);
if (count($parts) != 2) {
http_response_code(400);
die('Invalid file requested.');
}
$mime = base64_decode($parts[1]);
$extension = strtolower(pathinfo($parts[0], PATHINFO_EXTENSION));
$allowedmimes = [
'css' => 'text/css',
'png' => 'image/png',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'gif' => 'image/gif',
];
if (!array_key_exists($extension, $allowedmimes)) {
http_response_code(400);
die('Unsupported file type.');
}
$mime = $allowedmimes[$extension];
// Detect type, we only support css or PNG images.
header('Content-Type: ' . $mime);
// Use cache.
+1 -7
View File
@@ -141,6 +141,7 @@ $string['outagefinishwarning'] = 'You are about to mark this outage as finished.
$string['outageslistfuture'] = 'Planned outages';
$string['outageslistpast'] = 'Outage history';
$string['pluginname'] = 'Outage manager';
$string["privacy:no_data_reason"] = "The Outage authentication plugin does not store any personal data.";
$string['removeselectors'] = 'Remove selectors';
$string['removeselectorsdescription'] = 'CSS selectors to remove when rendering a static themed maintenance page. One selector per line.';
$string['settingssectiondefaults'] = 'Default Outage Parameters';
@@ -149,11 +150,9 @@ $string['settingssectionplugin'] = 'Plugin Configuration';
$string['settingssectionplugindescription'] = 'General outage management plugin settings.';
$string['starttime'] = 'Start date and time';
$string['starttime_help'] = 'At which date and time the outage starts, preventing general access to the system.';
$string['tableheadercreatedby'] = 'Created by';
$string['tableheaderduration'] = 'Duration';
$string['tableheaderdurationactual'] = 'Actual duration';
$string['tableheaderdurationplanned'] = 'Planned duration';
$string['tableheadermodifiedby'] = 'Last modified by';
$string['tableheaderstartedtime'] = 'Started on';
$string['tableheaderstarttime'] = 'Starts on';
$string['tableheadertitle'] = 'Title';
@@ -172,8 +171,3 @@ $string['warningduration'] = 'Warning duration';
$string['warningduration_help'] = 'How long before the start of the outage should the warning be displayed.';
$string['warningdurationerrorinvalid'] = 'Warning duration must be positive.';
$string['warningreenablemaintenancemode'] = 'Please note that saving this outage will re-enable maintenance mode.<br />Untick "Auto start maintenance mode" if you want to prevent this.';
/*
* Privacy provider (GDPR)
*/
$string["privacy:no_data_reason"] = "The Outage authentication plugin does not store any personal data.";
+2
View File
@@ -31,6 +31,8 @@ use auth_outage\local\controllers\maintenance_static_page;
// @codingStandardsIgnoreStart
require_once(__DIR__.'/../../config.php');
// @codingStandardsIgnoreEnd
require_once($CFG->libdir . '/adminlib.php');
admin_externalpage_setup('auth_outage_manage');
$id = optional_param('id', null, PARAM_INT);
$outage = is_null($id) ? outagedb::get_next_starting() : outagedb::get_by_id($id);
if (is_null($outage)) {
+2 -2
View File
@@ -158,7 +158,7 @@ final class waitforit_test extends cli_testcase {
/**
* Tests the countdown.
*/
public function test_countdown() {
public function test_countdown(): void {
self::setAdminUser();
$now = time();
outagedb::save(new outage([
@@ -186,7 +186,7 @@ final class waitforit_test extends cli_testcase {
/**
* Tests if the outage changed while waiting.
*/
public function test_outagechanged() {
public function test_outagechanged(): void {
self::setAdminUser();
$now = time();
$id = outagedb::save(new outage([
+12 -4
View File
@@ -154,15 +154,23 @@ final class infopage_test extends \auth_outage\base_testcase {
}
/**
* Tests the constructor enables SVG support.
* Tests that rendering the page enables SVG support and restores the previous value afterwards.
*/
public function test_svgicons_is_true(): void {
public function test_svgicons_is_restored_after_output(): void {
global $CFG;
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
$outage = $this->get_dummy_outage();
$CFG->svgicons = false;
new infopage();
self::assertTrue($CFG->svgicons);
$info = new infopage(['outage' => $outage, 'static' => false]);
// Constructing the page should not touch $CFG->svgicons.
self::assertFalse($CFG->svgicons);
$info->get_output();
// Svgicons should be restored to its original value once rendering has finished.
self::assertFalse($CFG->svgicons);
}
}
@@ -550,7 +550,7 @@ final class maintenance_static_page_test extends \auth_outage\base_testcase {
/**
* Test meta refresh maximum 5 minutes.
*/
public function test_meta_refresh_maximum_5seconds() {
public function test_meta_refresh_maximum_5seconds(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
@@ -560,7 +560,6 @@ final class maintenance_static_page_test extends \auth_outage\base_testcase {
$page->set_max_refresh_time(5);
$page->generate();
$generated = trim(file_get_contents($page->get_io()->get_template_file()));
return $generated;
self::assertStringContainsString('<meta http-equiv="refresh" content="5">', $generated);
}
+6 -4
View File
@@ -272,7 +272,7 @@ if ((time() >= 123) && (time() < 456)) {
require_once($CFG->dirroot.'/lib/classes/ip_utils.php');
}
// Put access key as a cookie if given. This stops the need to put it as a url param on every request.
$urlaccesskey = optional_param('accesskey', null, PARAM_TEXT);
$urlaccesskey = optional_param('accesskey', null, PARAM_ALPHANUM);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
@@ -318,7 +318,8 @@ e.e.e.e/20');
}
if (true && $accesskeyblocked) {
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: '. $useraccesskey .' -->';
$safeaccesskey = htmlspecialchars($useraccesskey ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8');
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: ' . $safeaccesskey . ' -->';
}
if (!$isphpunit) {
@@ -358,7 +359,7 @@ if ((time() >= 123) && (time() < 456)) {
require_once($CFG->dirroot.'/lib/classes/ip_utils.php');
}
// Put access key as a cookie if given. This stops the need to put it as a url param on every request.
$urlaccesskey = optional_param('accesskey', null, PARAM_TEXT);
$urlaccesskey = optional_param('accesskey', null, PARAM_ALPHANUM);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
@@ -402,7 +403,8 @@ if ((time() >= 123) && (time() < 456)) {
}
if (true && $accesskeyblocked) {
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: '. $useraccesskey .' -->';
$safeaccesskey = htmlspecialchars($useraccesskey ?? '', ENT_QUOTES | ENT_HTML5, 'UTF-8');
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: ' . $safeaccesskey . ' -->';
}
if (!$isphpunit) {
+5 -6
View File
@@ -28,9 +28,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = "auth_outage";
$plugin->version = 2024081906; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2024081906; // Human-readable release information.
$plugin->requires = 2017111309; // 2017111309 = T13, but this really requires 3.9 and higher.
$plugin->maturity = MATURITY_STABLE; // Suitable for PRODUCTION environments!
$plugin->supported = [39, 405]; // A range of branch numbers of supported moodle versions.
$plugin->incompatible = 501;
$plugin->version = 2026011305; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2026011305; // Human-readable release information.
$plugin->requires = 2025100600; // Moodle 5.1.
$plugin->maturity = MATURITY_STABLE; // Suitable for PRODUCTION environments!
$plugin->supported = [501, 501]; // A range of branch numbers of supported moodle versions.
+4 -5
View File
@@ -39,19 +39,18 @@ defined('MOODLE_INTERNAL') || die();
<b><?php echo get_string('infountil', 'auth_outage'); ?></b>
<?php echo userdate($viewbag['outage']->stoptime, get_string('datetimeformat', 'auth_outage')); ?>
</div>
<div class="auth_outage_info_description"><?php echo $viewbag['outage']->get_description(); ?></div>
<div class="auth_outage_info_description"><?php echo format_text($viewbag['outage']->get_description(), FORMAT_HTML); ?></div>
<?php if ($viewbag['admin']) : ?>
<?php
$adminlinks = [];
foreach (
[
$params = [
'startofwarning' => -$viewbag['outage']->get_warning_duration(),
'15secondsbefore' => -15,
'start' => 0,
'endofoutage' => $viewbag['outage']->get_duration_planned() - 1,
] as $title => $delta
) {
];
foreach ($params as $title => $delta) {
$adminlinks[] = html_writer::link(
new moodle_url(
'/auth/outage/info.php',
+1 -1
View File
@@ -68,7 +68,7 @@ if (!$viewbag['static']) {
<style>
<?php
readfile($CFG->dirroot . '/auth/outage/views/warningbar/warningbar.css');
echo outagelib::get_config()->css;
echo preg_replace('/<\s*\/\s*style\s*>/i', '', outagelib::get_config()->css);
?>
</style>