71 Commits

Author SHA1 Message Date
Benjamin Walker
f2b7d1c7dd Display creation info on manage outage page 2026-01-25 13:41:57 +11:00
abhinavgandham
f0f3112ea1 Fixed PHPdoc. 2026-01-22 22:15:35 +11:00
abhinavgandham
0ac6b14ed1 Fixed examples table syntax in default settings behat file. 2026-01-22 22:15:35 +11:00
abhinavgandham
b2c3fbd7b2 Removed more tests that are not needed. 2026-01-22 22:15:35 +11:00
abhinavgandham
840d2c39d9 Removed maintanance mode tests. 2026-01-22 22:15:35 +11:00
abhinavgandham
ddd56cd93f Removed maintenance later code in outagelib so that site does not go into hard cli mode when outage starts. 2026-01-22 22:15:35 +11:00
abhinavgandham
7d779f8fe9 Fixed PHPUnit test errors and failures. 2026-01-22 22:15:35 +11:00
abhinavgandham
ac29a02402 Modified unit tests to remove autostart, and quickstart guide and readme. 2026-01-22 22:15:35 +11:00
abhinavgandham
ffda33329c Codechecker fixes and removed other comments. 2026-01-22 22:15:35 +11:00
abhinavgandham
0bff6f5145 Issue #390: Reverted new 'Force off' option and dropdown conversion. 2026-01-22 22:15:35 +11:00
Matthew Hilton
bffd5f39f9 Merge pull request #388 from catalyst/issue-387
Issue 387: Add metadata header to outage pages
2026-01-19 12:47:02 +10:00
Peter Burnett
fcb2a681e7 Issue 387: Add metadata header to outage pages 2026-01-19 12:19:21 +10:00
abhinavgandham
59a62c4aa4 micro-bumped version in version.php. 2026-01-16 12:52:05 +11:00
abhinavgandham
073a682b01 CI codesniffer fixes. 2026-01-16 12:52:05 +11:00
abhinavgandham
da18e31dab Fixed default parameter in configselect and updated 'Force off' lang string. 2026-01-16 12:52:05 +11:00
abhinavgandham
1ef47a6233 Included logic for 'Force off' setting. 2026-01-16 12:52:05 +11:00
abhinavgandham
551a97142c Issue #390: Changed outage auto-start default parameter from checkbox to dropdown with option to fully disable. 2026-01-16 12:52:05 +11:00
Brendan Heywood
ceee32d889 Merge pull request #397 from catalyst/MOODLE_39_branchtable_unsupportedversion_fix
#Issue 390: Fixed branch table in readme and added version 501 as incompatible.
2026-01-13 16:51:12 +11:00
abhinavgandham
149223d10f #Issue 390: Fixed branch table in readme and added version 501 as incompatible. 2026-01-13 14:51:54 +10:00
Brendan Heywood
42b6ec3c87 Fix code standards 2026-01-13 14:50:05 +11:00
Brendan Heywood
6792b03ab0 Merge pull request #394 from catalyst/MOODLE_39_codecleanup
Issue #390: Code cleanup to fix code standards codesniffer errors.
2026-01-12 18:34:15 +11:00
abhinavgandham
7f968b2365 Issue #390: Code cleanup to fix code standards codesniffer errors. 2026-01-12 17:18:47 +10:00
Guillaume
42dbec5b4d Fix #314: Switch optional_param starttime to optional_param_array (#383)
* Fix #314: Switch optional_param starttime to optional_param_array

* convert default startime to timestamp

