MDL-73270 admin: Warn about xmlrpc webservice protocol enabled

Co-authored-by: Andrew Lyons <andrew@nicols.co.uk>
This commit is contained in:
Huong Nguyen 2022-01-07 09:43:17 +07:00
parent e63604fb6d
commit 683375af8b
17 changed files with 224 additions and 7 deletions

View File

@ -3729,6 +3729,8 @@
<ON_CHECK message="iscustomadminwarnings" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_xmlrpc_usage" level="optional">
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>

View File

@ -916,6 +916,12 @@ $showfeedbackencouragement = empty($CFG->enableuserfeedback);
// Check if the service and support content setting is enabled or not.
$servicesandsupportcontent = !isset($CFG->showservicesandsupportcontent) || $CFG->showservicesandsupportcontent;
// Check whether the XML-RPC protocol is enabled or not.
require_once($CFG->libdir . '/environmentlib.php');
$result = new environment_results('custom_checks');
$result = check_xmlrpc_usage($result);
$xmlrpcwarning = !is_null($result) ? get_string($result->getFeedbackStr(), 'admin') : '';
admin_externalpage_setup('adminnotifications');
$output = $PAGE->get_renderer('core', 'admin');
@ -924,4 +930,5 @@ echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisp
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl, $croninfrequent,
$showcampaigncontent, $showfeedbackencouragement, $servicesandsupportcontent);
$showcampaigncontent, $showfeedbackencouragement, $servicesandsupportcontent,
$xmlrpcwarning);

View File

@ -117,6 +117,7 @@ if ($form = data_submitted() and confirm_sesskey()) {
}
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
// Explain
echo $OUTPUT->box(get_string('ssoacldescr','mnet'));

View File

@ -81,6 +81,7 @@
$hosts = $DB->get_records_select('mnet_host', "id <> ? AND deleted = 0", array($CFG->mnet_localhost_id), 'wwwroot ASC');
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
?>
<form method="post" action="index.php">
<table align="center" width="635" class="generaltable" border="0" cellpadding="5" cellspacing="0">

View File

