2 Commits

Author SHA1 Message Date
Brendan Heywood
244084b4c0 Merge branch 'master' into admin-message 2020-11-04 10:02:18 +11:00
Brendan Heywood
c6cee3cd4f Added admin notifications #185 2020-02-15 01:01:06 +11:00
61 changed files with 514 additions and 369 deletions

View File

@@ -1,11 +0,0 @@
name: ci
on: [push, pull_request]
jobs:
test:
uses: catalyst/catalyst-moodle-workflows/.github/workflows/ci.yml@main
secrets:
moodle_org_token: ${{ secrets.MOODLE_ORG_TOKEN }}
with:
disable_behat: true

75
.travis.yml Normal file
View File

@@ -0,0 +1,75 @@
language: php
sudo: true
services:
- mysql
addons:
firefox: "47.0.1"
postgresql: "9.6"
apt:
packages:
- openjdk-8-jre
cache:
directories:
- $HOME/.composer/cache
- $HOME/.npm
php:
- 7.2
env:
- DB=pgsql MOODLE_BRANCH=MOODLE_36_STABLE NODEJS=8
- DB=mysqli MOODLE_BRANCH=MOODLE_36_STABLE NODEJS=8
- DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_38_STABLE
- DB=pgsql MOODLE_BRANCH=MOODLE_39_STABLE
- DB=mysqli MOODLE_BRANCH=MOODLE_39_STABLE
matrix:
include:
- php: 5.6
env: DB=pgsql MOODLE_BRANCH=MOODLE_33_STABLE NODEJS=8
- php: 7.0
env: DB=mysqli MOODLE_BRANCH=MOODLE_35_STABLE
- php: 7.1
env: DB=mysqli MOODLE_BRANCH=MOODLE_33_STABLE NODEJS=8
- php: 7.4
env: DB=mysqli MOODLE_BRANCH=master
- php: 7.4
env: DB=pgsql MOODLE_BRANCH=master
before_install:
- export MOODLE_VERSION=$(echo "$MOODLE_BRANCH" | cut -d'_' -f 2)
- phpenv config-rm xdebug.ini
- if [ "$NODEJS" = 8 ]; then
nvm install 8.9;
nvm use 8.9;
else
nvm install 14.0.0;
nvm use 14.0.0;
fi
- cd ../..
- composer selfupdate
- composer create-project -n --no-dev --prefer-dist blackboard-open-source/moodle-plugin-ci ci ^2
- export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH"
install:
- moodle-plugin-ci install
script:
- moodle-plugin-ci phplint
- moodle-plugin-ci phpcpd
- moodle-plugin-ci phpmd
- moodle-plugin-ci codechecker
- moodle-plugin-ci validate
- moodle-plugin-ci savepoints
- moodle-plugin-ci mustache
- moodle-plugin-ci grunt
- moodle-plugin-ci phpunit
# Behat tests are failing due to issue:
# https://github.com/blackboard-open-source/moodle-plugin-ci/issues/70
# Commenting it out until the issue is fixed.
# - moodle-plugin-ci behat

View File

