first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,115 @@
<?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 core\check\access;
use core\check\check;
use core\check\result;
/**
* Verifies sanity of default user role.
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class defaultuserrole extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_defaultuserrole_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
global $CFG, $DB;
$defaultrole = $DB->get_record('role', ['id' => $CFG->defaultuserroleid]);
return new \action_link(
new \moodle_url('/admin/roles/define.php', ['action' => 'view', 'roleid' => $defaultrole->id]),
get_string('definitionofrolex', 'core_role', role_get_name($defaultrole))
);
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $DB, $CFG;
$details = '';
if (!$defaultrole = $DB->get_record('role', ['id' => $CFG->defaultuserroleid])) {
$status = result::WARNING;
$summary = get_string('check_defaultuserrole_notset', 'report_security');
return new result($status, $summary, $details);
}
// Risky caps - usually very dangerous.
$sql = "SELECT rc.id, rc.contextid, rc.capability
FROM {role_capabilities} rc
JOIN {capabilities} cap ON cap.name = rc.capability
WHERE " . $DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS)) . " <> 0
AND rc.permission = :capallow
AND rc.roleid = :roleid";
$riskyresults = $DB->get_records_sql($sql, [
'capallow' => CAP_ALLOW,
'roleid' => $defaultrole->id,
]);
// If automatic approval is disabled, then the requestdelete capability is not risky.
if (!get_config('tool_dataprivacy', 'automaticdatadeletionapproval')) {
$riskyresults = array_filter($riskyresults, function ($object) {
return $object->capability !== 'tool/dataprivacy:requestdelete';
});
}
// Count the number of unique contexts that have risky caps.
$riskycount = count(array_unique(array_column($riskyresults, 'contextid')));
// It may have either none or 'user' archetype - nothing else, or else it would break during upgrades badly.
if ($defaultrole->archetype === '' or $defaultrole->archetype === 'user') {
$legacyok = true;
} else {
$legacyok = false;
}
if ($riskycount or !$legacyok) {
$status = result::CRITICAL;
$summary = get_string('check_defaultuserrole_error', 'report_security', role_get_name($defaultrole));
} else {
$status = result::OK;
$summary = get_string('check_defaultuserrole_ok', 'report_security');
}
$details = get_string('check_defaultuserrole_details', 'report_security');
return new result($status, $summary, $details);
}
}
+111
View File
@@ -0,0 +1,111 @@
<?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/>.
/**
* Verifies sanity of frontpage role
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies sanity of frontpage role
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class frontpagerole extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_frontpagerole_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=frontpagesettings#admin-defaultfrontpageroleid'),
get_string('frontpagesettings', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $DB, $CFG;
if (!$frontpagerole = $DB->get_record('role', array('id' => $CFG->defaultfrontpageroleid))) {
$status = result::INFO;
$summary = get_string('check_frontpagerole_notset', 'report_security');
$details = get_string('check_frontpagerole_details', 'report_security');
return new result($status, $summary, $details);
}
// Risky caps - usually very dangerous.
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {role_capabilities} rc
JOIN {capabilities} cap ON cap.name = rc.capability
WHERE " . $DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS)) . " <> 0
AND rc.permission = :capallow
AND rc.roleid = :roleid";
$riskycount = $DB->count_records_sql($sql, [
'capallow' => CAP_ALLOW,
'roleid' => $frontpagerole->id,
]);
// There is no legacy role type for frontpage yet - anyway we can not allow teachers or admins there!
if ($frontpagerole->archetype === 'teacher' or $frontpagerole->archetype === 'editingteacher'
or $frontpagerole->archetype === 'coursecreator' or $frontpagerole->archetype === 'manager') {
$legacyok = false;
} else {
$legacyok = true;
}
if ($riskycount or !$legacyok) {
$status = result::CRITICAL;
$summary = get_string('check_frontpagerole_error', 'report_security', role_get_name($frontpagerole));
} else {
$status = result::OK;
$summary = get_string('check_frontpagerole_ok', 'report_security');
}
$details = get_string('check_frontpagerole_details', 'report_security');
return new result($status, $summary, $details);
}
}
+109
View File
@@ -0,0 +1,109 @@
<?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/>.
/**
* Verifies sanity of guest role
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies sanity of guest role
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class guestrole extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_guestrole_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=userpolicies'),
get_string('userpolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $DB, $CFG;
if (!$guestrole = $DB->get_record('role', ['id' => $CFG->guestroleid])) {
$status = result::WARNING;
$summary = get_string('check_guestrole_notset', 'report_security');
return new result($status, $summary);
}
// Risky caps - usually very dangerous.
$sql = "SELECT COUNT(DISTINCT rc.contextid)
FROM {role_capabilities} rc
JOIN {capabilities} cap ON cap.name = rc.capability
WHERE " . $DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS)) . " <> 0
AND rc.permission = :capallow
AND rc.roleid = :roleid";
$riskycount = $DB->count_records_sql($sql, [
'capallow' => CAP_ALLOW,
'roleid' => $guestrole->id,
]);
// It may have either no or 'guest' archetype - nothing else, or else it would break during upgrades badly.
if ($guestrole->archetype === '' or $guestrole->archetype === 'guest') {
$legacyok = true;
} else {
$legacyok = false;
}
if ($riskycount or !$legacyok) {
$status = result::CRITICAL;
$summary = get_string('check_guestrole_error', 'report_security', format_string($guestrole->name));
} else {
$status = result::OK;
$summary = get_string('check_guestrole_ok', 'report_security');
}
$details = get_string('check_guestrole_details', 'report_security');
return new result($status, $summary, $details);
}
}
+91
View File
@@ -0,0 +1,91 @@
<?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/>.
/**
* Lists all admins.
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Lists all admins.
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class riskadmin extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_riskadmin_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/roles/admins.php'),
get_string('siteadministrators', 'role'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $DB, $CFG;
$userfieldsapi = \core_user\fields::for_userpic();
$userfields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
$sql = "SELECT $userfields
FROM {user} u
WHERE u.id IN ($CFG->siteadmins)";
$admins = $DB->get_records_sql($sql);
$admincount = count($admins);
foreach ($admins as $uid => $user) {
$url = "$CFG->wwwroot/user/view.php?id=$user->id";
$link = \html_writer::link($url, fullname($user, true) . ' (' . s($user->email) . ')');
$admins[$uid] = \html_writer::tag('li' , $link);
}
$admins = \html_writer::tag('ul', implode('', $admins));
$status = result::INFO;
$summary = get_string('check_riskadmin_ok', 'report_security', $admincount);
$details = get_string('check_riskadmin_detailsok', 'report_security', $admins);
return new result($status, $summary, $details);
}
}
+69
View File
@@ -0,0 +1,69 @@
<?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/>.
/**
* Lists all roles that have the ability to backup user data, as well as users
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Lists all roles that have the ability to backup user data, as well as users
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class riskbackup extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_riskbackup_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/roles/manage.php'),
get_string('manageroles', 'role'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
return new riskbackup_result();
}
}
@@ -0,0 +1,201 @@
<?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/>.
/**
* Lists all roles that have the ability to backup user data, as well as users
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
use context;
use stdClass;
use core\check\result;
/**
* Lists all roles that have the ability to backup user data, as well as users
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class riskbackup_result extends \core\check\result {
/** @var stdClass[] $systemroles */
private $systemroles;
/** @var stdClass[] $overriddenroles */
private $overriddenroles;
/** @var string $sqluserinfo */
private $sqluserinfo;
/**
* Constructor
*/
public function __construct() {
global $DB;
$syscontext = \context_system::instance();
$params = array('capability' => 'moodle/backup:userinfo', 'permission' => CAP_ALLOW, 'contextid' => $syscontext->id);
$sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype
FROM {role} r
JOIN {role_capabilities} rc ON rc.roleid = r.id
WHERE rc.capability = :capability
AND rc.contextid = :contextid
AND rc.permission = :permission";
$this->systemroles = $DB->get_records_sql($sql, $params);
// Ensure first field is unique (role.id + role_capabilities.contextid).
$roleidcontextfield = $DB->sql_concat_join("','", ['r.id', 'rc.contextid']);
$params = array('capability' => 'moodle/backup:userinfo', 'permission' => CAP_ALLOW, 'contextid' => $syscontext->id);
$sql = "SELECT DISTINCT {$roleidcontextfield} AS rolecontext, r.id, r.name, r.shortname, r.sortorder, r.archetype,
rc.contextid
FROM {role} r
JOIN {role_capabilities} rc ON rc.roleid = r.id
WHERE rc.capability = :capability
AND rc.contextid <> :contextid
AND rc.permission = :permission";
$this->overriddenroles = $DB->get_records_sql($sql, $params);
// List of users that are able to backup personal info
// note:
// "sc" is context where is role assigned,
// "c" is context where is role overridden or system context if in role definition.
$params = [
'capability' => 'moodle/backup:userinfo',
'permission' => CAP_ALLOW,
'context1' => CONTEXT_COURSE,
'context2' => CONTEXT_COURSE,
];
$this->sqluserinfo = "
FROM (SELECT DISTINCT rcx.contextid,
rcx.roleid
FROM {role_capabilities} rcx
WHERE rcx.permission = :permission
AND rcx.capability = :capability) rc
JOIN {context} c ON c.id = rc.contextid
JOIN {context} sc ON sc.contextlevel <= :context1
JOIN {role_assignments} ra ON ra.contextid = sc.id AND ra.roleid = rc.roleid
JOIN {user} u ON u.id = ra.userid AND u.deleted = 0
WHERE (sc.path = c.path OR
sc.path LIKE " . $DB->sql_concat('c.path', "'/%'") . " OR
c.path LIKE " . $DB->sql_concat('sc.path', "'/%'") . ")
AND c.contextlevel <= :context2";
$usercount = $DB->count_records_sql("SELECT COUNT('x') FROM (SELECT DISTINCT u.id $this->sqluserinfo) userinfo", $params);
$systemrolecount = empty($this->systemroles) ? 0 : count($this->systemroles);
$overriddenrolecount = empty($this->overriddenroles) ? 0 : count($this->overriddenroles);
if (max($usercount, $systemrolecount, $overriddenrolecount) > 0) {
$this->status = result::WARNING;
} else {
$this->status = result::OK;
}
$a = (object)array(
'rolecount' => $systemrolecount,
'overridecount' => $overriddenrolecount,
'usercount' => $usercount,
);
$this->summary = get_string('check_riskbackup_warning', 'report_security', $a);
}
/**
* Showing the full list of roles may be slow so defer it
*
* @return string
*/
public function get_details(): string {
global $CFG, $DB;
$details = '';
// Make a list of roles.
if ($this->systemroles) {
$links = array();
foreach ($this->systemroles as $role) {
$role->name = role_get_name($role);
$role->url = (new \moodle_url('/admin/roles/manage.php', ['action' => 'edit', 'roleid' => $role->id]))->out();
$links[] = \html_writer::tag('li', get_string('check_riskbackup_editrole', 'report_security', $role));
}
$links = \html_writer::tag('ul', implode('', $links));
$details .= get_string('check_riskbackup_details_systemroles', 'report_security', $links);
}
// Make a list of overrides to roles.
if ($this->overriddenroles) {
$links = array();
foreach ($this->overriddenroles as $role) {
$context = context::instance_by_id($role->contextid);
$role->name = role_get_name($role, $context, ROLENAME_BOTH);
$role->contextname = $context->get_context_name();
$role->url = (new \moodle_url('/admin/roles/override.php',
['contextid' => $role->contextid, 'roleid' => $role->id]))->out();
$links[] = \html_writer::tag('li', get_string('check_riskbackup_editoverride', 'report_security', $role));
}
$links = \html_writer::tag('ul', implode('', $links));
$details .= get_string('check_riskbackup_details_overriddenroles', 'report_security', $links);
}
// Get a list of affected users as well.
$users = array();
list($sort, $sortparams) = users_order_by_sql('u');
$params = [
'capability' => 'moodle/backup:userinfo',
'permission' => CAP_ALLOW,
'context1' => CONTEXT_COURSE,
'context2' => CONTEXT_COURSE,
];
$userfieldsapi = \core_user\fields::for_userpic();
$userfields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
$rs = $DB->get_recordset_sql("
SELECT DISTINCT $userfields,
ra.contextid,
ra.roleid
$this->sqluserinfo
ORDER BY $sort", array_merge($params, $sortparams));
foreach ($rs as $user) {
$context = \context::instance_by_id($user->contextid);
$url = new \moodle_url('/admin/roles/assign.php', ['contextid' => $user->contextid, 'roleid' => $user->roleid]);
$a = (object)array(
'fullname' => fullname($user),
'url' => $url->out(),
'email' => s($user->email),
'contextname' => $context->get_context_name(),
);
$users[] = \html_writer::tag('li', get_string('check_riskbackup_unassign', 'report_security', $a));
}
$rs->close();
if (!empty($users)) {
$users = \html_writer::tag('ul', implode('', $users));
$details .= get_string('check_riskbackup_details_users', 'report_security', $users);
}
return $details;
}
}
+76
View File
@@ -0,0 +1,76 @@
<?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/>.
/**
* Lists all users with XSS risk
*
* It would be great to combine this with risk trusts in user table,
* unfortunately nobody implemented user trust UI yet :-(
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
defined('MOODLE_INTERNAL') || die();
use core\check\result;
/**
* Lists all users with XSS risk
*
* It would be great to combine this with risk trusts in user table,
* unfortunately nobody implemented user trust UI yet :-(
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class riskxss extends \core\check\check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_riskxss_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/roles/manage.php'),
get_string('manageroles', 'role'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
return new riskxss_result();
}
}
+112
View File
@@ -0,0 +1,112 @@
<?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/>.
/**
* Lists all users with XSS risk
*
* It would be great to combine this with risk trusts in user table,
* unfortunately nobody implemented user trust UI yet :-(
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\access;
defined('MOODLE_INTERNAL') || die();
use core\check\result;
/**
* Lists all users with XSS risk
*
* It would be great to combine this with risk trusts in user table,
* unfortunately nobody implemented user trust UI yet :-(
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class riskxss_result extends \core\check\result {
/** @var array SQL parameters. */
protected $params = [];
/** @var string SQL statement. */
protected $sqlfrom;
/**
* Constructor
*/
public function __construct() {
global $DB;
$this->params = array('capallow' => CAP_ALLOW);
$this->sqlfrom = "FROM (SELECT DISTINCT rcx.contextid, rcx.roleid
FROM {role_capabilities} rcx
JOIN {capabilities} cap ON (cap.name = rcx.capability AND
" . $DB->sql_bitand('cap.riskbitmask', RISK_XSS) . " <> 0)
WHERE rcx.permission = :capallow) rc,
{context} c,
{context} sc,
{role_assignments} ra,
{user} u
WHERE c.id = rc.contextid
AND (sc.path = c.path OR
sc.path LIKE " . $DB->sql_concat('c.path', "'/%'") . " OR
c.path LIKE " . $DB->sql_concat('sc.path', "'/%'") . ")
AND u.id = ra.userid AND u.deleted = 0
AND ra.contextid = sc.id
AND ra.roleid = rc.roleid";
$count = $DB->count_records_sql("SELECT COUNT(DISTINCT u.id) $this->sqlfrom", $this->params);
if ($count == 0) {
$this->status = result::OK;
} else {
$this->status = result::WARNING;
}
$this->summary = get_string('check_riskxss_warning', 'report_security', $count);
}
/**
* Showing the full list of user may be slow so defer it
*
* @return string
*/
public function get_details(): string {
global $CFG, $DB;
$userfieldsapi = \core_user\fields::for_userpic();
$userfields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
$users = $DB->get_records_sql("SELECT DISTINCT $userfields $this->sqlfrom", $this->params);
foreach ($users as $uid => $user) {
$url = "$CFG->wwwroot/user/view.php?id=$user->id";
$link = \html_writer::link($url, fullname($user, true) . ' (' . s($user->email) . ')');
$users[$uid] = \html_writer::tag('li' , $link);
}
$users = \html_writer::tag('ul', implode('', $users));
return get_string('check_riskxss_details', 'report_security', $users);
}
}
+132
View File
@@ -0,0 +1,132 @@
<?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/>.
/**
* Base class for checks
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check;
use coding_exception;
/**
* Base class for checks
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class check {
/**
* @var string $component - The component / plugin this task belongs to.
*
* This can be autopopulated by the check manager.
* Otherwise, it is dynamically determined by get_component().
*/
protected $component = '';
/**
* Get the frankenstyle component name
*
* @return string
*/
public function get_component(): string {
// Return component if has been set by the manager.
if (!empty($this->component)) {
return $this->component;
}
// Else work it out based on the classname.
// Because the first part of the classname is always the component.
$parts = explode("\\", get_called_class());
if (empty($parts)) {
throw new coding_exception("Unable to determine component for check");
}
return $parts[0];
}
/**
* Get the frankenstyle component name
*
* @param string $component name
*/
public function set_component(string $component) {
$this->component = $component;
}
/**
* Get the check's id
*
* This defaults to the base name of the class which is ok in the most
* cases but if you have a check which can have multiple instances then
* you should override this to be unique.
*
* @return string must be unique within a component
*/
public function get_id(): string {
$class = get_class($this);
$id = explode("\\", $class);
return end($id);
}
/**
* Get the check reference
*
* @return string must be globally unique
*/
public function get_ref(): string {
$ref = $this->get_component();
if (!empty($ref)) {
$ref .= '_';
}
$ref .= $this->get_id();
return $ref;
}
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
$id = $this->get_id();
return get_string("check{$id}", $this->get_component());
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return null;
}
/**
* Return the result
*
* @return result object
*/
abstract public function get_result(): result;
}
+123
View File
@@ -0,0 +1,123 @@
<?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 core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Checks status of antivirus scanners by looking back at any recent scans.
*
* @package core
* @category check
* @author Kevin Pham <kevinpham@catalyst-au.net>
* @copyright Catalyst IT, 2021
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class antivirus extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_antivirus_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php', ['section' => 'manageantiviruses']),
get_string('antivirussettings', 'antivirus'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG, $DB;
$details = \html_writer::tag('p', get_string('check_antivirus_details', 'report_security'));
// If no scanners are enabled, then return an NA status since the results do not matter.
if (empty($CFG->antiviruses)) {
$status = result::NA;
$summary = get_string('check_antivirus_info', 'report_security');
return new result($status, $summary, $details);
}
$logmanager = get_log_manager();
$readers = $logmanager->get_readers('\core\log\sql_internal_table_reader');
// If reader is not a sql_internal_table_reader return UNKNOWN since we
// aren't able to fetch the required information. Legacy logs are not
// supported here. They do not hold enough adequate information to be
// used for these checks.
if (empty($readers)) {
$status = result::UNKNOWN;
$summary = get_string('check_antivirus_logstore_not_supported', 'report_security');
return new result($status, $summary, $details);
}
$reader = reset($readers);
// If there has been a recent timestamp within threshold period, then
// set the status to ERROR and describe the problem, e.g. X issues in
// the last N period.
$threshold = get_config('antivirus', 'threshold');
$params = [];
$params['lookback'] = time() - $threshold;
// Type of "targets" to include.
list($targetsqlin, $inparams) = $DB->get_in_or_equal([
'antivirus_scan_file',
'antivirus_scan_data',
], SQL_PARAMS_NAMED);
$params = array_merge($inparams, $params);
// Specify criteria for search.
$selectwhere = "timecreated > :lookback
AND target $targetsqlin
AND action = 'error'";
$totalerrors = $reader->get_events_select_count($selectwhere, $params);
if (!empty($totalerrors)) {
$status = result::ERROR;
$summary = get_string('check_antivirus_error', 'report_security', [
'errors' => $totalerrors,
'lookback' => format_time($threshold)
]);
} else if (!empty($CFG->antiviruses)) {
$status = result::OK;
// Fetch count of enabled antiviruses (we don't care about which ones).
$totalantiviruses = !empty($CFG->antiviruses) ? count(explode(',', $CFG->antiviruses)) : 0;
$summary = get_string('check_antivirus_ok', 'report_security', [
'scanners' => $totalantiviruses,
'lookback' => format_time($threshold)
]);
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,70 @@
<?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/>.
/**
* Verifies config.php is not writable anymore after installation
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies config.php is not writable anymore after installation
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class configrw extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_configrw_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_configrw_details', 'report_security');
if (is_writable($CFG->dirroot . '/config.php')) {
$status = result::WARNING;
$summary = get_string('check_configrw_warning', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_configrw_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,75 @@
<?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/>.
/**
* Verifies displaying of errors
*
* Problem for lib files and 3rd party code because we can not disable debugging
* in these scripts (they do not include config.php)
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\result;
use core\check\check;
/**
* Verifies displaying of errors
*
* Problem for lib files and 3rd party code because we can not disable debugging
* in these scripts (they do not include config.php)
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class displayerrors extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_displayerrors_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
$details = get_string('check_displayerrors_details', 'report_security');
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
$status = result::WARNING;
$summary = get_string('check_displayerrors_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_displayerrors_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,83 @@
<?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/>.
/**
* Environment check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Environment check
*
* @package core
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class environment extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('environment', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/environment.php'),
get_string('environment', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require_once($CFG->libdir.'/environmentlib.php');
list($status, $details) = check_moodle_environment($CFG->release, ENV_SELECT_NEWER);
if ($status) {
$summary = get_string('environmentok', 'admin');
$status = result::OK;
} else {
$summary = get_string('environmenterrortodo', 'admin');
$status = result::ERROR;
}
return new result($status, $summary, '');
}
}
@@ -0,0 +1,69 @@
<?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/>.
/**
* Verifies the status of preventexecpath
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies the status of preventexecpath
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class preventexecpath extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_preventexecpath_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_preventexecpath_details', 'report_security');
if (empty($CFG->preventexecpath)) {
$status = result::WARNING;
$summary = get_string('check_preventexecpath_warning', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_preventexecpath_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,307 @@
<?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/>.
/**
* Check the presence of public paths via curl.
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Check the public access of various paths.
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class publicpaths extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_publicpaths_name', 'report_security');
}
/**
* Returns a list of test urls and metadata.
*/
public function get_pathsets() {
global $CFG;
// The intention here is that each pattern is a simple regex such that
// in future perhaps the various webserver config could be generated as more
// pattens are added to these checks.
return [
[
'pattern' => '/vendor/',
'404' => [
'vendor/',
'vendor/bin/behat',
],
'details' => get_string('check_vendordir_details', 'report_security', ['path' => $CFG->dirroot.'/vendor']),
'summary' => get_string('check_vendordir_info', 'report_security'),
],
[
'pattern' => '/node_modules/',
'404' => [
'node_modules/',
'node_modules/cli/cli.js',
],
'summary' => get_string('check_nodemodules_info', 'report_security'),
'details' => get_string('check_nodemodules_details', 'report_security',
['path' => $CFG->dirroot . '/node_modules']),
],
[
'pattern' => '^\..*',
'404' => [
'.git/',
'.git/HEAD',
'.github/FUNDING.yml',
'.stylelintrc',
],
],
[
'pattern' => 'composer.json',
'404' => [
'composer.json',
],
],
[
'pattern' => '.lock',
'404' => [
'composer.lock',
],
],
[
'pattern' => 'environment.xml',
'404' => [
'admin/environment.xml',
],
],
[
'pattern' => '',
'404' => [
'doesnotexist', // Just to make sure that real 404s are still 404s.
],
'summary' => '',
],
[
'pattern' => '',
'404' => [
'lib/classes/',
],
'summary' => get_string('check_dirindex_info', 'report_security'),
],
[
'pattern' => 'db/install.xml',
'404' => [
'lib/db/install.xml',
'mod/assign/db/install.xml',
],
],
[
'pattern' => 'readme.txt',
'404' => [
'lib/scssphp/readme_moodle.txt',
'mod/resource/readme.txt',
],
],
[
'pattern' => 'README',
'404' => [
'mod/README.txt',
'mod/book/README.md',
'mod/chat/README.txt',
],
],
[
'pattern' => '/upgrade.txt',
'404' => [
'auth/manual/upgrade.txt',
'lib/upgrade.txt',
],
],
[
'pattern' => 'phpunit.xml',
'404' => ['phpunit.xml.dist'],
],
[
'pattern' => '/fixtures/',
'404' => [
'privacy/tests/fixtures/logo.png',
'enrol/lti/tests/fixtures/input.xml',
],
],
[
'pattern' => '/behat/',
'404' => ['blog/tests/behat/delete.feature'],
],
];
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG, $OUTPUT;
$status = result::OK;
$details = '';
$summary = get_string('check_publicpaths_ok', 'report_security');
$errors = [];
$c = new \curl();
$paths = $this->get_pathsets();
$table = new \html_table();
$table->align = ['center', 'right', 'left'];
$table->size = ['1%', '1%', '1%', '1%', '1%', '99%'];
$table->head = [
get_string('status'),
get_string('checkexpected'),
get_string('checkactual'),
get_string('url'),
get_string('category'),
get_string('details'),
];
$table->attributes['class'] = 'flexible generaltable generalbox table-sm';
$table->data = [];
// Used to track duplicated errors.
$lastdetail = '-';
$curl = new \curl();
$requests = [];
// Build up a list of all url so we can load them in parallel.
foreach ($paths as $path) {
foreach (['200', '404'] as $expected) {
if (!isset($path[$expected])) {
continue;
}
foreach ($path[$expected] as $test) {
$requests[] = [
'nobody' => true,
'header' => 1,
'url' => $CFG->wwwroot . '/' . $test,
'returntransfer' => true,
];
}
}
}
$headers = $curl->download($requests);
foreach ($paths as $path) {
foreach (['200', '404'] as $expected) {
if (!isset($path[$expected])) {
continue;
}
foreach ($path[$expected] as $test) {
$rowsummary = '';
$rowdetail = '';
$url = $CFG->wwwroot . '/' . $test;
// Parse the HTTP header to get the 200 / 404 code.
$header = array_shift($headers);
$actual = strtok($header, "\n");
$actual = strtok($actual, " ");
$actual = strtok(" ");
if ($actual != $expected) {
if (isset($path['summary'])) {
$rowsummary = $path['summary'];
} else {
$rowsummary = get_string('check_publicpaths_generic',
'report_security', $path['pattern']);
}
// Special case where a 404 is ideal but a 403 is ok too.
if ($actual == 403) {
$result = new result(result::INFO, '', '');
$rowsummary .= get_string('check_publicpaths_403', 'report_security');
} else {
$result = new result(result::ERROR, '', '');
$status = result::ERROR;
$summary = get_string('check_publicpaths_warning', 'report_security');
}
$rowdetail = isset($path['details']) ? $path['details'] : $rowsummary;
if (empty($errors[$path['pattern']])) {
$summary .= '<li>' . $rowsummary . '</li>';
$errors[$path['pattern']] = 1;
}
} else {
$result = new result(result::OK, '', '');
}
$table->data[] = [
$OUTPUT->check_result($result),
$expected,
$actual,
$OUTPUT->action_link($url, $test, null, ['target' => '_blank']),
"<pre>{$path['pattern']}</pre>",
];
// Merge duplicate details to display a nicer table.
if ($rowdetail == $lastdetail) {
$duplicates++;
} else {
$duplicates = 1;
}
$detailcell = new \html_table_cell($rowdetail);
$detailcell->rowspan = $duplicates;
$rows = count($table->data);
$table->data[$rows - $duplicates][5] = $detailcell;
$lastdetail = $rowdetail;
}
}
}
$details .= \html_writer::table($table);
return new result($status, $summary, $details);
}
/**
* Link to the dev docs for more info.
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url(\get_docs_url('Installing_Moodle#Set_up_your_server')),
get_string('moodledocs'));
}
}
@@ -0,0 +1,80 @@
<?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/>.
/**
* Verifies fatal misconfiguration of dataroot
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\result;
/**
* Verifies fatal misconfiguration of dataroot
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class unsecuredataroot extends \core\check\check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_unsecuredataroot_name', 'report_security');
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require_once($CFG->libdir.'/adminlib.php');
$details = get_string('check_unsecuredataroot_details', 'report_security');
$insecuredataroot = is_dataroot_insecure(true);
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
$status = result::ERROR;
$summary = get_string('check_unsecuredataroot_warning', 'report_security', $CFG->dataroot);
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
$status = result::CRITICAL;
$summary = get_string('check_unsecuredataroot_error', 'report_security', $CFG->dataroot);
} else {
$status = result::OK;
$summary = get_string('check_unsecuredataroot_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,85 @@
<?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/>.
/**
* Upgrade check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\environment;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Upgrade check
*
* @package core
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class upgradecheck extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('checkupgradepending', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/index.php?cache=1'),
get_string('notifications', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require("$CFG->dirroot/version.php");
$newversion = "$release ($version)";
if ($version < $CFG->version) {
$status = result::ERROR;
$summary = get_string('downgradedcore', 'error');
} else if (moodle_needs_upgrading()) {
$status = result::ERROR;
$summary = get_string('cliupgradepending', 'admin');
} else {
$status = result::OK;
$summary = get_string('cliupgradenoneed', 'core_admin', $newversion);
}
return new result($status, $summary);
}
}
+153
View File
@@ -0,0 +1,153 @@
<?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 core\check\external;
use admin_root;
use admin_setting_check;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
use context_system;
use invalid_parameter_exception;
/**
* Webservice to get result of a given check.
*
* @package core
* @category check
* @copyright 2023 Matthew Hilton <matthewhilton@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class get_result_admintree extends external_api {
/**
* Defines parameters
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'admintreeid' => new external_value(PARAM_TEXT, 'ID of node in admintree'),
'settingname' => new external_value(PARAM_TEXT, 'Name of setting'),
'includedetails' => new external_value(PARAM_BOOL, 'If the details should be included in the response.
Depending on the check, details could be slower to return.', VALUE_DEFAULT, false),
]);
}
/**
* Gets the result of the check and returns it.
* @param string $admintreeid ID of admin_setting to find check object from
* @param string $settingname Name of admin_setting to find check object from
* @param bool $includedetails If the details should be included in the response.
* @param admin_root|null $admintree Root of admin tree to use (for unit testing)
* @return array returned data
*/
public static function execute(string $admintreeid, string $settingname, bool $includedetails,
admin_root $admintree = null): array {
global $OUTPUT, $CFG;
// Validate parameters.
self::validate_parameters(self::execute_parameters(), [
'admintreeid' => $admintreeid,
'settingname' => $settingname,
'includedetails' => $includedetails,
]);
// Context and capability checks.
$context = context_system::instance();
self::validate_context($context);
require_admin();
require_once($CFG->libdir . '/adminlib.php');
// Find admin node so we can load the check object.
$check = self::get_check_from_setting($admintreeid, $settingname, $admintree);
if (empty($check)) {
throw new invalid_parameter_exception("Could not find check object using admin tree.");
}
// Execute the check and get the result.
$result = $check->get_result();
// Build the response.
$data = [
'status' => s($result->get_status()),
'summary' => s($result->get_summary()),
'html' => s($OUTPUT->check_full_result($check, $result, $includedetails)),
];
// Since details might be slower to obtain, we allow this to be optionally returned.
if ($includedetails) {
$data['details'] = s($result->get_details());
}
return $data;
}
/**
* Finds the check from the admin tree.
*
* @param string $settingid ID of the adming_setting
* @param string $settingname Name of the admin_setting
* @param admin_root|null $tree Admin tree to use (for unit testing). Null will default to the admin_get_root()
*/
private static function get_check_from_setting(string $settingid, string $settingname, admin_root $tree = null) {
// Since settings do not know exactly who their parents are in the tree, we must search for the setting.
if (empty($tree)) {
$tree = \admin_get_root();
}
// Search for the setting name.
// To do this, we must search in each category.
$categories = $tree->search($settingname);
$allsettings = array_map(function($c) {
return $c->settings;
}, array_values($categories));
// Flatten the array.
$allsettings = array_merge(...$allsettings);
// Find the one that matches the unique id exactly and are check settings.
$matchingsettings = array_filter($allsettings, function($s) use ($settingid) {
return $s->get_id() == $settingid && $s instanceof admin_setting_check;
});
// There was either none found or more than one found.
// In this case, we cannot determine which to use so just return null.
if (count($matchingsettings) != 1) {
return null;
}
$setting = current($matchingsettings);
return $setting->get_check();
}
/**
* Defines return structure.
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'status' => new external_value(PARAM_TEXT, 'Result status constant'),
'summary' => new external_value(PARAM_TEXT, 'Summary of result'),
'html' => new external_value(PARAM_TEXT, 'Rendered full html result', VALUE_OPTIONAL),
'details' => new external_value(PARAM_TEXT, 'Details of result (if includedetails was enabled)', VALUE_OPTIONAL),
]);
}
}
+90
View File
@@ -0,0 +1,90 @@
<?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/>.
/**
* Verifies if https enabled only secure cookies allowed
*
* This prevents redirections and sending of cookies to unsecure port.
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\http;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies if https enabled only secure cookies allowed
*
* This prevents redirections and sending of cookies to unsecure port.
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cookiesecure extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_cookiesecure_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=httpsecurity#admin-cookiesecure'),
get_string('httpsecurity', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_cookiesecure_details', 'report_security');
if (!is_https()) {
$status = result::WARNING;
$summary = get_string('check_cookiesecure_http', 'report_security');
return new result($status, $summary, $details);
}
if (!is_moodle_cookie_secure()) {
$status = result::ERROR;
$summary = get_string('check_cookiesecure_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_cookiesecure_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
+157
View File
@@ -0,0 +1,157 @@
<?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/>.
/**
* Check API manager
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check;
defined('MOODLE_INTERNAL') || die();
/**
* Check API manager
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class manager {
/**
* The list of valid check types
*/
public const TYPES = ['status', 'security', 'performance'];
/**
* Return all status checks
*
* @param string $type of checks to fetch
* @return array of check objects
*/
public static function get_checks(string $type): array {
if (!in_array($type, self::TYPES)) {
throw new \moodle_exception("Invalid check type '$type'");
}
$method = 'get_' . $type . '_checks';
$checks = self::$method();
return $checks;
}
/**
* Return all performance checks
*
* @return array of check objects
*/
public static function get_performance_checks(): array {
$checks = [
new performance\designermode(),
new performance\cachejs(),
new performance\debugging(),
new performance\backups(),
new performance\stats(),
new performance\dbschema(),
];
// Any plugin can add status checks to this report by implementing a callback
// <component>_status_checks() which returns a check object.
$morechecks = get_plugins_with_function('performance_checks', 'lib.php');
foreach ($morechecks as $plugintype => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$result = $pluginfunction();
foreach ($result as $check) {
$check->set_component($plugintype . '_' . $plugin);
$checks[] = $check;
}
}
}
return $checks;
}
/**
* Return all status checks
*
* @return array of check objects
*/
public static function get_status_checks(): array {
$checks = [
new environment\environment(),
new environment\upgradecheck(),
new environment\antivirus(),
];
// Any plugin can add status checks to this report by implementing a callback
// <component>_status_checks() which returns a check object.
$morechecks = get_plugins_with_function('status_checks', 'lib.php');
foreach ($morechecks as $plugintype => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$result = $pluginfunction();
foreach ($result as $check) {
$check->set_component($plugintype . '_' . $plugin);
$checks[] = $check;
}
}
}
return $checks;
}
/**
* Return all security checks
*
* @return array of check objects
*/
public static function get_security_checks(): array {
$checks = [
new environment\displayerrors(),
new environment\unsecuredataroot(),
new environment\publicpaths(),
new environment\configrw(),
new environment\preventexecpath(),
new security\embed(),
new security\openprofiles(),
new security\crawlers(),
new security\passwordpolicy(),
new security\emailchangeconfirmation(),
new security\webcron(),
new http\cookiesecure(),
new access\riskadmin(),
new access\riskxss(),
new access\riskbackup(),
new access\defaultuserrole(),
new access\guestrole(),
new access\frontpagerole(),
];
// Any plugin can add security checks to this report by implementing a callback
// <component>_security_checks() which returns a check object.
$morechecks = get_plugins_with_function('security_checks', 'lib.php');
foreach ($morechecks as $plugintype => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$result = $pluginfunction();
foreach ($result as $check) {
$check->set_component($plugintype . '_' . $plugin);
$checks[] = $check;
}
}
}
return $checks;
}
}
+84
View File
@@ -0,0 +1,84 @@
<?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/>.
/**
* Backups check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\performance;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Backups check
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class backups extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_backup', 'report_performance');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php', ['section' => 'automated']),
get_string('automatedsetup', 'backup'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
require_once($CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php');
$automatedbackupsenabled = get_config('backup', 'backup_auto_active');
if ($automatedbackupsenabled == \backup_cron_automated_helper::AUTO_BACKUP_ENABLED) {
$status = result::WARNING;
$summary = get_string('check_backup_comment_enable', 'report_performance');
} else {
$status = result::OK;
$summary = get_string('check_backup_comment_disable', 'report_performance');
}
$details = get_string('check_backup_details', 'report_performance');
return new result($status, $summary, $details);
}
}
+81
View File
@@ -0,0 +1,81 @@
<?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/>.
/**
* CacheJS check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\performance;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* CacheJS check
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cachejs extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('cachejs', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/search.php', ['query' => 'cachejs']),
get_string('cachejs', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
if (empty($CFG->cachejs)) {
$status = result::CRITICAL;
$summary = get_string('check_cachejs_comment_disable', 'report_performance');
} else {
$status = result::OK;
$summary = get_string('check_cachejs_comment_enable', 'report_performance');
}
$details = get_string('check_cachejs_details', 'report_performance');
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,85 @@
<?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/>.
/**
* DB schema performance check
*
* @package core
* @category check
* @copyright 2021 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\performance;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* DB schema performance check
*
* @copyright 2021 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class dbschema extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_dbschema_name', 'report_performance');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url(\get_docs_url('Verify_Database_Schema')),
get_string('moodledocs'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $DB;
$dbmanager = $DB->get_manager();
$schema = $dbmanager->get_install_xml_schema();
if (!$errors = $dbmanager->check_database_schema($schema)) {
return new result(result::OK, get_string('check_dbschema_ok', 'report_performance'), '');
}
$details = '';
foreach ($errors as $tablename => $items) {
$details .= \html_writer::tag('h4', $tablename);
foreach ($items as $item) {
$details .= \html_writer::tag('pre', $item);
}
}
return new result(result::ERROR, get_string('check_dbschema_errors', 'report_performance'), $details);
}
}
@@ -0,0 +1,81 @@
<?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/>.
/**
* Debugging check
*
* @package core
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\performance;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Debugging check
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class debugging extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('debug', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php', ['section' => 'debugging']),
get_string('debug', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
if (!$CFG->debugdeveloper) {
$status = result::OK;
$summary = get_string('check_debugmsg_comment_nodeveloper', 'report_performance');
} else {
$status = result::WARNING;
$summary = get_string('check_debugmsg_comment_developer', 'report_performance');
}
$details = get_string('check_debugmsg_details', 'report_performance');
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,82 @@
<?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/>.
/**
* Designer mode
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\performance;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Designer mode
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class designermode extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('themedesignermode', 'admin');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/search.php', ['query' => 'themedesignermode']),
get_string('themedesignermode', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $DB, $CFG;
if (empty($CFG->themedesignermode)) {
$status = result::OK;
$summary = get_string('check_themedesignermode_comment_disable', 'report_performance');
} else {
$status = result::CRITICAL;
$summary = get_string('check_themedesignermode_comment_enable', 'report_performance');
}
$details = get_string('check_themedesignermode_details', 'report_performance');
return new result($status, $summary, $details);
}
}
+72
View File
@@ -0,0 +1,72 @@
<?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 core\check\performance;
use core\check\check;
use core\check\result;
/**
* Stats check
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class stats extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('stats');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/search.php', ['query' => 'enablestats']),
get_string('enablestats', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
if (!empty($CFG->enablestats)) {
$status = result::WARNING;
$summary = get_string('check_enablestats_comment_enable', 'report_performance');
} else {
$status = result::OK;
$summary = get_string('check_enablestats_comment_disable', 'report_performance');
}
$details = get_string('check_enablestats_details', 'report_performance');
return new result($status, $summary, $details);
}
}
+192
View File
@@ -0,0 +1,192 @@
<?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/>.
/**
* A check result class
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check;
defined('MOODLE_INTERNAL') || die();
/**
* A check object returns a result object
*
* Most checks can use this an instance of this directly but if you have a
* 'details' which is computationally expensive then extend this and overide
* the get_details() method so that it is only called when it will be needed.
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class result implements \renderable {
/**
* This is used to notify if a check does not apply.
*
* In most cases if a check doesn't apply a check object shouldn't be made.
* This state exists for when you always want visibilty of the check itself.
* Can be useful for a check which depends on another check and it helps
* focus on the other check which matters more.
*/
const NA = 'na';
/**
* Ideally all checks should be ok.
*/
const OK = 'ok';
/**
* This is used to show info for a check.
*
* This is equivalent to OK but could be used for alerting to potential
* future warnings such as a deprecation in a service.
*/
const INFO = 'info';
/**
* This means we could not determine the state.
*
* An example might be an expensive check done via cron, and it has never run.
* It would be prudent to consider an unknown check as a warning or error.
*/
const UNKNOWN = 'unknown';
/**
* Warnings
*
* Something is not ideal and should be addressed, eg usability or the
* speed of the site may be affected, but it may self heal (eg a load spike)
*/
const WARNING = 'warning';
/**
* This is used to notify if a check failed.
*
* Something is wrong with a component and a feature is not working.
*/
const ERROR = 'error';
/**
* This is used to notify if a check is a major critical issue.
*
* An error which is affecting everyone in a major way.
*/
const CRITICAL = 'critical';
/**
* @var string $status - status
*/
protected $status = self::UNKNOWN;
/**
* @var string summary - should be roughly 1 line of plain text and may change depending on the state.
*/
protected $summary = '';
/**
* @var string details about check.
*
* This may be a large amount of preformatted html text, possibly describing all the
* different states and actions to address them.
*/
protected $details = '';
/**
* Get the check reference label
*
* @return string must be globally unique
*/
public function get_ref(): string {
$ref = $this->get_component();
if (!empty($ref)) {
$ref .= '_';
}
$ref .= $this->get_id();
return $ref;
}
/**
* Constructor
*
* @param string $status code
* @param string $summary a 1 liner summary
* @param string $details as a html chunk
*/
public function __construct($status, $summary, $details = '') {
$this->status = $status;
$this->summary = $summary;
$this->details = $details;
}
/**
* Get the check status
*
* @return string one of the consts eg result::OK
*/
public function get_status(): string {
return $this->status;
}
/**
* Summary of the check
* @return string formatted html
*/
public function get_summary(): string {
return $this->summary;
}
/**
* Get the check detailed info
* @return string formatted html
*/
public function get_details(): string {
return $this->details;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param \renderer_base $output typically, the renderer that's calling this function
* @return array data context for a mustache template
*/
public function export_for_template(\renderer_base $output) {
return array(
'status' => clean_text(get_string('status' . $this->status)),
'isna' => $this->status === self::NA,
'isok' => $this->status === self::OK,
'isinfo' => $this->status === self::INFO,
'isunknown' => $this->status === self::UNKNOWN,
'iswarning' => $this->status === self::WARNING,
'iserror' => $this->status === self::ERROR,
'iscritical' => $this->status === self::CRITICAL,
);
}
/**
* Which mustache template?
*
* @return string path to mustache template
*/
public function get_template_name(): string {
return 'core/check/result';
}
}
+89
View File
@@ -0,0 +1,89 @@
<?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/>.
/**
* Verifies web crawler (search engine) access
*
* Not combined with disabled guest access because attackers might gain guest
* access by modifying browser signature.
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies web crawler (search engine) access
*
* Not combined with disabled guest access because attackers might gain guest
* access by modifying browser signature.
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class crawlers extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_crawlers_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=sitepolicies#admin-opentowebcrawlers'),
get_string('sitepolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_crawlers_details', 'report_security');
if (empty($CFG->opentowebcrawlers)) {
$status = result::OK;
$summary = get_string('check_crawlers_ok', 'report_security');
} else if (!empty($CFG->guestloginbutton)) {
$status = result::INFO;
$summary = get_string('check_crawlers_info', 'report_security');
} else {
$status = result::ERROR;
$summary = get_string('check_crawlers_error', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,86 @@
<?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/>.
/**
* Verifies email confirmation - spammers were changing mails very often
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies email confirmation - spammers were changing mails very often
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class emailchangeconfirmation extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_emailchangeconfirmation_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=sitepolicies#admin-emailchangeconfirmation'),
get_string('sitepolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_emailchangeconfirmation_details', 'report_security');
if (empty($CFG->emailchangeconfirmation)) {
if (empty($CFG->allowemailaddresses)) {
$status = result::WARNING;
$summary = get_string('check_emailchangeconfirmation_error', 'report_security');
} else {
$status = result::INFO;
$summary = get_string('check_emailchangeconfirmation_info', 'report_security');
}
} else {
$status = result::OK;
$summary = get_string('check_emailchangeconfirmation_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
+80
View File
@@ -0,0 +1,80 @@
<?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/>.
/**
* Verifies sloppy embedding - this should have been removed long ago!!
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies sloppy embedding - this should have been removed long ago!!
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class embed extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_embed_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=sitepolicies#admin-allowobjectembed'),
get_string('sitepolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_embed_details', 'report_security');
if (!empty($CFG->allowobjectembed)) {
$status = result::ERROR;
$summary = get_string('check_embed_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_embed_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,80 @@
<?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/>.
/**
* Verifies open profiles - originally open by default, not anymore because spammer abused it a lot
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies open profiles - originally open by default, not anymore because spammer abused it a lot
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class openprofiles extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_openprofiles_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=sitepolicies#admin-forcelogin'),
get_string('sitepolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_openprofiles_details', 'report_security');
if (empty($CFG->forcelogin) and empty($CFG->forceloginforprofiles)) {
$status = result::WARNING;
$summary = get_string('check_openprofiles_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_openprofiles_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
@@ -0,0 +1,80 @@
<?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/>.
/**
* Verifies if password policy set
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies if password policy set
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class passwordpolicy extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_passwordpolicy_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=sitepolicies#admin-passwordpolicy'),
get_string('sitepolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$details = get_string('check_passwordpolicy_details', 'report_security');
if (empty($CFG->passwordpolicy)) {
$status = result::WARNING;
$summary = get_string('check_passwordpolicy_error', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_passwordpolicy_ok', 'report_security');
}
return new result($status, $summary, $details);
}
}
+84
View File
@@ -0,0 +1,84 @@
<?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/>.
/**
* Verifies the status of web cron
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check\security;
defined('MOODLE_INTERNAL') || die();
use core\check\check;
use core\check\result;
/**
* Verifies the status of web cron
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @copyright 2008 petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class webcron extends check {
/**
* Get the short check name
*
* @return string
*/
public function get_name(): string {
return get_string('check_webcron_name', 'report_security');
}
/**
* A link to a place to action this
*
* @return \action_link|null
*/
public function get_action_link(): ?\action_link {
return new \action_link(
new \moodle_url('/admin/settings.php?section=sitepolicies#admin-cronclionly'),
get_string('sitepolicies', 'admin'));
}
/**
* Return result
* @return result
*/
public function get_result(): result {
global $CFG;
$croncli = $CFG->cronclionly;
$cronremotepassword = $CFG->cronremotepassword;
if (empty($croncli) && empty($cronremotepassword)) {
$status = result::WARNING;
$summary = get_string('check_webcron_warning', 'report_security');
} else {
$status = result::OK;
$summary = get_string('check_webcron_ok', 'report_security');
}
$details = get_string('check_webcron_details', 'report_security');
return new result($status, $summary, $details);
}
}
+145
View File
@@ -0,0 +1,145 @@
<?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/>.
/**
* A table of check results
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\check;
defined('MOODLE_INTERNAL') || die();
/**
* A table of check results
*
* @copyright 2020 Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class table implements \renderable {
/**
* @var \moodle_url $url
*/
protected $url = '';
/**
* @var string $type What type of checks
*/
protected $type = '';
/**
* @var check $detail a specific check to focus on
*/
public $detail = '';
/**
* @var array $checks shown in this table
*/
public $checks = [];
/**
* Constructor
*
* @param string $type of check
* @param string $url of report
* @param string $detail check to focus on
*/
public function __construct($type, $url, $detail = '') {
// We may need a bit more memory and this may take a long time to process.
\raise_memory_limit(MEMORY_EXTRA);
\core_php_time_limit::raise();
$this->type = $type;
$this->url = $url;
$this->checks = \core\check\manager::get_checks($type);
if ($detail) {
$this->checks = array_filter($this->checks, function($check) use ($detail) {
return $detail == $check->get_ref();
});
if (!empty($this->checks)) {
$this->detail = reset($this->checks);
}
}
}
/**
* Render a table of checks
*
* @param renderer $output to use
* @return string html output
*/
public function render($output) {
$table = new \html_table();
$table->data = [];
$table->head = [
get_string('status'),
get_string('check'),
get_string('summary'),
get_string('action'),
];
$table->colclasses = [
'rightalign status',
'leftalign check',
'leftalign summary',
'leftalign action',
];
$table->id = $this->type . 'reporttable';
$table->attributes = ['class' => 'admintable ' . $this->type . 'report generaltable'];
foreach ($this->checks as $check) {
$ref = $check->get_ref();
$result = $check->get_result();
$component = $check->get_component();
$actionlink = $check->get_action_link();
$link = new \moodle_url($this->url, ['detail' => $ref]);
$row = [];
$row[] = $output->check_result($result);
$row[] = $output->action_link($link, $check->get_name());
$row[] = $result->get_summary()
. '<br>'
. \html_writer::start_tag('small')
. $output->action_link($link, get_string('moreinfo'))
. \html_writer::end_tag('small');
if ($actionlink) {
$row[] = $output->render($actionlink);
} else {
$row[] = '';
}
$table->data[] = $row;
}
$html = \html_writer::table($table);
if ($this->detail && $result) {
$html .= $output->heading(get_string('details'), 3);
$html .= $output->box($result->get_details(), 'generalbox boxwidthnormal boxaligncenter');
$html .= $output->continue_button($this->url);
}
return $html;
}
}