@ -51,6 +51,8 @@ if ($hostid && $DB->get_field('mnet_host', 'deleted', array('id' => $hostid)) !=
$PAGE->set_url('/admin/mnet/peers.php');
admin_externalpage_setup($adminsection);
$deprecatenotify = mnet_get_deprecation_notice();
if (!extension_loaded('openssl')) {
print_error('requiresopenssl', 'mnet');
}
@ -90,6 +92,7 @@ if ($formdata = $simpleform->get_data()) {
$formdata->oldpublickey = $mnet_peer->public_key; // set this so we can confirm on form post without having to recreate the mnet_peer object
$reviewform->set_data($mnet_peer);
echo $OUTPUT->header();
echo $OUTPUT->render($deprecatenotify);
echo $OUTPUT->box_start();
$reviewform->display();
echo $OUTPUT->box_end();
@ -177,6 +180,7 @@ if ($formdata = $reviewform->get_data()) {
}
} else if ($reviewform->is_submitted()) { // submitted, but errors
echo $OUTPUT->header();
echo $OUTPUT->render($deprecatenotify);
echo $OUTPUT->box_start();
$reviewform->display();
echo $OUTPUT->box_end();
@ -187,6 +191,7 @@ if ($formdata = $reviewform->get_data()) {
// normal flow - just display all hosts with links
echo $OUTPUT->header();
echo $OUTPUT->render($deprecatenotify);
$hosts = mnet_get_hosts(true);
// print the table to display the register all hosts setting

View File

@ -44,4 +44,5 @@ if (isset($mnet_peer->id) && $mnet_peer->id > 0) {
} else {
$tabs[] = new tabobject('mnetdetails', '#', $strmnetedithost, $strmnetedithost, false);
}
echo $OUTPUT->render(mnet_get_deprecation_notice());
print_tabs(array($tabs), $currenttab);

View File

@ -1,5 +1,6 @@
<?php
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
?>
<div id="trustedhosts"><!-- See theme/standard/styles_layout.css #trustedhosts .generaltable for rules -->
<table cellspacing="0" cellpadding="5" class="generaltable generalbox" >

View File

@ -285,6 +285,7 @@ class core_admin_renderer extends plugin_renderer_base {
* @param bool $showcampaigncontent Whether the campaign content should be visible or not.
* @param bool $showfeedbackencouragement Whether the feedback encouragement content should be displayed or not.
* @param bool $showservicesandsupport Whether the services and support content should be displayed or not.
* @param string $xmlrpcwarning XML-RPC deprecation warning message.
*
* @return string HTML to output.
*/
@ -293,7 +294,8 @@ class core_admin_renderer extends plugin_renderer_base {
$buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0,
$themedesignermode = false, $devlibdir = false, $mobileconfigured = false,
$overridetossl = false, $invalidforgottenpasswordurl = false, $croninfrequent = false,
$showcampaigncontent = false, bool $showfeedbackencouragement = false, bool $showservicesandsupport = false) {
$showcampaigncontent = false, bool $showfeedbackencouragement = false, bool $showservicesandsupport = false,
$xmlrpcwarning = '') {
global $CFG;
$output = '';
@ -317,6 +319,7 @@ class core_admin_renderer extends plugin_renderer_base {
$output .= $this->registration_warning($registered);
$output .= $this->mobile_configuration_warning($mobileconfigured);
$output .= $this->forgotten_password_url_warning($invalidforgottenpasswordurl);
$output .= $this->mnet_deprecation_warning($xmlrpcwarning);
$output .= $this->userfeedback_encouragement($showfeedbackencouragement);
$output .= $this->services_and_support_content($showservicesandsupport);
$output .= $this->campaign_content($showcampaigncontent);
@ -2238,4 +2241,18 @@ class core_admin_renderer extends plugin_renderer_base {
return $output;
}
/**
* Display a warning about the deprecation of Mnet.
*
* @param string $xmlrpcwarning The warning message
* @return string HTML to output.
*/
protected function mnet_deprecation_warning($xmlrpcwarning) {
if (empty($xmlrpcwarning)) {
return '';
}
return $this->warning($xmlrpcwarning);
}
}

View File

@ -49,6 +49,8 @@ $ADMIN->add('mnet', new admin_externalpage('trustedhosts', new lang_string('trus
if (isset($CFG->mnet_dispatcher_mode) and $CFG->mnet_dispatcher_mode !== 'off') {
$profilefields = new admin_settingpage('mnetprofilefields', new lang_string('profilefields', 'mnet'),
'moodle/site:config');
$profilefields->add(new admin_setting_heading('mnetprofilefields/xmlrpcmnet', '',
$OUTPUT->render(mnet_get_deprecation_notice())));
$ADMIN->add('mnet', $profilefields);
$fields = mnet_profile_field_options();

View File

@ -27,6 +27,11 @@ defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
require_once($CFG->dirroot.'/lib/outputlib.php');
$notify = new \core\output\notification(get_string('xmlrpcmnetauthenticationenabled', 'admin'),
\core\output\notification::NOTIFY_WARNING);
$settings->add(new admin_setting_heading('auth_mnet/xmlrpcmnet', '',
$OUTPUT->render($notify)));
// Introductory explanation.
$settings->add(new admin_setting_heading('auth_mnet/pluginname', '',
new lang_string('auth_mnetdescription', 'auth_mnet')));

View File

@ -1523,6 +1523,10 @@ $string['warningiconvbuggy'] = 'Your version of the iconv library does not suppo
$string['webproxy'] = 'Web proxy';
$string['webproxyinfo'] = 'Fill in the following options if your Moodle server cannot access the internet directly. Internet access is required for the download of environment data, language packs, RSS feeds, timezones, etc.<br /><em>The PHP cURL extension is highly recommended.</em>';
$string['xmlrpcrecommended'] = 'The XMLRPC extension is useful for web services and Moodle networking.';
$string['xmlrpcmaharaenabled'] = 'It has been detected that the Mahara ePortfolio is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer supported by PHP.';
$string['xmlrpcmnetauthenticationenabled'] = 'It has been detected that the MNet authentication is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer supported by PHP.';
$string['xmlrpcmnetenabled'] = 'It has been detected that the Moodle Networking is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer supported by PHP.';
$string['xmlrpcwebserviceenabled'] = 'It has been detected that the XML-RPC Web Service protocol is enabled on your site. This feature relies on the PHP XML-RPC extension which is no longer supported by PHP.';
$string['yuicomboloading'] = 'YUI combo loading';
$string['ziprequired'] = 'The Zip PHP extension is now required by Moodle, info-ZIP binaries or PclZip library are not used anymore.';
$string['manageqbanks'] = 'Manage question bank plugins';

View File

@ -7138,6 +7138,11 @@ class admin_setting_manageauths extends admin_setting {
}
$return = $OUTPUT->heading(get_string('actauthhdr', 'auth'), 3, 'main');
if (in_array('mnet', $authsenabled)) {
$notify = new \core\output\notification(get_string('xmlrpcmnetauthenticationenabled', 'admin'),
\core\output\notification::NOTIFY_WARNING);
$return .= $OUTPUT->render($notify);
}
$return .= $OUTPUT->box_start('generalbox authsui');
$table = new html_table();
@ -10382,16 +10387,21 @@ class admin_setting_managewebserviceprotocols extends admin_setting {
$strversion = get_string('version');
$protocols_available = core_component::get_plugin_list('webservice');
$active_protocols = empty($CFG->webserviceprotocols) ? array() : explode(',', $CFG->webserviceprotocols);
$activeprotocols = empty($CFG->webserviceprotocols) ? array() : explode(',', $CFG->webserviceprotocols);
ksort($protocols_available);
foreach ($active_protocols as $key=>$protocol) {
foreach ($activeprotocols as $key => $protocol) {
if (empty($protocols_available[$protocol])) {
unset($active_protocols[$key]);
unset($activeprotocols[$key]);
}
}
$return = $OUTPUT->heading(get_string('actwebserviceshhdr', 'webservice'), 3, 'main');
if (in_array('xmlrpc', $activeprotocols)) {
$notify = new \core\output\notification(get_string('xmlrpcwebserviceenabled', 'admin'),
\core\output\notification::NOTIFY_WARNING);
$return .= $OUTPUT->render($notify);
}
$return .= $OUTPUT->box_start('generalbox webservicesui');
$table = new html_table();
@ -10413,7 +10423,7 @@ class admin_setting_managewebserviceprotocols extends admin_setting {
$version = isset($plugin->version) ? $plugin->version : '';
// hide/show link
if (in_array($protocol, $active_protocols)) {
if (in_array($protocol, $activeprotocols)) {
$hideshow = "<a href=\"$url&amp;action=disable&amp;webservice=$protocol\">";
$hideshow .= $OUTPUT->pix_icon('t/hide', $strdisable) . '</a>';
$displayname = "<span>$name</span>";

View File

@ -1526,4 +1526,97 @@ class upgradelib_test extends advanced_testcase {
$this->assertEquals('admin_dir_usage', $result->getInfo());
$this->assertFalse($result->getStatus());
}
/**
* Test the check_xmlrpc_usage check when the XML-RPC web service method is not set.
*
* @return void
*/
public function test_check_xmlrpc_webservice_is_not_set(): void {
global $CFG;
$this->resetAfterTest();
$result = new environment_results('custom_checks');
$this->assertNull(check_xmlrpc_usage($result));
$CFG->webserviceprotocols = 'rest';
$result = new environment_results('custom_checks');
$this->assertNull(check_xmlrpc_usage($result));
}
/**
* Test the check_xmlrpc_usage check when the XML-RPC web service method is set.
*
* @return void
*/
public function test_check_xmlrpc_webservice_is_set(): void {
global $CFG;
$this->resetAfterTest();
$CFG->webserviceprotocols = 'xmlrpc,rest';
$result = new environment_results('custom_checks');
$this->assertInstanceOf(environment_results::class, check_xmlrpc_usage($result));
$this->assertEquals('xmlrpc_webservice_usage', $result->getInfo());
$this->assertFalse($result->getStatus());
}
/**
* Test the check_xmlrpc_usage check when the MNet is turned on but no host was set up.
*
* @return void
*/
public function test_check_xmlrpc_mnet_host_is_not_set(): void {
global $CFG;
$this->resetAfterTest();
$CFG->mnet_dispatcher_mode = 'strict';
$result = new environment_results('custom_checks');
$this->assertNull(check_xmlrpc_usage($result));
}
/**
* Test the check_xmlrpc_usage check when the MNet is turned on and the host was set up.
*
* @return void
*/
public function test_check_xmlrpc_mnet_host_is_set(): void {
global $CFG, $DB;
$this->resetAfterTest();
$CFG->mnet_dispatcher_mode = 'strict';
// Add a mnet host.
$mnethost = new stdClass();
$mnethost->name = 'A mnet host';
$mnethost->public_key = 'A random public key!';
$mnethost->id = $DB->insert_record('mnet_host', $mnethost);
$result = new environment_results('custom_checks');
$this->assertInstanceOf(environment_results::class, check_xmlrpc_usage($result));
$this->assertEquals('xmlrpc_mnet_usage', $result->getInfo());
$this->assertFalse($result->getStatus());
}
/**
* Test the check_xmlrpc_usage check when the MNet is turned on and the Mahara portfolios was set up.
*
* @return void
*/
public function test_check_xmlrpc_mahara_portfolios_is_set(): void {
global $CFG;
$this->resetAfterTest();
$CFG->mnet_dispatcher_mode = 'strict';
// Enable the Mahara portfolios.
\core\plugininfo\portfolio::enable_plugin('mahara', 1);
$result = new environment_results('custom_checks');
$this->assertInstanceOf(environment_results::class, check_xmlrpc_usage($result));
$this->assertEquals('xmlrpc_mahara_usage', $result->getInfo());
$this->assertFalse($result->getStatus());
}
}

View File

@ -2732,3 +2732,55 @@ function check_admin_dir_usage(environment_results $result): ?environment_result
return $result;
}
/**
* Check whether the XML-RPC protocol is enabled and warn if so.
*
* The XML-RPC protocol will be removed in a future version (4.1) as it is no longer supported by PHP.
*
* See MDL-70889 for further information.
*
* @param environment_results $result
* @return null|environment_results
*/
function check_xmlrpc_usage(environment_results $result): ?environment_results {
global $CFG;
// Checking Web Service protocols.
if (!empty($CFG->webserviceprotocols)) {
$plugins = array_flip(explode(',', $CFG->webserviceprotocols));
if (array_key_exists('xmlrpc', $plugins)) {
$result->setInfo('xmlrpc_webservice_usage');
$result->setFeedbackStr('xmlrpcwebserviceenabled');
return $result;
}
}
if (isset($CFG->mnet_dispatcher_mode) && $CFG->mnet_dispatcher_mode == 'strict') {
// Checking Mnet hosts.
$mnethosts = mnet_get_hosts();
if ($mnethosts) {
$actualhost = 0;
foreach ($mnethosts as $mnethost) {
if ($mnethost->id != $CFG->mnet_all_hosts_id) {
$actualhost++;
}
}
if ($actualhost > 0) {
$result->setInfo('xmlrpc_mnet_usage');
$result->setFeedbackStr('xmlrpcmnetenabled');
return $result;
}
}
// Checking Mahara.
$portfolios = \core\plugininfo\portfolio::get_enabled_plugins();
if (array_key_exists('mahara', $portfolios)) {
$result->setInfo('xmlrpc_mahara_usage');
$result->setFeedbackStr('xmlrpcmaharaenabled');
return $result;
}
}
return null;
}

View File

@ -145,7 +145,10 @@ class mnet_environment {
set_config('openssl', implode('@@@@@@@@', $this->keypair), 'mnet');
$DB->update_record('mnet_host', $this);
error_log('New public key has been generated. It expires ' . date('Y/m/d h:i:s', $this->public_key_expires));
if (!PHPUNIT_TEST) {
// We don't want to output this log for PHPUnit since it will make the test to fail as risky.
error_log('New public key has been generated. It expires ' . date('Y/m/d h:i:s', $this->public_key_expires));
}
}
function get_private_key() {

View File

@ -924,3 +924,15 @@ function mnet_strip_user($user, $fields) {
}
return $user;
}
/**
* Return the deprecation notice of the Mnet.
*
* @return \core\output\notification
*/
function mnet_get_deprecation_notice(): \core\output\notification {
$notice = new \core\output\notification(get_string('xmlrpcmnetenabled', 'admin'),
\core\output\notification::NOTIFY_WARNING);
return $notice;
}

View File

@ -32,6 +32,7 @@ admin_externalpage_setup('mnetenrol');
$service = mnetservice_enrol::get_instance();
echo $OUTPUT->header();
echo $OUTPUT->render(mnet_get_deprecation_notice());
echo $OUTPUT->heading_with_help(get_string('clientname', 'mnetservice_enrol'), 'clientname', 'mnetservice_enrol');
if (!$service->is_available()) {