* fix error debug warning
2025-12-03 17:39:53 +11:00
Brendan Heywood
5d064a0bec Merge pull request #353 from catalyst/fix-define
Fix bootstrap define #352
2025-11-29 16:46:21 +11:00
Brendan Heywood
d16ae47a5f Fix bootstrap define #352 2025-11-29 15:51:50 +11:00
Brendan Heywood
1e3572be9f Improve comments when blocked 2025-10-22 16:09:21 +11:00
Jason den Dulk
0222741c3d Merge pull request #379 from catalyst/378-add-install-check
Issue #378: Add install check to before_standard_top_of_body_html_generation()
2025-09-16 18:25:43 +10:00
jasondendulk
611c7a000c Issue #378: Add install check to before_standard_top_of_body_html_generation() 2025-09-16 08:54:15 +10:00
Kevin Pham
f994a97a7d Merge pull request #369 from catalyst/368-clean-ob
[#368] Ensure output buffer is empty before serving files
2025-02-27 11:27:51 +11:00
Matthew Hilton
da0f7c5865 [#368] Ensure output buffer is empty before serving files 2025-02-27 08:30:43 +10:00
Dan Marsden
da080f8d65 Merge pull request #367 from SashaAnastasi/MOODLE_39_STABLE-phpunit10
outagelib: adjust exception trigger for phpunit10
2025-02-20 14:33:42 +13:00
Sasha Anastasi
b01dd8723e remove superfluous conditional 2025-02-20 14:17:15 +13:00
Sasha Anastasi
99452cb4f3 outagelib: adjust exception trigger for phpunit10 2025-02-20 13:01:11 +13:00
Dan Marsden
6e70c45547 Update README.md with latest supported branches. 2025-02-19 10:59:04 +13:00
Matthew Hilton
03362c084c Merge pull request #362 from catalyst/fix-blocked-url
Fix URL is blocked message when not behind a proxy/load balancer
2025-02-11 09:02:02 +10:00
Rossco Hellmans
51db933862 Fix URL is blocked message when not behind a proxy/load balancer
When there is no proxy/load balancer and curlsecurityblockedhosts is set to
default (i.e. has 127.0.0.1 in it) fetching the outage page will result in
a "The URL is blocked." message. This resolves that issue by passing
ignoresecurity to the curl object.
2025-02-10 16:36:34 +10:00
Misha Golenkov
11fbe64c46 Merge pull request #361 from catalyst/359-MOODLE_39_STABLE-fix
Issue #358: Use pix_icon to render icons
2025-01-30 13:32:00 +11:00
djarrancotleanu
0114db359b Issue #358: Use pix_icon to render icons 2025-01-30 10:50:43 +10:00
Djarran Cotleanu
aedf7a5a17 Merge pull request #359 from niko-hoogeveen/MOODLE_39_STABLE-issue358
Issue #358: Added some extra styling for outage icons
2025-01-30 09:25:36 +10:00
Niko Hoogeveen
3f79129774 Issue #358: Added some extra styling for outage icons 2025-01-28 15:02:34 -05:00
Dmitrii Metelkin
43d82333ca Merge pull request #355 from catalyst/issue354-39
Fix #354
2025-01-15 15:40:55 +11:00
david adamson
0dfede6084 Fix #354 2025-01-15 14:09:28 +11:00
Brendan Heywood
7f55f5d403 Merge pull request #351 from catalyst/issue-350-MOODLE_39_STABLE-test-errors
Fix #350: Do not setcookie during unit tests
2024-11-28 07:32:42 +11:00
djarrancotleanu
2a55769a86 Fix #350: Update unit tests with changes made to climaintenance.php 2024-11-27 09:55:51 +10:00
djarrancotleanu
68959e336d Fix #350: Do not setcookie during unit tests 2024-11-25 15:42:36 +10:00
Scott Verbeek
386a623bb3 Merge pull request #348 from catalyst/issue-347
[#347] Fix typo in the title link
2024-10-16 11:07:39 +10:00
Jwalit Shah
e01fa3797e [#347] Fix typo in the title link 2024-10-16 11:49:56 +11:00
Dan Marsden
5aac578c98 Merge pull request #346 from catalyst/fix343
Fix343
2024-10-01 11:44:20 +13:00
Dan Marsden
329e92445c Add supported 405 branch. 2024-10-01 10:27:31 +13:00
Dan Marsden
07d4fc89b8 Fix #343 - rename function to prevent unit test failure in 4.5 2024-10-01 10:25:56 +13:00
Matthew Hilton
a40e198d3e Merge pull request #345 from catalyst/access-key-fix
Fix: make access key and allowed ips OR conditional
2024-09-30 10:44:32 +10:00
Rossco Hellmans
c5485849d5 Fix: make access key and allowed ips OR conditional
Access keys and allowed IPs should be indpendant of each other and when
at least one of them is satisfied the user should be allowed in.
2024-09-27 12:34:47 +10:00
Rossco Hellmans
cba55cdc69 Merge pull request #341 from catalyst/access-key
[#340] Access key exclusion method
2024-08-20 10:26:53 +10:00
Matthew Hilton
bfa9569e3b [#340] Access key exclusion method 2024-08-19 14:31:14 +10:00
Rossco Hellmans
abcb087a58 Merge pull request #342 from catalyst/fixup-ci-and-codingstandards
cleanup: fixup to match coding standards
2024-08-09 10:59:49 +10:00
Matthew Hilton
97b118593d cleanup: fixup to match coding standards 2024-08-05 15:22:03 +10:00
Benjamin Walker
dae83f45ba Change hook callback to string #336 (#337) 2024-05-24 15:56:32 +10:00
Brendan Heywood
c9b5a9ad92 Merge pull request #335 from catalyst/add-hook-callbacks-334
Implement new hook callbacks #334
2024-05-21 00:32:53 -05:00
Benjamin Walker
541b2d4407 Implement new hook callbacks #334 2024-05-21 14:13:16 +10:00
Dan Marsden
e281b59eb4 Merge pull request #331 from catalyst/330-fix-grammar-in-langstring
fix: small grammatical issue for default description
2024-03-22 18:39:27 +13:00
Kevin Pham
b90d17d84a fix: small grammatical issue for default description
In speaking, we use a /ə/ before a consonant sound.

Resolves #330
2024-03-22 16:32:41 +11:00
Kevin Pham
24678ab31e Merge pull request #329 from catalyst/issue-328-remove-fontawesome-map
issue #328: remove unused fontawesome icon map
2024-01-05 14:33:54 +11:00
ScottVerbeek
94afadac9d issue #146: display icon for calendar event 2024-01-05 13:22:12 +10:00
ScottVerbeek
57b5a229c0 issue #328: remove unused fontawesome icon map 2024-01-04 15:32:56 +10:00
Brendan Heywood
bf7e2e5a97 Merge pull request #324 from cybernotic/MOODLE_39_STABLE
Comment out line 33 as this is killing behat test runs
2023-08-03 15:52:38 +10:00
David Kwaw
3f64f702c4 Remove MOODLE_INTERNAL test as it is killing the behat test runs 2023-08-03 15:43:09 +10:00
Brendan Heywood
cf0969c933 Merge pull request #322 from catalyst/MOODLE_39_STABLE-issue_321-no-require-config.php
Issue#321 bootstrap.php: remove require(config.php)
2023-07-05 10:54:16 +10:00
Srdjan
4aa5976ea8 Make Moodle linter happy. Mainly tests. 2023-07-04 15:04:30 +10:00
Srdjan
143862e25a Issue#321 bootstrap.php: remove require(config.php)
bootstrap.php is supposed to be required from config.php, so it makes
no sense to require config.php in bootstrap.php.
2023-07-03 15:50:30 +10:00
Dan Marsden
bed817cd5e Merge pull request #320 from catalyst/date-format-support-php8.1
Improve date format method compatiability for PHP 8.1
2023-06-13 10:22:51 +12:00
michaelkotlyar
755dcf8152 Improve date format method compatiability for PHP 8.1 2023-06-12 16:12:11 +12:00
80 changed files with 1532 additions and 1369 deletions

View File

@@ -6,5 +6,7 @@ on: [push, pull_request]
jobs:
ci:
uses: catalyst/catalyst-moodle-workflows/.github/workflows/ci.yml@main
secrets:
moodle_org_token: ${{ secrets.MOODLE_ORG_TOKEN }}
with:
disable_behat: true

View File

@@ -1,21 +0,0 @@
#
# Whenever version.php is changed, add the latest version
# to the Moodle Plugins directory at https://moodle.org/plugins
#
name: Releasing in the Plugins directory
on:
push:
branches:
- MOODLE_39_STABLE
paths:
- 'version.php'
jobs:
workflow_group_39_plus_release:
uses: catalyst/catalyst-moodle-workflows/.github/workflows/group-39-plus-release.yml@main
with:
plugin_name: auth_outage
disable_behat: true
secrets:
moodle_org_token: ${{ secrets.MOODLE_ORG_TOKEN }}

View File

@@ -98,9 +98,8 @@ Execute the commands from your Moodle instalation directory and leave the browse
1) Create an outage
This command will create an outage starting in 30 seconds, with a warning period of 15 seconds.
It will automatically start (trigger maintenance mode).
`php auth/outage/cli/create.php -w=20 -s=30 --autostart=Y`
`php auth/outage/cli/create.php -w=20 -s=30`
Refresh the page but you will not see anything yet.

View File

@@ -1,16 +1,21 @@
![GitHub Workflow Status (branch)](https://img.shields.io/github/actions/workflow/status/catalyst/moodle-auth_outage/ci.yml?branch=MOODLE_39_STABLE)
[![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)
# Moodle Outage manager plugin
* [Version Support](#version-support)
* [What is this?](#what-is-this)
* [Moodle Requirements](#moodle-requirements)
* [Screenshots](#screenshots)
* [Installation](#installation)
* [Theme configuration](#theme-configuration)
* [How to use](#how-to-use)
* [Quick Guide](#quick-guide)
* [Why is it an auth plugin?](#why-it-is-an-auth-plugin)
* [Feedback and issues](#feedback-and-issues)
- [Moodle Outage manager plugin](#moodle-outage-manager-plugin)
- [What is this?](#what-is-this)
- [Moodle Requirements](#moodle-requirements)
- [Branches](#branches)
- [Screenshots](#screenshots)
- [Installation](#installation)
- [Theme configuration](#theme-configuration)
- [Custom Theme Additional SCSS](#custom-theme-additional-scss)
- [How to use](#how-to-use)
- [Quick Guide](#quick-guide)
- [Why it is an auth plugin?](#why-it-is-an-auth-plugin)
- [Tester restriction options](#tester-restriction-options)
- [IP restriction](#ip-restriction)
- [Access key](#access-key)
- [Feedback and issues](#feedback-and-issues)
What is this?
-------------
@@ -35,14 +40,19 @@ If you have an older version of Moodle you can still make it work but you will
need to manually add one extra plugin, please check:
* https://github.com/catalyst/moodle-local_outage
Branches
Moodle supported branches
--------
| Moodle version | Totara | Branch | PHP |
| ------------------ | --------------- | ---------------- | ---- |
| Moodle 3.9+ | Totara 13+ | MOODLE_39_STABLE | 7.2+ |
| Moodle 3.3 to 3.8 | Totara 11 to 12 | MOODLE_38_STABLE | 7.1+ |
| Moodle 2.7 to 3.2 | | MOODLE_32_STABLE | 5.5+ |
| | Totara up to 10 | TOTARA_10 | 5.5+ |
| Version | Branch | PHP |
|-------------|-------------------|------|
| Moodle 3.9+ | MOODLE_39_STABLE | 7.2+ |
Totara supported branches
--------
| Version | Branch | PHP |
| --------------- | ---------------- | ---- |
| Totara 19 | TOTARA_19 | 7.2+ |
| Totara 13-18 | MOODLE_39_STABLE | 7.2+ |
Screenshots
-----------
@@ -157,7 +167,6 @@ Creates a new outage.
-h, --help shows parameters help.
-c, --clone clone another outage except for the start time.
-a, --autostart must be Y or N, sets if the outage automatically triggers maintenance mode.
-w, --warn how many seconds before it starts to display a warning.
-s, --start in how many seconds should this outage start or unix time to start outage. Required.
-d, --duration how many seconds should the outage last.
@@ -178,6 +187,18 @@ Why it is an auth plugin?
One of the graduated stages this plugin introduces is a 'tester only' mode which disables login for most normal users. This is conceptually similar to the maintenance mode but enables testers to login and confirm the state after an upgrade without needing full admin privileges.
Tester restriction options
------------
Two options are available to restrict the site to only let testers in during the tester phase.
Note: these restrictions build on each other; If both are enabled, users must meet both criteria to be allowed in.
## IP restriction
Only allow users from a certain IP or range of ips to enter.
## Access key
Users provide an access key in the URL params on first page load, which is then stored as a cookie for 24 hours. If the access key matches the one setup for the outage, they are allowed in.
## Using IP restriction with access key
Users will be allowed if they are from the configured allowed ips OR if they provide the correct access key.
Feedback and issues
-------------------

View File

@@ -32,7 +32,7 @@ use auth_outage\local\outagelib;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/authlib.php');
require_once($CFG->libdir . '/authlib.php');
/**
* auth_plugin_outage class.

View File

@@ -13,6 +13,7 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file should run before config.php requires '/lib/setup.php'.
*
@@ -28,20 +29,19 @@
*
* @var stdClass $CFG
*/
define('MOODLE_INTERNAL', true);
// This call is required by Moodle, but this script should have been called by config.php anyway.
// @codingStandardsIgnoreStart
require_once(__DIR__.'/../../config.php');
// @codingStandardsIgnoreEnd
defined('MOODLE_INTERNAL') || die();
//
// We need the CFG->dataroot, if not set yet this script is called too early in config.php file.
if (!isset($CFG->dataroot)) {
return;
}
// 1) Make sure we replace the configurations for behat as we have not ran 'lib/setup.php' yet.
if (!empty($CFG->behat_wwwroot) or !empty($CFG->behat_dataroot) or !empty($CFG->behat_prefix)) {
require_once(__DIR__.'/../../lib/behat/lib.php');
if (!empty($CFG->behat_wwwroot) || !empty($CFG->behat_dataroot) || !empty($CFG->behat_prefix)) {
require_once(__DIR__ . '/../../lib/behat/lib.php');
behat_update_vars_for_process();
if (behat_is_test_site()) {
$beforebehatcfg = $CFG;
@@ -75,18 +75,20 @@ if (!empty($_SERVER['REQUEST_URI'])) {
if (array_key_exists('path', $rooturl) && !empty($rooturl['path'])) {
$path = $rooturl['path'];
}
$url = $path.'/auth/outage/info.php';
$url = $path . '/auth/outage/info.php';
$outageinfo = strpos($_SERVER['REQUEST_URI'], $url) === 0 ? true : false;
}
$allowed = !file_exists($CFG->dataroot.'/climaintenance.php') // Not in maintenance mode.
$allowed = !file_exists($CFG->dataroot . '/climaintenance.php') // Not in maintenance mode.
|| (defined('ABORT_AFTER_CONFIG') && ABORT_AFTER_CONFIG) // Only config requested.
|| (defined('CLI_SCRIPT') && CLI_SCRIPT) // Allow CLI scripts.
|| $outageinfo // Allow outage info requests.
|| (defined('NO_AUTH_OUTAGE') && NO_AUTH_OUTAGE); // Allow any page should not be blocked by maintenance mode.
if (!$allowed) {
// Call the climaintenance.php which will check for allowed IPs.
// Call the climaintenance.php which will check for the conditions
// that have been baked into it from the frontend (ip, accesskey, etc...).
$CFG->dirroot = dirname(dirname(dirname(__FILE__))); // It is not defined yet but the script below needs it.
require($CFG->dataroot.'/climaintenance.php'); // This call may terminate the script here or not.
require($CFG->dataroot . '/climaintenance.php'); // This call may terminate the script here or not.
}
// 4) Set flag this file was loaded.

View File

@@ -31,7 +31,7 @@ header('Cache-Control: public, max-age=10,s-maxage=10');
// @codingStandardsIgnoreEnd
define('NO_AUTH_OUTAGE', true);
require_once(__DIR__.'/../../config.php');
require_once(__DIR__ . '/../../config.php');
$active = outagedb::get_active();

View File

@@ -14,22 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* calendar class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\calendar;
use auth_outage\local\outage;
use calendar_event;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot.'/calendar/lib.php');
require_once($CFG->dirroot . '/calendar/lib.php');
/**
* calendar class.
@@ -62,7 +53,7 @@ class calendar {
$event = self::load($outage->id);
if (is_null($event)) {
debugging('Cannot update calendar entry for outage #'.$outage->id.', event not found. Creating it...');
debugging('Cannot update calendar entry for outage #' . $outage->id . ', event not found. Creating it...');
self::create($outage);
} else {
$event->update(self::create_data($outage), false);
@@ -78,7 +69,7 @@ class calendar {
// If not found (was not created before) ignore it.
if (is_null($event)) {
debugging('Cannot delete calendar entry for outage #'.$outageid.', event not found. Ignoring it...');
debugging('Cannot delete calendar entry for outage #' . $outageid . ', event not found. Ignoring it...');
} else {
$event->delete();
}
@@ -98,6 +89,7 @@ class calendar {
'userid' => 0,
'modulename' => '',
'instance' => $outage->id,
'component' => 'auth_outage',
'eventtype' => 'auth_outage',
'timestart' => $outage->starttime,
'visible' => true,

View File

@@ -14,18 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outagedb class.
*
* The DB Context to manipulate Outages.
* It will also commit changes to the calendar as you change outages.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\dml;
use auth_outage\calendar\calendar;
@@ -38,7 +26,7 @@ use coding_exception;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot.'/calendar/lib.php');
require_once($CFG->dirroot . '/calendar/lib.php');
/**
* outagedb class.
@@ -130,7 +118,6 @@ class outagedb {
// Create calendar entry.
calendar::create($outage);
} else {
$other = (array) $outage;
$other['title'] = $outage->get_title();
$event = outage_updated::create([
@@ -220,8 +207,10 @@ class outagedb {
$outagecache = new outage(json_decode($outageinfo));
}
if ($outagecache && $outagecache->warntime <= $time && $outagecache->stoptime >= $time
&& (!$outagecache->finished || $outagecache->finished >= $time)) {
if (
$outagecache && $outagecache->warntime <= $time && $outagecache->stoptime >= $time
&& (!$outagecache->finished || $outagecache->finished >= $time)
) {
return $outagecache;
}
return null;
@@ -250,7 +239,8 @@ class outagedb {
':datetime1 < stoptime AND (finished IS NULL OR :datetime2 < finished)',
['datetime1' => $time, 'datetime2' => $time],
'starttime ASC, stoptime DESC, title ASC',
'*');
'*'
);
foreach ($rs as $r) {
$outages[] = new outage($r);
}
@@ -282,7 +272,8 @@ class outagedb {
'NOT (:datetime1 < stoptime AND (finished IS NULL OR :datetime2 < finished))',
['datetime1' => $time, 'datetime2' => $time],
'stoptime DESC, starttime DESC, title ASC',
'*');
'*'
);
foreach ($rs as $r) {
$outages[] = new outage($r);
}
@@ -307,12 +298,12 @@ class outagedb {
$outage = self::get_by_id($id);
if (is_null($outage)) {
debugging('Cannot finish outage #'.$id.': outage not found.');
debugging('Cannot finish outage #' . $id . ': outage not found.');
return;
}
if (!$outage->is_ongoing($time)) {
debugging('Cannot finish outage #'.$id.': outage not ongoing.');
debugging('Cannot finish outage #' . $id . ': outage not ongoing.');
return;
}
@@ -351,37 +342,6 @@ class outagedb {
return (count($data) == 0) ? null : new outage(array_shift($data));
}
/**
* Gets the next outage which has not started yet and has the autostart flag set to true.
* @param null $time Timestamp reference for current time.
* @return outage|null The outage or null if not found.
* @throws coding_exception
*/
public static function get_next_autostarting($time = null) {
global $DB;
if ($time === null) {
$time = time();
}
if (!is_int($time) || ($time <= 0)) {
throw new coding_exception('$time must be null or a positive int.', $time);
}
$data = $DB->get_records_select(
'auth_outage',
'(:datetime <= starttime) AND (autostart = 1)',
['datetime' => $time],
'starttime ASC',
'*',
0,
1
);
// Not using $DB->get_record_select instead because there is no 'limit' parameter.
// Allowing multiple records still raises an internal error.
return (count($data) == 0) ? null : new outage(array_shift($data));
}
/**
* Gets an ongoing outage (between start and stop time but not finished).
* @param int|null $time Timestamp considered to check for outages, null for current date/time.

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Toutage_created class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\event;
use core\event\base;

View File

@@ -14,14 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outage_deleted class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\event;
use core\event\base;

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outage_updated class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\event;
use core\event\base;

View File

@@ -14,22 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* delete class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\form\outage;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/formslib.php');
/**
* delete class.

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* edit class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\form\outage;
use auth_outage\local\outage;
@@ -31,7 +22,7 @@ use moodleform;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->libdir . '/formslib.php');
/**
* edit class.
@@ -57,9 +48,6 @@ class edit extends moodleform {
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);
$mform->addElement('checkbox', 'autostart', get_string('autostart', 'auth_outage'));
$mform->addHelpButton('autostart', 'autostart', 'auth_outage');
$mform->addElement('duration', 'warningduration', get_string('warningduration', 'auth_outage'));
$mform->addHelpButton('warningduration', 'warningduration', 'auth_outage');
@@ -73,7 +61,7 @@ class edit extends moodleform {
'text',
'title',
get_string('title', 'auth_outage'),
'maxlength="'.self::TITLE_MAX_CHARS.'" size="60"'
'maxlength="' . self::TITLE_MAX_CHARS . '" size="60"'
);
$mform->setType('title', PARAM_TEXT);
$mform->addHelpButton('title', 'title', 'auth_outage');
@@ -84,6 +72,23 @@ class edit extends moodleform {
$mform->addElement('static', 'usagehints', '', get_string('textplaceholdershint', 'auth_outage'));
$mform->addElement('static', 'warningreenablemaintenancemode', '');
$mform->addElement(
'advcheckbox',
'useaccesskey',
get_string('useaccesskey', 'auth_outage'),
get_string('useaccesskey:desc', 'auth_outage'),
0
);
$mform->addElement('text', 'accesskey', get_string('accesskey', 'auth_outage'));
$mform->setType('accesskey', PARAM_TEXT);
$mform->disabledIf('accesskey', 'useaccesskey');
$mform->addHelpButton('accesskey', 'accesskey', 'auth_outage');
$mform->addElement('text', 'metadata', get_string('metadata', 'auth_outage'));
$mform->setType('metadata', PARAM_TEXT);
$mform->addHelpButton('metadata', 'metadata', 'auth_outage');
$this->add_action_buttons();
}
@@ -126,17 +131,18 @@ class edit extends moodleform {
return null;
}
if ($data->description['format'] != '1') {
debugging('Not implemented for format '.$data->description['format'], DEBUG_DEVELOPER);
debugging('Not implemented for format ' . $data->description['format'], DEBUG_DEVELOPER);
return null;
}
$outagedata = [
'id' => ($data->id === 0) ? null : $data->id,
'autostart' => (isset($data->autostart) && ($data->autostart == 1)),
'starttime' => $data->starttime,
'stoptime' => $data->starttime + $data->outageduration,
'warntime' => $data->starttime - $data->warningduration,
'title' => $data->title,
'description' => $data->description['text'],
'accesskey' => $data->useaccesskey ? $data->accesskey : null,
'metadata' => $data->metadata ?? null,
];
return new outage($outagedata);
}
@@ -154,27 +160,33 @@ class edit extends moodleform {
if ($outage instanceof outage) {
$this->_form->setDefaults([
'id' => $outage->id,
'autostart' => $outage->autostart,
'starttime' => $outage->starttime,
'outageduration' => $outage->get_duration_planned(),
'warningduration' => $outage->get_warning_duration(),
'title' => $outage->title,
'description' => ['text' => $outage->description, 'format' => '1'],
'accesskey' => $outage->accesskey,
'useaccesskey' => !empty($outage->accesskey),
'metadata' => $outage->metadata,
]);
// If the default_autostart is configured in config, then force autostart to be the default value.
if (array_key_exists('auth_outage', $CFG->forced_plugin_settings)
&& array_key_exists('default_autostart', $CFG->forced_plugin_settings['auth_outage'])) {
if (
array_key_exists('auth_outage', $CFG->forced_plugin_settings)
&& array_key_exists('default_autostart', $CFG->forced_plugin_settings['auth_outage'])
) {
$this->_form->setDefaults([
'autostart' => $CFG->forced_plugin_settings['auth_outage']['default_autostart']
'autostart' => $CFG->forced_plugin_settings['auth_outage']['default_autostart'],
]);
$mform->freeze('autostart');
}
if (!empty($outage->id) && $outage->autostart && $outage->starttime < time() && $outage->stoptime > time()) {
$warning = $mform->getElement('warningreenablemaintenancemode');
$warning->setValue($OUTPUT->notification(get_string('warningreenablemaintenancemode', 'auth_outage'),
'notifywarning'));
$warning->setValue($OUTPUT->notification(
get_string('warningreenablemaintenancemode', 'auth_outage'),
'notifywarning'
));
}
} else {
throw new coding_exception('$outage must be an outage object.', $outage);

View File

@@ -14,22 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* finish class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\form\outage;
use moodleform;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->libdir . '/formslib.php');
/**
* finish class.

View File

@@ -0,0 +1,47 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace auth_outage;
use auth_outage\local\outagelib;
use core\hook\output\before_standard_top_of_body_html_generation;
/**
* Hook callbacks for auth_outage.
*
* @package auth_outage
* @author Benjamin Walker (benjaminwalker@catalyst-au.net)
* @copyright 2024 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class hook_callbacks {
/**
* Inject the warning bar into the page if there is currently an outage.
*
* @param before_standard_top_of_body_html_generation $hook
*/
public static function before_standard_top_of_body_html_generation(before_standard_top_of_body_html_generation $hook): void {
global $CFG;
if (during_initial_install() || isset($CFG->upgraderunning)) {
// Do nothing during installation or upgrade.
return;
}
// Get code to inject.
$hook->add_html(outagelib::get_inject_code());
}
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* cli_exception class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use Exception;
@@ -85,9 +76,9 @@ class cli_exception extends Exception {
* cliexception constructor.
* @param string $message An explanation of the exception.
* @param int $code Exit code to be used.
* @param Exception $previous Another exception as reference or null.
* @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);
public function __construct($message, $code = 1, ?Exception $previous = null) {
parent::__construct('*ERROR* ' . $message, $code, $previous = null);
}
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* clibase class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\local\outagelib;
@@ -50,12 +41,12 @@ abstract class clibase {
/**
* clibase constructor.
* @param array $options The parameters to use.
* @param array|null $options The parameters to use.
* @throws cli_exception
*/
public function __construct(array $options = null) {
public function __construct(?array $options = null) {
global $CFG;
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->libdir . '/clilib.php');
$warning = outagelib::generate_plugin_configuration_warning();
if ($warning) {
@@ -66,11 +57,13 @@ abstract class clibase {
if (is_null($options)) {
// Using Moodle CLI API to read the parameters.
list($options, $unrecognized) = cli_get_params($this->generate_options(), $this->generate_shortcuts());
[$options, $unrecognized] = cli_get_params($this->generate_options(), $this->generate_shortcuts());
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
throw new cli_exception(get_string('cliunknowoption', 'admin', $unrecognized),
cli_exception::ERROR_PARAMETER_UNKNOWN);
throw new cli_exception(
get_string('cliunknowoption', 'admin', $unrecognized),
cli_exception::ERROR_PARAMETER_UNKNOWN
);
}
} else {
// If not using Moodle CLI API to read parameters, ensure all keys exist.
@@ -138,13 +131,13 @@ abstract class clibase {
$options = $this->generate_options();
$shorts = array_flip($this->generate_shortcuts());
printf("%s\n\n", get_string('cli'.$cliname.'help', 'auth_outage'));
printf("%s\n\n", get_string('cli' . $cliname . 'help', 'auth_outage'));
foreach (array_keys($options) as $long) {
$text = get_string('cli'.$cliname.'param'.$long, 'auth_outage');
$short = isset($shorts[$long]) ? ('-'.$shorts[$long].',') : '';
$long = '--'.$long;
$text = get_string('cli' . $cliname . 'param' . $long, 'auth_outage');
$short = isset($shorts[$long]) ? ('-' . $shorts[$long] . ',') : '';
$long = '--' . $long;
printf(" %-4s %-20s %s\n", $short, $long, $text);
}
printf("\n%s\n\n", get_string('cli'.$cliname.'examples', 'auth_outage'));
printf("\n%s\n\n", get_string('cli' . $cliname . 'examples', 'auth_outage'));
}
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* create class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
@@ -37,7 +28,8 @@ 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.
*/
@@ -52,7 +44,6 @@ class create extends clibase {
return [
'help' => false,
'clone' => null,
'autostart' => null,
'warn' => null,
'start' => null,
'duration' => null,
@@ -69,7 +60,6 @@ class create extends clibase {
*/
public function generate_shortcuts() {
return [
'a' => 'autostart',
'b' => 'block',
'c' => 'clone',
'd' => 'duration',
@@ -92,7 +82,7 @@ class create extends clibase {
// Check if any extra parameter was given.
foreach (array_keys($defaults) as $key) {
if (!array_key_exists($key, $missing)) {
throw new coding_exception('$default['.$key.'] is not valid.');
throw new coding_exception('$default[' . $key . '] is not valid.');
}
unset($missing[$key]);
}
@@ -100,7 +90,7 @@ class create extends clibase {
// Check if any required parameter is missing.
foreach (array_keys($missing) as $k => $v) {
if (is_null($v)) {
throw new coding_exception('$default[] missing: '.$k);
throw new coding_exception('$default[] missing: ' . $k);
}
}
@@ -119,8 +109,10 @@ class create extends clibase {
// If not help mode, 'start' is required and cannot use default.
if (is_null($this->options['start'])) {
throw new cli_exception(get_string('clierrormissingparamaters', 'auth_outage'),
cli_exception::ERROR_PARAMETER_MISSING);
throw new cli_exception(
get_string('clierrormissingparamaters', 'auth_outage'),
cli_exception::ERROR_PARAMETER_MISSING
);
}
// If cloning, set defaults to outage being cloned.
@@ -132,7 +124,7 @@ class create extends clibase {
$options = $this->merge_options();
$id = $this->create_outage($options);
if ($options['block']) {
if ($options['block'] && !$options['onlyid']) {
$block = new waitforit(['outageid' => $id]);
$block->execute();
}
@@ -172,7 +164,6 @@ class create extends clibase {
// an outage 47 years in advance.
$start = $options['start'] > 1500000000 ? $options['start'] : $this->time + $options['start'];
$outage = new outage([
'autostart' => $options['autostart'],
'warntime' => $start - $options['warn'],
'starttime' => $start,
'stoptime' => $start + $options['duration'],
@@ -198,13 +189,14 @@ class create extends clibase {
private function clone_defaults() {
$id = $this->options['clone'];
if (!is_number($id) || ($id <= 0)) {
throw new cli_exception(get_string('clierrorinvalidvaluenotid', 'auth_outage', ['param' => 'clone']),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvaluenotid', 'auth_outage', ['param' => 'clone']),
cli_exception::ERROR_PARAMETER_INVALID
);
}
$outage = outagedb::get_by_id((int)$id);
$this->set_defaults([
'autostart' => $outage->autostart,
'warn' => $outage->get_warning_duration(),
'duration' => $outage->get_duration_planned(),
'title' => $outage->title,
@@ -227,10 +219,6 @@ class create extends clibase {
$options[$param] = $this->merge_options_check_parameters_string_nonempty($options[$param], $param);
}
foreach (['autostart'] as $param) {
$options[$param] = $this->merge_options_check_parameters_bool($options[$param], $param);
}
return $options;
}
@@ -243,13 +231,17 @@ class create extends clibase {
*/
private function merge_options_check_parameters_int_nonnegative($option, $param) {
if (!is_number($option)) {
throw new cli_exception(get_string('clierrorinvalidvaluenotnumber', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvaluenotnumber', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID
);
}
$option = (int)$option;
if ($option < 0) {
throw new cli_exception(get_string('clierrorinvalidvaluenegativenumber', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvaluenegativenumber', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID
);
}
return $option;
}
@@ -263,13 +255,17 @@ class create extends clibase {
*/
private function merge_options_check_parameters_string_nonempty($option, $param) {
if (!is_string($option)) {
throw new cli_exception(get_string('clierrorinvalidvaluenotstring', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvaluenotstring', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID
);
}
$option = trim($option);
if (strlen($option) == 0) {
throw new cli_exception(get_string('clierrorinvalidvalueemptystring', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvalueemptystring', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID
);
}
return $option;
}
@@ -296,7 +292,9 @@ class create extends clibase {
}
}
throw new cli_exception(get_string('clierrorinvalidvaluenotbool', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvaluenotbool', 'auth_outage', ['param' => $param]),
cli_exception::ERROR_PARAMETER_INVALID
);
}
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* finish class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
@@ -75,16 +66,20 @@ class finish extends clibase {
// Cannot run during CLI_MAINTENANCE mode.
if (CLI_MAINTENANCE) {
throw new cli_exception(get_string('cliinmaintenancemode', 'auth_outage'),
cli_exception::ERROR_MAINTENANCE_MODE);
throw new cli_exception(
get_string('cliinmaintenancemode', 'auth_outage'),
cli_exception::ERROR_MAINTENANCE_MODE
);
}
// Requires outageid or active but not both at the same time.
$byid = !is_null($this->options['outageid']);
$byactive = $this->options['active'];
if ($byid == $byactive) {
throw new cli_exception(get_string('cliwaitforiterroridxoractive', 'auth_outage'),
cli_exception::ERROR_PARAMETER_MISSING);
throw new cli_exception(
get_string('cliwaitforiterroridxoractive', 'auth_outage'),
cli_exception::ERROR_PARAMETER_MISSING
);
}
$outage = $this->get_outage();
@@ -106,8 +101,10 @@ class finish extends clibase {
} else {
$id = $this->options['outageid'];
if (!is_number($id) || ($id <= 0)) {
throw new cli_exception(get_string('clierrorinvalidvalue', 'auth_outage', ['param' => 'outageid']),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvalue', 'auth_outage', ['param' => 'outageid']),
cli_exception::ERROR_PARAMETER_INVALID
);
}
$outage = outagedb::get_by_id((int)$id);
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* waitforit class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
@@ -99,8 +90,10 @@ class waitforit extends clibase {
$byid = !is_null($this->options['outageid']);
$byactive = $this->options['active'];
if ($byid == $byactive) {
throw new cli_exception(get_string('cliwaitforiterroridxoractive', 'auth_outage'),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('cliwaitforiterroridxoractive', 'auth_outage'),
cli_exception::ERROR_PARAMETER_INVALID
);
}
$this->verbose('Verbose mode activated.');
@@ -109,11 +102,11 @@ class waitforit extends clibase {
while ($sleep = $this->wait_for_outage_to_start($outage)) {
if (is_null($this->sleepcallback)) {
$this->verbose('Sleeping for '.$sleep.' second(s).');
$this->verbose('Sleeping for ' . $sleep . ' second(s).');
sleep($sleep);
$this->time = time();
} else {
$this->verbose('Calling callback to sleep '.$sleep.' second(s).');
$this->verbose('Calling callback to sleep ' . $sleep . ' second(s).');
$callback = $this->sleepcallback;
$this->time = $callback($sleep);
}
@@ -129,7 +122,7 @@ class waitforit extends clibase {
return;
}
$time = \core_date::strftime('%F %T %Z');
$time = date('Y-m-d H:i:s T', time());
printf("[%s] %s\n", $time, $message);
}
@@ -145,10 +138,12 @@ class waitforit extends clibase {
} else {
$id = $this->options['outageid'];
if (!is_number($id) || ($id <= 0)) {
throw new cli_exception(get_string('clierrorinvalidvalue', 'auth_outage', ['param' => 'outageid']),
cli_exception::ERROR_PARAMETER_INVALID);
throw new cli_exception(
get_string('clierrorinvalidvalue', 'auth_outage', ['param' => 'outageid']),
cli_exception::ERROR_PARAMETER_INVALID
);
}
$this->verbose('Querying database for outage #'.$id.'...');
$this->verbose('Querying database for outage #' . $id . '...');
$outage = outagedb::get_by_id((int)$id);
}
@@ -156,7 +151,7 @@ class waitforit extends clibase {
throw new cli_exception(get_string('clierroroutagenotfound', 'auth_outage'), cli_exception::ERROR_OUTAGE_NOT_FOUND);
}
$this->verbose('Found outage #'.$outage->id.': '.$outage->get_title());
$this->verbose('Found outage #' . $outage->id . ': ' . $outage->get_title());
return $outage;
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* infopage class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\controllers;
use auth_outage\dml\outagedb;
@@ -53,9 +44,9 @@ class infopage {
/**
* infopage_controller constructor.
* @param array $params Parameters to use or null to get from Moodle API (request).
* @param array|null $params Parameters to use or null to get from Moodle API (request).
*/
public function __construct(array $params = null) {
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.
@@ -118,12 +109,19 @@ class infopage {
// No hooks injecting into this page, do it manually.
echo outagelib::get_inject_code();
// Inject metadata into the header before output.
if (!empty($this->outage->metadata)) {
header('X-Outage-Metadata: ' . $this->outage->metadata);
header('X-Outage-StartTime: ' . $this->outage->starttime);
header('X-Outage-EndTime: ' . $this->outage->stoptime);
}
echo $OUTPUT->header();
$viewbag = [
'admin' => is_siteadmin(),
'outage' => $this->outage,
];
require($CFG->dirroot.'/auth/outage/views/info/content.php');
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)) {
@@ -142,7 +140,7 @@ class infopage {
}
if (!is_null($params['id']) && !is_null($params['outage']) && ($params['id'] !== $params['outage']->id)) {
throw new coding_exception('Provided id and outage->id do not match.', $params['id'].'/'.$params['outage']->id);
throw new coding_exception('Provided id and outage->id do not match.', $params['id'] . '/' . $params['outage']->id);
}
if (is_null($params['id']) && is_null($params['outage'])) {

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* maintenance_static_page class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\controllers;
use auth_outage\local\outage;
@@ -58,8 +49,15 @@ class maintenance_static_page {
} else if (PHPUNIT_TEST || defined('BEHAT_SITE_RUNNING')) {
$html = '<html></html>';
} else {
// Inject metadata into the header before output.
if (!empty($outage->metadata)) {
header('X-Outage-Metadata: ' . $outage->metadata);
header('X-Outage-StartTime: ' . $outage->starttime);
header('X-Outage-EndTime: ' . $outage->stoptime);
}
$data = maintenance_static_page_io::file_get_data(
$CFG->wwwroot.'/auth/outage/info.php?auth_outage_hide_warning=1&static=1&id='.$outage->id);
$CFG->wwwroot . '/auth/outage/info.php?auth_outage_hide_warning=1&static=1&id=' . $outage->id
);
$html = $data['contents'];
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* maintenance_static_page_generator class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\controllers;
use auth_outage\local\outagelib;
@@ -83,7 +74,6 @@ class maintenance_static_page_generator {
$this->io->cleanup();
if (!is_null($this->dom)) {
// This can take a while to process using repeated curls.
core_php_time_limit::raise();
@@ -193,9 +183,9 @@ class maintenance_static_page_generator {
$fullurl = $originalurl;
} else if ($originalurl[0] == '/') {
$rooturl = parse_url($CFG->wwwroot);
$fullurl = $rooturl['scheme'].'://'.$rooturl['host'].$originalurl;
$fullurl = $rooturl['scheme'] . '://' . $rooturl['host'] . $originalurl;
} else {
$fullurl = $baseref.'/'.$originalurl;
$fullurl = $baseref . '/' . $originalurl;
}
$saved = $this->io->save_url_file($fullurl);
@@ -262,7 +252,7 @@ class maintenance_static_page_generator {
$fullurl = (string) new moodle_url($matches[1]);
}
$newurl = $this->io->generate_file_url($fullurl);
$updated = preg_replace(self::PATTERN, ' url('.$newurl.') ', $style);
$updated = preg_replace(self::PATTERN, ' url(' . $newurl . ') ', $style);
$element->setAttribute('style', $updated);
}
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* maintenance_static_page_io class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\controllers;
use auth_outage\local\outagelib;
@@ -70,7 +61,7 @@ class maintenance_static_page_io {
}
if ($result['contents'] === false) {
debugging('Cannot fetch: '.$file);
debugging('Cannot fetch: ' . $file);
$result = ['contents' => '', 'mime' => 'unknown'];
}
return $result;
@@ -94,9 +85,9 @@ class maintenance_static_page_io {
public function get_template_file() {
global $CFG;
if ($this->preview) {
return $this->get_resources_folder().'/climaintenance.html';
return $this->get_resources_folder() . '/climaintenance.html';
} else {
return $CFG->dataroot.'/climaintenance.template.html';
return $CFG->dataroot . '/climaintenance.template.html';
}
}
@@ -111,10 +102,10 @@ class maintenance_static_page_io {
global $CFG;
// If you change the path, also change file auth/outage/bootstrap.php as it does not use this reference.
$dir = $CFG->dataroot.'/auth_outage/climaintenance';
$dir = $CFG->dataroot . '/auth_outage/climaintenance';
if ($this->preview) {
$dir = $dir.'/preview';
$dir = $dir . '/preview';
}
return $dir;
}
@@ -164,18 +155,18 @@ class maintenance_static_page_io {
$dir = realpath($dir);
$safedir = $this->get_resources_folder();
if (substr($dir, 0, strlen($safedir)) !== $safedir) {
throw new invalid_parameter_exception('Unsafe to delete: '.$dir);
throw new invalid_parameter_exception('Unsafe to delete: ' . $dir);
}
if (!is_dir($dir)) {
throw new coding_exception('Not a directory: '.$dir);
throw new coding_exception('Not a directory: ' . $dir);
}
$files = scandir($dir);
foreach ($files as $file) {
if (($file == '.') || ($file == '..')) {
continue;
}
$file = $dir.'/'.$file;
$file = $dir . '/' . $file;
if (is_file($file)) {
unlink($file);
continue;
@@ -184,7 +175,7 @@ class maintenance_static_page_io {
$this->delete_directory_recursively($file);
continue;
}
throw new coding_exception('Not a file or directory: '.$file);
throw new coding_exception('Not a file or directory: ' . $file);
}
rmdir($dir);
}
@@ -220,7 +211,7 @@ class maintenance_static_page_io {
global $CFG;
if (!self::is_url($url)) {
debugging('Found a relative url ('.$url.') -- is it using moodle_url()?');
debugging('Found a relative url (' . $url . ') -- is it using moodle_url()?');
return null; // Leave hardcoded URLs as it is.
}
@@ -236,12 +227,12 @@ class maintenance_static_page_io {
$data = self::file_get_data($url);
$mime = trim(base64_encode($data['mime']), '=');
$url = sha1($data['contents']).'.'.$mime;
$filepath = $this->get_resources_folder().'/'.$url;
$url = sha1($data['contents']) . '.' . $mime;
$filepath = $this->get_resources_folder() . '/' . $url;
file_put_contents($filepath, $data['contents']);
if ($this->preview) {
$url = 'preview/'.$url;
$url = 'preview/' . $url;
}
return ['file' => $filepath, 'url' => $url];

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outage class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local;
use coding_exception;
@@ -67,11 +58,6 @@ class outage {
*/
public $id = null;
/**
* @var bool|null Maintenance mode auto start flag.
*/
public $autostart = null;
/**
* @var int|null Start Time timestamp.
*/
@@ -117,6 +103,16 @@ class outage {
*/
public $lastmodified = null;
/**
* @var string|null access key, or null if not enabled.
*/
public $accesskey = null;
/**
* @var string|null metadata string, or null if not enabled.
*/
public $metadata = null;
/**
* outage constructor.
* @param stdClass|array|null $data The data for the outage.
@@ -293,9 +289,6 @@ class outage {
foreach ($fs as $f) {
$this->$f = ($this->$f === null) ? null : (int)$this->$f;
}
// Adjust bool fields.
$this->autostart = ($this->autostart === null) ? null : (bool)$this->autostart;
}
/**

View File

@@ -14,20 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outagelib class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local;
use auth_outage\dml\outagedb;
use auth_outage\local\controllers\maintenance_static_page;
use auth_outage\output\renderer;
use coding_exception;
use curl;
use Exception;
@@ -36,8 +26,7 @@ use invalid_parameter_exception;
use stdClass;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../../lib.php');
require_once(__DIR__ . '/../../lib.php');
/**
* outagelib class.
@@ -48,7 +37,6 @@ require_once(__DIR__.'/../../lib.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class outagelib {
/** Outage start. */
const OUTAGE_START = '<!-- OUTAGESTART -->';
@@ -68,7 +56,7 @@ class outagelib {
global $CFG;
require_once($CFG->libdir . '/filelib.php');
$curl = new curl();
$curl = new curl(['ignoresecurity' => true]);
$contents = $curl->get($file);
$info = $curl->get_info();
if (!empty($info['content_type'])) {
@@ -146,7 +134,7 @@ class outagelib {
$renderer = $PAGE->get_renderer('auth_outage');
return $renderer->render_warningbar($active, $time, false, $preview);
} catch (Exception $e) {
debugging('Exception occured while injecting our code: '.$e->getMessage());
debugging('Exception occured while injecting our code: ' . $e->getMessage());
debugging($e->getTraceAsString(), DEBUG_DEVELOPER);
}
}
@@ -185,7 +173,6 @@ class outagelib {
'allowedips' => '',
'css' => '',
'default_time' => '',
'default_autostart' => '0',
'default_duration' => (string)(60 * 60),
'default_warning_duration' => (string)(60 * 60),
'default_title' => get_string('defaulttitlevalue', 'auth_outage'),
@@ -206,9 +193,6 @@ class outagelib {
$outage = outagedb::get_ongoing();
if (is_null($outage)) {
$outage = outagedb::get_next_starting();
$ongoingoutage = false;
} else {
$ongoingoutage = true;
}
// Set json formatted outage string to cache.
@@ -216,9 +200,6 @@ class outagelib {
maintenance_static_page::create_from_outage($outage)->generate();
self::update_climaintenance_code($outage);
if (!$ongoingoutage || $reenablemaint || is_null($outage)) {
self::update_maintenance_later($outage);
}
}
/**
@@ -230,25 +211,6 @@ class outagelib {
return (!empty($result['contents']));
}
/**
* Calls Moodle API - set_maintenance_later() to set when the next outage starts.
* @param outage|null $outage Outage or null if no scheduled outage.
*/
private static function update_maintenance_later($outage) {
if (is_null($outage) || !$outage->autostart) {
unset_config('maintenance_later');
} else {
$message = get_config('moodle', 'maintenance_message');
if ($message) {
debugging('Disabling $CFG->maintenance_message to allow our template page to take place.');
debugging('Previous value: '.$message);
// We cannot do much if forced config, but the logs will show the error.
unset_config('maintenance_message');
}
set_config('maintenance_later', $outage->starttime);
self::maintenance_config_log($outage);
}
}
/**
* Checks if we should try to inject an warning bar.
@@ -264,7 +226,7 @@ class outagelib {
self::$injectcalled = true;
// Do not inject into admin/settings.php.
if ($_SERVER['SCRIPT_NAME'] == '/'.$CFG->admin.'/settings.php') {
if ($_SERVER['SCRIPT_NAME'] == '/' . $CFG->admin . '/settings.php') {
if (optional_param('section', '', PARAM_RAW) === 'additionalhtml') {
return false;
}
@@ -277,7 +239,7 @@ class outagelib {
// Used to test the try block in case of errors.
if (PHPUNIT_TEST && optional_param('auth_outage_break_code', false, PARAM_INT)) {
(new stdClass())->invalidfield; // Triggers an exception.
throw new coding_exception('Exception triggered');
}
// Nothing preventing the injection.
@@ -290,57 +252,102 @@ class outagelib {
* @param int $starttime Outage start time.
* @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.
*
* @return string
* @throws invalid_parameter_exception
*/
public static function create_climaintenancephp_code($starttime, $stoptime, $allowedips) {
public static function create_climaintenancephp_code($starttime, $stoptime, $allowedips, $accesskey = null, $metadata = null) {
global $CFG;
if (!is_int($starttime) || !is_int($stoptime)) {
throw new invalid_parameter_exception('Make sure $startime and $stoptime are integers.');
}
if (!is_string($allowedips) || (trim($allowedips) == '')) {
throw new invalid_parameter_exception('$allowedips must be a valid string.');
}
// I know Moodle validation would clean up this field, but just in case, let's ensure no
// single-quotes (and double for the sake of it) are present otherwise it would break the code.
$allowedips = addslashes($allowedips);
$cookiesecure = is_moodle_cookie_secure();
// Since Moodle 4.3 cookiehttponly is default to true and this CFG is not set.
// so if not set, default to true.
$cookiehttponly = isset($CFG->cookiehttponly) ? (bool) $CFG->cookiehttponly : true;
$code = <<<'EOT'
<?php
if ((time() >= {{STARTTIME}}) && (time() < {{STOPTIME}})) {
define('MOODLE_INTERNAL', true);
if (!defined('MOODLE_INTERNAL')) {
define('MOODLE_INTERNAL', true);
}
require_once($CFG->dirroot.'/lib/moodlelib.php');
if (file_exists($CFG->dirroot.'/lib/classes/ip_utils.php')) {
require_once($CFG->dirroot.'/lib/classes/ip_utils.php');
}
if (!remoteip_in_list('{{ALLOWEDIPS}}')) {
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');
header('X-Moodle-Maintenance: manager');
if ((defined('AJAX_SCRIPT') && AJAX_SCRIPT) || (defined('WS_SERVER') && WS_SERVER)) {
// 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);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
setcookie('auth_outage_accesskey', $urlaccesskey, time() + 86400, '/', '', {{COOKIESECURE}}, {{COOKIEHTTPONLY}});
}
// Use url access key if given, else the cookie, else null.
$useraccesskey = $urlaccesskey ?: $_COOKIE['auth_outage_accesskey'] ?? null;
$ipblocked = !remoteip_in_list('{{ALLOWEDIPS}}');
$accesskeyblocked = $useraccesskey != '{{ACCESSKEY}}';
$allowed = ({{USEACCESSKEY}} && !$accesskeyblocked) || ({{USEALLOWEDIPS}} && !$ipblocked);
if (!$allowed) {
if (!$isphpunit) {
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');
header('X-Moodle-Maintenance: manager');
if (!empty({{METADATA}})) {
header('X-Outage-Metadata: ' . {{METADATA}});
}
header('X-Outage-StartTime: ' . '{{STARTTIME}}');
header('X-Outage-EndTime: ' . '{{STOPTIME}}');
}
if (!$isphpunit && ((defined('AJAX_SCRIPT') && AJAX_SCRIPT) || (defined('WS_SERVER') && WS_SERVER))) {
exit(0);
}
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);
if ({{USEALLOWEDIPS}} && $ipblocked) {
echo '<!-- auth_outage blocked your ip: '.getremoteaddr('n/a').' -->';
}
if ({{USEACCESSKEY}} && $accesskeyblocked) {
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: '. $useraccesskey .' -->';
}
if (!$isphpunit) {
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.');
}
// The file above should always exist, but just in case...
die('We are currently under maintentance, please try again later.');
}
}
EOT;
$search = ['{{STARTTIME}}', '{{STOPTIME}}', '{{ALLOWEDIPS}}', '{{YOURIP}}'];
$replace = [$starttime, $stoptime, $allowedips, getremoteaddr('n/a')];
$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)];
return str_replace($search, $replace, $code);
}
@@ -354,7 +361,7 @@ EOT;
*/
public static function update_climaintenance_code($outage) {
global $CFG;
$file = $CFG->dataroot.'/climaintenance.php';
$file = $CFG->dataroot . '/climaintenance.php';
if (!is_null($outage) && !($outage instanceof outage)) {
throw new coding_exception('$outage must be null or an outage object.');
@@ -362,17 +369,20 @@ EOT;
$config = self::get_config();
$allowedips = trim($config->allowedips);
$accesskey = $outage->accesskey ?? null;
$metadata = $outage->metadata ?? null;
if (is_null($outage) || ($allowedips == '')) {
// If no outage, or allowed ips is null and access key is null (i.e. no blocking required).
if (is_null($outage) || ($allowedips == '' && empty($accesskey))) {
if (file_exists($file)) {
unlink($file);
}
} else {
$code = self::create_climaintenancephp_code($outage->starttime, $outage->stoptime, $allowedips);
$code = self::create_climaintenancephp_code($outage->starttime, $outage->stoptime, $allowedips, $accesskey, $metadata);
$dir = dirname($file);
if (!file_exists($dir) || !is_dir($dir)) {
throw new file_exception('Directory must exists: '.$dir);
throw new file_exception('Directory must exists: ' . $dir);
}
file_put_contents($file, $code);
}
@@ -388,8 +398,10 @@ EOT;
$message = [];
if (trim(self::get_config()->allowedips) != ''
&& (!isset($CFG->auth_outage_bootstrap_loaded) || !$CFG->auth_outage_bootstrap_loaded)) {
if (
trim(self::get_config()->allowedips) != ''
&& (!isset($CFG->auth_outage_bootstrap_loaded) || !$CFG->auth_outage_bootstrap_loaded)
) {
$message[] = get_string('configurationwarning', 'auth_outage');
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* base_table class.
*
* @package auth_outage
* @author Daniel Thee Roperto <danielroperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\output\manage;
use auth_outage\local\outage;
@@ -31,8 +22,7 @@ use html_writer;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir . '/tablelib.php');
/**
* base_table class.
@@ -68,12 +58,47 @@ class base_table extends flexible_table {
global $PAGE;
$id = (is_null($id) ? self::$autoid++ : $id);
parent::__construct('auth_outage_manage_'.$id);
parent::__construct('auth_outage_manage_' . $id);
$this->define_baseurl($PAGE->url);
$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.
@@ -87,12 +112,7 @@ class base_table extends flexible_table {
// View button.
$buttons .= html_writer::link(
new moodle_url('/auth/outage/info.php', ['id' => $outage->id]),
html_writer::empty_tag('img', [
'src' => $OUTPUT->image_url('t/preview'),
'alt' => get_string('view'),
'class' => 'iconsmall',
]),
$OUTPUT->pix_icon('t/preview', get_string('view'), 'moodle', ['class' => 'iconsmall']),
[
'title' => get_string('view'),
'target' => '_blank',
@@ -103,11 +123,7 @@ class base_table extends flexible_table {
if ($editdelete) {
$buttons .= html_writer::link(
new moodle_url('/auth/outage/edit.php', ['edit' => $outage->id]),
html_writer::empty_tag('img', [
'src' => $OUTPUT->image_url('t/edit'),
'alt' => get_string('edit'),
'class' => 'iconsmall',
]),
$OUTPUT->pix_icon('t/edit', get_string('edit'), 'moodle', ['class' => 'iconsmall']),
['title' => get_string('edit')]
);
}
@@ -115,12 +131,7 @@ class base_table extends flexible_table {
// Clone button.
$buttons .= html_writer::link(
new moodle_url('/auth/outage/edit.php', ['clone' => $outage->id]),
html_writer::empty_tag('img', [
'src' => $OUTPUT->image_url('t/copy'),
'alt' => get_string('clone', 'auth_outage'),
'class' => 'iconsmall',
]),
$OUTPUT->pix_icon('t/copy', get_string('clone', 'auth_outage'), 'moodle', ['class' => 'iconsmall']),
['title' => get_string('clone', 'auth_outage')]
);
@@ -128,11 +139,7 @@ class base_table extends flexible_table {
if ($outage->is_ongoing()) {
$buttons .= html_writer::link(
new moodle_url('/auth/outage/finish.php', ['id' => $outage->id]),
html_writer::empty_tag('img', [
'src' => $OUTPUT->image_url('t/check'),
'alt' => get_string('finish', 'auth_outage'),
'class' => 'iconsmall',
]),
$OUTPUT->pix_icon('t/check', get_string('finish', 'auth_outage'), 'moodle', ['class' => 'iconsmall']),
['title' => get_string('finish', 'auth_outage')]
);
}
@@ -141,11 +148,7 @@ class base_table extends flexible_table {
if ($editdelete) {
$buttons .= html_writer::link(
new moodle_url('/auth/outage/delete.php', ['id' => $outage->id]),
html_writer::empty_tag('img', [
'src' => $OUTPUT->image_url('t/delete'),
'alt' => get_string('delete'),
'class' => 'iconsmall',
]),
$OUTPUT->pix_icon('t/delete', get_string('delete'), 'moodle', ['class' => 'iconsmall']),
['title' => get_string('delete')]
);
}

View File

@@ -14,22 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* history_table class.
*
* @package auth_outage
* @author Daniel Thee Roperto <danielroperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\output\manage;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir . '/tablelib.php');
/**
* history_table class.
@@ -46,7 +36,7 @@ class history_table extends base_table {
public function __construct() {
parent::__construct();
$this->define_columns(['warning', 'starts', 'durationplanned', 'durationactual', 'title', 'actions']);
$this->define_columns(['warning', 'starts', 'duration', 'durationactual', 'title', 'created', 'modified', 'actions']);
$this->define_headers([
get_string('tableheaderwarnbefore', 'auth_outage'),
@@ -54,9 +44,10 @@ 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'),
]
);
]);
$this->setup();
}
@@ -75,6 +66,8 @@ 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),
]);
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* planned_table class.
*
* @package auth_outage
* @author Daniel Thee Roperto <danielroperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\output\manage;
use auth_outage\local\outage;
@@ -30,8 +21,7 @@ use html_writer;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/tablelib.php');
require_once($CFG->libdir . '/tablelib.php');
/**
* planned_table class.
@@ -48,13 +38,15 @@ class planned_table extends base_table {
public function __construct() {
parent::__construct();
$this->define_columns(['warning', 'starts', 'duration', 'title', 'actions']);
$this->define_columns(['warning', 'starts', 'duration', 'title', 'created', 'modified', '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'),
]);
@@ -68,7 +60,7 @@ class planned_table extends base_table {
public function show_data(array $outages) {
foreach ($outages as $outage) {
$title = html_writer::link(
new moodle_url('/auth/outage/edit.php', ['id' => $outage->id]),
new moodle_url('/auth/outage/edit.php', ['edit' => $outage->id]),
$outage->get_title(),
['title' => get_string('edit')]
);
@@ -78,6 +70,8 @@ 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),
]);
}

View File

@@ -14,15 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* auth_outage_renderer class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\output;
use auth_outage\local\outage;
@@ -54,7 +45,7 @@ class renderer extends plugin_renderer_base {
$viewbag['viewfile'] = $view;
unset($view);
require($CFG->dirroot.'/auth/outage/views/'.$viewbag['viewfile']);
require($CFG->dirroot . '/auth/outage/views/' . $viewbag['viewfile']);
}
/**
@@ -97,8 +88,8 @@ class renderer extends plugin_renderer_base {
* @return string HTML for the page.
*/
public function renderdeleteconfirmation(outage $outage) {
return $this->rendersubtitle('outagedelete').
html_writer::tag('p', get_string('outagedeletewarning', 'auth_outage')).
return $this->rendersubtitle('outagedelete') .
html_writer::tag('p', get_string('outagedeletewarning', 'auth_outage')) .
$this->renderoutage($outage, false);
}
@@ -108,8 +99,8 @@ class renderer extends plugin_renderer_base {
* @return string HTML for the page.
*/
public function renderfinishconfirmation(outage $outage) {
return $this->rendersubtitle('outagefinish').
html_writer::tag('p', get_string('outagefinishwarning', 'auth_outage')).
return $this->rendersubtitle('outagefinish') .
html_writer::tag('p', get_string('outagefinishwarning', 'auth_outage')) .
$this->renderoutage($outage, false);
}
@@ -156,7 +147,7 @@ class renderer extends plugin_renderer_base {
$created = core_user::get_user($outage->createdby, 'firstname,lastname', MUST_EXIST);
$created = html_writer::link(
new moodle_url('/user/profile.php', ['id' => $outage->createdby]),
trim($created->firstname.' '.$created->lastname)
trim($created->firstname . ' ' . $created->lastname)
);
}
@@ -166,7 +157,7 @@ class renderer extends plugin_renderer_base {
$modified = core_user::get_user($outage->modifiedby, 'firstname,lastname', MUST_EXIST);
$modified = html_writer::link(
new moodle_url('/user/profile.php', ['id' => $outage->modifiedby]),
trim($modified->firstname.' '.$modified->lastname)
trim($modified->firstname . ' ' . $modified->lastname)
);
}
@@ -194,33 +185,35 @@ class renderer extends plugin_renderer_base {
$start = outagelib::OUTAGE_START;
$end = outagelib::OUTAGE_END;
$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::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', get_string('tableheaderwarnbefore', 'auth_outage').': ').
html_writer::tag('b', get_string('tableheaderwarnbefore', 'auth_outage') . ': ') .
format_time($outage->get_warning_duration())
).
) .
html_writer::div(
html_writer::tag('b', get_string('tableheaderstarttime', 'auth_outage').': ').
html_writer::tag('b', get_string('tableheaderstarttime', 'auth_outage') . ': ') .
userdate($outage->starttime, get_string('datetimeformat', 'auth_outage'))
).
) .
html_writer::div(
html_writer::tag('b', get_string('tableheaderdurationplanned', 'auth_outage').': ').
html_writer::tag('b', get_string('tableheaderdurationplanned', 'auth_outage') . ': ') .
format_time($outage->get_duration_planned())
).
) .
html_writer::div(
html_writer::tag('b', get_string('tableheaderdurationactual', 'auth_outage').': ').
html_writer::tag('b', get_string('tableheaderdurationactual', 'auth_outage') . ': ') .
$finished
).
) .
html_writer::div(
html_writer::tag('small',
'Created by '.$created.
', modified by '.$modified.' on '.
html_writer::tag(
'small',
'Created by ' . $created .
', modified by ' . $modified . ' on ' .
userdate($outage->lastmodified, get_string('datetimeformat', 'auth_outage'))
)
).
($buttons ? html_writer::div($linkedit.$linkdelete) : '')
) .
($buttons ? html_writer::div($linkedit . $linkdelete) : '')
)
);
return $start . $outagehtml . $end;

View File

@@ -13,6 +13,9 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace auth_outage\privacy;
/**
* Privacy Subsystem implementation for auth_outage.
*
@@ -20,22 +23,8 @@
* @copyright 2018 Olivier SECRET <olivier.secret@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\privacy;
use core_privacy\local\legacy_polyfill;
/**
* Privacy provider for the authentication manual.
*
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\null_provider {
use legacy_polyfill;
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
@@ -45,8 +34,7 @@ class provider implements
*
* @return string
*/
public static function _get_reason() {
public static function get_reason(): string {
return 'privacy:no_data_reason';
}
}

View File

@@ -14,18 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* update_static_page class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\task;
use auth_outage\local\controllers\infopage;
use auth_outage\local\outagelib;
use core\task\scheduled_task;

View File

@@ -28,8 +28,8 @@ use auth_outage\local\cli\create;
use auth_outage\local\outagelib;
define('CLI_SCRIPT', true);
require_once(__DIR__.'/../../../config.php');
require_once($CFG->libdir.'/clilib.php');
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir . '/clilib.php');
try {
$cli = new create();

View File

@@ -27,8 +27,8 @@ use auth_outage\local\cli\cli_exception;
use auth_outage\local\cli\finish;
define('CLI_SCRIPT', true);
require_once(__DIR__.'/../../../config.php');
require_once($CFG->libdir.'/clilib.php');
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir . '/clilib.php');
try {
$cli = new finish();
@@ -36,4 +36,3 @@ try {
} catch (cli_exception $e) {
cli_error($e->getMessage());
}

View File

@@ -27,8 +27,8 @@ use auth_outage\local\cli\cli_exception;
use auth_outage\local\cli\waitforit;
define('CLI_SCRIPT', true);
require_once(__DIR__.'/../../../config.php');
require_once($CFG->libdir.'/clilib.php');
require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir . '/clilib.php');
try {
$cli = new waitforit();
@@ -36,4 +36,3 @@ try {
} catch (cli_exception $e) {
cli_error($e->getMessage());
}

View File

@@ -26,12 +26,12 @@
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'auth/outage:viewinfo' => array(
'auth/outage:viewinfo' => [
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'archetypes' => [
'guest' => CAP_ALLOW,
'user' => CAP_ALLOW,
)
),
],
],
];

34
db/hooks.php Normal file
View File

@@ -0,0 +1,34 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Hook callbacks for auth_outage
*
* @package auth_outage
* @author Benjamin Walker (benjaminwalker@catalyst-au.net)
* @copyright 2024 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$callbacks = [
[
'hook' => \core\hook\output\before_standard_top_of_body_html_generation::class,
'callback' => '\auth_outage\hook_callbacks::before_standard_top_of_body_html_generation',
'priority' => 0,
],
];

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="auth/outage/db" VERSION="20160922" COMMENT="XMLDB file for Moodle auth/outage"
<XMLDB PATH="auth/outage/db" VERSION="20260120" COMMENT="XMLDB file for Moodle auth/outage"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
@@ -7,7 +7,6 @@
<TABLE NAME="auth_outage" COMMENT="Table used for auth/outage plugin. Holds information about all past, current and future outages.">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="autostart" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" COMMENT="If the maintenance mode should be automatically triggered once this outage startes."/>
<FIELD NAME="warntime" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="When the outage will start showing a warning for that outage."/>
<FIELD NAME="starttime" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="When outage starts."/>
<FIELD NAME="stoptime" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="When outage ends."/>
@@ -17,6 +16,8 @@
<FIELD NAME="modifiedby" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Who last modified this entry."/>
<FIELD NAME="lastmodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="When was this entry last modified."/>
<FIELD NAME="finished" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Timestamp of when the outage really finished."/>
<FIELD NAME="accesskey" TYPE="char" LENGTH="16" NOTNULL="false" SEQUENCE="false" COMMENT="Unique key used to access during outage"/>
<FIELD NAME="metadata" TYPE="text" NOTNULL="false" SEQUENCE="false" COMMENT="metadata to be exposed in outage page headers"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>

View File

@@ -47,5 +47,50 @@ function xmldb_auth_outage_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2016092200, 'auth', 'outage');
}
if ($oldversion < 2024081900) {
// Define field accesskey to be added to auth_outage.
$table = new xmldb_table('auth_outage');
$field = new xmldb_field('accesskey', XMLDB_TYPE_CHAR, '16', null, null, null, null, 'finished');
// Conditionally launch add field accesskey.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Outage savepoint reached.
upgrade_plugin_savepoint(true, 2024081900, 'auth', 'outage');
}
if ($oldversion < 2024081901) {
// 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');
// Conditionally launch add field metadata.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Outage savepoint reached.
upgrade_plugin_savepoint(true, 2024081901, 'auth', 'outage');
}
if ($oldversion < 2024081902) {
// Getting the table auth_outage and target field to remove from the table.
$table = new xmldb_table('auth_outage');
$field = new xmldb_field('autostart');
// Conditionally launch drop field autostart.
if ($dbman->field_exists($table, $field)) {
$dbman->drop_field($table, $field);
}
// Removing the default_autostart config as it is no longer used.
unset_config('default_autostart', 'auth_outage');
// Outage savepoint reached.
upgrade_plugin_savepoint(true, 2024081902, 'auth', 'outage');
}
return true;
}

View File

@@ -27,9 +27,9 @@ use auth_outage\dml\outagedb;
use auth_outage\form\outage\delete;
use auth_outage\output\renderer;
require_once(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/formslib.php');
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/formslib.php');
admin_externalpage_setup('auth_outage_manage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));
@@ -46,7 +46,7 @@ if ($mform->is_cancelled()) {
$id = required_param('id', PARAM_INT);
$outage = outagedb::get_by_id($id);
if ($outage == null) {
throw new invalid_parameter_exception('Outage #'.$id.' not found.');
throw new invalid_parameter_exception('Outage #' . $id . ' not found.');
}
$dataid = new stdClass();

View File

@@ -27,11 +27,11 @@ use auth_outage\dml\outagedb;
use auth_outage\form\outage\edit;
use auth_outage\local\outage;
use auth_outage\local\outagelib;
use auth_outage\output\renderer;
require_once(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/formslib.php');
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/formslib.php');
admin_externalpage_setup('auth_outage_manage');
$output = $PAGE->get_renderer('auth_outage');
@@ -48,7 +48,24 @@ if ($mform->is_cancelled()) {
$clone = optional_param('clone', 0, PARAM_INT);
$edit = optional_param('edit', 0, PARAM_INT);
$time = optional_param('starttime', 0, PARAM_INT);
if (array_key_exists('starttime', $_POST) && is_array($_POST['starttime'])) {
$start = optional_param_array('starttime', [], PARAM_INT);
} else {
$start = optional_param('starttime', 0, PARAM_INT);
}
if (!empty($start['year']) && !empty($start['month']) && !empty($start['day'])) {
$hour = $start['hour'] ?? 0;
$minute = $start['minute'] ?? 0;
$time = make_timestamp(
(int) $start['year'],
(int) $start['month'],
(int) $start['day'],
(int) $hour,
(int) $minute
);
} else {
$time = 0;
}
if ($clone && $edit) {
throw new invalid_parameter_exception('Cannot provide both clone and edit ids.');
}
@@ -67,12 +84,12 @@ if ($clone) {
}
$outage = new outage([
'autostart' => $config->default_autostart,
'starttime' => $time,
'stoptime' => $time + $config->default_duration,
'warntime' => $time - $config->default_warning_duration,
'title' => $config->default_title,
'description' => $config->default_description,
'metadata' => $config->default_metadata,
]);
$action = 'outagecreate';
}
@@ -83,7 +100,7 @@ if ($outage == null) {
$mform->set_data($outage);
$PAGE->navbar->add(get_string($action.'crumb', 'auth_outage'));
$PAGE->navbar->add(get_string($action . 'crumb', 'auth_outage'));
echo $output->header();
echo $output->rendersubtitle($action);
$mform->display();

View File

@@ -45,13 +45,13 @@ if (count($parts) != 2) {
$mime = base64_decode($parts[1]);
// Detect type, we only support css or PNG images.
header('Content-Type: '.$mime);
header('Content-Type: ' . $mime);
// Use cache.
$lifetime = 60 * 60 * 24; // 1 day.
header('Expires: '.gmdate('D, d M Y H:i:s', time() + $lifetime).' GMT');
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $lifetime) . ' GMT');
header('Pragma: ');
header('Cache-Control: public, max-age='.$lifetime);
header('Cache-Control: public, max-age=' . $lifetime);
header('Accept-Ranges: none');
@@ -60,7 +60,7 @@ header('Accept-Ranges: none');
*/
function auth_outage_bootstrap_callback() {
// Not using classes as classloader has not been initialized yet. Keep it minimalist.
require_once(__DIR__.'/lib.php');
require_once(__DIR__ . '/lib.php');
$file = auth_outage_get_climaintenance_resource_file($_GET['file']);
if (is_null($file)) {
// @codingStandardsIgnoreStart
@@ -69,6 +69,11 @@ function auth_outage_bootstrap_callback() {
http_response_code(404);
die('File not found.');
}
// Ensure there is nothing in the output buffer.
// otherwise the file will not be read correctly.
ob_clean();
readfile($file);
exit(0);
}
@@ -79,5 +84,5 @@ require_once(__DIR__.'/../../config.php');
// We should never reach here if config.php and auth/outage/bootstrap.php intercepted it correctly.
// If config.php did not execute the callback function we can use the debugging function here.
debugging('Your config.php is not properly configured for auth/outage plugin. '.
debugging('Your config.php is not properly configured for auth/outage plugin. ' .
'Please check the plugin settings for information.');

View File

@@ -27,9 +27,9 @@ use auth_outage\dml\outagedb;
use auth_outage\form\outage\finish;
use auth_outage\output\renderer;
require_once(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/formslib.php');
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/formslib.php');
admin_externalpage_setup('auth_outage_manage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));
@@ -46,7 +46,7 @@ if ($mform->is_cancelled()) {
$id = required_param('id', PARAM_INT);
$outage = outagedb::get_by_id($id);
if ($outage == null) {
throw new invalid_parameter_exception('Outage #'.$id.' not found.');
throw new invalid_parameter_exception('Outage #' . $id . ' not found.');
}
$dataid = new stdClass();

View File

@@ -23,13 +23,19 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['accesskey'] = 'Access key';
$string['accesskey_help'] = 'Testers should pass the access key initially in the url parameters e.g. ?accesskey=xyz. This will then be stored in a cookie for 24 hours, during which the url parameter will not be necessary.<br /><b>Note:</b> the access key is in addition to any IP restrictions setup.';
$string['allowedipsempty'] = 'No one will be blocked by IP because the list is empty. You can add your own IP address (<i>{$a->ip}</i>) and block all other IPs. IP blocking is in addition to access key blocking (if setup in outage)';
$string['allowedipshasmyip'] = 'Your IP (<i>{$a->ip}</i>) is in the list and your IP will not be blocked out during an Outage.';
$string['allowedipshasntmyip'] = 'Your IP (<i>{$a->ip}</i>) is not in the list and your IP will be blocked out during an outage.';
$string['allowedipsnoconfig'] = 'Your config.php does not have the extra setup to allow blocking via IP.<br />Please refer to our <a href="https://github.com/catalyst/moodle-auth_outage#installation" target="_blank">README.md</a> file for more information.';
$string['auth_outagedescription'] = 'Auxiliary plugin that warns users about a future outage and prevents them from logging in once the outage starts.';
$string['autostart'] = 'Auto start maintenance mode.';
$string['autostart_help'] = 'If selected, when the outage starts it will automatically turn on Moodle maintenance mode.';
$string['builtinallowediplist'] = 'Builtin Allowed IP List';
$string['builtinallowediplist_desc'] = 'A second allowed IP list which makes it easier to have some IPs forced in config.php and others editable in the UI';
$string['clicreatehelp'] = 'Creates a new outage.';
$string['clicreateexamples'] = "Create an outage starting in 10 seconds\n\n> php create.php -s=10";
$string['clicreatehelp'] = 'Creates a new outage.';
$string['clicreateparamautostart'] = 'must be Y or N, sets if the outage automatically triggers maintenance mode.';
$string['clicreateparamblock'] = 'blocks until outage starts.';
$string['clicreateparamclone'] = 'clone another outage except for the start time.';
@@ -40,16 +46,28 @@ $string['clicreateparamonlyid'] = 'only outputs the new outage id, useful for sc
$string['clicreateparamstart'] = 'in how many seconds should this outage start or unix time to start outage. Required.';
$string['clicreateparamtitle'] = 'the title of the outage.';
$string['clicreateparamwarn'] = 'how many seconds before it starts to display a warning.';
$string['clifinishhelp'] = 'Finishes an ongoing outage.';
$string['clierrorinvalidvalue'] = 'Invalid value for parameter: {$a->param}';
$string['clierrorinvalidvalueemptystring'] = 'Param --{$a->param} must not be an empty string';
$string['clierrorinvalidvaluenegativenumber'] = 'Param --{$a->param} must be a positive number';
$string['clierrorinvalidvaluenotbool'] = 'Param --{$a->param} must be set to either Y or N';
$string['clierrorinvalidvaluenotid'] = 'Param --{$a->param} must be an id number';
$string['clierrorinvalidvaluenotnumber'] = 'Param --{$a->param} must be a number';
$string['clierrorinvalidvaluenotstring'] = 'Param --{$a->param} must be a string';
$string['clierrormissingparamaters'] = 'You must specify the start time, use --help for more information.';
$string['clierroroutagechanged'] = 'Outage was changed while waiting.';
$string['clierroroutageended'] = 'Outage has already ended.';
$string['clierroroutagenotfound'] = 'Outage not found.';
$string['clifinishexamples'] = '';
$string['clifinishhelp'] = 'Finishes an ongoing outage.';
$string['clifinishnotongoing'] = 'Outage is not ongoing.';
$string['clifinishparamhelp'] = 'shows parameters help.';
$string['clifinishparamactive'] = 'finishes the currently active outage.';
$string['clifinishparamhelp'] = 'shows parameters help.';
$string['clifinishparamoutageid'] = 'the id of the outage to finish.';
$string['cliinmaintenancemode'] = 'Moodle maintenance mode is on. Use "php admin/cli/maintenance.php --disable" to disable it before finishing the outage.';
$string['clioutagecreated'] = 'Outage created, id: {$a->id}';
$string['cliwaitforiterroridxoractive'] = 'You must use --outageid=# or --active parameter but not both.';
$string['cliwaitforithelp'] = 'Waits until an outage starts.';
$string['cliwaitforitexamples'] = '';
$string['cliwaitforithelp'] = 'Waits until an outage starts.';
$string['cliwaitforitoutagestarted'] = 'Outage started!';
$string['cliwaitforitoutagestartingin'] = 'Outage starting in {$a->countdown}.';
$string['cliwaitforitparamactive'] = 'wait for the currently active outage.';
@@ -57,39 +75,29 @@ $string['cliwaitforitparamhelp'] = 'shows parameters help.';
$string['cliwaitforitparamoutageid'] = 'the id of the outage to wait until it starts.';
$string['cliwaitforitparamsleep'] = 'maximum amount of seconds before status output.';
$string['cliwaitforitparamverbose'] = 'enable verbose mode.';
$string['clierrorinvalidvalue'] = 'Invalid value for parameter: {$a->param}';
$string['clierrorinvalidvaluenotid'] = 'Param --{$a->param} must be an id number';
$string['clierrorinvalidvaluenotbool'] = 'Param --{$a->param} must be set to either Y or N';
$string['clierrorinvalidvaluenotnumber'] = 'Param --{$a->param} must be a number';
$string['clierrorinvalidvaluenegativenumber'] = 'Param --{$a->param} must be a positive number';
$string['clierrorinvalidvaluenotstring'] = 'Param --{$a->param} must be a string';
$string['clierrorinvalidvalueemptystring'] = 'Param --{$a->param} must not be an empty string';
$string['clierrormissingparamaters'] = 'You must specify the start time, use --help for more information.';
$string['clierroroutagechanged'] = 'Outage was changed while waiting.';
$string['clierroroutageended'] = 'Outage has already ended.';
$string['clierroroutagenotfound'] = 'Outage not found.';
$string['clioutagecreated'] = 'Outage created, id: {$a->id}';
$string['clone'] = 'Clone';
$string['configurationwarning'] = 'The outage plugin is not properly configured, please refer to <a href="https://github.com/catalyst/moodle-auth_outage/blob/master/README.md#installation" target="_blank">README.md</a> for more information.';
$string['configurationdisabled'] = 'The authentication plugin \'Outage\' is disabled. Please enable it in the site administration it and try again.';
$string['configurationinaccessiblewwwroot'] = 'Could not access <b>{$a->wwwroot}</b> from the server, creation of outages may fail.';
$string['configurationwarning'] = 'The outage plugin is not properly configured, please refer to <a href="https://github.com/catalyst/moodle-auth_outage/blob/master/README.md#installation" target="_blank">README.md</a> for more information.';
$string['datetimeformat'] = '%a %d %h %Y at %I:%M%P %Z';
$string['defaultdescription'] = 'Description';
$string['defaultdescriptiondescription'] = 'Default warning message for outages. Use {{start}} and {{stop}} placeholders as required.';
$string['defaultdescriptionvalue'] = 'There is maintenance scheduled from {{start}} to {{stop}} and our system will not be available during that time.';
$string['defaultlayoutcss'] = 'Layout CSS';
$string['defaultlayoutcssdescription'] = 'This CSS code can be used to override the Outage Warning Bar CSS.';
$string['defaultmetadata'] = 'Default metadata';
$string['defaultmetadatadescription'] = 'The default metadata to include in the outage settings, to be used as a template for new outages. E.g. JIRA-{ticketno}.';
$string['defaultoutageautostart'] = 'Outage auto start';
$string['defaultoutageautostartdescription'] = 'If the outage should automatically trigger maintenance mode once it starts, locking down the whole site.';
$string['defaultoutageduration'] = 'Outage duration';
$string['defaultoutagedurationdescription'] = 'Default duration (in minutes) of an outage.';
$string['defaultwarningduration'] = 'Warning duration';
$string['defaultwarningdurationdescription'] = 'Default warning time (in minutes) for outages.';
$string['defaulttime'] = 'Default time';
$string['defaulttimedescription'] = 'The default time for the next outage, expressed in natural language eg "next Thursday 7pm". See <a target=_blank href="https://www.php.net/manual/en/datetime.formats.relative.php">PHP relative dates</a>';
$string['defaulttitle'] = 'Title';
$string['defaulttitledescription'] = 'Default title for outages. Use {{start}} and {{stop}} placeholders as required.';
$string['defaulttitlevalue'] = 'System down from {{start}} for {{duration}}';
$string['defaultdescription'] = 'Description';
$string['defaultdescriptiondescription'] = 'Default warning message for outages. Use {{start}} and {{stop}} placeholders as required.';
$string['defaultdescriptionvalue'] = 'There is an scheduled maintenance from {{start}} to {{stop}} and our system will not be available during that time.';
$string['defaultwarningduration'] = 'Warning duration';
$string['defaultwarningdurationdescription'] = 'Default warning time (in minutes) for outages.';
$string['description'] = 'Public Description';
$string['description_help'] = 'A full description of the outage, publicly visible by all users.';
$string['finish'] = 'Finish';
@@ -97,29 +105,26 @@ $string['info15secondsbefore'] = '15 seconds before';
$string['infoendofoutage'] = 'end of outage';
$string['infofrom'] = 'From:';
$string['infohidewarning'] = 'no warning bar';
$string['infountil'] = 'Until:';
$string['infopagestaticgenerated'] = 'This warning was generated on {$a->time}.';
$string['infostart'] = 'start';
$string['infostartofwarning'] = 'start of warning';
$string['infostaticpage'] = 'static page';
$string['infopagestaticgenerated'] = 'This warning was generated on {$a->time}.';
$string['infountil'] = 'Until:';
$string['ips_combine'] = 'The IPs listed above will be combined with the IPs listed below.';
$string['allowedipsempty'] = 'When the allowed IPs list is empty we will not block anyone. You can add your own IP address (<i>{$a->ip}</i>) and block all other IPs.';
$string['allowedipshasmyip'] = 'Your IP (<i>{$a->ip}</i>) is in the list and you will not be blocked out during an Outage.';
$string['allowedipshasntmyip'] = 'Your IP (<i>{$a->ip}</i>) is not in the list and you will be blocked out during an outage.';
$string['allowedipsnoconfig'] = 'Your config.php does not have the extra setup to allow blocking via IP.<br />Please refer to our <a href="https://github.com/catalyst/moodle-auth_outage#installation" target="_blank">README.md</a> file for more information.';
$string['logformaintmodeconfig'] = 'Update maintenance mode configuration.';
$string['logformaintmodeconfigcomplete'] = 'Updating maintenance mode configuration complete.';
$string['menusettings'] = 'Settings';
$string['menumanage'] = 'Manage outages';
$string['menusettings'] = 'Settings';
$string['messageoutagebackonline'] = 'We are back online!';
$string['messageoutagebackonlinedescription'] = 'You may resume browsing safely.';
$string['messageoutageongoing'] = 'Back online at {$a->stop}.';
$string['messageoutagewarning'] = 'Shutting down in {{countdown}}';
$string['metadata'] = 'Outage metadata';
$string['metadata_help'] = 'Data here will be output in the outage page as a meta tag in the header of the outage page.';
$string['na'] = 'n/a';
$string['notfound'] = 'No outages found.';
$string['outage:updatenotify'] = '';
$string['outage:viewinfo'] = 'View outage info';
$string['outageedit'] = 'Edit outage';
$string['outageeditcrumb'] = 'Edit';
$string['outageclone'] = 'Clone outage';
$string['outageclonecrumb'] = 'Clone';
$string['outagecreate'] = 'Create outage';
@@ -127,13 +132,14 @@ $string['outagecreatecrumb'] = 'Create';
$string['outagedelete'] = 'Delete outage';
$string['outagedeletewarning'] = 'You are about to permanently delete the outage below. This cannot be undone.';
$string['outageduration'] = 'Outage duration';
$string['outagedurationerrorinvalid'] = 'Outage duration must be positive.';
$string['outageduration_help'] = 'How long the outage lasts after it starts.';
$string['outagedurationerrorinvalid'] = 'Outage duration must be positive.';
$string['outageedit'] = 'Edit outage';
$string['outageeditcrumb'] = 'Edit';
$string['outagefinish'] = 'Finish outage';
$string['outagefinishwarning'] = 'You are about to mark this outage as finished. The system will be immediately back online.';
$string['outageslistfuture'] = 'Planned outages';
$string['outageslistpast'] = 'Outage history';
$string['outage:updatenotify'] = '';
$string['pluginname'] = 'Outage manager';
$string['removeselectors'] = 'Remove selectors';
$string['removeselectorsdescription'] = 'CSS selectors to remove when rendering a static themed maintenance page. One selector per line.';
@@ -143,24 +149,28 @@ $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['tableheaderdurationplanned'] = 'Planned duration';
$string['tableheaderdurationactual'] = 'Actual duration';
$string['tableheaderstarttime'] = 'Starts on';
$string['tableheaderdurationplanned'] = 'Planned duration';
$string['tableheadermodifiedby'] = 'Last modified by';
$string['tableheaderstartedtime'] = 'Started on';
$string['tableheaderwarnbefore'] = 'Warns before';
$string['tableheaderstarttime'] = 'Starts on';
$string['tableheadertitle'] = 'Title';
$string['tableheaderwarnbefore'] = 'Warns before';
$string['tablestarttimefutureformat'] = '{$a->absolute}<br />In {$a->relative}';
$string['tablestarttimepastformat'] = '{$a->absolute}<br />{$a->relative} ago';
$string['taskupdatestaticpage'] = 'Update static outage page';
$string['textplaceholdershint'] = 'You can use {{start}}, {{stop}} and {{duration}} as placeholders on the title and description.';
$string['titleerrorinvalid'] = 'Title cannot be left blank.';
$string['titleerrortoolong'] = 'Title cannot have more than {$a} characters.';
$string['title'] = 'Title';
$string['title_help'] = 'A short title to for this outage. It will be displayed on the warning bar and on the calendar.';
$string['warningdurationerrorinvalid'] = 'Warning duration must be positive.';
$string['titleerrorinvalid'] = 'Title cannot be left blank.';
$string['titleerrortoolong'] = 'Title cannot have more than {$a} characters.';
$string['useaccesskey'] = 'Use access key';
$string['useaccesskey:desc'] = 'Require testers to access site during outage by providing the access key below';
$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.';
/*

18
lib.php
View File

@@ -48,7 +48,7 @@ function auth_outage_get_climaintenance_resource_file($file) {
// We are not using any external libraries or references in this file (we have not gully loaded config.php yet).
// If you change the path below maybe you need to change maintenance_static_page::get_resources_folder() as well.
$resourcedir = rtrim($CFG->dataroot, '/'); // In case the configuration has a trailing slash.
$resourcedir = $resourcedir.'/auth_outage/climaintenance';
$resourcedir = $resourcedir . '/auth_outage/climaintenance';
// Protect against path traversal attacks.
$basename = basename($file);
@@ -61,24 +61,16 @@ function auth_outage_get_climaintenance_resource_file($file) {
return null;
}
$realpath = realpath($resourcedir.'/'.$file);
$realpath = realpath($resourcedir . '/' . $file);
return ($realpath == false) ? null : $realpath;
}
/**
* Display required icon for the calendar events.
*
* @return array
*/
function auth_outage_get_fontawesome_icon_map() {
return [
'core:i/auth_outageevent' => 'fa-power-off',
];
}
/**
* Inject the warning bar into the page if there is currently an outage.
*
* This is a legacy callback that is used for compatibility with older Moodle versions.
* Moodle 4.4+ will use auth_outage\hook_callbacks::before_standard_top_of_body_html_generation instead.
*
* @return string|void
*/
function auth_outage_before_standard_top_of_body_html() {

View File

@@ -27,8 +27,8 @@ use auth_outage\dml\outagedb;
use auth_outage\output\renderer;
use auth_outage\local\outagelib;
require_once(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/adminlib.php');
admin_externalpage_setup('auth_outage_manage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));

BIN
pix/auth_outage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

1
pix/auth_outage.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512" preserveAspectRatio="xMinYMid meet"><!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V256c0 17.7 14.3 32 32 32s32-14.3 32-32V32zM143.5 120.6c13.6-11.3 15.4-31.5 4.1-45.1s-31.5-15.4-45.1-4.1C49.7 115.4 16 181.8 16 256c0 132.5 107.5 240 240 240s240-107.5 240-240c0-74.2-33.8-140.6-86.6-184.6c-13.6-11.3-33.8-9.4-45.1 4.1s-9.4 33.8 4.1 45.1c38.9 32.3 63.5 81 63.5 135.4c0 97.2-78.8 176-176 176s-176-78.8-176-176c0-54.4 24.7-103.1 63.5-135.4z"/></svg>

After

Width:  |  Height:  |  Size: 686 B

View File

@@ -43,13 +43,6 @@ if ($hassiteconfig) {
get_string('settingssectiondefaultsdescription', 'auth_outage') . $description
));
$settings->add(new admin_setting_configcheckbox(
'auth_outage/default_autostart',
get_string('defaultoutageautostart', 'auth_outage'),
get_string('defaultoutageautostartdescription', 'auth_outage'),
$defaults['default_autostart']
));
$settings->add(new admin_setting_configduration(
'auth_outage/default_warning_duration',
get_string('defaultwarningduration', 'auth_outage'),
@@ -78,6 +71,16 @@ if ($hassiteconfig) {
$defaults['default_title'],
PARAM_TEXT
));
$settings->add(
new admin_setting_configtext(
'auth_outage/default_metadata',
get_string('defaultmetadata', 'auth_outage'),
get_string('defaultmetadatadescription', 'auth_outage'),
'',
PARAM_TEXT
)
);
$settings->add(new admin_setting_configtextarea(
'auth_outage/default_description',
get_string('defaultdescription', 'auth_outage'),
@@ -89,7 +92,8 @@ if ($hassiteconfig) {
$settings->add(new admin_setting_heading(
'plugin',
get_string('settingssectionplugin', 'auth_outage'),
get_string('settingssectionplugindescription', 'auth_outage')));
get_string('settingssectionplugindescription', 'auth_outage')
));
$settings->add(new admin_setting_configtextarea(
'auth_outage/css',
@@ -152,7 +156,8 @@ if ($hassiteconfig) {
// Clear '$settings' to prevent adding again outsite category.
$settings = null;
// Add options.
$ADMIN->add('auth_outage',
$ADMIN->add(
'auth_outage',
new admin_externalpage(
'auth_outage_manage',
get_string('menumanage', 'auth_outage'),

View File

@@ -14,6 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace auth_outage;
use auth_outage\dml\outagedb;
use auth_outage\local\outage;
/**
* Base testcase for auth outage tests.
*
@@ -30,19 +35,7 @@
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\dml\outagedb;
use auth_outage\local\outage;
/**
* auth_outage_base_testcase class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class auth_outage_base_testcase extends advanced_testcase {
abstract class base_testcase extends \advanced_testcase {
/**
* Checks PHPUnit version and calls the functions accordingly.
* @param string $exception Expected exception class.
@@ -70,8 +63,8 @@ abstract class auth_outage_base_testcase extends advanced_testcase {
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);
$guestrole = $DB->get_record('role', ['shortname' => 'guest']);
role_change_permission($guestrole->id, \context_system::instance(), 'auth/outage:viewinfo', CAP_PREVENT);
$this->setGuestUser();
}
@@ -86,7 +79,6 @@ abstract class auth_outage_base_testcase extends advanced_testcase {
return new outage([
'id' => 1,
'autostart' => false,
'warntime' => $now - 100,
'starttime' => $now + 100,
'stoptime' => $now + 200,

View File

@@ -30,7 +30,7 @@ use auth_outage\local\outage;
use Behat\Gherkin\Node\TableNode;
use Behat\Mink\Exception\ExpectationException;
require_once(__DIR__.'/../../../../lib/behat/behat_base.php');
require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
/**
* Steps definitions related to auth_outage.
@@ -88,10 +88,9 @@ class behat_auth_outage extends behat_base {
*/
public function there_is_a_outage($type) {
$data = [
'autostart' => false,
'finished' => null,
'title' => 'Example of '.$type.' outage',
'description' => 'An outage: '.$type,
'title' => 'Example of ' . $type . ' outage',
'description' => 'An outage: ' . $type,
];
switch ($type) {
case 'waiting':
@@ -121,7 +120,7 @@ class behat_auth_outage extends behat_base {
$data['stoptime'] = time() - (60 * 60 * 2); // Stopped 1 hour ago.
break;
default:
throw new InvalidArgumentException('$type='.$type.' is not valid.');
throw new InvalidArgumentException('$type=' . $type . ' is not valid.');
}
outagedb::save(new outage($data));
}
@@ -136,8 +135,8 @@ class behat_auth_outage extends behat_base {
$expected = ($action == 'Edit') ? 2 : 1; // Edit is an action through the title or button.
$found = $this->how_many_times_can_i_see_action($action);
if ($found != $expected) {
throw new ExpectationException('"'.$action.'" action not found, expected '.$expected.
' but found '.$found.'.', $this->getSession());
throw new ExpectationException('"' . $action . '" action not found, expected ' . $expected .
' but found ' . $found . '.', $this->getSession());
}
}
@@ -149,7 +148,7 @@ class behat_auth_outage extends behat_base {
*/
public function i_should_not_see_the_action($action) {
if ($this->how_many_times_can_i_see_action($action) != 0) {
throw new ExpectationException('"'.$action.'" action was found', $this->getSession());
throw new ExpectationException('"' . $action . '" action was found', $this->getSession());
}
}
@@ -159,7 +158,7 @@ class behat_auth_outage extends behat_base {
* @param string $name
*/
public function i_should_see_an_empty_settings_text_area($name) {
$this->assertSession()->fieldValueEquals('s_auth_outage_'.$name, '');
$this->assertSession()->fieldValueEquals('s_auth_outage_' . $name, '');
}
/**
@@ -177,7 +176,7 @@ class behat_auth_outage extends behat_base {
*/
private function how_many_times_can_i_see_action($action) {
$selector = 'css';
$locator = "div[role='main'] a[title='".$action."']";
$locator = "div[role='main'] a[title='" . $action . "']";
$items = $this->getSession()->getPage()->findAll($selector, $locator);
return count($items);
}
@@ -188,7 +187,7 @@ class behat_auth_outage extends behat_base {
* @param string $action Action button to click.
*/
public function i_click_on_the_action_button($action) {
$node = $this->get_selected_node('css_element', "div[role='main'] table nobr a[title='".$action."']");
$node = $this->get_selected_node('css_element', "div[role='main'] table nobr a[title='" . $action . "']");
$this->ensure_node_is_visible($node);
$node->click();
}
@@ -205,7 +204,7 @@ class behat_auth_outage extends behat_base {
$count = count($this->getSession()->getWindowNames());
if ($count != 2) {
throw new ExpectationException('Number of windows: '.$count, $this->getSession());
throw new ExpectationException('Number of windows: ' . $count, $this->getSession());
}
}
@@ -220,17 +219,18 @@ class behat_auth_outage extends behat_base {
$container = $this->getSession()->getPage()->findAll('css', $element);
if (count($container) == 0) {
throw new ExpectationException('"'.$element.'" element not found', $this->getSession());
throw new ExpectationException('"' . $element . '" element not found', $this->getSession());
}
$container = $container[0];
$xpathliteral = $this->getSession()->getSelectorsHandler()->xpathLiteral($text);
$xpath = "/descendant-or-self::*[contains(., $xpathliteral)]".
$xpath = "/descendant-or-self::*[contains(., $xpathliteral)]" .
"[count(descendant::*[contains(., $xpathliteral)]) = 0]";
$found = $this->find_all('xpath', $xpath, false, $container);
if (count($found) == 0) {
throw new ExpectationException('"'.$text.'" text was not found in the "'.$element.'" element', $this->getSession());
throw new ExpectationException('"' . $text . '" text was not found in the "' . $element .
'" element', $this->getSession());
}
foreach ($found as $node) {
@@ -238,8 +238,10 @@ class behat_auth_outage extends behat_base {
return;
}
}
throw new ExpectationException('"'.$text.'" text was found in the "'.$element.'" element but was not visible',
$this->getSession());
throw new ExpectationException(
'"' . $text . '" text was found in the "' . $element . '" element but was not visible',
$this->getSession()
);
}
/**
@@ -252,7 +254,7 @@ class behat_auth_outage extends behat_base {
$locator = "#auth_outage_warningbar_box";
$items = $this->getSession()->getPage()->findAll($selector, $locator);
if (count($items) > 0) {
throw new ExpectationException($locator.' found, not expected.', $this->getSession());
throw new ExpectationException($locator . ' found, not expected.', $this->getSession());
}
}
@@ -269,7 +271,6 @@ class behat_auth_outage extends behat_base {
// Set defaults.
$row = array_merge(
[
'autostart' => 'no',
'warnbefore' => 60,
'startsin' => 0,
'stopsafter' => 60,
@@ -279,16 +280,12 @@ class behat_auth_outage extends behat_base {
],
$row
);
if (($row['autostart'] != 'yes') && ($row['autostart'] != 'no')) {
throw new Exception('autostart must be yes or no, found: '.$row['autostart']);
}
if ($row['finished'] == '') {
$row['finished'] = null;
}
$starttime = $time + $row['startsin'];
$this->outage = new outage([
'autostart' => ($row['autostart'] == 'yes'),
'warntime' => $starttime - $row['warnbefore'],
'starttime' => $starttime,
'stoptime' => $starttime + $row['stopsafter'],
@@ -318,7 +315,7 @@ class behat_auth_outage extends behat_base {
$seconds += 5; // Give it some extra time to pool the server.
break;
default:
throw new Exception('Invalid $what='.$what);
throw new Exception('Invalid $what=' . $what);
}
if ($seconds >= 0) {
$seconds++; // Give one extra second for things to happen.
@@ -332,7 +329,7 @@ class behat_auth_outage extends behat_base {
*/
private function is_behat_3() {
global $version;
list($behat) = explode('.', $version);
[$behat] = explode('.', $version);
return ($behat >= 3);
}
}

View File

@@ -14,7 +14,6 @@ Feature: Change the default settings
Scenario Outline: Check if I can save the default settings.
When I navigate to "Plugins > Authentication > Outage manager > Settings" in site administration
And I set the following fields to these values:
| s_auth_outage_default_autostart | <autostart> |
| s_auth_outage_default_warning_duration[v] | <warning> |
| s_auth_outage_default_warning_duration[u] | 60 |
| s_auth_outage_default_duration[v] | <duration> |
@@ -26,7 +25,6 @@ Feature: Change the default settings
Then I should see "Changes saved"
When I visit the Create Outage Page
Then the following fields match these values:
| autostart | <autostart> |
| warningduration[number] | <warning> |
| warningduration[timeunit] | 60 |
| outageduration[number] | <duration> |
@@ -35,6 +33,6 @@ Feature: Change the default settings
| description[text] | <description> |
Examples:
| autostart | warning | duration | title | description | css |
| 1 | 15 | 30 | An Outage | My outage until {stop}. | /* Some CSS. */ |
| 0 | 30 | 45 | My Behat Outage {start} | My outage with <b>HTML</b>. | /* More CSS. */ |
| warning | duration | title | description | css |
| 15 | 30 | An Outage | My outage until {stop}. | /* Some CSS. */ |
| 30 | 45 | My Behat Outage {start} | My outage with <b>HTML</b>. | /* More CSS. */ |

View File

@@ -23,7 +23,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\calendar\calendar;
namespace auth_outage\calendar;
use auth_outage\local\outage;
/**
@@ -36,8 +37,9 @@ use auth_outage\local\outage;
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\calendar\calendar
*/
class auth_outage_calendar_test extends advanced_testcase {
final class calendar_test extends \advanced_testcase {
/**
* @var outage|null The calendar entry owner.
*/
@@ -46,14 +48,13 @@ class auth_outage_calendar_test extends advanced_testcase {
/**
* Creates an outage and checks if its in the calendar.
*/
public function test_create() {
public function test_create(): void {
$this->resetAfterTest(true);
self::setAdminUser();
$time = time();
self::$outage = new outage([
'id' => 1,
'autostart' => false,
'warntime' => $time - 100,
'starttime' => $time,
'stoptime' => $time + (2 * 60 * 60),
@@ -67,14 +68,13 @@ class auth_outage_calendar_test extends advanced_testcase {
/**
* Updates an outage and checks the calendar.
*/
public function test_update() {
public function test_update(): void {
$this->resetAfterTest(true);
self::setAdminUser();
$time = time();
self::$outage = new outage([
'id' => 1,
'autostart' => false,
'warntime' => $time - 100,
'starttime' => $time,
'stoptime' => $time + (2 * 60 * 60),
@@ -91,14 +91,13 @@ class auth_outage_calendar_test extends advanced_testcase {
/**
* Deletes an outage and checks the calendar.
*/
public function test_delete() {
public function test_delete(): void {
$this->resetAfterTest(true);
self::setAdminUser();
$time = time();
self::$outage = new outage([
'id' => 1,
'autostart' => false,
'warntime' => $time - 100,
'starttime' => $time,
'stoptime' => $time + (2 * 60 * 60),
@@ -116,14 +115,13 @@ class auth_outage_calendar_test extends advanced_testcase {
/**
* Try to update a non existing outage.
*/
public function test_update_notfound() {
public function test_update_notfound(): void {
$this->resetAfterTest(true);
self::setAdminUser();
$time = time();
$outage = new outage([
'id' => 1,
'autostart' => false,
'warntime' => $time - 100,
'starttime' => $time,
'stoptime' => $time + (2 * 60 * 60),
@@ -139,7 +137,7 @@ class auth_outage_calendar_test extends advanced_testcase {
/**
* Try to delete a non existing outage.
*/
public function test_delete_notfound() {
public function test_delete_notfound(): void {
$this->resetAfterTest(true);
self::setAdminUser();

View File

@@ -23,7 +23,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\dml\outagedb;
namespace auth_outage\dml;
use auth_outage\local\outage;
/**
@@ -36,8 +37,9 @@ use auth_outage\local\outage;
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\dml\outagedb
*/
class auth_outage_events_test extends advanced_testcase {
final class events_test extends \advanced_testcase {
/**
* @var outage|null Outage used in the tests.
*/
@@ -52,7 +54,7 @@ class auth_outage_events_test extends advanced_testcase {
* Saves an outage and check if the event was created.
* @return array With the outage id and the event id.
*/
public function test_save() {
public function test_save(): void {
global $DB;
self::setAdminUser();
$this->resetAfterTest(true);
@@ -60,7 +62,6 @@ class auth_outage_events_test extends advanced_testcase {
// Save new outage.
$now = time();
$outage = new outage([
'autostart' => false,
'warntime' => $now - 60,
'starttime' => 60,
'stoptime' => 120,
@@ -84,7 +85,7 @@ class auth_outage_events_test extends advanced_testcase {
/**
* Updates an outage and checks if the event was updated.
*/
public function test_update() {
public function test_update(): void {
global $DB;
self::setAdminUser();
@@ -93,7 +94,6 @@ class auth_outage_events_test extends advanced_testcase {
// Save new outage.
$now = time();
$outage = new outage([
'autostart' => false,
'warntime' => $now - 60,
'starttime' => 60,
'stoptime' => 120,
@@ -122,7 +122,7 @@ class auth_outage_events_test extends advanced_testcase {
/**
* Deletes an outage and checks if the event was deleted.
*/
public function test_delete() {
public function test_delete(): void {
global $DB;
self::setAdminUser();
@@ -131,7 +131,6 @@ class auth_outage_events_test extends advanced_testcase {
// Save new outage.
$now = time();
$outage = new outage([
'autostart' => false,
'warntime' => $now - 60,
'starttime' => 60,
'stoptime' => 120,

View File

@@ -25,10 +25,12 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\dml;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/base_testcase.php');
require_once(__DIR__ . '/../base_testcase.php');
/**
* installation_test test class.
@@ -39,24 +41,24 @@ require_once(__DIR__.'/base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\dml\outagedb
*/
class auth_outage_installation_test extends auth_outage_base_testcase {
final class installation_test extends \auth_outage\base_testcase {
/**
* Checks if plugin cleans up data after uninstall.
*
* See Issue #57.
*/
public function test_uninstall() {
public function test_uninstall(): void {
global $CFG, $DB;
$this->resetAfterTest();
static::setAdminUser();
$dbman = $DB->get_manager();
// Create a future outage with autostart.
// Create a future outage.
$now = time();
$outage = new outage([
'autostart' => true,
'starttime' => $now + (1 * 60 * 60),
'stoptime' => $now + (2 * 60 * 60),
'warntime' => $now - (2 * 60 * 60),
@@ -64,31 +66,39 @@ class auth_outage_installation_test extends auth_outage_base_testcase {
'description' => 'Description',
]);
ob_start();
\auth_outage\dml\outagedb::save($outage);
outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
self::assertSame(1, $DB->count_records_select('event', "eventtype = 'auth_outage'", null));
// Uninstall plugin.
require_once($CFG->libdir.'/adminlib.php');
$progress = new progress_trace_buffer(new text_progress_trace(), false);
core_plugin_manager::instance()->uninstall_plugin('auth_outage', $progress);
require_once($CFG->libdir . '/adminlib.php');
$progress = new \progress_trace_buffer(new \text_progress_trace(), false);
\core_plugin_manager::instance()->uninstall_plugin('auth_outage', $progress);
$progress->finished();
self::assertStringContainsString('++ Success ++', $progress->get_buffer());
// Check ...
self::assertSame(0, $DB->count_records_select('event', "eventtype = 'auth_outage'", null),
'The outage events were not removed.');
self::assertFalse(file_exists($CFG->dataroot.'/climaintenance.php'),
'The maintenance template file was not deleted.');
self::assertFalse(get_config('moodle', 'maintenance_later'),
'Maintenance later must not be set.'); // Issue #57.
self::assertFalse($dbman->table_exists('auth_outage'),
'Table "auth_outage" was not dropped.');
self::assertSame(
0,
$DB->count_records_select('event', "eventtype = 'auth_outage'", null),
'The outage events were not removed.'
);
self::assertFalse(
file_exists($CFG->dataroot . '/climaintenance.php'),
'The maintenance template file was not deleted.'
);
self::assertFalse(
get_config('moodle', 'maintenance_later'),
'Maintenance later must not be set.'
); // Issue #57.
self::assertFalse(
$dbman->table_exists('auth_outage'),
'Table "auth_outage" was not dropped.'
);
// Create tables back so tests do not fail with MySQL ...
require_once($CFG->libdir.'/upgradelib.php');
$DB->get_manager()->install_from_xmldb_file($CFG->dirroot.'/auth/outage/db/install.xml');
require_once($CFG->libdir . '/upgradelib.php');
$DB->get_manager()->install_from_xmldb_file($CFG->dirroot . '/auth/outage/db/install.xml');
}
}

View File

@@ -23,11 +23,12 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\dml\outagedb;
namespace auth_outage\dml;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../base_testcase.php');
require_once(__DIR__ . '/../base_testcase.php');
/**
* outagedb_test tests class.
@@ -36,8 +37,9 @@ require_once(__DIR__.'/../base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\dml\outagedb
*/
class auth_outage_outagedb_test extends auth_outage_base_testcase {
final class outagedb_test extends \auth_outage\base_testcase {
/**
* Creates an array of ids in from the given outages array.
* @param outage[] $outages An array of outages.
@@ -54,7 +56,6 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Helper function to create an outage then save it to the database.
*
* @param bool $autostart If outage should automatically start.
* @param int $now Timestamp for now, such as time().
* @param int $warning In how many hours the warning starts. Can be negative.
* @param int $start In how many hours this outage starts. Can be negative.
@@ -63,9 +64,8 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
* @param int|null $finished In how many hours this outage is marked as finished. Can be negative or null.
* @return int Id the of created outage.
*/
private static function saveoutage($autostart, $now, $warning, $start, $stop, $title, $finished = null) {
private static function saveoutage($now, $warning, $start, $stop, $title, $finished = null) {
return outagedb::save(new outage([
'autostart' => $autostart,
'warntime' => $now + ($warning * 60 * 60),
'starttime' => $now + ($start * 60 * 60),
'stoptime' => $now + ($stop * 60 * 60),
@@ -86,7 +86,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Make sure we can save and update.
*/
public function test_save() {
public function test_save(): void {
$this->resetAfterTest(true);
// Save new outage.
$id = outagedb::save($this->createoutage(1));
@@ -99,7 +99,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Create a few outages, fetch them and check if fields match.
*/
public function test_saved_fields() {
public function test_saved_fields(): void {
$this->resetAfterTest(true);
for ($i = 0; $i < 4; $i++) {
$expected = $this->createoutage($i);
@@ -110,14 +110,14 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
$expected->createdby = $actual->createdby;
$expected->modifiedby = $actual->modifiedby;
// Check if fields are the same.
self::assertEquals($expected, $actual, 'Failed for $i='.$i);
self::assertEquals($expected, $actual, 'Failed for $i=' . $i);
}
}
/**
* Make sure we can get existing entries and null if not found.
*/
public function test_getbyid() {
public function test_getbyid(): void {
$this->resetAfterTest(true);
// Create something.
$id = outagedb::save($this->createoutage(1));
@@ -134,7 +134,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Make sure we can delete stuff.
*/
public function test_delete() {
public function test_delete(): void {
$this->resetAfterTest(true);
// Create something.
$id = outagedb::save($this->createoutage(1));
@@ -147,11 +147,11 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Make sure we can finish outages.
*/
public function test_finish() {
public function test_finish(): void {
$now = time();
$this->resetAfterTest(true);
// Create it.
$id = self::saveoutage(false, $now, -3, -2, 2, 'An ongoing outage.');
$id = self::saveoutage($now, -3, -2, 2, 'An ongoing outage.');
$outage = outagedb::get_by_id($id);
self::assertTrue($outage->is_active($now));
self::assertTrue($outage->is_ongoing($now));
@@ -167,7 +167,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Make sure getall brings all entries.
*/
public function test_getall() {
public function test_getall(): void {
$this->resetAfterTest(true);
$amount = 10;
// Should start empty.
@@ -184,7 +184,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Perform some tests on the data itself, checking values after inserted and updated.
*/
public function test_basiccrud() {
public function test_basiccrud(): void {
$this->resetAfterTest(true);
// Create some outages.
@@ -202,7 +202,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
self::assertNotNull($inserted);
// Check its data.
foreach (['starttime', 'stoptime', 'warntime', 'title', 'description'] as $field) {
self::assertSame($outage->$field, $inserted->$field, 'Field '.$field.' does not match.');
self::assertSame($outage->$field, $inserted->$field, 'Field ' . $field . ' does not match.');
}
// Check generated data.
self::assertGreaterThan(0, $inserted->id);
@@ -210,11 +210,11 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
self::assertNotNull($inserted->createdby);
self::assertNotNull($inserted->modifiedby);
// Change it.
$inserted->title = 'Title ID'.$id;
$inserted->title = 'Title ID' . $id;
outagedb::save($inserted);
// Get it again and check data.
$updated = outagedb::get_by_id($id);
self::assertSame('Title ID'.$id, $updated->title);
self::assertSame('Title ID' . $id, $updated->title);
self::assertSame($inserted->description, $updated->description);
// Delete it.
outagedb::delete($id);
@@ -226,7 +226,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::get_active() method.
*/
public function test_getactive() {
public function test_getactive(): void {
$this->resetAfterTest(true);
// Have a consistent time for now (no seconds variation), helps debugging.
@@ -235,46 +235,56 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
self::assertEquals([], outagedb::get_all(), 'Ensure there are no other outages that can affect the test.');
self::assertNull(outagedb::get_active($now), 'There should be no active outage at this point.');
self::saveoutage(false, $now, 1, 2, 3, 'An outage that starts in the future and is not in warning period.');
self::saveoutage($now, 1, 2, 3, 'An outage that starts in the future and is not in warning period.');
self::assertNull(outagedb::get_active($now), 'No active outages yet.');
self::saveoutage(false, $now, -3, -2, -1, 'An outage that is already in the past.');
self::saveoutage($now, -3, -2, -1, 'An outage that is already in the past.');
self::assertNull(outagedb::get_active($now), 'No active outages yet.');
$activeid = self::saveoutage(false, $now, -2, 1, 2, 'An outage in warning period.');
$activeid = self::saveoutage($now, -2, 1, 2, 'An outage in warning period.');
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
$activeid = self::saveoutage(false, $now, -2, 0, 2, 'An outage starts now.');
$activeid = self::saveoutage($now, -2, 0, 2, 'An outage starts now.');
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
self::saveoutage(false, $now, -2, 0, -1, 'Invalid outage.');
self::saveoutage($now, -2, 0, -1, 'Invalid outage.');
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
self::saveoutage(false, $now, -2, 0, 0, 'Invalid outage.');
self::saveoutage($now, -2, 0, 0, 'Invalid outage.');
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
self::saveoutage(false, $now, -1, 2, 3,
'Another outage in warning period, but ignored as it starts after the previous one.');
self::saveoutage(
$now,
-1,
2,
3,
'Another outage in warning period, but ignored as it starts after the previous one.'
);
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
self::saveoutage(false, $now, -3, -2, 2, 'An finished outage.', -1);
self::saveoutage($now, -3, -2, 2, 'An finished outage.', -1);
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
$activeid = self::saveoutage(false, $now, -3, -2, 2, 'An ongoing outage.');
$activeid = self::saveoutage($now, -3, -2, 2, 'An ongoing outage.');
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
self::saveoutage(false, $now, -3, -1, 1, 'Another ongoing outage but ignored because it started after the previous one.');
self::saveoutage($now, -3, -1, 1, 'Another ongoing outage but ignored because it started after the previous one.');
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
self::saveoutage(false, $now, -3, -2, 1,
'Another ongoing outage starting at the same time, but ignored as it stops before the previous one.');
self::saveoutage(
$now,
-3,
-2,
1,
'Another ongoing outage starting at the same time, but ignored as it stops before the previous one.'
);
self::assertSame($activeid, outagedb::get_active($now)->id, 'Wrong active outage picked.');
}
/**
* Tests the outagedb::get_all_unended() method.
*/
public function test_getallunended() {
public function test_getallunended(): void {
$this->resetAfterTest(true);
// Have a consistent time for now (no seconds variation), helps debugging.
@@ -283,49 +293,73 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
self::assertEquals([], outagedb::get_all(), 'Ensure there are no other outages that can affect the test.');
self::assertEquals([], outagedb::get_all_unended($now), 'There should be no future outages at this point.');
self::saveoutage(false, $now, -3, -2, -1, 'A past outage.');
self::saveoutage($now, -3, -2, -1, 'A past outage.');
self::assertEquals([], outagedb::get_all_unended($now), 'No future outages yet.');
self::saveoutage(false, $now, -3, -2, 2, 'A finished outage.', -1);
self::saveoutage($now, -3, -2, 2, 'A finished outage.', -1);
self::assertEquals([], outagedb::get_all_unended($now), 'No future outages yet.');
$id1 = self::saveoutage(false, $now, 2, 3, 4, 'A future outage.');
self::assertEquals([$id1],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id1 = self::saveoutage($now, 2, 3, 4, 'A future outage.');
self::assertEquals(
[$id1],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id2 = self::saveoutage(false, $now, 1, 4, 5, 'Another future outage.');
self::assertEquals([$id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id2 = self::saveoutage($now, 1, 4, 5, 'Another future outage.');
self::assertEquals(
[$id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id3 = self::saveoutage(false, $now, 1, 3, 5, 'Yet another future outage.');
self::assertEquals([$id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id3 = self::saveoutage($now, 1, 3, 5, 'Yet another future outage.');
self::assertEquals(
[$id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id4 = self::saveoutage(false, $now, -2, 1, 2, 'An outage in warning period.');
self::assertEquals([$id4, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id4 = self::saveoutage($now, -2, 1, 2, 'An outage in warning period.');
self::assertEquals(
[$id4, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id5 = self::saveoutage(false, $now, -1, 2, 3, 'Another outage in warning period.');
self::assertEquals([$id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id5 = self::saveoutage($now, -1, 2, 3, 'Another outage in warning period.');
self::assertEquals(
[$id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id6 = self::saveoutage(false, $now, -3, -2, 2, 'An ongoing outage.');
self::assertEquals([$id6, $id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id6 = self::saveoutage($now, -3, -2, 2, 'An ongoing outage.');
self::assertEquals(
[$id6, $id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id7 = self::saveoutage(false, $now, -3, -1, 1, 'Another ongoing outage.');
self::assertEquals([$id6, $id7, $id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id7 = self::saveoutage($now, -3, -1, 1, 'Another ongoing outage.');
self::assertEquals(
[$id6, $id7, $id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
$id8 = self::saveoutage(false, $now, -3, -2, 1, 'Yet another ongoing outage.');
self::assertEquals([$id6, $id8, $id7, $id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)), 'Wrong future data.');
$id8 = self::saveoutage($now, -3, -2, 1, 'Yet another ongoing outage.');
self::assertEquals(
[$id6, $id8, $id7, $id4, $id5, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_unended($now)),
'Wrong future data.'
);
}
/**
* Tests the outagedb::get_all_ended() method.
*/
public function test_getallended() {
public function test_getallended(): void {
$this->resetAfterTest(true);
// Have a consistent time for now (no seconds variation), helps debugging.
@@ -334,36 +368,48 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
self::assertEquals([], outagedb::get_all(), 'Ensure there are no other outages that can affect the test.');
self::assertEquals([], outagedb::get_all_ended($now), 'There should be no future outages at this point.');
self::saveoutage(false, $now, -2, 1, 2, 'An outage in warning period.');
self::saveoutage($now, -2, 1, 2, 'An outage in warning period.');
self::assertEquals([], outagedb::get_all_ended($now), 'No past outages yet.');
self::saveoutage(false, $now, -3, -2, 2, 'An ongoing outage.');
self::saveoutage($now, -3, -2, 2, 'An ongoing outage.');
self::assertEquals([], outagedb::get_all_ended($now), 'No past outages yet.');
self::saveoutage(false, $now, 2, 3, 4, 'A future outage.');
self::saveoutage($now, 2, 3, 4, 'A future outage.');
self::assertEquals([], outagedb::get_all_ended($now), 'No past outages yet.');
$id1 = self::saveoutage(false, $now, -8, -6, -4, 'A past outage.');
self::assertEquals([$id1],
self::createidarray(outagedb::get_all_ended($now)), 'Wrong past data.');
$id1 = self::saveoutage($now, -8, -6, -4, 'A past outage.');
self::assertEquals(
[$id1],
self::createidarray(outagedb::get_all_ended($now)),
'Wrong past data.'
);
$id2 = self::saveoutage(false, $now, -8, -7, -5, 'Another past outage.');
self::assertEquals([$id1, $id2],
self::createidarray(outagedb::get_all_ended($now)), 'Wrong past data.');
$id2 = self::saveoutage($now, -8, -7, -5, 'Another past outage.');
self::assertEquals(
[$id1, $id2],
self::createidarray(outagedb::get_all_ended($now)),
'Wrong past data.'
);
$id3 = self::saveoutage(false, $now, -8, -5, -3, 'Yet another past outage.');
self::assertEquals([$id3, $id1, $id2],
self::createidarray(outagedb::get_all_ended($now)), 'Wrong past data.');
$id3 = self::saveoutage($now, -8, -5, -3, 'Yet another past outage.');
self::assertEquals(
[$id3, $id1, $id2],
self::createidarray(outagedb::get_all_ended($now)),
'Wrong past data.'
);
$id4 = self::saveoutage(false, $now, -3, -2, 2, 'A finished outage.', -1);
self::assertEquals([$id4, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_ended($now)), 'Wrong past data.');
$id4 = self::saveoutage($now, -3, -2, 2, 'A finished outage.', -1);
self::assertEquals(
[$id4, $id3, $id1, $id2],
self::createidarray(outagedb::get_all_ended($now)),
'Wrong past data.'
);
}
/**
* Tests the outagedb::get_by_id() with an invalid parameter.
*/
public function test_getbyid_invalid() {
public function test_getbyid_invalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::get_by_id(-1);
@@ -372,7 +418,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::delete() with an invalid parameter.
*/
public function test_delete_invalid() {
public function test_delete_invalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::delete(-1);
@@ -381,7 +427,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::get_active() with an invalid parameter.
*/
public function test_getactive_invalid() {
public function test_getactive_invalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::get_active(-1);
@@ -390,7 +436,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::get_all_unended() with an invalid parameter.
*/
public function test_getallunended_invalid() {
public function test_getallunended_invalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::get_all_unended(-1);
@@ -399,7 +445,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Checks we can execute outagedb::get_all_unended() without parameters (now).
*/
public function test_getallunended_now() {
public function test_getallunended_now(): void {
$this->resetAfterTest(true);
self::assertEmpty(outagedb::get_all_unended());
}
@@ -407,7 +453,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::get_all_ended() with an invalid parameter.
*/
public function test_getallended_invalid() {
public function test_getallended_invalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::get_all_ended(-1);
@@ -416,7 +462,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Checks we can execute outagedb::test_getallended_now() without parameters (now).
*/
public function test_getallended_now() {
public function test_getallended_now(): void {
$this->resetAfterTest(true);
self::assertEmpty(outagedb::get_all_ended());
}
@@ -424,7 +470,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::finish() with an invalid parameter.
*/
public function test_finish_invalid() {
public function test_finish_invalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::finish(1, -1);
@@ -433,7 +479,7 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::finish() with a non existing outage.
*/
public function test_finish_now_notfound() {
public function test_finish_now_notfound(): void {
$this->resetAfterTest(true);
outagedb::finish(1);
self::assertCount(1, $this->getDebuggingMessages());
@@ -443,11 +489,10 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Try to finish not ongoing outages.
*/
public function test_finish_notongoing() {
public function test_finish_notongoing(): void {
$this->resetAfterTest(true);
$time = time();
$outage = new outage([
'autostart' => false,
'warntime' => $time + (60 * 60 * 24 * 1),
'starttime' => $time + (60 * 60 * 24 * 2),
'stoptime' => $time + (60 * 60 * 24 * 3),
@@ -465,21 +510,12 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
/**
* Tests the outagedb::get_next_starting() with an invalid parameter.
*/
public function test_getnextstartinginvalid() {
public function test_getnextstartinginvalid(): void {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::get_next_starting(-1);
}
/**
* Tests the outagedb::get_next_autostarting() with an invalid parameter.
*/
public function test_getnextautostartinginvalid() {
$this->resetAfterTest(true);
$this->set_expected_exception('coding_exception');
outagedb::get_next_autostarting(-1);
}
/**
* Helper function to create an outage for tests.
* @param int $i Used to populate the information.
@@ -487,11 +523,10 @@ class auth_outage_outagedb_test extends auth_outage_base_testcase {
*/
private function createoutage($i) {
return new outage([
'autostart' => ($i % 2 == 0),
'starttime' => $i * 100,
'stoptime' => $i * 100 + 50,
'warntime' => $i * 60,
'title' => 'The Title '.$i,
'title' => 'The Title ' . $i,
'description' => 'A <b>description</b> in HTML.',
]);
}

View File

@@ -23,13 +23,12 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\form\outage\delete;
use auth_outage\form\outage\edit;
use auth_outage\form\outage\finish;
namespace auth_outage\form\outage;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../base_testcase.php');
require_once(__DIR__ . '/../../base_testcase.php');
/**
* forms_test test class.
@@ -38,26 +37,27 @@ require_once(__DIR__.'/../base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\form\outage\edit
*/
class auth_outage_forms_test extends auth_outage_base_testcase {
final class forms_test extends \auth_outage\base_testcase {
/**
* Create a delete form.
*/
public function test_delete() {
public function test_delete(): void {
new delete();
}
/**
* Create a finish form.
*/
public function test_finish() {
public function test_finish(): void {
new finish();
}
/**
* Mock some data and check values.
*/
public function test_edit_valid() {
public function test_edit_valid(): void {
if ($this->skip_because_moodle_is_below_30('Moodle POST mocking was fixed in Moodle 30.')) {
return;
}
@@ -67,7 +67,6 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
self::assertFalse($edit->is_cancelled());
$outage = $edit->get_data();
self::assertInstanceOf('\\auth_outage\\local\\outage', $outage);
self::assertSame(false, $outage->autostart);
self::assertSame(60, $outage->get_warning_duration());
self::assertSame(mktime(14, 15, 0, 2, 1, 2013), $outage->starttime);
self::assertSame(2 * 60 * 60, $outage->get_duration_planned());
@@ -78,7 +77,7 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check invalid warning duration.
*/
public function test_edit_invalid_warning() {
public function test_edit_invalid_warning(): void {
if ($this->skip_because_moodle_is_below_30('Moodle POST mocking was fixed in Moodle 30.')) {
return;
}
@@ -93,7 +92,7 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check invalid outage duration.
*/
public function test_edit_invalid_duration() {
public function test_edit_invalid_duration(): void {
if ($this->skip_because_moodle_is_below_30('Moodle POST mocking was fixed in Moodle 30.')) {
return;
}
@@ -107,7 +106,7 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check invalid title (empty).
*/
public function test_edit_invalid_title() {
public function test_edit_invalid_title(): void {
if ($this->skip_because_moodle_is_below_30('Moodle POST mocking was fixed in Moodle 30.')) {
return;
}
@@ -121,14 +120,14 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check invalid title (too long).
*/
public function test_edit_invalid_title_toolong() {
public function test_edit_invalid_title_toolong(): void {
if ($this->skip_because_moodle_is_below_30('Moodle POST mocking was fixed in Moodle 30.')) {
return;
}
$this->mock_edit_post();
$_POST['title'] = 'This is a very long time, it is so long that at some point it should not be valid. '.
'With a very long title used in this place we should get a form validation error. '.
$_POST['title'] = 'This is a very long time, it is so long that at some point it should not be valid. ' .
'With a very long title used in this place we should get a form validation error. ' .
'Do you think this title is long enough?';
$edit = new edit();
self::assertNull($edit->get_data());
@@ -137,7 +136,7 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check invalid format for description.
*/
public function test_edit_description_invalid_format() {
public function test_edit_description_invalid_format(): void {
if ($this->skip_because_moodle_is_below_30('Moodle POST mocking was fixed in Moodle 30.')) {
return;
}
@@ -153,9 +152,8 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check if set data works properly.
*/
public function test_setdata() {
public function test_setdata(): void {
$outage = new outage([
'autostart' => false,
'warntime' => time() - 60,
'starttime' => time(),
'stoptime' => time() + 60,
@@ -169,7 +167,7 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
/**
* Check edit::set_data() with invalid parameter.
*/
public function test_setdata_invalid() {
public function test_setdata_invalid(): void {
$edit = new edit();
$this->set_expected_exception('coding_exception');
$edit->set_data(null);
@@ -208,7 +206,7 @@ class auth_outage_forms_test extends auth_outage_base_testcase {
// The bugfix MDL-56250 in only applies to Moodle 30+.
// Before that the form validation test is meaningless (results are cached), so skip it.
if ($CFG->branch < 30) {
$this->markTestSkipped('Some tests can only run in Moodle 30+. '.$reason);
$this->markTestSkipped('Some tests can only run in Moodle 30+. ' . $reason);
return true;
}

View File

@@ -14,18 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* tests for lib.php
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2017 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/base_testcase.php');
require_once(__DIR__.'/../../lib.php');
require_once(__DIR__ . '/base_testcase.php');
require_once(__DIR__ . '/../lib.php');
/**
* tests for lib.php
@@ -34,18 +27,19 @@ require_once(__DIR__.'/../../lib.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2017 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers ::auth_outage_get_climaintenance_resource_file
*/
class auth_outage_lib_test extends auth_outage_base_testcase {
final class lib_test extends base_testcase {
/**
* Test this plugin gets climaintenance resource file.
*/
public function test_auth_outage_get_climaintenance_resource_file_resolves_a_file() {
public function test_auth_outage_get_climaintenance_resource_file_resolves_a_file(): void {
global $CFG;
$dir = $CFG->dataroot.'/auth_outage/climaintenance';
$dir = $CFG->dataroot . '/auth_outage/climaintenance';
mkdir($dir, 0777, true);
// Create a file.
$expected = $dir.'/example.txt';
$expected = $dir . '/example.txt';
file_put_contents($expected, 'Outage Unit Test Message');
// Get that file.
@@ -61,17 +55,17 @@ class auth_outage_lib_test extends auth_outage_base_testcase {
/**
* Regression test for issue #104.
*/
public function test_auth_outage_get_climaintenance_resource_file_resolves_a_file_with_symlink() {
public function test_auth_outage_get_climaintenance_resource_file_resolves_a_file_with_symlink(): void {
global $CFG;
// Create a file.
$realdir = $CFG->dataroot.'/auth_outage/climaintenance_real';
$realdir = $CFG->dataroot . '/auth_outage/climaintenance_real';
mkdir($realdir, 0777, true);
$realfile = $realdir.'/example.txt';
$realfile = $realdir . '/example.txt';
file_put_contents($realfile, 'Outage Unit Test Message');
// Create a symlink.
$symdir = $CFG->dataroot.'/auth_outage/climaintenance';
$symdir = $CFG->dataroot . '/auth_outage/climaintenance';
if (!symlink($realdir, $symdir)) {
unlink($realfile);
rmdir($realdir);
@@ -93,18 +87,18 @@ class auth_outage_lib_test extends auth_outage_base_testcase {
/**
* Test this plugin gets climaintenance resource file and prevents path traversal attack.
*/
public function test_auth_outage_get_climaintenance_resource_file_prevent_path_traversal() {
public function test_auth_outage_get_climaintenance_resource_file_prevent_path_traversal(): void {
global $CFG;
$dir = $CFG->dataroot.'/auth_outage/climaintenance';
$dir = $CFG->dataroot . '/auth_outage/climaintenance';
mkdir($dir, 0777, true);
// Create a file.
$expected = $dir.'/example.txt';
$expected = $dir . '/example.txt';
file_put_contents($expected, 'Outage Unit Test Message');
// Create a sensitive file.
$sensitivefile = $CFG->dataroot.'/auth_outage/nuclear_silo_passwords.txt';
$sensitivefile = $CFG->dataroot . '/auth_outage/nuclear_silo_passwords.txt';
file_put_contents($sensitivefile, 'The password to launch the ICBM: 123456');
// Path Traversal Attack.

View File

@@ -23,11 +23,10 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\local\cli\cli_exception;
use auth_outage\local\cli\create;
namespace auth_outage\local\cli;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/cli_testcase.php');
require_once(__DIR__ . '/cli_testcase.php');
/**
* cli_test test class.
@@ -36,12 +35,13 @@ require_once(__DIR__.'/cli_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\cli\create
*/
class auth_outage_cli_test extends auth_outage_cli_testcase {
final class cli_test extends cli_testcase {
/**
* Tests providing an unknown parameter.
*/
public function test_invalidargumentparam() {
public function test_invalidargumentparam(): void {
$this->set_parameters(['--aninvalidparameter']);
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_UNKNOWN);
new create();
@@ -50,7 +50,7 @@ class auth_outage_cli_test extends auth_outage_cli_testcase {
/**
* Tests providing another unknow parameter (without --).
*/
public function test_invalidargumentgiven() {
public function test_invalidargumentgiven(): void {
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_UNKNOWN);
new create(['anotherinvalidparameter']);
}
@@ -58,7 +58,7 @@ class auth_outage_cli_test extends auth_outage_cli_testcase {
/**
* Tests setting reference times.
*/
public function test_setreferencetime() {
public function test_setreferencetime(): void {
$cli = new create(['start' => 0]);
$cli->set_referencetime(1);
$cli->set_referencetime(60 * 60 * 24 * 7);
@@ -67,7 +67,7 @@ class auth_outage_cli_test extends auth_outage_cli_testcase {
/**
* Tests setting an invalid reference time.
*/
public function test_setreferencetime_invalid() {
public function test_setreferencetime_invalid(): void {
$this->set_parameters(['--start=60']);
$cli = new create();
$this->set_expected_exception('coding_exception');
@@ -77,7 +77,7 @@ class auth_outage_cli_test extends auth_outage_cli_testcase {
/**
* Tests the help.
*/
public function test_help() {
public function test_help(): void {
$this->set_parameters(['-h']);
$cli = new create();
$output = $this->execute($cli);
@@ -88,7 +88,7 @@ class auth_outage_cli_test extends auth_outage_cli_testcase {
/**
* Tests the cli_exception.
*/
public function test_exception() {
public function test_exception(): void {
$this->set_expected_cli_exception(cli_exception::ERROR_UNDEFINED);
throw new cli_exception('An CLI exception.');
}
@@ -96,11 +96,11 @@ class auth_outage_cli_test extends auth_outage_cli_testcase {
/**
* Tests with the auth_outage plugin disabled.
*/
public function test_authdisabled() {
public function test_authdisabled(): void {
// Disable all auth plugins.
set_config('auth', '');
\core\session\manager::gc(); // Remove stale sessions.
core_plugin_manager::reset_caches();
\core_plugin_manager::reset_caches();
// Try to create an CLI object.
$this->set_expected_cli_exception(cli_exception::ERROR_PLUGIN_CONFIGURATION);
new create();

View File

@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* auth_outage_cli_testcase class.
* cli_testcase class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
@@ -23,20 +23,20 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\local\cli\clibase;
namespace auth_outage\local\cli;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../../base_testcase.php');
require_once(__DIR__ . '/../../base_testcase.php');
/**
* auth_outage_cli_testcase class.
* cli_testcase class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class auth_outage_cli_testcase extends auth_outage_base_testcase {
abstract class cli_testcase extends \auth_outage\base_testcase {
/**
* Always enable the auth outage plugin, resets after test and set no parameters.
*/
@@ -49,7 +49,7 @@ abstract class auth_outage_cli_testcase extends auth_outage_base_testcase {
// Enable auth plugins.
set_config('auth', 'outage');
\core\session\manager::gc(); // Remove stale sessions.
core_plugin_manager::reset_caches();
\core_plugin_manager::reset_caches();
$this->set_parameters([]);
parent::setUp();

View File

@@ -23,13 +23,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
use auth_outage\local\cli\cli_exception;
use auth_outage\local\cli\create;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/cli_testcase.php');
require_once(__DIR__ . '/cli_testcase.php');
/**
* create_test test class.
@@ -38,12 +38,13 @@ require_once(__DIR__.'/cli_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\cli\create
*/
class auth_outage_create_test extends auth_outage_cli_testcase {
final class create_test extends cli_testcase {
/**
* Tests without any arguments.
*/
public function test_noarguments() {
public function test_noarguments(): void {
$cli = new create();
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_MISSING);
$this->execute($cli);
@@ -52,7 +53,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests when the start time is not a valid number.
*/
public function test_invalidparam_notanumber() {
public function test_invalidparam_notanumber(): void {
$cli = new create(['start' => 'some day']);
$cli->set_defaults([
'warn' => 50,
@@ -68,7 +69,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests when providing a negative start time.
*/
public function test_invalidparam_negative() {
public function test_invalidparam_negative(): void {
$cli = new create(['start' => -1]);
$cli->set_defaults([
'warn' => 50,
@@ -84,7 +85,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests providing an empty title.
*/
public function test_invalidparam_emptystring() {
public function test_invalidparam_emptystring(): void {
$cli = new create(['start' => 0, 'title' => '']);
$cli->set_defaults([
'warn' => 50,
@@ -100,7 +101,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests if not providing the title (it will be send as true).
*/
public function test_invalidparam_notastring() {
public function test_invalidparam_notastring(): void {
$cli = new create(['start' => 0, 'title' => true]);
$cli->set_defaults([
'warn' => 50,
@@ -116,7 +117,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests the help.
*/
public function test_help() {
public function test_help(): void {
$this->set_parameters(['--help']);
$cli = new create();
$output = $this->execute($cli);
@@ -127,7 +128,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests the options and shortcuts.
*/
public function test_options() {
public function test_options(): void {
$cli = new create();
$options = $cli->generate_options();
@@ -144,9 +145,8 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests creating with all given options.
*/
public function test_create_withoptions() {
public function test_create_withoptions(): void {
$this->set_parameters([
'--autostart=true',
'--warn=10',
'--start=0',
'--duration=30',
@@ -173,10 +173,9 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests creating with the onlyid parameter.
*/
public function test_create_onlyid() {
public function test_create_onlyid(): void {
$this->set_parameters([
'--onlyid',
'--autostart=N',
'--warn=10',
'--start=0',
'--duration=30',
@@ -187,8 +186,10 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
$cli = new create();
$cli->set_referencetime($now);
$id = $this->execute($cli);
// Check if the id contains is only a number (parameter onlyid).
$id = trim($id);
// Extracting only the id digits from the output.
preg_match('/(\d+)\s*$/', $id, $matches);
// Passing the proper id into the id variable.
$id = $matches ? $matches[1] : null;
self::assertTrue(is_number($id));
$id = (int)$id;
// Check creted outage.
@@ -204,7 +205,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests creating using some default values.
*/
public function test_create_withdefaults() {
public function test_create_withdefaults(): void {
$this->set_parameters([
'--warn=100',
'--start=50',
@@ -213,7 +214,6 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
$cli = new create();
$cli->set_referencetime($now);
$cli->set_defaults([
'autostart' => false,
'warn' => 50,
'start' => 200,
'duration' => 300,
@@ -237,12 +237,11 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests creating with clone.
*/
public function test_create_withclone() {
public function test_create_withclone(): void {
self::setAdminUser();
$now = time();
// Create the outage to clone.
$original = new outage([
'autostart' => false,
'warntime' => $now - 120,
'starttime' => $now,
'stoptime' => $now + 120,
@@ -254,14 +253,17 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
$this->set_parameters([
'--onlyid',
'--start=60',
'--clone='.$id,
'--clone=' . $id,
]);
$cli = new create();
$cli->set_referencetime($now);
$id = trim($this->execute($cli));
// Extracting only the id digits from the output.
preg_match('/(\d+)\s*$/', $id, $matches);
// Passing the proper id into the id variable.
$id = $matches ? (int)$matches[1] : null;
// Check cloned data.
$cloned = outagedb::get_by_id((int)$id);
self::assertSame($now + 60, $cloned->starttime);
self::assertSame($now, $cloned->starttime);
self::assertSame($original->get_warning_duration(), $cloned->get_warning_duration());
self::assertSame($original->get_duration_planned(), $cloned->get_duration_planned());
self::assertSame($original->title, $cloned->title);
@@ -271,7 +273,7 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests creating with an invalid clone id.
*/
public function test_create_withclone_invalid() {
public function test_create_withclone_invalid(): void {
$this->set_parameters([
'--start=60',
'--clone=-1',
@@ -284,10 +286,9 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests creating with the block flag.
*/
public function test_create_withblock() {
public function test_create_withblock(): void {
// Not an extensive test in the blocking API, cliwaitforit tests should cover them deeper.
$this->set_parameters([
'--autostart=N',
'--block',
'--warn=60',
'--start=0',
@@ -306,26 +307,9 @@ class auth_outage_create_test extends auth_outage_cli_testcase {
/**
* Tests providing an invalid option as default.
*/
public function test_setdefaults_extra() {
public function test_setdefaults_extra(): void {
$cli = new create([]);
$this->set_expected_exception('coding_exception');
$cli->set_defaults(['aninvalidparameter' => 'value']);
}
/**
* Tests with an invalud autostart bool value.
*/
public function test_invalid_bool() {
$this->set_parameters([
'--autostart=maybe',
'--warn=60',
'--start=0',
'--duration=600',
'--title=Title',
'--description=Description',
]);
$cli = new create();
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_INVALID);
$cli->execute();
}
}

View File

@@ -23,13 +23,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
use auth_outage\local\cli\cli_exception;
use auth_outage\local\cli\finish;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/cli_testcase.php');
require_once(__DIR__ . '/cli_testcase.php');
/**
* finish_test test class.
@@ -38,12 +38,13 @@ require_once(__DIR__.'/cli_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\cli\finish
*/
class auth_outage_finish_test extends auth_outage_cli_testcase {
final class finish_test extends cli_testcase {
/**
* Tests the constructor.
*/
public function test_constructor() {
public function test_constructor(): void {
$cli = new finish();
self::assertNotNull($cli);
}
@@ -51,7 +52,7 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests the generated options and shortcuts.
*/
public function test_options() {
public function test_options(): void {
$cli = new finish();
$options = $cli->generate_options();
@@ -68,7 +69,7 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests the help.
*/
public function test_help() {
public function test_help(): void {
$this->set_parameters(['--help']);
$cli = new finish();
$text = $this->execute($cli);
@@ -79,7 +80,7 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests if running without arguments.
*/
public function test_noarguments() {
public function test_noarguments(): void {
$cli = new finish();
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_MISSING);
$this->execute($cli);
@@ -88,18 +89,17 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests finishing an already ended outage.
*/
public function test_endedoutage() {
public function test_endedoutage(): void {
self::setAdminUser();
$now = time();
$id = outagedb::save(new outage([
'autostart' => false,
'warntime' => $now - 200,
'starttime' => $now - 100,
'stoptime' => $now - 50,
'title' => 'Title',
'description' => 'Description',
]));
$this->set_parameters(['-id='.$id]);
$this->set_parameters(['-id=' . $id]);
$cli = new finish();
$cli->set_referencetime($now);
$this->set_expected_cli_exception(cli_exception::ERROR_OUTAGE_INVALID);
@@ -109,18 +109,17 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests finishing an outage.
*/
public function test_finish() {
public function test_finish(): void {
self::setAdminUser();
$now = time();
$id = outagedb::save(new outage([
'autostart' => false,
'warntime' => $now - 200,
'starttime' => $now - 100,
'stoptime' => $now + 100,
'title' => 'Title',
'description' => 'Description',
]));
$this->set_parameters(['-id='.$id]);
$this->set_parameters(['-id=' . $id]);
$cli = new finish();
$cli->set_referencetime($now);
$this->execute($cli);
@@ -129,7 +128,7 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests finishing an active outage when it does not exists.
*/
public function test_activenotfound() {
public function test_activenotfound(): void {
self::setAdminUser();
$this->set_parameters(['-a']);
$cli = new finish();
@@ -140,7 +139,7 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests providing an invalid outage id.
*/
public function test_invalidid() {
public function test_invalidid(): void {
self::setAdminUser();
$this->set_parameters(['-id=theid']);
$cli = new finish();
@@ -151,7 +150,7 @@ class auth_outage_finish_test extends auth_outage_cli_testcase {
/**
* Tests when the outage is not found.
*/
public function test_idnotfound() {
public function test_idnotfound(): void {
self::setAdminUser();
$this->set_parameters(['-id=99999']);
$cli = new finish();

View File

@@ -23,13 +23,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
use auth_outage\local\cli\cli_exception;
use auth_outage\local\cli\waitforit;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/cli_testcase.php');
require_once(__DIR__ . '/cli_testcase.php');
/**
* waitforit_test test class.
@@ -38,12 +38,13 @@ require_once(__DIR__.'/cli_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\cli\waitforit
*/
class auth_outage_waitforit_test extends auth_outage_cli_testcase {
final class waitforit_test extends cli_testcase {
/**
* Tests the constructor.
*/
public function test_constructor() {
public function test_constructor(): void {
$cli = new waitforit();
self::assertNotNull($cli);
}
@@ -51,7 +52,7 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests the generated options.
*/
public function test_generateoptions() {
public function test_generateoptions(): void {
$cli = new waitforit();
$options = $cli->generate_options();
foreach (array_keys($options) as $k) {
@@ -62,7 +63,7 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests the generated shortcut options.
*/
public function test_generateshortcuts() {
public function test_generateshortcuts(): void {
$cli = new waitforit();
$options = $cli->generate_options();
$shorts = $cli->generate_shortcuts();
@@ -74,7 +75,7 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests if help works.
*/
public function test_help() {
public function test_help(): void {
$this->set_parameters(['--help']);
$cli = new waitforit();
$text = $this->execute($cli);
@@ -85,7 +86,7 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Checks if providing an outageid and active parameter.
*/
public function test_bothparams() {
public function test_bothparams(): void {
$this->set_parameters(['--outageid=1', '--active']);
$cli = new waitforit();
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_INVALID);
@@ -95,7 +96,7 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests with an invalid outage id
*/
public function test_invalidoutageid() {
public function test_invalidoutageid(): void {
$this->set_parameters(['-id=-1']);
$cli = new waitforit();
$this->set_expected_cli_exception(cli_exception::ERROR_PARAMETER_INVALID);
@@ -105,7 +106,7 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests with an active outage when it does not exists.
*/
public function test_outagenotfound() {
public function test_outagenotfound(): void {
$this->set_parameters(['-a']);
$cli = new waitforit();
$this->set_expected_cli_exception(cli_exception::ERROR_OUTAGE_NOT_FOUND);
@@ -115,18 +116,17 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests with an outage that already ended.
*/
public function test_endedoutage() {
public function test_endedoutage(): void {
self::setAdminUser();
$now = time();
$id = outagedb::save(new outage([
'autostart' => false,
'warntime' => $now - 200,
'starttime' => $now - 100,
'stoptime' => $now - 50,
'title' => 'Title',
'description' => 'Description',
]));
$this->set_parameters(['-id='.$id]);
$this->set_parameters(['-id=' . $id]);
$cli = new waitforit();
$cli->set_referencetime($now);
$this->set_expected_cli_exception(cli_exception::ERROR_OUTAGE_INVALID);
@@ -136,11 +136,10 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
/**
* Tests waiting for an existing active outage, verbose mode.
*/
public function test_activeverbose() {
public function test_activeverbose(): void {
self::setAdminUser();
$now = time();
outagedb::save(new outage([
'autostart' => false,
'warntime' => $now - 10,
'starttime' => $now + 1,
'stoptime' => $now + 10,
@@ -163,7 +162,6 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
self::setAdminUser();
$now = time();
outagedb::save(new outage([
'autostart' => false,
'warntime' => $now,
'starttime' => $now + 45,
'stoptime' => $now + (60 * 60),
@@ -192,7 +190,6 @@ class auth_outage_waitforit_test extends auth_outage_cli_testcase {
self::setAdminUser();
$now = time();
$id = outagedb::save(new outage([
'autostart' => false,
'warntime' => $now,
'starttime' => $now + (2 * 60 * 60),
'stoptime' => $now + (60 * 60),

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,7 @@
a {
font-size: 200%;
}
div {
background-image: url('/moodle/auth/outage/tests/local/controllers/fixtures/catalyst.png');
}

View File

@@ -0,0 +1,7 @@
a {
font-size: 200%;
}
div {
background-image: url(/moodle/auth/outage/tests/local/controllers/fixtures/catalyst.png);
}

View File

@@ -23,11 +23,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\local\controllers\infopage;
namespace auth_outage\local\controllers;
use auth_outage\local\outage;
use context_system;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../../base_testcase.php');
require_once(__DIR__ . '/../../base_testcase.php');
/**
* Tests performed on infopage controller class and update_static_page task class.
@@ -36,12 +38,13 @@ require_once(__DIR__.'/../../base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\controllers\infopage
*/
class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
final class infopage_test extends \auth_outage\base_testcase {
/**
* Tests the constructor.
*/
public function test_constructor() {
public function test_constructor(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
new infopage();
@@ -50,7 +53,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Tests the constructor with given parameters.
*/
public function test_constructor_withparams() {
public function test_constructor_withparams(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
$_GET = ['id' => 1, 'static' => 'true'];
@@ -60,7 +63,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Tests the constructor with different id and outage id.
*/
public function test_constructor_idmismatch() {
public function test_constructor_idmismatch(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
$outage = $this->get_dummy_outage();
@@ -71,7 +74,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Tests the constructor with an invalid outage.
*/
public function test_constructor_invalidoutage() {
public function test_constructor_invalidoutage(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
$this->set_expected_exception('coding_exception', 'Provided outage is not a valid outage object. (My outage)');
@@ -81,7 +84,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Checks the output of the info page.
*/
public function test_output() {
public function test_output(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
$outage = $this->get_dummy_outage();
@@ -94,7 +97,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Checks the output of the info page.
*/
public function test_output_without_permission() {
public function test_output_without_permission(): void {
$this->revoke_info_page_permissions();
$this->assertFalse(has_capability('auth/outage:viewinfo', context_system::instance()));
@@ -108,7 +111,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Checks the output of the info page.
*/
public function test_output_without_permission_but_static() {
public function test_output_without_permission_but_static(): void {
$this->revoke_info_page_permissions();
$this->assertFalse(has_capability('auth/outage:viewinfo', context_system::instance()));
@@ -122,7 +125,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Checks the output of the info page.
*/
public function test_output_with_forcelogin() {
public function test_output_with_forcelogin(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
set_config('forcelogin', true);
@@ -137,7 +140,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Checks the output of the info page.
*/
public function test_output_with_forcelogin_if_static() {
public function test_output_with_forcelogin_if_static(): void {
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));
set_config('forcelogin', true);
@@ -153,7 +156,7 @@ class auth_outage_infopagecontroller_test extends auth_outage_base_testcase {
/**
* Tests the constructor enables SVG support.
*/
public function test_svgicons_is_true() {
public function test_svgicons_is_true(): void {
global $CFG;
$this->assertTrue(has_capability('auth/outage:viewinfo', context_system::instance()));

View File

@@ -23,13 +23,13 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\local\controllers\maintenance_static_page;
use auth_outage\local\controllers\maintenance_static_page_io;
use auth_outage\local\controllers\maintenance_static_page_generator;
namespace auth_outage\local\controllers;
use auth_outage\task\update_static_page;
use DOMDocument;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../../base_testcase.php');
require_once(__DIR__ . '/../../base_testcase.php');
/**
* maintenance_static_page_test class.
@@ -38,44 +38,47 @@ require_once(__DIR__.'/../../base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\controllers\maintenance_static_page_generator
*/
class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase {
final class maintenance_static_page_test extends \auth_outage\base_testcase {
/**
* Test template file.
*/
public function test_templatefile() {
public function test_templatefile(): void {
global $CFG;
$page = maintenance_static_page::create_from_html('<html></html>');
self::assertSame($CFG->dataroot.'/climaintenance.template.html', $page->get_io()->get_template_file());
self::assertSame($CFG->dataroot . '/climaintenance.template.html', $page->get_io()->get_template_file());
$page->get_io()->set_preview(true);
self::assertSame($CFG->dataroot.'/auth_outage/climaintenance/preview/climaintenance.html',
$page->get_io()->get_template_file());
self::assertSame(
$CFG->dataroot . '/auth_outage/climaintenance/preview/climaintenance.html',
$page->get_io()->get_template_file()
);
}
/**
* Test resources folder.
*/
public function test_resourcesfolder() {
public function test_resourcesfolder(): void {
global $CFG;
$page = maintenance_static_page::create_from_html('<html></html>');
self::assertSame($CFG->dataroot.'/auth_outage/climaintenance', $page->get_io()->get_resources_folder());
self::assertSame($CFG->dataroot . '/auth_outage/climaintenance', $page->get_io()->get_resources_folder());
$page->get_io()->set_preview(true);
self::assertSame($CFG->dataroot.'/auth_outage/climaintenance/preview', $page->get_io()->get_resources_folder());
self::assertSame($CFG->dataroot . '/auth_outage/climaintenance/preview', $page->get_io()->get_resources_folder());
}
/**
* Test create from outage.
*/
public function test_createfromoutage() {
public function test_createfromoutage(): void {
// How to fetch a page from PHPUnit environment?
}
/**
* Test create from HTML.
*/
public function test_createfromhtml() {
public function test_createfromhtml(): void {
$html = "<!DOCTYPE html>\n<html><head><title>Title</title></head><body>Content</body></html>";
$expected = "<!DOCTYPE html>\n<html><head><title>Title</title><meta http-equiv=\"refresh\" content=\"300\">".
$expected = "<!DOCTYPE html>\n<html><head><title>Title</title><meta http-equiv=\"refresh\" content=\"300\">" .
"</head><body>Content</body></html>";
self::assertSame($expected, $this->generated_page_html($html));
}
@@ -83,9 +86,9 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove script tags.
*/
public function test_removescripttags() {
$html = "<!DOCTYPE html>\n".
'<html><head><script type="text/javascript" src="http://xyz"></script><title>Title</title></head>'.
public function test_removescripttags(): void {
$html = "<!DOCTYPE html>\n" .
'<html><head><script type="text/javascript" src="http://xyz"></script><title>Title</title></head>' .
'<body>Content<script> a < 5; x > 3</script></body></html>';
maintenance_static_page::create_from_html($html)->generate();
@@ -96,12 +99,12 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove script tags.
*/
public function test_updatelinkstylesheet() {
$localcsslink = $this->get_fixture_path('simple.css');
public function test_updatelinkstylesheet(): void {
$localcsslink = $this->get_fixture_path_location('simple.css');
$externalcsslink = 'http://google.com/coolstuff.css';
$html = "<!DOCTYPE html>\n".
'<html><head><link href="'.$localcsslink.'" rel="stylesheet" /><title>Title</title></head>'.
'<body>Content<link rel="stylesheet" href="'.$externalcsslink.'"></body></html>';
$html = "<!DOCTYPE html>\n" .
'<html><head><link href="' . $localcsslink . '" rel="stylesheet" /><title>Title</title></head>' .
'<body>Content<link rel="stylesheet" href="' . $externalcsslink . '"></body></html>';
$generated = $this->generated_page_html($html);
self::assertStringContainsString('www.example.com/moodle/auth/outage/file.php?file=', $generated);
@@ -112,66 +115,72 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test update link style sheet urls.
*/
public function test_updatelinkstylesheet_urls() {
$localcsslink = $this->get_fixture_path('withurls.css');
$html = "<!DOCTYPE html>\n".
'<html><head><link href="'.$localcsslink.'" rel="stylesheet" /><title>Title</title></head>'.
public function test_updatelinkstylesheet_urls(): void {
$localcsslink = $this->get_fixture_path_location('withurls.css');
$html = "<!DOCTYPE html>\n" .
'<html><head><link href="' . $localcsslink . '" rel="stylesheet" /><title>Title</title></head>' .
'<body>Content</body></html>';
$page = maintenance_static_page::create_from_html($html);
$page->generate();
// Check for css file.
self::assertFileExists($page->get_io()->get_resources_folder().'/d8643101d96b093e642b15544e4d1f7815b5ba55.dGV4dC9wbGFpbg');
self::assertFileExists($page->get_io()->get_resources_folder() .
'/53365950336b070c0b26ca50e7d0dad962c364e6.dGV4dC9wbGFpbg');
// Check for catalyst.png file referenced in url(..) of css.
self::assertFileExists($page->get_io()->get_resources_folder().'/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n');
self::assertFileExists($page->get_io()->get_resources_folder() .
'/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n');
}
/**
* Test update link style sheet urls quoted.
*/
public function test_updatelinkstylesheet_urls_quoted() {
$localcsslink = $this->get_fixture_path('withurls-quoted.css');
$html = "<!DOCTYPE html>\n".
'<html><head><link href="'.$localcsslink.'" rel="stylesheet" /><title>Title</title></head>'.
public function test_updatelinkstylesheet_urls_quoted(): void {
$localcsslink = $this->get_fixture_path_location('withurls-quoted.css');
$html = "<!DOCTYPE html>\n" .
'<html><head><link href="' . $localcsslink . '" rel="stylesheet" /><title>Title</title></head>' .
'<body>Content</body></html>';
$page = maintenance_static_page::create_from_html($html);
$page->generate();
// Check for css file.
self::assertFileExists($page->get_io()->get_resources_folder().'/9fe2374b03953e1949d54ab750be2d8706891c03.dGV4dC9wbGFpbg');
self::assertFileExists($page->get_io()->get_resources_folder()
. '/e0b34925c1f939c247a4b50d6bf08c76088def39.dGV4dC9wbGFpbg');
// Check for catalyst.png file referenced in url(..) of css.
self::assertFileExists($page->get_io()->get_resources_folder().'/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n');
self::assertFileExists($page->get_io()->get_resources_folder()
. '/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n');
}
/**
* Test update link style sheet urls with sub dir.
*/
public function test_updatelinkstylesheet_urls_subdir() {
$localcsslink = $this->get_fixture_path('subdir/withurls-subdir.css');
$html = "<!DOCTYPE html>\n".
'<html><head><link href="'.$localcsslink.'" rel="stylesheet" /><title>Title</title></head>'.
public function test_updatelinkstylesheet_urls_subdir(): void {
$localcsslink = $this->get_fixture_path_location('subdir/withurls-subdir.css');
$html = "<!DOCTYPE html>\n" .
'<html><head><link href="' . $localcsslink . '" rel="stylesheet" /><title>Title</title></head>' .
'<body>Content</body></html>';
$page = maintenance_static_page::create_from_html($html);
$page->generate();
// Check for css file.
self::assertFileExists($page->get_io()->get_resources_folder().'/beb44281e23b9d872056bf0230cea34535e8cdea.dGV4dC9wbGFpbg');
self::assertFileExists($page->get_io()->get_resources_folder() .
'/beb44281e23b9d872056bf0230cea34535e8cdea.dGV4dC9wbGFpbg');
// Check for file referenced in url(..) of css.
self::assertFileExists($page->get_io()->get_resources_folder().'/a02a8a442fa82d5205ffb24722d9df7f35161f56.dGV4dC9wbGFpbg');
self::assertFileExists($page->get_io()->get_resources_folder() .
'/a02a8a442fa82d5205ffb24722d9df7f35161f56.dGV4dC9wbGFpbg');
}
/**
* Test update images to file.php style link.
*/
public function test_updateimages() {
$localimglink = $this->get_fixture_path('catalyst.png');
public function test_updateimages(): void {
$localimglink = $this->get_fixture_path_location('catalyst.png');
$externalimglink = 'http://google.com/coolstyle.css';
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
'<body><img src="'.$localimglink.'">Content<img src="'.$externalimglink.'" /></body></html>';
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body><img src="' . $localimglink . '">Content<img src="' . $externalimglink . '" /></body></html>';
$generated = $this->generated_page_html($html);
self::assertStringContainsString('www.example.com/moodle/auth/outage/file.php?file=', $generated);
@@ -182,10 +191,10 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test update favicon to file.php style link.
*/
public function test_updatelinkfavicon() {
$link = $this->get_fixture_path('catalyst.png');
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title><link rel="shortcut icon" href="'.$link.'""></head>'.
public function test_updatelinkfavicon(): void {
$link = $this->get_fixture_path_location('catalyst.png');
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title><link rel="shortcut icon" href="' . $link . '""></head>' .
'<body>Content</body></html>';
$generated = $this->generated_page_html($html);
@@ -198,44 +207,45 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
* Data provider for test_update_inline_background_images
* @return array
*/
public function test_update_inline_background_images_provider() {
public static function update_inline_background_images_provider(): array {
return [
// Empty string.
["", false],
// URLs that should be retrieved.
["color: #FF00FF; background: lightblue url(/pluginfile.php/1/theme_custom/banner/251298630/0001.png) no-repeat", true],
["background: lightblue url(https://www.example.com/moodle/pluginfile.php/1/theme_custom/banner/251298630/0001.png) no-repeat", true],
["background: lightblue
url(https://www.example.com/moodle/pluginfile.php/1/theme_custom/banner/251298630/0001.png) no-repeat", true],
["background:url('https://www.example.com/moodle/pluginfile.php/1/theme_custom/banner/251298630/0001.png')", true],
["background-image : url( /pix/help.png);", true],
["background-image: url ('/pix/help.png')", true],
// URLs that should not be retrieved.
["background-image:url(data:image/gif;base64,R0lGODlhYADIAP=)", false],
["background-image:url('data:image/gif;base64,R0lGODlhYADIAP=')", false]
["background-image:url('data:image/gif;base64,R0lGODlhYADIAP=')", false],
];
}
/**
* Tests update_inline_background_images() method to update the background images.
*
* @dataProvider test_update_inline_background_images_provider
* @dataProvider update_inline_background_images_provider
* @param string $stylecontent Content of the style to test
* @param bool $rewrite Flag if URL should be rewritten
* @throws coding_exception
*/
public function test_update_inline_background_images($stylecontent, $rewrite) {
public function test_update_inline_background_images($stylecontent, $rewrite): void {
global $CFG;
$this->resetAfterTest(true);
$generator = new maintenance_static_page_generator(new DOMDocument(), new maintenance_static_page_io());
$html = '<!DOCTYPE html>\n'.
'<html><head><title>Title</title></head>'.
'<body><div style="'.$stylecontent.'">Content</div></body></html>';
$html = '<!DOCTYPE html>\n' .
'<html><head><title>Title</title></head>' .
'<body><div style="' . $stylecontent . '">Content</div></body></html>';
// Temporarily disable debugging to prevent errors because file does not exist
// Temporarily disable debugging to prevent errors because file does not exist.
$debuglevel = $CFG->debug;
$CFG->debug = '';
$generated = $this->generated_page_html($html);
// Restore debugging level
// Restore debugging level.
$CFG->debug = $debuglevel;
$matches = $generator->get_url_from_inline_style($stylecontent);
if ($rewrite) {
@@ -250,10 +260,10 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test update preview path to file.php style link.
*/
public function test_previewpath() {
$link = $this->get_fixture_path('catalyst.png');
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title><link rel="shortcut icon" href="'.$link.'""></head>'.
public function test_previewpath(): void {
$link = $this->get_fixture_path_location('catalyst.png');
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title><link rel="shortcut icon" href="' . $link . '""></head>' .
'<body>Content</body></html>';
$page = maintenance_static_page::create_from_html($html);
$page->get_io()->set_preview(true);
@@ -281,7 +291,7 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Checks if we can create and execute a task to update outage pages.
*/
public function test_tasks() {
public function test_tasks(): void {
$this->resetAfterTest(true);
$task = new update_static_page();
self::assertNotEmpty($task->get_name());
@@ -291,9 +301,9 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Tests updating the static page when there is no outage but the file existed before.
*/
public function test_updatestaticpage_hasfile() {
public function test_updatestaticpage_hasfile(): void {
global $CFG;
$file = $CFG->dataroot.'/climaintenance.template.html';
$file = $CFG->dataroot . '/climaintenance.template.html';
touch($file);
self::assertFileExists($file);
maintenance_static_page::create_from_outage(null)->generate();
@@ -308,23 +318,23 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Tests created file.
*/
public function test_createdfile() {
public function test_createdfile(): void {
global $CFG;
$link = $this->get_fixture_path('catalyst.png');
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
'<body>Content<img src="'.$link.'" /></body></html>';
$link = $this->get_fixture_path_location('catalyst.png');
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>Content<img src="' . $link . '" /></body></html>';
$page = maintenance_static_page::create_from_html($html);
$page->generate();
// This checks if content is correct and mime type is correct from the encoded name.
$file = $page->get_io()->get_resources_folder().'/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n';
$file = $page->get_io()->get_resources_folder() . '/ff7f7f87a26a908fc72930eaefb6b57306361d16.aW1hZ2UvcG5n';
self::assertFileExists($file);
// We can still assert the contents really match, not just the hash.
$found = file_get_contents($file);
$expected = file_get_contents($CFG->dirroot.'/auth/outage/tests/phpunit/local/controllers/fixtures/catalyst.png');
$expected = file_get_contents(__DIR__ . '/fixtures/catalyst.png');
self::assertSame($found, $expected);
}
@@ -335,14 +345,14 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
*
* @return string
*/
private function get_fixture_path($file) {
return (string)new moodle_url('/auth/outage/tests/phpunit/local/controllers/fixtures/'.$file);
private function get_fixture_path_location($file) {
return (string)new \moodle_url('/auth/outage/tests/local/controllers/fixtures/' . $file);
}
/**
* Test saving empty string for template file.
*/
public function test_invalid_string_saving_template_empty() {
public function test_invalid_string_saving_template_empty(): void {
$io = new maintenance_static_page_io();
$this->set_expected_exception('coding_exception');
$io->save_template_file('');
@@ -351,7 +361,7 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test saving non string for template file.
*/
public function test_invalid_string_saving_template_nostring() {
public function test_invalid_string_saving_template_nostring(): void {
$io = new maintenance_static_page_io();
$this->set_expected_exception('coding_exception');
$io->save_template_file(50);
@@ -360,22 +370,25 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test get url for file.
*/
public function test_get_url_for_file() {
public function test_get_url_for_file(): void {
$io = new maintenance_static_page_io();
self::assertStringContainsString('www.example.com/moodle/auth/outage/file.php?file=img.png', $io->get_url_for_file('img.png'));
self::assertStringContainsString(
'www.example.com/moodle/auth/outage/file.php?file=img.png',
$io->get_url_for_file('img.png')
);
}
/**
* Return array of url data provider and true or false.
*/
public function is_url_dataprovider() {
public static function is_url_dataprovider(): array {
return [
[true, 'http://catalyst.net.nz'],
[true, 'https://www.catalyst-au.net/'],
[false, '/homepage'],
[false, 'file://homepage'],
[true, '//catalyst-au.net/img/test.jpg'],
[false, '://www.catalyst-au.net/img/test.jpg']
[false, '://www.catalyst-au.net/img/test.jpg'],
];
}
@@ -385,15 +398,15 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
* @param string $result expected result
* @param string $url url to be checked
*/
public function test_is_url($result, $url) {
public function test_is_url($result, $url): void {
self::assertEquals($result, maintenance_static_page_io::is_url($url));
}
/**
* Test file get_data.
*/
public function test_file_get_data() {
$file = __DIR__.'/fixtures/catalyst.png';
public function test_file_get_data(): void {
$file = __DIR__ . '/fixtures/catalyst.png';
$found = maintenance_static_page_io::file_get_data($file);
self::assertSame(file_get_contents($file), $found['contents']);
self::assertSame('image/png', $found['mime']);
@@ -402,8 +415,8 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test invalid file get_data.
*/
public function test_file_get_data_invalidfile() {
$found = maintenance_static_page_io::file_get_data(__DIR__.'/fixtures/invalidfile');
public function test_file_get_data_invalidfile(): void {
$found = maintenance_static_page_io::file_get_data(__DIR__ . '/fixtures/invalidfile');
self::assertSame('', $found['contents']);
self::assertSame('unknown', $found['mime']);
self::assertCount(1, $this->getDebuggingMessages());
@@ -413,18 +426,51 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test invalid file get_data.
*/
public function test_file_get_data_invalidfilename() {
public function test_file_get_data_invalidfilename(): void {
$this->set_expected_exception('coding_exception');
maintenance_static_page_io::file_get_data(200);
}
/**
* Test file_get_data with curlsecurityblockedhosts.
* We will use an external URL to test passing ignoresecurity inside of file_get_data works,
* ideally in real code we should only be calling file_get_data with internal URLs.
*/
public function test_file_get_data_curlsecurityblockedhosts(): void {
global $CFG, $USER;
$testhtml = $this->getExternalTestFileUrl('/test.html');
$url = new \moodle_url($testhtml);
$host = $url->get_host();
set_config('curlsecurityblockedhosts', $host); // Blocks $host.
// Test a regular curl with the default security enabled does in fact get blocked.
$curl = new \curl();
$contents = $curl->get($testhtml);
$expected = $curl->get_security()->get_blocked_url_string();
self::assertSame($expected, $contents);
self::assertSame(0, $curl->get_errno());
if ($CFG->branch >= 403) {
self::assertDebuggingCalled(
"Blocked $testhtml: The URL is blocked. [user {$USER->id}]",
DEBUG_NONE
);
}
// Test file_get_data does return the page and isn't blocked by security.
$found = maintenance_static_page_io::file_get_data($url->out());
$expected = '47250a973d1b88d9445f94db4ef2c97a';
self::assertSame($expected, md5($found['contents']));
self::assertSame('text/html', $found['mime']);
}
/**
* Test remove css selector.
*/
public function test_remove_css_selector() {
public function test_remove_css_selector(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>Content<b class="removeme">Goodbye cruel world.</b></body></html>';
set_config('remove_selectors', '.removeme', 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -436,10 +482,10 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove css selector id.
*/
public function test_remove_css_selector_id() {
public function test_remove_css_selector_id(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>Content<b id="removeme">Goodbye cruel world.</b></body></html>';
set_config('remove_selectors', '#removeme', 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -451,13 +497,13 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove css selector with multi lines.
*/
public function test_remove_css_selector_with_multiline() {
public function test_remove_css_selector_with_multiline(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
'<body>'.
'<b class="deleteme">Goodbye cruel world.</b>'.
'<b class="removeme">Goodbye cruel world.</b>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>' .
'<b class="deleteme">Goodbye cruel world.</b>' .
'<b class="removeme">Goodbye cruel world.</b>' .
'</body></html>';
set_config('remove_selectors', ".removeme\n.deleteme", 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -470,13 +516,13 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove css selector needs trim.
*/
public function test_remove_css_selector_needing_trim() {
public function test_remove_css_selector_needing_trim(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
'<body>'.
'<b class="deleteme">Goodbye cruel world.</b>'.
'<b class="removeme">Goodbye cruel world.</b>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>' .
'<b class="deleteme">Goodbye cruel world.</b>' .
'<b class="removeme">Goodbye cruel world.</b>' .
'</body></html>';
set_config('remove_selectors', " .removeme \n .deleteme ", 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -489,13 +535,13 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove css selector with empty line.
*/
public function test_remove_css_selector_with_empty_line() {
public function test_remove_css_selector_with_empty_line(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
'<body>'.
'<b class="deleteme">Goodbye cruel world.</b>'.
'<b class="removeme">Goodbye cruel world.</b>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>' .
'<b class="deleteme">Goodbye cruel world.</b>' .
'<b class="removeme">Goodbye cruel world.</b>' .
'</body></html>';
set_config('remove_selectors', "\n\n.removeme\n\n\n\n.deleteme\n\n", 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -508,10 +554,10 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test remove css selector with invalid id.
*/
public function test_remove_css_selector_with_invalid_id() {
public function test_remove_css_selector_with_invalid_id(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>Content<b id="removeme">Goodbye cruel world.</b></body></html>';
set_config('remove_selectors', '#invalidid', 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -523,10 +569,10 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Test meta refresh 5 minutes.
*/
public function test_meta_refresh_5minutes() {
public function test_meta_refresh_5minutes(): void {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>Content<b id="removeme">Goodbye cruel world.</b></body></html>';
set_config('remove_selectors', '#invalidid', 'auth_outage');
$generated = $this->generated_page_html($html);
@@ -539,8 +585,8 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
*/
public function test_meta_refresh_maximum_5seconds() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
'<html><head><title>Title</title></head>'.
$html = "<!DOCTYPE html>\n" .
'<html><head><title>Title</title></head>' .
'<body>Content<b id="removeme">Goodbye cruel world.</b></body></html>';
set_config('remove_selectors', '#invalidid', 'auth_outage');
$page = maintenance_static_page::create_from_html($html);
@@ -556,7 +602,7 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
* Data provider for test_get_urls_from_stylesheet
* @return array
*/
public function test_get_urls_from_stylesheet_provider() {
public static function get_urls_from_stylesheet_provider(): array {
return [
// Empty string.
["", 0],
@@ -578,12 +624,12 @@ class auth_outage_maintenance_static_page_test extends auth_outage_base_testcase
/**
* Tests get_urls_from_stylesheet() method to get all appropriate URLS from the file.
*
* @dataProvider test_get_urls_from_stylesheet_provider
* @dataProvider get_urls_from_stylesheet_provider
* @param string $filecontent Content of the file
* @param int $count Expected quantity of found URLs
* @throws coding_exception
*/
public function test_get_urls_from_stylesheet($filecontent, $count) {
public function test_get_urls_from_stylesheet($filecontent, $count): void {
$this->resetAfterTest(true);
$generator = new maintenance_static_page_generator(new DOMDocument(), new maintenance_static_page_io());
$matches = $generator->get_urls_from_stylesheet($filecontent);

View File

@@ -14,19 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outage_test test class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use auth_outage\local\outage;
namespace auth_outage\local;
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__.'/../base_testcase.php');
require_once(__DIR__ . '/../base_testcase.php');
/**
* outage_test test class.
@@ -35,12 +26,13 @@ require_once(__DIR__.'/../base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\outage
*/
class auth_outage_outage_test extends auth_outage_base_testcase {
final class outage_test extends \auth_outage\base_testcase {
/**
* Tests the constructor.
*/
public function test_constructor() {
public function test_constructor(): void {
$outage = new outage();
// Very important, this should never change.
self::assertNull($outage->id, 'New empty outage can never have an id set.');
@@ -53,10 +45,9 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests the constructor, giving data as an object.
*/
public function test_constructor_object() {
$obj = new stdClass();
public function test_constructor_object(): void {
$obj = new \stdClass();
$obj->id = 1;
$obj->autostart = true;
$obj->warntime = 2;
$obj->starttime = 3;
$obj->finished = 4;
@@ -65,7 +56,6 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
$obj->description = 'Description';
$outage = new outage($obj);
self::assertSame($obj->id, $outage->id);
self::assertSame($obj->autostart, $outage->autostart);
self::assertSame($obj->warntime, $outage->warntime);
self::assertSame($obj->starttime, $outage->starttime);
self::assertSame($obj->finished, $outage->finished);
@@ -77,7 +67,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests the constructor with invalid data.
*/
public function test_constructor_invalid() {
public function test_constructor_invalid(): void {
$this->set_expected_exception('coding_exception');
new outage('My outage');
}
@@ -85,7 +75,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests getting the stage considering the current time (now).
*/
public function test_getstage_now() {
public function test_getstage_now(): void {
$now = time();
// Make sure it is in the past.
$outage = new outage([
@@ -101,7 +91,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests getting the stage providing an invalid time reference.
*/
public function test_getstage_invalidtime() {
public function test_getstage_invalidtime(): void {
$outage = new outage();
$this->set_expected_exception('coding_exception');
$outage->get_stage(-1);
@@ -110,7 +100,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests is_ongoing() with different outage stages.
*/
public function test_isongoing() {
public function test_isongoing(): void {
$now = time();
// In the past.
@@ -147,7 +137,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests is_active() with different outage stages.
*/
public function test_isactive() {
public function test_isactive(): void {
$now = time();
// In the past.
@@ -194,7 +184,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests different outage stages.
*/
public function test_stages() {
public function test_stages(): void {
$now = time();
$outage = new outage([
@@ -269,7 +259,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests if getting title and description replaces the placeholders.
*/
public function test_gettitle_getdescription() {
public function test_gettitle_getdescription(): void {
$now = time();
$outage = new outage([
'warntime' => $now - 50,
@@ -290,7 +280,7 @@ class auth_outage_outage_test extends auth_outage_base_testcase {
/**
* Tests getting the durations.
*/
public function test_getdurations() {
public function test_getdurations(): void {
$outage = new outage(['starttime' => 1000]);
self::assertNull($outage->get_duration_actual());

View File

@@ -14,24 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* outagelib_test test class.
*
* @package auth_outage
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_outage\local;
use auth_outage\dml\outagedb;
use auth_outage\local\outage;
use auth_outage\local\outagelib;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir.'/adminlib.php');
require_once(__DIR__.'/../base_testcase.php');
require_once($CFG->libdir . '/adminlib.php');
require_once(__DIR__ . '/../base_testcase.php');
/**
* outagelib_test test class.
@@ -40,58 +30,19 @@ require_once(__DIR__.'/../base_testcase.php');
* @author Daniel Thee Roperto <daniel.roperto@catalyst-au.net>
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @covers \auth_outage\local\outagelib
*/
class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check if maintenance message is disabled as needed.
*/
public function test_maintenancemessage() {
$this->resetAfterTest(true);
static::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => true,
'warntime' => $now,
'starttime' => $now + 100,
'stoptime' => $now + 200,
'title' => 'Title',
'description' => 'Description',
]);
set_config('maintenance_message', 'A message.');
ob_start();
outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
self::assertFalse((bool)get_config('moodle', 'maintenance_message'));
self::assertCount(2, $this->getDebuggingMessages());
$this->resetDebugging();
}
/**
* Check if maintenance later is removed if no outage set.
*/
public function test_maintenancelater_nonext() {
$this->resetAfterTest(true);
set_config('maintenance_later', time() + (60 * 60 * 24 * 7)); // In 1 week.
self::assertNotEmpty(get_config('moodle', 'maintenance_later'));
outagelib::prepare_next_outage();
self::assertEmpty(get_config('moodle', 'maintenance_later'));
}
final class outagelib_test extends \auth_outage\base_testcase {
/**
* Check outagelib::inject() works as expected.
*/
public function test_inject() {
public function test_inject(): void {
global $OUTPUT;
$this->resetAfterTest(true);
self::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => true,
'warntime' => $now,
'starttime' => $now + 100,
'stoptime' => $now + 200,
@@ -102,7 +53,6 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
$outage->id = outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
outagelib::reset_injectcalled();
// Get full header to avoid interactions with other single inject plugins.
@@ -120,7 +70,7 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check outagelib::inject() will not break the page if something goes wrong.
*/
public function test_inject_broken() {
public function test_inject_broken(): void {
$_GET = ['auth_outage_break_code' => '1'];
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
@@ -131,13 +81,12 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check if injection works with preview.
*/
public function test_inject_preview() {
public function test_inject_preview(): void {
global $CFG;
$this->resetAfterTest(true);
self::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => true,
'warntime' => $now,
'starttime' => $now + 100,
'stoptime' => $now + 200,
@@ -148,7 +97,6 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
$outage->id = outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
$_GET = ['auth_outage_preview' => (string)$outage->id];
@@ -161,7 +109,7 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check if injection works with invalid preview without stopping the page.
*/
public function test_inject_preview_notfound() {
public function test_inject_preview_notfound(): void {
global $CFG;
$_GET = ['auth_outage_preview' => '1'];
@@ -174,13 +122,12 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Test injection with preview and delta.
*/
public function test_inject_preview_withdelta() {
public function test_inject_preview_withdelta(): void {
global $CFG;
$this->resetAfterTest(true);
self::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => true,
'warntime' => $now,
'starttime' => $now + 100,
'stoptime' => $now + 200,
@@ -191,7 +138,6 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
$outage->id = outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
$_GET = ['auth_outage_preview' => (string)$outage->id, 'auth_outage_delta' => '500'];
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
@@ -202,7 +148,7 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Test injection without active outage.
*/
public function test_inject_noactive() {
public function test_inject_noactive(): void {
outagelib::reset_injectcalled();
outagelib::get_inject_code();
}
@@ -210,11 +156,10 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check if get config works without getting defaults.
*/
public function test_get_config() {
public function test_get_config(): void {
$this->resetAfterTest(true);
$keys = [
'css',
'default_autostart',
'default_description',
'default_duration',
'default_title',
@@ -224,12 +169,12 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
];
// Set config with values.
foreach ($keys as $k) {
set_config($k, $k.'_value', 'auth_outage');
set_config($k, $k . '_value', 'auth_outage');
}
// Ensure it is not using any defaults.
$config = outagelib::get_config();
foreach ($keys as $k) {
self::assertSame($config->$k, $k.'_value', 'auth_outage');
self::assertSame($config->$k, $k . '_value', 'auth_outage');
}
set_config('allowedips_forced', 'allowedips_forced_value', 'auth_outage');
@@ -240,12 +185,11 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check that config has key.
*/
public function test_config_keys() {
public function test_config_keys(): void {
$this->resetAfterTest(true);
$keys = [
'allowedips',
'css',
'default_autostart',
'default_description',
'default_duration',
'default_title',
@@ -261,12 +205,11 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check if get config works getting defaults when needed.
*/
public function test_get_config_invalid() {
public function test_get_config_invalid(): void {
$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');
set_config('default_duration', " \n", 'auth_outage');
set_config('default_title', " \n", 'auth_outage');
@@ -283,14 +226,13 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Check if outagelib::inject() does not inject on admin/settings.php?section=additionalhtml
*/
public function test_inject_settings() {
public function test_inject_settings(): void {
global $CFG;
$this->resetAfterTest(true);
self::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => true,
'warntime' => $now,
'starttime' => $now + 100,
'stoptime' => $now + 200,
@@ -301,7 +243,6 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
$outage->id = outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
// Pretend we are there...
$_SERVER['SCRIPT_FILENAME'] = '/var/www/alternativepath/admin/settings.php'; // Issue #88 regression test.
@@ -316,44 +257,82 @@ class auth_outage_outagelib_test extends auth_outage_base_testcase {
/**
* Test create maintenance php code
*/
public function test_createmaintenancephpcode() {
public function test_createmaintenancephpcode(): void {
global $CFG;
$CFG->cookiehttponly = false;
$expected = <<<'EOT'
<?php
if ((time() >= 123) && (time() < 456)) {
define('MOODLE_INTERNAL', true);
if (!defined('MOODLE_INTERNAL')) {
define('MOODLE_INTERNAL', true);
}
require_once($CFG->dirroot.'/lib/moodlelib.php');
if (file_exists($CFG->dirroot.'/lib/classes/ip_utils.php')) {
require_once($CFG->dirroot.'/lib/classes/ip_utils.php');
}
if (!remoteip_in_list('hey\'\"you
// 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);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
setcookie('auth_outage_accesskey', $urlaccesskey, time() + 86400, '/', '', true, false);
}
// Use url access key if given, else the cookie, else null.
$useraccesskey = $urlaccesskey ?: $_COOKIE['auth_outage_accesskey'] ?? null;
$ipblocked = !remoteip_in_list('hey\'\"you
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');
header('X-Moodle-Maintenance: manager');
if ((defined('AJAX_SCRIPT') && AJAX_SCRIPT) || (defined('WS_SERVER') && WS_SERVER)) {
e.e.e.e/20');
$accesskeyblocked = $useraccesskey != '12345';
$allowed = (true && !$accesskeyblocked) || (true && !$ipblocked);
if (!$allowed) {
if (!$isphpunit) {
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');
header('X-Moodle-Maintenance: manager');
if (!empty('testmeta')) {
header('X-Outage-Metadata: ' . 'testmeta');
}
header('X-Outage-StartTime: ' . '123');
header('X-Outage-EndTime: ' . '456');
}
if (!$isphpunit && ((defined('AJAX_SCRIPT') && AJAX_SCRIPT) || (defined('WS_SERVER') && WS_SERVER))) {
exit(0);
}
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);
if (true && $ipblocked) {
echo '<!-- auth_outage blocked your ip: '.getremoteaddr('n/a').' -->';
}
if (true && $accesskeyblocked) {
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: '. $useraccesskey .' -->';
}
if (!$isphpunit) {
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.');
}
// The file above should always exist, but just in case...
die('We are currently under maintentance, please try again later.');
}
}
EOT;
$found = outagelib::create_climaintenancephp_code(123, 456, "hey'\"you\na.b.c.d\ne.e.e.e/20");
$found = outagelib::create_climaintenancephp_code(123, 456, "hey'\"you\na.b.c.d\ne.e.e.e/20", '12345', 'testmeta');
self::assertSame($expected, $found);
}
@@ -361,51 +340,88 @@ EOT;
* Test create maintenance php code without age
*
* @param string $configkey The key of the config.
* @dataProvider test_createmaintenancephpcode_withoutage_provider
* @dataProvider createmaintenancephpcode_withoutage_provider
*/
public function test_createmaintenancephpcode_withoutage($configkey) {
public function test_createmaintenancephpcode_withoutage($configkey): void {
global $CFG;
$this->resetAfterTest(true);
$CFG->cookiehttponly = false;
$expected = <<<'EOT'
<?php
if ((time() >= 123) && (time() < 456)) {
define('MOODLE_INTERNAL', true);
if (!defined('MOODLE_INTERNAL')) {
define('MOODLE_INTERNAL', true);
}
require_once($CFG->dirroot.'/lib/moodlelib.php');
if (file_exists($CFG->dirroot.'/lib/classes/ip_utils.php')) {
require_once($CFG->dirroot.'/lib/classes/ip_utils.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');
header('X-Moodle-Maintenance: manager');
if ((defined('AJAX_SCRIPT') && AJAX_SCRIPT) || (defined('WS_SERVER') && WS_SERVER)) {
// 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);
$isphpunit = defined('PHPUNIT_TEST');
if (!empty($urlaccesskey) && !$isphpunit) {
setcookie('auth_outage_accesskey', $urlaccesskey, time() + 86400, '/', '', true, false);
}
// Use url access key if given, else the cookie, else null.
$useraccesskey = $urlaccesskey ?: $_COOKIE['auth_outage_accesskey'] ?? null;
$ipblocked = !remoteip_in_list('127.0.0.1');
$accesskeyblocked = $useraccesskey != '5678';
$allowed = (true && !$accesskeyblocked) || (true && !$ipblocked);
if (!$allowed) {
if (!$isphpunit) {
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');
header('X-Moodle-Maintenance: manager');
if (!empty(NULL)) {
header('X-Outage-Metadata: ' . NULL);
}
header('X-Outage-StartTime: ' . '123');
header('X-Outage-EndTime: ' . '456');
}
if (!$isphpunit && ((defined('AJAX_SCRIPT') && AJAX_SCRIPT) || (defined('WS_SERVER') && WS_SERVER))) {
exit(0);
}
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);
if (true && $ipblocked) {
echo '<!-- auth_outage blocked your ip: '.getremoteaddr('n/a').' -->';
}
if (true && $accesskeyblocked) {
echo '<!-- auth_outage blocked by missing or incorrect access key, access key given: '. $useraccesskey .' -->';
}
if (!$isphpunit) {
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.');
}
// The file above should always exist, but just in case...
die('We are currently under maintentance, please try again later.');
}
}
EOT;
$outage = new outage([
'starttime' => 123,
'stoptime' => 456,
'accesskey' => '5678',
]);
$file = $CFG->dataroot.'/climaintenance.php';
$file = $CFG->dataroot . '/climaintenance.php';
set_config($configkey, '127.0.0.1', 'auth_outage');
outagelib::update_climaintenance_code($outage);
@@ -414,22 +430,27 @@ EOT;
self::assertSame($found, $expected);
}
public function test_createmaintenancephpcode_withoutage_provider(): array {
/**
* Provides values to test_createmaintenancephpcode_withoutage
* @return array
*/
public static function createmaintenancephpcode_withoutage_provider(): array {
return [['allowedips'], ['allowedips_forced']];
}
/**
* Test create maintenance php code without IPs
* Test create maintenance php code without IPs or accesskey
*/
public function test_createmaintenancephpcode_withoutips() {
public function test_createmaintenancephpcode_withoutips_or_accesskey(): void {
global $CFG;
$this->resetAfterTest(true);
$outage = new outage([
'starttime' => 123,
'stoptime' => 456,
'accesskey' => null,
]);
$file = $CFG->dataroot.'/climaintenance.php';
$file = $CFG->dataroot . '/climaintenance.php';
set_config('allowedips', '', 'auth_outage');
set_config('allowedips_forced', '', 'auth_outage');
@@ -446,9 +467,9 @@ EOT;
/**
* Test create maintenance php code without outage
*/
public function test_createmaintenancephpcode_withoutoutage() {
public function test_createmaintenancephpcode_withoutoutage(): void {
global $CFG;
$file = $CFG->dataroot.'/climaintenance.php';
$file = $CFG->dataroot . '/climaintenance.php';
touch($file);
outagelib::update_climaintenance_code(null);
@@ -460,25 +481,10 @@ EOT;
}
}
/**
* Related to Issue #70: Creating ongoing outage does not trigger maintenance file creation.
*/
public function test_preparenextoutage_notautostart() {
global $CFG;
$this->create_outage();
// The method outagelib::prepare_next_outage() should have been called by save().
foreach ([$CFG->dataroot.'/climaintenance.template.html', $CFG->dataroot.'/climaintenance.php'] as $file) {
self::assertFileExists($file);
unlink($file);
}
}
/**
* Regression Test - Issue #82: When changing the IP address list it should recreate the maintenance files.
*/
public function test_when_we_change_allowed_ips_in_settings_it_updates_the_templates() {
public function test_when_we_change_allowed_ips_in_settings_it_updates_the_templates(): void {
global $CFG;
$this->create_outage();
@@ -487,7 +493,7 @@ EOT;
set_config('s_auth_outage_allowedips', '127', 'auth_outage');
// The method outagelib::prepare_next_outage() should have been called from admin_write_settings().
foreach ([$CFG->dataroot.'/climaintenance.template.html', $CFG->dataroot.'/climaintenance.php'] as $file) {
foreach ([$CFG->dataroot . '/climaintenance.template.html', $CFG->dataroot . '/climaintenance.php'] as $file) {
self::assertFileExists($file);
unlink($file);
}
@@ -496,7 +502,7 @@ EOT;
/**
* Problem detected while solving Issue #82.
*/
public function test_when_we_change_remove_selectors_in_settings_it_updates_the_templates() {
public function test_when_we_change_remove_selectors_in_settings_it_updates_the_templates(): void {
global $CFG;
$this->create_outage();
@@ -505,53 +511,22 @@ EOT;
set_config('s_auth_outage_remove_selectors', '.something', 'auth_outage');
// The method outagelib::prepare_next_outage() should have been called from admin_write_settings().
foreach ([$CFG->dataroot.'/climaintenance.template.html', $CFG->dataroot.'/climaintenance.php'] as $file) {
foreach ([$CFG->dataroot . '/climaintenance.template.html', $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.
// Backwards compatibility with older PHPUnit - use old assertFile method.
if (method_exists($this, 'assertFileDoesNotExist')) {
self::assertFileDoesNotExist($CFG->dataroot.'/climaintenance.html');
} else {
self::assertFileNotExists($CFG->dataroot.'/climaintenance.html');
}
}
/**
* Regression test for issue #85.
*/
public function test_it_can_inject_in_settings_if_not_additional_html() {
public function test_it_can_inject_in_settings_if_not_additional_html(): void {
global $CFG;
$this->resetAfterTest(true);
self::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => true,
'warntime' => $now,
'starttime' => $now + 100,
'stoptime' => $now + 200,
@@ -562,7 +537,6 @@ EOT;
$outage->id = outagedb::save($outage);
$text = trim(ob_get_contents());
ob_end_clean();
self::assertStringContainsString('Update maintenance mode configuration', $text);
// Pretend we are there...
$_SERVER['SCRIPT_FILENAME'] = '/var/www/alternativepath/admin/settings.php'; // Issue #88 regression test.
$_SERVER['SCRIPT_NAME'] = '/admin/settings.php';
@@ -581,7 +555,6 @@ EOT;
self::setAdminUser();
$now = time();
$outage = new outage([
'autostart' => false,
'warntime' => $now - 200,
'starttime' => $now - 100,
'stoptime' => $now + 200,
@@ -594,6 +567,154 @@ EOT;
// Enable outage plugin so settings can be changed.
set_config('auth', 'outage');
\core\session\manager::gc(); // Remove stale sessions.
core_plugin_manager::reset_caches();
\core_plugin_manager::reset_caches();
}
/**
* Provides values to test_evaluation_maintenancepage
* @return array
*/
public static function evaluation_maintenancepage_provider(): array {
$blockedipout = '<!-- auth_outage blocked your ip:';
$blockedaccesskeyout = '<!-- auth_outage blocked by missing or incorrect access key, access key given:';
return [
// IP set up, access key not set up.
'ip allowed, no access key setup' => [
'allowedips' => '127.0.0.1',
'iptouse' => '127.0.0.1',
'accesskey' => null,
'accesskeytouse' => null,
'expectedoutputs' => [],
],
'ip not allowed, no access key setup' => [
'allowedips' => '5.5.5.5',
'iptouse' => '127.0.0.1',
'accesskey' => null,
'accesskeytouse' => null,
'expectedoutputs' => [$blockedipout],
],
// IP not set up, access key set up.
'access key incorrect, no ip setup' => [
'allowedips' => null,
'iptouse' => null,
'accesskey' => '12345',
'accesskeytouse' => 'wrong',
'expectedoutputs' => [$blockedaccesskeyout],
],
'access key correct, no ip setup' => [
'allowedips' => null,
'iptouse' => null,
'accesskey' => '12345',
'accesskeytouse' => '12345',
'expectedoutputs' => [],
],
// Both IP and access key set up.
'access key incorrect, ip incorrect' => [
'allowedips' => '127.0.0.1',
'iptouse' => '5.5.5.5',
'accesskey' => '12345',
'accesskeytouse' => 'wrong',
'expectedoutputs' => [$blockedipout, $blockedaccesskeyout],
],
'access key correct, ip incorrect' => [
'allowedips' => '127.0.0.1',
'iptouse' => '5.5.5.5',
'accesskey' => '12345',
'accesskeytouse' => '12345',
'expectedoutputs' => [],
],
'access key incorrect, ip correct' => [
'allowedips' => '127.0.0.1',
'iptouse' => '127.0.0.1',
'accesskey' => '12345',
'accesskeytouse' => 'wrong',
'expectedoutputs' => [],
],
'access key correct, ip correct' => [
'allowedips' => '127.0.0.1',
'iptouse' => '127.0.0.1',
'accesskey' => '12345',
'accesskeytouse' => '12345',
'expectedoutputs' => [],
],
];
}
/**
* Tests the evaluation logic of the generated maintenance page.
*
* @param string|null $allowedips config to set as allowed ips - null to not set
* @param string|null $iptouse ip to 'fake' as the remote ip, or null to not set.
* @param string|null $accesskey config to set as the access key in the outage - null to not set
* @param string|null $accesskeytouse access key to pass in as fake url params - null to not set
* @param array $expectedoutputs expected output strings, if empty will test that the output was also empty.
*
* @dataProvider evaluation_maintenancepage_provider
*
* We need this because we modify the request headers,
* see https://github.com/sebastianbergmann/phpunit/issues/720#issuecomment-10421092
* @runInSeparateProcess
*/
public function test_evaluation_maintenancepage(
?string $allowedips,
?string $iptouse,
?string $accesskey,
?string $accesskeytouse,
array $expectedoutputs
): void {
global $CFG, $_SERVER, $_GET;
$this->resetAfterTest(true);
self::setAdminUser();
$now = time();
$outage = new outage([
'warntime' => $now - 200,
'starttime' => $now - 100,
'stoptime' => $now + 200,
'title' => 'Title',
'description' => 'Description',
'accesskey' => $accesskey,
]);
if (!is_null($allowedips)) {
set_config('allowedips', $allowedips, 'auth_outage');
}
// Ensure if the file exists we clean it (e.g. from a previous test run).
$file = $CFG->dataroot . '/climaintenance.php';
if (file_exists($file)) {
unlink($file);
}
// This basically sets the output of getremoteaddr().
if (!is_null($iptouse)) {
$_SERVER['REMOTE_ADDR'] = $iptouse;
}
// This sets the output of optional_param().
if (!is_null($accesskeytouse)) {
$_GET['accesskey'] = $accesskeytouse;
}
outagelib::update_climaintenance_code($outage);
self::assertFileExists($file);
// Require the file to execute it.
// Normally this would die, but we have baked some goodies in there
// that stop it die'ing during a unit test.
ob_start();
require($file);
$contents = ob_get_clean();
// Check each output is as expected.
foreach ($expectedoutputs as $expectedoutput) {
$this->assertStringContainsString($expectedoutput, $contents);
}
// Ensure if nothing was expected, that it is empty.
if (empty($expectedoutputs)) {
$this->assertEmpty($contents);
}
}
}

View File

@@ -1,7 +0,0 @@
a {
font-size: 200%;
}
div {
background-image: url('/moodle/auth/outage/tests/phpunit/local/controllers/fixtures/catalyst.png');
}

View File

@@ -1,7 +0,0 @@
a {
font-size: 200%;
}
div {
background-image: url(/moodle/auth/outage/tests/phpunit/local/controllers/fixtures/catalyst.png);
}

View File

@@ -28,8 +28,9 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = "auth_outage";
$plugin->version = 2023012700; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2023012700; // Human-readable release information.
$plugin->version = 2024081903; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2024081903; // 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, 401]; // A range of branch numbers of supported moodle versions.
$plugin->supported = [39, 405]; // A range of branch numbers of supported moodle versions.
$plugin->incompatible = 501;

View File

@@ -24,6 +24,7 @@
*
* @var array $viewbag
*/
// phpcs:disable moodle.Commenting.MissingDocblock.File
defined('MOODLE_INTERNAL') || die();
?>
@@ -40,15 +41,17 @@ defined('MOODLE_INTERNAL') || die();
</div>
<div class="auth_outage_info_description"><?php echo $viewbag['outage']->get_description(); ?></div>
<?php if ($viewbag['admin']): ?>
<?php if ($viewbag['admin']) : ?>
<?php
$adminlinks = [];
foreach ([
foreach (
[
'startofwarning' => -$viewbag['outage']->get_warning_duration(),
'15secondsbefore' => -15,
'start' => 0,
'endofoutage' => $viewbag['outage']->get_duration_planned() - 1,
] as $title => $delta) {
] as $title => $delta
) {
$adminlinks[] = html_writer::link(
new moodle_url(
'/auth/outage/info.php',
@@ -58,7 +61,7 @@ defined('MOODLE_INTERNAL') || die();
'auth_outage_delta' => $delta,
]
),
get_string('info'.$title, 'auth_outage')
get_string('info' . $title, 'auth_outage')
);
}
$adminlinks[] = html_writer::link(

View File

@@ -22,6 +22,7 @@
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// phpcs:disable moodle.Commenting.MissingDocblock.File
use auth_outage\output\manage\history_table;
use auth_outage\output\manage\planned_table;
@@ -40,11 +41,11 @@ echo $viewbag['warning'];
<section id="section_planned_outages">
<?php echo $output->rendersubtitle('outageslistfuture'); ?>
<?php if (empty($viewbag['unended'])): ?>
<?php if (empty($viewbag['unended'])) : ?>
<p>
<small><?php echo get_string('notfound', 'auth_outage'); ?></small>
</p>
<?php else: ?>
<?php else : ?>
<?php
$table = new planned_table();
$table->show_data($viewbag['unended']);
@@ -64,7 +65,7 @@ echo $viewbag['warning'];
$urlnew->param('starttime', $next);
echo $output->single_button($urlnew, get_string('outagecreate', 'auth_outage'));
if ($default) {
echo ' ' . userdate( $next, get_string('datetimeformat', 'auth_outage'));
echo ' ' . userdate($next, get_string('datetimeformat', 'auth_outage'));
}
}
endif; ?>
@@ -72,11 +73,11 @@ echo $viewbag['warning'];
<section id="section_outage_history">
<?php echo $output->rendersubtitle('outageslistpast'); ?>
<?php if (empty($viewbag['ended'])): ?>
<?php if (empty($viewbag['ended'])) : ?>
<p>
<small><?php echo get_string('notfound', 'auth_outage'); ?></small>
</p>
<?php else: ?>
<?php else : ?>
<?php
$table = new history_table();
$table->show_data($viewbag['ended']);

View File

@@ -22,6 +22,7 @@
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// phpcs:disable moodle.Commenting.MissingDocblock.File
use auth_outage\local\outagelib;
@@ -46,23 +47,27 @@ if (!$viewbag['static']) {
['target' => '_blank', 'class' => 'auth_outage_warningbar_box_title']
);
if (is_siteadmin()) {
$url = new moodle_url('/auth/outage/finish.php', ['id' => $viewbag['outage']->id]);
$text = html_writer::empty_tag('img', [
'src' => $OUTPUT->image_url('t/check'),
'alt' => get_string('finish', 'auth_outage'),
'class' => 'iconsmall',
]).' '.get_string('finish', 'auth_outage');
$attr = [
'title' => get_string('finish', 'auth_outage'),
'class' => 'auth_outage_warningbar_box_finish',
];
$title .= ' '.html_writer::span(html_writer::link($url, $text, $attr), '', ['id' => 'auth_outage_warningbar_button']);
$link = html_writer::link(
new moodle_url('/auth/outage/finish.php', ['id' => $viewbag['outage']->id]),
$OUTPUT->pix_icon(
't/check',
get_string('finish', 'auth_outage'),
'moodle',
['class' => 'iconsmall']
)
. get_string('finish', 'auth_outage'),
[
'title' => get_string('finish', 'auth_outage'),
'class' => 'auth_outage_warningbar_box_finish',
]
);
$title .= ' ' . html_writer::span($link, '', ['id' => 'auth_outage_warningbar_button']);
}
}
?>
<style>
<?php
readfile($CFG->dirroot.'/auth/outage/views/warningbar/warningbar.css');
readfile($CFG->dirroot . '/auth/outage/views/warningbar/warningbar.css');
echo outagelib::get_config()->css;
?>
</style>
@@ -74,11 +79,11 @@ if (!$viewbag['static']) {
</div>
</div>
<?php if (!$viewbag['static']): ?>
<?php if (!$viewbag['static']) : ?>
<script>
document.body.className += ' auth_outage';
<?php
require(__DIR__.'/warningbar.js');
require(__DIR__ . '/warningbar.js');
$json = json_encode([
'countdown' => $countdown,
'ongoing' => $ongoing,
@@ -90,7 +95,7 @@ if (!$viewbag['static']) {
'preview' => $viewbag['preview'],
'checkfinishedurl' => (string)(new moodle_url('/auth/outage/checkfinished.php')),
]);
echo 'authOutageWarningBar.init('.$json.');';
echo 'authOutageWarningBar.init(' . $json . ');';
?>
</script>
<?php endif;