@@ -1,4 +1,6 @@
[![ci](https://github.com/catalyst/moodle-auth_outage/actions/workflows/ci.yml/badge.svg?branch=MOODLE_38_STABLE)](https://github.com/catalyst/moodle-auth_outage/actions/workflows/ci.yml?branch=MOODLE_38_STABLE)
<a href="https://travis-ci.org/catalyst/moodle-auth_outage">
<img src="https://travis-ci.org/catalyst/moodle-auth_outage.svg?branch=master">
</a>
# Moodle Outage manager plugin
* [Version Support](#version-support)
@@ -44,10 +46,8 @@ Branches
| ----------------- | ----------- | ---- |
| Moodle 2.7 to 3.2 | MOODLE_32_STABLE | 5.5+ |
| Totara up to 10 | TOTARA_10 | 5.5+ |
| Moodle 3.3 to 3.8 | MOODLE_38_STABLE | 7.1+ |
| Totara 11 to 12 | MOODLE_38_STABLE | 7.1+ |
| Moodle 3.9+ | MOODLE_39_STABLE | 7.2+ |
| Totara 13+ | MOODLE_39_STABLE | 7.2+ |
| Moodle 3.3+ | master | 7.0+ |
| Totara 11+ | master | 7.0+ |
Screenshots
-----------

View File

@@ -58,6 +58,7 @@ class auth_plugin_outage extends auth_plugin_base {
/**
* Always returns false (password wrong or user does not exist).
*
* @inheritdoc PHPMD will not warn about unused parameters if overriding.
* @param string $username Not used in this plugin.
* @param string $password Not used in this plugin.
* @return bool False
@@ -65,4 +66,11 @@ class auth_plugin_outage extends auth_plugin_base {
public function user_login($username, $password) {
return false;
}
/**
* Login page hook.
*/
public function loginpage_hook() {
outagelib::inject();
}
}

View File

@@ -30,9 +30,7 @@
*/
// This call is required by Moodle, but this script should have been called by config.php anyway.
// @codingStandardsIgnoreStart
require_once(__DIR__.'/../../config.php');
// @codingStandardsIgnoreEnd
// We need the CFG->dataroot, if not set yet this script is called too early in config.php file.
if (!isset($CFG->dataroot)) {
@@ -73,7 +71,7 @@ if (!empty($_SERVER['REQUEST_URI'])) {
$rooturl = parse_url($CFG->wwwroot);
$path = '';
if (array_key_exists('path', $rooturl) && !empty($rooturl['path'])) {
$path = $rooturl['path'];
$path = $rooturl['url'];
}
$url = $path.'/auth/outage/info.php';
$outageinfo = strpos($_SERVER['REQUEST_URI'], $url) === 0 ? true : false;
@@ -81,8 +79,7 @@ if (!empty($_SERVER['REQUEST_URI'])) {
$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.
|| $outageinfo; // Allow outage info requests.
if (!$allowed) {
// Call the climaintenance.php which will check for allowed IPs.
$CFG->dirroot = dirname(dirname(dirname(__FILE__))); // It is not defined yet but the script below needs it.

View File

@@ -25,12 +25,6 @@
use auth_outage\dml\outagedb;
define('NO_MOODLE_COOKIES', true);
// @codingStandardsIgnoreStart
header('Cache-Control: public, max-age=10,s-maxage=10');
// @codingStandardsIgnoreEnd
define('NO_AUTH_OUTAGE', true);
require_once(__DIR__.'/../../config.php');
$active = outagedb::get_active();

View File

@@ -96,6 +96,79 @@ class outagedb {
return new outage($outage);
}
/**
* Also sends all admins the event as a message
*
* @param $outage
* @param $event
*/
private static function notify($outage, $event) {
$admins = get_admins();
foreach ($admins as $admin) {
self::notify_user($outage, $event, $admin);
}
}
/**
* Send outage info to one user
*
* @param $outage outage
* @param $event event
* @param $to user object
*/
private static function notify_user($outage, $event, $to) {
global $SITE, $CFG;
$from = \core_user::get_user($event->userid);
$fields = [
'site_shortname' => $SITE->shortname,
'site_fullname' => $SITE->fullname,
'site_wwwroot' => $CFG->wwwroot,
'outage_id' => $outage->id,
'outage_title' => $outage->get_title(),
'outage_desc' => $outage->get_description(),
'outage_start' => userdate($outage->starttime, get_string('datetimeformat', 'auth_outage')),
'outage_stop' => userdate($outage->stoptime, get_string('datetimeformat', 'auth_outage')),
'outage_duration' => format_time($outage->get_duration_planned()),
'event_name' => $event->get_name(),
'event_desc' => $event->get_description(),
'event_link' => $event->get_url()->out(),
'from_name' => fullname($from),
'to_name' => fullname($to),
'prefs_link' => (new \moodle_url('/message/notificationpreferences.php'))->out(),
];
$message = new \core\message\message();
$message->component = 'auth_outage';
$message->name = 'updatenotify';
$message->userto = $to;
$message->subject = get_string('messagesubject', 'auth_outage', $fields);
$message->fullmessage = get_string('messagetext', 'auth_outage', $fields);
$message->fullmessagehtml = get_string('messagehtml', 'auth_outage', $fields);
$message->fullmessageformat = FORMAT_HTML;
$threadid = generate_email_messageid('outage' . $outage->id);
$message->userfrom = $from;
$message->userfrom->customheaders = [
"In-Reply-To: $threadid",
"References: $threadid",
"Thread-Topic: " . $message->subject,
"Thread-Index: $threadid",
];
$message->notification = '1';
$messageid = message_send($message);
}
/**
* Saves an outage to the database.
*
@@ -126,6 +199,7 @@ class outagedb {
]);
$event->add_record_snapshot('auth_outage', (object)(array) $outage);
$event->trigger();
self::notify($outage, $event);
// Create calendar entry.
calendar::create($outage);
@@ -140,6 +214,7 @@ class outagedb {
$event->add_record_snapshot('auth_outage', (object)(array) $outage);
$event->trigger();
self::notify($outage, $event);
// Remove the createdby field so it does not get updated.
unset($outage->createdby);
@@ -183,6 +258,7 @@ class outagedb {
$event->add_record_snapshot('auth_outage', $previous);
$event->trigger();
self::notify($outage, $event);
// Delete it and remove from calendar.
$DB->delete_records('auth_outage', ['id' => $id]);

View File

@@ -28,6 +28,8 @@ namespace auth_outage\event;
use core\event\base;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* outage_created class.
*
@@ -37,13 +39,23 @@ use moodle_url;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class outage_created extends base {
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoutagecreated', 'auth_outage');
}
/**
* Returns non-localised event description with id's for admin use only.
*
* @return string
*/
public function get_description() {
return "The user with the id '{$this->userid}' created outage {$this->other['id']} '{$this->other['title']}'";
return "The user with the id '{$this->userid}' scheduled outage {$this->other['id']} '{$this->other['title']}'";
}
/**

View File

@@ -27,6 +27,8 @@ namespace auth_outage\event;
use core\event\base;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* outage_deleted class.
*
@@ -36,6 +38,16 @@ use moodle_url;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class outage_deleted extends base {
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoutagedeleted', 'auth_outage');
}
/**
* Returns non-localised event description with id's for admin use only.
*

View File

@@ -28,6 +28,8 @@ namespace auth_outage\event;
use core\event\base;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* outage_updated class.
*
@@ -37,6 +39,16 @@ use moodle_url;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class outage_updated extends base {
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventoutageupdated', 'auth_outage');
}
/**
* Returns non-localised event description with id's for admin use only.
*

View File

@@ -27,6 +27,8 @@ namespace auth_outage\local\cli;
use Exception;
defined('MOODLE_INTERNAL') || die();
/**
* cli_exception class.
*

View File

@@ -29,6 +29,8 @@ use auth_outage\local\outagelib;
use coding_exception;
use core\session\manager;
defined('MOODLE_INTERNAL') || die();
/**
* clibase class.
*
@@ -104,18 +106,18 @@ abstract class clibase {
* Generates all options (parameters) available for the CLI command.
* @return mixed[] Options.
*/
abstract public function generate_options();
public abstract function generate_options();
/**
* Generate all short forms for the available options.
* @return string[] Short form options.
*/
abstract public function generate_shortcuts();
public abstract function generate_shortcuts();
/**
* Executes the CLI script.
*/
abstract public function execute();
public abstract function execute();
/**
* Change session to admin user.

View File

@@ -29,6 +29,8 @@ use auth_outage\dml\outagedb;
use auth_outage\local\outage;
use coding_exception;
defined('MOODLE_INTERNAL') || die();
/**
* create class.
*

View File

@@ -28,6 +28,8 @@ namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
/**
* finish class.
*

View File

@@ -28,6 +28,8 @@ namespace auth_outage\local\cli;
use auth_outage\dml\outagedb;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
/**
* waitforit class.
*

View File

@@ -32,6 +32,8 @@ use coding_exception;
use context_system;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* infopage class.
*
@@ -91,6 +93,7 @@ class infopage {
/**
* Generates and outputs the HTML for the info page.
* @uses redirect
* @SuppressWarnings(PHPMD.UnusedLocalVariable) $viewbag is used inside 'require'.
*/
public function output() {
global $PAGE, $CFG, $OUTPUT;
@@ -105,7 +108,7 @@ class infopage {
$PAGE->set_url(new moodle_url('/auth/outage/info.php'));
// No hooks injecting into this page, do it manually.
echo outagelib::get_inject_code();
outagelib::inject();
echo $OUTPUT->header();
$viewbag = [

View File

@@ -29,6 +29,8 @@ use auth_outage\local\outage;
use coding_exception;
use DOMDocument;
defined('MOODLE_INTERNAL') || die();
/**
* maintenance_static_page class.
*
@@ -120,7 +122,6 @@ class maintenance_static_page {
}
/**
* Gets generator io.
* @return maintenance_static_page_io
*/
public function get_io() {

View File

@@ -32,6 +32,8 @@ use DOMElement;
use invalid_state_exception;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* maintenance_static_page_generator class.
*
@@ -93,7 +95,6 @@ class maintenance_static_page_generator {
}
/**
* Gets maintenance_static_page_io.
* @return maintenance_static_page_io
*/
public function get_io() {
@@ -251,7 +252,7 @@ class maintenance_static_page_generator {
/**
* Fetches all elements based on the given selector.
*
* @param string $selector element selector
* @param $selector
*
* @return DOMElement[]
*/
@@ -269,7 +270,7 @@ class maintenance_static_page_generator {
/**
* Fetch all elements which contains the given class.
*
* @param string $class element class
* @param $class
*
* @return DOMElement[]
*/
@@ -285,9 +286,6 @@ class maintenance_static_page_generator {
return $matches;
}
/**
* Adds meta refresh to head element.
*/
private function add_meta_refresh() {
$meta = $this->dom->createElement('meta');
$meta->setAttribute('http-equiv', 'refresh');
@@ -300,7 +298,6 @@ class maintenance_static_page_generator {
}
/**
* Gets refresh time.
* @return int
*/
public function get_refresh_time() {
@@ -308,7 +305,6 @@ class maintenance_static_page_generator {
}
/**
* Sets refresh time.
* @param int $refreshtime
*/
public function set_refresh_time($refreshtime) {

View File

@@ -31,6 +31,8 @@ use finfo;
use invalid_parameter_exception;
use moodle_url;
defined('MOODLE_INTERNAL') || die();
/**
* maintenance_static_page_io class.
*
@@ -42,13 +44,11 @@ use moodle_url;
class maintenance_static_page_io {
/**
* Checks if the given string starts with "http://" or "https://".
* Also checks for "//" at the start of image, which setting_file_url still uses.
*
* @param string $url url string for check
* @param $url
* @return bool
*/
public static function is_url($url) {
return ((bool) preg_match('#^http(s)?://#', $url) || (bool) preg_match('#^//#', $url));
return (bool)preg_match('#^http(s)?://#', $url);
}
/**
@@ -80,7 +80,6 @@ class maintenance_static_page_io {
protected $preview = false;
/**
* Sets preview
* @param boolean $preview
*/
public function set_preview($preview) {

View File

@@ -28,6 +28,8 @@ namespace auth_outage\local;
use coding_exception;
use stdClass;
defined('MOODLE_INTERNAL') || die();
/**
* outage class.
*

View File

@@ -49,10 +49,8 @@ require_once(__DIR__.'/../../lib.php');
*/
class outagelib {
/** Outage start. */
const OUTAGE_START = '<!-- OUTAGESTART -->';
/** Outage end. */
const OUTAGE_END = '<!-- OUTAGEEND -->';
/**
@@ -60,14 +58,7 @@ class outagelib {
*/
private static $injectcalled = false;
/**
* Fetches page.
* @param string $file file to be fetched
*/
public static function fetch_page($file) {
global $CFG;
require_once($CFG->libdir . '/filelib.php');
$curl = new curl();
$contents = $curl->get($file);
$info = $curl->get_info();
@@ -80,15 +71,15 @@ class outagelib {
}
/**
* Resets inject called to allow the code to be regenerated.
* Calls inject even if it was already called before.
*/
public static function reset_injectcalled() {
public static function reinject() {
self::$injectcalled = false;
self::inject();
}
/**
* Given a time, usually now, when is the next outage window?
* @param int $time time for next window
*/
public static function get_next_window($time = null) {
@@ -108,12 +99,11 @@ class outagelib {
/**
* Will check for ongoing or warning outages and will return the message bar as required.
*
* @return string|void CSS and HTML for the warning bar if it should be displayed
* Will check for ongoing or warning outages and will attach the message bar as required.
*/
public static function get_inject_code() {
global $PAGE;
public static function inject() {
global $CFG;
// Ensure we do not kill the whole website in case of an error.
try {
// Check if we should inject the code.
@@ -121,6 +111,8 @@ class outagelib {
return;
}
self::clean_outages();
// Check for a previewing outage, then for an active outage.
$previewid = optional_param('auth_outage_preview', null, PARAM_INT);
$time = time();
@@ -143,8 +135,8 @@ class outagelib {
}
// There is a previewing or active outage.
$renderer = $PAGE->get_renderer('auth_outage');
return $renderer->render_warningbar($active, $time, false, $preview);
$CFG->additionalhtmltopofbody = renderer::get()->render_warningbar($active, $time, false, $preview).
$CFG->additionalhtmltopofbody;
} catch (Exception $e) {
debugging('Exception occured while injecting our code: '.$e->getMessage());
debugging($e->getTraceAsString(), DEBUG_DEVELOPER);
@@ -212,9 +204,6 @@ class outagelib {
}
}
/**
* Checks if wwwroot accessible.
*/
private static function check_wwwroot_accessible() {
global $CFG;
$result = self::fetch_page($CFG->wwwroot);
@@ -372,14 +361,16 @@ EOT;
* Generates a warning message in case the plugin is not active and configured.
*
* @return string
*
* @internal stdClass $CFG
* @internal bootstrap_renderer $OUTPUT
*/
public static function generate_plugin_configuration_warning() {
global $CFG, $OUTPUT, $PAGE;
$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');
}
@@ -405,4 +396,26 @@ EOT;
return $message;
}
/**
* Checks $CFG->additionalhtmltopofbody for saved outages and removes them.
* We should only be temporarily injecting into that variable and not saving them to the database.
*
* @return string the cleaned content
*/
public static function clean_outages() {
global $CFG;
// Replace the content to clean up pages that do not have the injection.
$re = '/' . self::OUTAGE_START . '[\s\S]*' . self::OUTAGE_END . '/m';
$replaced = preg_replace($re, '', $CFG->additionalhtmltopofbody);
// We have removed the outages and any duplicates as it should be injected and not saved to $CFG.
if ($CFG->additionalhtmltopofbody != $replaced) {
set_config('additionalhtmltopofbody', $replaced);
return $replaced;
}
return '';
}
}

View File

@@ -48,10 +48,6 @@ class base_table extends flexible_table {
*/
private static $autoid = 0;
/**
* Creates start time string.
* @param string $starttime start time
*/
protected static function create_starttime_string($starttime) {
$absolute = userdate($starttime, get_string('datetimeformat', 'auth_outage'));
$relative = $starttime - time();

View File

@@ -33,6 +33,8 @@ use html_writer;
use moodle_url;
use plugin_renderer_base;
defined('MOODLE_INTERNAL') || die();
/**
* auth_outage_renderer class.
*
@@ -42,6 +44,15 @@ use plugin_renderer_base;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
/**
* Returns the outage renderer.
* @return renderer The outage renderer.
*/
public static function get() {
global $PAGE;
return $PAGE->get_renderer('auth_outage');
}
/**
* Outputs the view in a separate scope to avoid conflicts with variable names.
* @param string $view View PHP file.
@@ -64,13 +75,6 @@ class renderer extends plugin_renderer_base {
* @return string The rendered view code.
*/
public function render_view($view, $viewbag = []) {
// Do not render if the request are from some layouts.
$excludelayout = ['embedded', 'popup', 'secure', 'maintenance'];
if (in_array($this->page->pagelayout, $excludelayout)) {
return '';
}
ob_start();
$this->output_view($view, $viewbag);
$html = ob_get_contents();
@@ -150,6 +154,8 @@ class renderer extends plugin_renderer_base {
* @return string The formatted HTML.
*/
private function renderoutage(outage $outage, $buttons) {
global $OUTPUT;
if ($outage->createdby == 0) {
$created = get_string('na', 'auth_outage');
} else {
@@ -173,14 +179,14 @@ class renderer extends plugin_renderer_base {
$url = new moodle_url('/auth/outage/edit.php', ['edit' => $outage->id]);
$img = html_writer::empty_tag(
'img',
['src' => $this->output->image_url('t/edit'), 'alt' => get_string('edit'), 'class' => 'iconsmall']
['src' => $OUTPUT->image_url('t/edit'), 'alt' => get_string('edit'), 'class' => 'iconsmall']
);
$linkedit = html_writer::link($url, $img, ['title' => get_string('edit')]);
$url = new moodle_url('/auth/outage/delete.php', ['id' => $outage->id]);
$img = html_writer::empty_tag(
'img',
['src' => $this->output->image_url('t/delete'), 'alt' => get_string('delete'), 'class' => 'iconsmall']
['src' => $OUTPUT->image_url('t/delete'), 'alt' => get_string('delete'), 'class' => 'iconsmall']
);
$linkdelete = html_writer::link($url, $img, ['title' => get_string('delete')]);

View File

@@ -23,6 +23,8 @@
namespace auth_outage\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\local\legacy_polyfill;
/**

View File

@@ -29,6 +29,8 @@ use auth_outage\local\controllers\infopage;
use auth_outage\local\outagelib;
use core\task\scheduled_task;
defined('MOODLE_INTERNAL') || die();
/**
* update_static_page class.
*

37
db/access.php Normal file
View File

@@ -0,0 +1,37 @@
<?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/>.
/**
* Defines capabilities
*
* @package auth_outage
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = [
'auth/outage:updatenotify' => [
'captype' => 'write',
'riskbitmask' => RISK_XSS,
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => [
'manager' => CAP_ALLOW,
]
],
];

32
db/messages.php Normal file
View File

@@ -0,0 +1,32 @@
<?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/>.
/**
* Defines message providers for outage
*
* @package auth_outage
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$messageproviders = [
'updatenotify' => [
'capability' => 'auth/outage:updatenotify',
]
];

View File

@@ -24,11 +24,14 @@
*/
use auth_outage\local\controllers\maintenance_static_page;
defined('MOODLE_INTERNAL') || die();
/**
* Auth Outage plugin uninstall code.
* @return bool result
* @throws moodle_exception
*/
function xmldb_auth_outage_uninstall() {
global $DB;

View File

@@ -22,6 +22,7 @@
* @copyright 2016 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Outage plugin upgrade code

View File

@@ -33,7 +33,6 @@ require_once($CFG->libdir.'/formslib.php');
admin_externalpage_setup('auth_outage_manage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));
$output = $PAGE->get_renderer('auth_outage');
$mform = new delete();
if ($mform->is_cancelled()) {
@@ -53,10 +52,10 @@ $dataid = new stdClass();
$dataid->id = $outage->id;
$mform->set_data($dataid);
echo $output->header();
echo $OUTPUT->header();
echo $output->renderdeleteconfirmation($outage);
echo renderer::get()->renderdeleteconfirmation($outage);
$mform->display();
echo $output->footer();
echo $OUTPUT->footer();

View File

@@ -34,7 +34,6 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/formslib.php');
admin_externalpage_setup('auth_outage_manage');
$output = $PAGE->get_renderer('auth_outage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));
$mform = new edit();
@@ -84,7 +83,7 @@ if ($outage == null) {
$mform->set_data($outage);
$PAGE->navbar->add(get_string($action.'crumb', 'auth_outage'));
echo $output->header();
echo $output->rendersubtitle($action);
echo $OUTPUT->header();
echo renderer::get()->rendersubtitle($action);
$mform->display();
echo $output->footer();
echo $OUTPUT->footer();

View File

@@ -57,6 +57,7 @@ header('Accept-Ranges: none');
/**
* Callback used in bootstrap.
* @SupressWarnings(PHPMD)
*/
function auth_outage_bootstrap_callback() {
// Not using classes as classloader has not been initialized yet. Keep it minimalist.
@@ -73,9 +74,7 @@ function auth_outage_bootstrap_callback() {
exit(0);
}
// @codingStandardsIgnoreStart
require_once(__DIR__.'/../../config.php');
// @codingStandardsIgnoreEnd
// 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.

View File

@@ -33,7 +33,6 @@ require_once($CFG->libdir.'/formslib.php');
admin_externalpage_setup('auth_outage_manage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));
$output = $PAGE->get_renderer('auth_outage');
$mform = new finish();
if ($mform->is_cancelled()) {
@@ -53,10 +52,10 @@ $dataid = new stdClass();
$dataid->id = $outage->id;
$mform->set_data($dataid);
echo $output->header();
echo $OUTPUT->header();
echo $output->renderfinishconfirmation($outage);
echo renderer::get()->renderfinishconfirmation($outage);
$mform->display();
echo $output->footer();
echo $OUTPUT->footer();

View File

@@ -25,9 +25,7 @@
use auth_outage\local\controllers\infopage;
// @codingStandardsIgnoreStart
require_once(__DIR__.'/../../config.php');
// @codingStandardsIgnoreEnd
$info = new infopage();
$info->output();

View File

@@ -90,6 +90,9 @@ $string['defaultdescriptiondescription'] = 'Default warning message for outages.
$string['defaultdescriptionvalue'] = 'There is an scheduled maintenance from {{start}} to {{stop}} and our system will not be available during that time.';
$string['description'] = 'Public Description';
$string['description_help'] = 'A full description of the outage, publicly visible by all users.';
$string['eventoutagecreated'] = 'Outage scheduled';
$string['eventoutagedeleted'] = 'Outage cancelled';
$string['eventoutageupdated'] = 'Outage updated';
$string['finish'] = 'Finish';
$string['info15secondsbefore'] = '15 seconds before';
$string['infoendofoutage'] = 'end of outage';
@@ -110,6 +113,45 @@ $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['messageprovider:updatenotify'] = 'Changes to planned outages';
$string['messagesubject'] = '[{$a->site_shortname}] {$a->event_name} #{$a->outage_id}: {$a->outage_start}';
$string['messagetext'] = '{$a->event_name}
{$a->site_fullname} ({$a->site_wwwroot})
{$a->event_link}
ID: {$a->outage_id}
NAME: {$a->outage_title}
START: {$a->outage_start}
DURATION: {$a->outage_duration}
DESCRIPTION:
{$a->outage_desc}
--
To unsubscribe visit:
{$a->prefs_link}';
$string['messagehtml'] = '
<h3>{$a->event_name}</h3>
<p>{$a->site_fullname} (<a href="{$a->site_wwwroot}">{$a->site_wwwroot}</a>)</p>
<p><a href="{$a->event_link}">{$a->event_link}</a></p>
<h4>Name:</h4>
<p>{$a->outage_title}</p>
<h4>Start:</h4>
<p>{$a->outage_start}</p>
<h4>Duration:</h4>
<p>{$a->outage_duration}</p>
<h4>Description:</h4>
<p>{$a->outage_desc}</p>
<hr>
<p>To unsubscribe visit:<br>
<a href="{$a->prefs_link}">{$a->prefs_link}</a></p>
';
$string['na'] = 'n/a';
$string['notfound'] = 'No outages found.';
$string['outageedit'] = 'Edit outage';

35
lib.php
View File

@@ -25,6 +25,29 @@
use auth_outage\local\outagelib;
defined('MOODLE_INTERNAL') || die;
/**
* Used in Moodle 30+ when a user is logged on.
*/
function auth_outage_extend_navigation_user_settings() {
outagelib::inject();
}
/**
* Used in Moodle 30+ on the frontpage.
*/
function auth_outage_extend_navigation_frontpage() {
outagelib::inject();
}
/**
* Used in Moodle 31+ when a user is logged on.
*/
function auth_outage_extend_navigation_user() {
outagelib::inject();
}
/**
* Used for adminlib::set_updatedcallback which requires a string that resolves to a function.
*
@@ -39,7 +62,7 @@ function auth_outage_outagelib_prepare_next_outage() {
*
* To keep it minimalist it was not added to the outagelib.php class.
*
* @param string $file Filename to fetch from sitedata
* @param $file string Filename to fetch from sitedata
* @return string|null Full path to the sitedata file or null if file is not valid.
*/
function auth_outage_get_climaintenance_resource_file($file) {
@@ -75,13 +98,3 @@ function auth_outage_get_fontawesome_icon_map() {
'core:i/auth_outageevent' => 'fa-power-off',
];
}
/**
* Inject the warning bar into the page if there is currently an outage.
*
* @return string|void
*/
function auth_outage_before_standard_top_of_body_html() {
// Get code to inject.
return outagelib::get_inject_code();
}

View File

@@ -32,17 +32,16 @@ require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('auth_outage_manage');
$PAGE->set_url(new moodle_url('/auth/outage/manage.php'));
$output = $PAGE->get_renderer('auth_outage');
echo $output->header();
echo $OUTPUT->header();
// Give it a consistent time so all outages are listed. Useful when debugging.
$now = time();
$output->output_view('manage.php', [
renderer::get()->output_view('manage.php', [
'unended' => outagedb::get_all_unended($now),
'ended' => outagedb::get_all_ended($now),
'warning' => outagelib::generate_plugin_configuration_warning(),
]);
echo $output->footer();
echo $OUTPUT->footer();

View File

@@ -28,9 +28,7 @@
use auth_outage\dml\outagedb;
use auth_outage\local\controllers\maintenance_static_page;
// @codingStandardsIgnoreStart
require_once(__DIR__.'/../../config.php');
// @codingStandardsIgnoreEnd
$id = optional_param('id', null, PARAM_INT);
$outage = is_null($id) ? outagedb::get_next_starting() : outagedb::get_by_id($id);
if (is_null($outage)) {

View File

@@ -26,6 +26,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* auth_outage_renderer class.
*

View File

@@ -39,6 +39,7 @@ require_once(__DIR__.'/../../../../lib/behat/behat_base.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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class behat_auth_outage extends behat_base {
/**
@@ -154,7 +155,6 @@ class behat_auth_outage extends behat_base {
}
/**
* Check if an specific action is not visible.
* @Then /^I should see an empty settings text area "([^"]*)"$/
* @param string $name
*/
@@ -163,7 +163,6 @@ class behat_auth_outage extends behat_base {
}
/**
* Check if an specific action is not visible.
* @When /^I go to the "Outage Settings" page$/
*/
public function i_go_to_the_outage_settings_page() {
@@ -322,7 +321,7 @@ class behat_auth_outage extends behat_base {
}
if ($seconds >= 0) {
$seconds++; // Give one extra second for things to happen.
$this->getSession()->wait($seconds * 1000);
$this->getSession()->wait($seconds * 1000, false);
}
}

View File

@@ -1,48 +0,0 @@
@auth @auth_outage @javascript @_file_upload @_switch_iframe
Feature: Disable warning bar in embedded layout
In order alert users about an outage
As any user
I need to view the warning bar, but not in embedded layout
Background:
Given the authentication plugin "outage" is enabled
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "activities" exist:
| activity | name | intro | introformat | course | content | contentformat | idnumber |
| page | PageName1 | PageDesc1 | 1 | C1 | H5Ptest | 1 | 1 |
And the "displayh5p" filter is "on"
Scenario: Disable warning bar in embedded h5p in book activity
Given I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "File" to section "1"
And I set the following fields to these values:
| Name | ipsumFile |
And I upload "h5p/tests/fixtures/ipsums.h5p" file to "Select files" filemanager
And I press "Save and return to course"
And I follow "PageName1"
And I navigate to "Edit settings" in current page administration
And I click on "Insert H5P" "button" in the "#fitem_id_page" "css_element"
And I click on "Browse repositories..." "button" in the "Insert H5P" "dialogue"
And I click on "Server files" "link" in the ".fp-repo-area" "css_element"
And I click on "ipsumFile (File)" "link"
And I click on "ipsums.h5p" "link"
And I click on "Select this file" "button"
And I click on "Insert H5P" "button" in the "Insert H5P" "dialogue"
And I wait until the page is ready
And I click on "Save and display" "button"
When there is the following outage:
| warnbefore | startsin |
| 0 | 0 |
And I reload the page
Then I should see "Back online at" in the warning bar
And I should not see "Lorum ipsum"
# Switch to iframe created by filter
And I switch to "h5p-iframe" class iframe
And I should not see the warning bar
# Switch to iframe created by embed.php page
And I switch to "h5p-iframe" class iframe
And I should see "Lorum ipsum"
And I should not see the warning bar

View File

@@ -33,6 +33,8 @@
use auth_outage\dml\outagedb;
defined('MOODLE_INTERNAL') || die();
/**
* auth_outage_base_testcase class.
*
@@ -40,6 +42,7 @@ use auth_outage\dml\outagedb;
* @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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
abstract class auth_outage_base_testcase extends advanced_testcase {
/**
@@ -63,20 +66,14 @@ abstract class auth_outage_base_testcase extends advanced_testcase {
}
}
/**
* Setup testcase.
*/
public function setUp(): void {
public function setUp() {
global $CFG;
parent::setUp();
$this->resetAfterTest(true);
}
/**
* Tear down to restore the original DB reference.
*/
public function tearDown(): void {
public function tearDown() {
global $DB;
foreach (outagedb::get_all() as $i => $outage) {

View File

@@ -26,6 +26,8 @@
use auth_outage\calendar\calendar;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
/**
* calendar_test test class.
*

View File

@@ -36,6 +36,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class outagedb_test extends auth_outage_base_testcase {
/**
@@ -78,7 +79,7 @@ class outagedb_test extends auth_outage_base_testcase {
/**
* Ensure DB tests run as admin.
*/
public function setUp(): void {
public function setUp() {
parent::setUp();
$this->setAdminUser();
}

View File

@@ -26,6 +26,8 @@
use auth_outage\dml\outagedb;
use auth_outage\local\outage;
defined('MOODLE_INTERNAL') || die();
/**
* events_test tests class.
*

View File

@@ -198,10 +198,6 @@ class forms_test extends auth_outage_base_testcase {
];
}
/**
* Skip tests for moodle below 30.
* @param string $reason reason to be filled
*/
private function skip_because_moodle_is_below_30($reason = '') {
global $CFG;

View File

@@ -39,6 +39,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class installation_test extends auth_outage_base_testcase {
/**

View File

@@ -34,11 +34,9 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class lib_test extends auth_outage_base_testcase {
/**
* Test this plugin gets climaintenance resource file.
*/
public function test_auth_outage_get_climaintenance_resource_file_resolves_a_file() {
global $CFG;
$dir = $CFG->dataroot.'/auth_outage/climaintenance';
@@ -90,9 +88,6 @@ class lib_test extends auth_outage_base_testcase {
self::assertSame($realfile, $actual);
}
/**
* Test this plugin gets climaintenance resource file and prevents path traversal attack.
*/
public function test_auth_outage_get_climaintenance_resource_file_prevent_path_traversal() {
global $CFG;

View File

@@ -36,6 +36,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class cli_test extends auth_outage_cli_testcase {
/**

View File

@@ -35,12 +35,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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
abstract class auth_outage_cli_testcase extends auth_outage_base_testcase {
/**
* Always enable the auth outage plugin, resets after test and set no parameters.
*/
public function setUp(): void {
public function setUp() {
global $CFG;
// PHPUnit does not load config.php file.

View File

@@ -38,6 +38,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class create_test extends auth_outage_cli_testcase {
/**

View File

@@ -38,6 +38,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class finish_test extends auth_outage_cli_testcase {
/**

View File

@@ -38,6 +38,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class waitforit_test extends auth_outage_cli_testcase {
/**

View File

@@ -36,6 +36,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class infopagecontroller_test extends auth_outage_base_testcase {
/**

View File

@@ -38,11 +38,10 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
* @SuppressWarnings(methods) Allow as many methods as needed.
*/
class maintenance_static_page_test extends auth_outage_base_testcase {
/**
* Test template file.
*/
public function test_templatefile() {
global $CFG;
$page = maintenance_static_page::create_from_html('<html></html>');
@@ -52,9 +51,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
$page->get_io()->get_template_file());
}
/**
* Test resources folder.
*/
public function test_resourcesfolder() {
global $CFG;
$page = maintenance_static_page::create_from_html('<html></html>');
@@ -63,16 +59,10 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertSame($CFG->dataroot.'/auth_outage/climaintenance/preview', $page->get_io()->get_resources_folder());
}
/**
* Test create from outage.
*/
public function test_createfromoutage() {
// How to fetch a page from PHPUnit environment?
}
/**
* Test create from HTML.
*/
public function test_createfromhtml() {
$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\">".
@@ -80,9 +70,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertSame($expected, $this->generated_page_html($html));
}
/**
* 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>'.
@@ -93,9 +80,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertNotContains('<script', $generated);
}
/**
* Test remove script tags.
*/
public function test_updatelinkstylesheet() {
$localcsslink = $this->get_fixture_path('simple.css');
$externalcsslink = 'http://google.com/coolstuff.css';
@@ -109,9 +93,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertContains($externalcsslink, $generated);
}
/**
* Test update link style sheet urls.
*/
public function test_updatelinkstylesheet_urls() {
$localcsslink = $this->get_fixture_path('withurls.css');
$html = "<!DOCTYPE html>\n".
@@ -127,9 +108,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
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".
@@ -145,9 +123,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
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".
@@ -163,9 +138,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
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');
$externalimglink = 'http://google.com/coolstyle.css';
@@ -179,9 +151,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertContains($externalimglink, $generated);
}
/**
* Test update favicon to file.php style link.
*/
public function test_updatelinkfavicon() {
$link = $this->get_fixture_path('catalyst.png');
$html = "<!DOCTYPE html>\n".
@@ -193,9 +162,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertContains('www.example.com/moodle/auth/outage/file.php?file=', $generated);
}
/**
* Test update preview path to file.php style link.
*/
public function test_previewpath() {
$link = $this->get_fixture_path('catalyst.png');
$html = "<!DOCTYPE html>\n".
@@ -246,9 +212,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertFileNotExists($file);
}
/**
* Tests created file.
*/
public function test_createdfile() {
global $CFG;
@@ -272,7 +235,7 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
/**
* Gets a fixture file for this test case.
*
* @param string $file file name
* @param $file
*
* @return string
*/
@@ -280,59 +243,30 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
return (string)new moodle_url('/auth/outage/tests/phpunit/local/controllers/fixtures/'.$file);
}
/**
* Test saving empty string for template file.
*/
public function test_invalid_string_saving_template_empty() {
$io = new maintenance_static_page_io();
$this->set_expected_exception('coding_exception');
$io->save_template_file('');
}
/**
* Test saving non string for template file.
*/
public function test_invalid_string_saving_template_nostring() {
$io = new maintenance_static_page_io();
$this->set_expected_exception('coding_exception');
$io->save_template_file(50);
}
/**
* Test get url for file.
*/
public function test_get_url_for_file() {
$io = new maintenance_static_page_io();
self::assertContains('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() {
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']
];
public function test_is_url() {
self::assertTrue(maintenance_static_page_io::is_url('http://catalyst.net.nz'));
self::assertTrue(maintenance_static_page_io::is_url('https://www.catalyst-au.net/'));
self::assertFalse(maintenance_static_page_io::is_url('/homepage'));
self::assertFalse(maintenance_static_page_io::is_url('file://homepage'));
}
/**
* Test if it is url
* @dataProvider is_url_dataprovider
* @param string $result expected result
* @param string $url url to be checked
*/
public function test_is_url($result, $url) {
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';
$found = maintenance_static_page_io::file_get_data($file);
@@ -340,9 +274,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertSame('image/png', $found['mime']);
}
/**
* Test invalid file get_data.
*/
public function test_file_get_data_invalidfile() {
$found = maintenance_static_page_io::file_get_data(__DIR__.'/fixtures/invalidfile');
self::assertSame('', $found['contents']);
@@ -351,17 +282,11 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
phpunit_util::reset_debugging();
}
/**
* Test invalid file get_data.
*/
public function test_file_get_data_invalidfilename() {
$this->set_expected_exception('coding_exception');
maintenance_static_page_io::file_get_data(200);
}
/**
* Test remove css selector.
*/
public function test_remove_css_selector() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -374,9 +299,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertNotContains('Goodbye cruel world', $generated);
}
/**
* Test remove css selector id.
*/
public function test_remove_css_selector_id() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -389,9 +311,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertNotContains('Goodbye cruel world', $generated);
}
/**
* Test remove css selector with multi lines.
*/
public function test_remove_css_selector_with_multiline() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -408,9 +327,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertNotContains('Goodbye cruel world', $generated);
}
/**
* Test remove css selector needs trim.
*/
public function test_remove_css_selector_needing_trim() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -427,9 +343,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertNotContains('Goodbye cruel world', $generated);
}
/**
* Test remove css selector with empty line.
*/
public function test_remove_css_selector_with_empty_line() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -446,9 +359,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertNotContains('Goodbye cruel world', $generated);
}
/**
* Test remove css selector with invalid id.
*/
public function test_remove_css_selector_with_invalid_id() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -461,9 +371,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertContains('Goodbye cruel world', $generated);
}
/**
* Test meta refresh 5 minutes.
*/
public function test_meta_refresh_5minutes() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".
@@ -475,9 +382,6 @@ class maintenance_static_page_test extends auth_outage_base_testcase {
self::assertContains('<meta http-equiv="refresh" content="300">', $generated);
}
/**
* Test meta refresh maximum 5 minutes.
*/
public function test_meta_refresh_maximum_5seconds() {
$this->resetAfterTest(true);
$html = "<!DOCTYPE html>\n".

View File

@@ -35,6 +35,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class outage_test extends auth_outage_base_testcase {
/**

View File

@@ -40,6 +40,7 @@ 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
* @SuppressWarnings(public) Allow as many methods as needed.
*/
class outagelib_test extends auth_outage_base_testcase {
/**
@@ -81,7 +82,7 @@ class outagelib_test extends auth_outage_base_testcase {
* Check outagelib::inject() works as expected.
*/
public function test_inject() {
global $OUTPUT;
global $CFG;
$this->resetAfterTest(true);
self::setAdminUser();
@@ -95,18 +96,16 @@ class outagelib_test extends auth_outage_base_testcase {
'description' => 'Description',
]);
$outage->id = outagedb::save($outage);
self::assertEmpty($CFG->additionalhtmltopofbody);
outagelib::reset_injectcalled();
// Get full header to avoid interactions with other single inject plugins.
$header1 = $OUTPUT->standard_top_of_body_html();
self::assertContains('<style>', $header1);
self::assertContains('<script>', $header1);
outagelib::reinject();
self::assertContains('<style>', $CFG->additionalhtmltopofbody);
self::assertContains('<script>', $CFG->additionalhtmltopofbody);
// Should not inject more than once.
$size = strlen($OUTPUT->standard_top_of_body_html());
self::assertSame($size, strlen($OUTPUT->standard_top_of_body_html()));
// Check styles aren't reinjected.
self::assertNotContains('<style>', $OUTPUT->standard_top_of_body_html());
// Should not inject more than once with the inject() function.
$size = strlen($CFG->additionalhtmltopofbody);
outagelib::inject();
self::assertSame($size, strlen($CFG->additionalhtmltopofbody));
}
/**
@@ -114,8 +113,7 @@ class outagelib_test extends auth_outage_base_testcase {
*/
public function test_inject_broken() {
$_GET = ['auth_outage_break_code' => '1'];
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
outagelib::reinject();
self::assertCount(2, phpunit_util::get_debugging_messages());
phpunit_util::reset_debugging();
}
@@ -137,13 +135,12 @@ class outagelib_test extends auth_outage_base_testcase {
'description' => 'Description',
]);
$outage->id = outagedb::save($outage);
self::assertEmpty($CFG->additionalhtmltopofbody);
$_GET = ['auth_outage_preview' => (string)$outage->id];
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
self::assertContains('<style>', $header);
self::assertContains('<script>', $header);
outagelib::reinject();
self::assertContains('<style>', $CFG->additionalhtmltopofbody);
self::assertContains('<script>', $CFG->additionalhtmltopofbody);
}
/**
@@ -151,12 +148,11 @@ class outagelib_test extends auth_outage_base_testcase {
*/
public function test_inject_preview_notfound() {
global $CFG;
self::assertEmpty($CFG->additionalhtmltopofbody);
$_GET = ['auth_outage_preview' => '1'];
// Should not throw exception or halt anything, silently ignore it.
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
self::assertEmpty($header);
outagelib::reinject();
self::assertEmpty($CFG->additionalhtmltopofbody);
}
/**
@@ -176,20 +172,18 @@ class outagelib_test extends auth_outage_base_testcase {
'description' => 'Description',
]);
$outage->id = outagedb::save($outage);
self::assertEmpty($CFG->additionalhtmltopofbody);
$_GET = ['auth_outage_preview' => (string)$outage->id, 'auth_outage_delta' => '500'];
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
outagelib::reinject();
// Still empty, delta is too high (outage ended).
self::assertEmpty($header);
self::assertEmpty($CFG->additionalhtmltopofbody);
}
/**
* Test injection without active outage.
*/
public function test_inject_noactive() {
outagelib::reset_injectcalled();
outagelib::get_inject_code();
outagelib::reinject();
}
/**
@@ -279,20 +273,17 @@ class outagelib_test extends auth_outage_base_testcase {
'description' => 'Description',
]);
$outage->id = outagedb::save($outage);
self::assertEmpty($CFG->additionalhtmltopofbody);
// Pretend we are there...
$_SERVER['SCRIPT_FILENAME'] = '/var/www/alternativepath/admin/settings.php'; // Issue #88 regression test.
$_SERVER['SCRIPT_NAME'] = '/admin/settings.php';
$_GET['section'] = 'additionalhtml';
outagelib::reset_injectcalled();
$header = outagelib::get_inject_code();
outagelib::reinject();
self::assertEmpty($header);
self::assertEmpty($CFG->additionalhtmltopofbody);
}
/**
* Test create maintenance php code
*/
public function test_createmaintenancephpcode() {
$expected = <<<'EOT'
<?php
@@ -334,9 +325,6 @@ EOT;
self::assertSame($expected, $found);
}
/**
* Test create maintenance php code without age
*/
public function test_createmaintenancephpcode_withoutage() {
global $CFG;
$this->resetAfterTest(true);
@@ -388,9 +376,6 @@ EOT;
self::assertSame($found, $expected);
}
/**
* Test create maintenance php code without IPs
*/
public function test_createmaintenancephpcode_withoutips() {
global $CFG;
$this->resetAfterTest(true);
@@ -407,9 +392,6 @@ EOT;
self::assertFileNotExists($file);
}
/**
* Test create maintenance php code without outage
*/
public function test_createmaintenancephpcode_withoutoutage() {
global $CFG;
$file = $CFG->dataroot.'/climaintenance.php';
@@ -517,20 +499,17 @@ EOT;
'description' => 'Description',
]);
$outage->id = outagedb::save($outage);
self::assertEmpty($CFG->additionalhtmltopofbody);
// Pretend we are there...
$_SERVER['SCRIPT_FILENAME'] = '/var/www/alternativepath/admin/settings.php'; // Issue #88 regression test.
$_SERVER['SCRIPT_NAME'] = '/admin/settings.php';
$_GET['section'] = 'notadditionalhtml';
outagelib::reset_injectcalled();
outagelib::reinject();
$header = outagelib::get_inject_code();
self::assertNotEmpty($header);
self::assertNotEmpty($CFG->additionalhtmltopofbody);
}
/**
* Creates outage for tests.
*/
private function create_outage() {
$this->resetAfterTest(true);
self::setAdminUser();

View File

@@ -28,8 +28,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = "auth_outage";
$plugin->version = 2021032503; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2021032503; // Human-readable release information.
$plugin->version = 2020032500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->release = 2020032500; // Human-readable release information.
$plugin->requires = 2017051500; // Requires 3.3 and higher.
$plugin->maturity = MATURITY_STABLE; // Suitable for PRODUCTION environments!
$plugin->supported = [33, 38]; // A range of branch numbers of supported moodle versions.

View File

@@ -31,15 +31,14 @@ use auth_outage\local\outagelib;
defined('MOODLE_INTERNAL') || die();
global $PAGE;
$output = $PAGE->get_renderer('auth_outage');
global $OUTPUT;
$urlnew = new moodle_url('/auth/outage/edit.php');
echo $viewbag['warning'];
?>
<section id="section_planned_outages">
<?php echo $output->rendersubtitle('outageslistfuture'); ?>
<?php echo renderer::get()->rendersubtitle('outageslistfuture'); ?>
<?php if (empty($viewbag['unended'])): ?>
<p>
<small><?php echo get_string('notfound', 'auth_outage'); ?></small>
@@ -62,7 +61,7 @@ echo $viewbag['warning'];
echo '<p>';
$next = outagelib::get_next_window($next);
$urlnew->param('starttime', $next);
echo $output->single_button($urlnew, get_string('outagecreate', 'auth_outage'));
echo $OUTPUT->single_button($urlnew, get_string('outagecreate', 'auth_outage'));
if ($default) {
echo ' ' . userdate( $next, get_string('datetimeformat', 'auth_outage'));
}
@@ -71,7 +70,7 @@ echo $viewbag['warning'];
</section>
<section id="section_outage_history">
<?php echo $output->rendersubtitle('outageslistpast'); ?>
<?php echo renderer::get()->rendersubtitle('outageslistpast'); ?>
<?php if (empty($viewbag['ended'])): ?>
<p>
<small><?php echo get_string('notfound', 'auth_outage'); ?></small>

View File

@@ -99,30 +99,14 @@ a.auth_outage_warningbar_box_finish:hover {
background-color: black;
}
.auth_outage_warningbar_spacer {
height: 80px;
}
body.auth_outage #nav-drawer {
top: 150px;
}
body.auth_outage nav.fixed-top.navbar {
top: 100px;
}
body.auth_outage #page {
margin-top: 150px;
}
body.auth_outage.path-mod-assign [data-region="grading-navigation-panel"] {
top: 100px;
}
body.auth_outage.path-mod-assign [data-region="grade-panel"] {
top: 185px;
}
body.auth_outage .layout.fullscreen {
top: 150px;
}
body.auth_outage .modal-dialog {
margin: calc(150px + 1.75rem) auto;
}
}

View File

@@ -74,6 +74,8 @@ if (!$viewbag['static']) {
</div>
</div>
<div class="auth_outage_warningbar_spacer">&nbsp;</div>
<?php if (!$viewbag['static']): ?>
<script>
document.body.className += ' auth_outage';