From df227f38199fafbe25621b92cb6da856f9389d4b Mon Sep 17 00:00:00 2001 From: "Eloy Lafuente (stronk7)" Date: Fri, 21 Oct 2022 19:30:07 +0200 Subject: [PATCH] MDL-76052 webservice_xmlrpc: Remove it completely from core Normal removal procedure: - Remove the plugin completely from core. - Document it in the webservices upgrade.txt file. - Add a core upgrade step to proceed to remove any configuration if the plugin has not been re-installed manually. Plus: - Remove a few remaining uses in the hub/sites registration scripts, that were moved from xmlrpc to hand.made rest calls by MDL-31436 (Moodle 3.4.1 and up) and never removed then. - Remove the php-xmlrpc extension as a recommendation in composer. - Remove "xmlrpc" from various comments, trivial cleanup. Note: - While working on this MDL-76078 has been created about to fix a serious design problem detected (it does not affect functionality). That's out from this issue scope. --- composer.json | 1 - lib/classes/hub/api.php | 3 +- lib/classes/plugin_manager.php | 4 +- lib/classes/plugininfo/webservice.php | 4 - lib/db/upgrade.php | 26 ++ version.php | 2 +- webservice/lib.php | 2 +- webservice/upgrade.txt | 9 +- .../xmlrpc/classes/privacy/provider.php | 46 ---- webservice/xmlrpc/db/access.php | 36 --- .../xmlrpc/lang/en/webservice_xmlrpc.php | 29 --- webservice/xmlrpc/lib.php | 138 ----------- webservice/xmlrpc/locallib.php | 230 ------------------ webservice/xmlrpc/server.php | 57 ----- webservice/xmlrpc/simpleserver.php | 44 ---- .../xmlrpc/tests/fixtures/array_response.xml | 22 -- .../xmlrpc/tests/fixtures/fault_response.xml | 21 -- .../xmlrpc/tests/fixtures/value_response.xml | 10 - webservice/xmlrpc/tests/lib_test.php | 218 ----------------- webservice/xmlrpc/tests/locallib_test.php | 163 ------------- .../xmlrpc/tests/xmlrpc_server_test.php | 114 --------- webservice/xmlrpc/version.php | 30 --- 22 files changed, 38 insertions(+), 1171 deletions(-) delete mode 100644 webservice/xmlrpc/classes/privacy/provider.php delete mode 100644 webservice/xmlrpc/db/access.php delete mode 100644 webservice/xmlrpc/lang/en/webservice_xmlrpc.php delete mode 100644 webservice/xmlrpc/lib.php delete mode 100644 webservice/xmlrpc/locallib.php delete mode 100644 webservice/xmlrpc/server.php delete mode 100644 webservice/xmlrpc/simpleserver.php delete mode 100644 webservice/xmlrpc/tests/fixtures/array_response.xml delete mode 100644 webservice/xmlrpc/tests/fixtures/fault_response.xml delete mode 100644 webservice/xmlrpc/tests/fixtures/value_response.xml delete mode 100644 webservice/xmlrpc/tests/lib_test.php delete mode 100644 webservice/xmlrpc/tests/locallib_test.php delete mode 100644 webservice/xmlrpc/tests/xmlrpc_server_test.php delete mode 100644 webservice/xmlrpc/version.php diff --git a/composer.json b/composer.json index 15677c887e7..8168f7d3826 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,6 @@ "ext-sqlsrv": "Needed when Moodle uses MS SQL Server database.", "ext-oci8": "Needed when Moodle uses Oracle database.", "ext-tokenizer": "Enabling Tokenizer PHP extension is recommended, it improves Moodle Networking functionality.", - "ext-xmlrpc": "Enabling XMLRPC PHP extension is useful for web services and Moodle networking.", "ext-soap": "Enabling SOAP PHP extension is useful for web services and some plugins.", "ext-sodium": "Enabling Sodium PHP extension is recommended, it is used by Moodle encryption API.", "ext-exif": "Enabling Exif PHP extension is recommended, it is used by Moodle to parse image meta data." diff --git a/lib/classes/hub/api.php b/lib/classes/hub/api.php index 7f8979d93ab..1cf8bd95fa4 100644 --- a/lib/classes/hub/api.php +++ b/lib/classes/hub/api.php @@ -25,7 +25,6 @@ namespace core\hub; defined('MOODLE_INTERNAL') || die(); -use webservice_xmlrpc_client; use moodle_exception; use curl; use stdClass; @@ -370,4 +369,4 @@ class api { public static function upload_course_backup($hubcourseid, \stored_file $backupfile) { debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); } -} \ No newline at end of file +} diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index a78d0431346..243538161d3 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -1745,7 +1745,7 @@ class core_plugin_manager { 'binarius', 'boxxie', 'brick', 'canvas', 'formal_white', 'formfactor', 'fusion', 'leatherbound', 'magazine', 'mymobile', 'nimble', 'nonzero', 'overlay', 'serenity', 'sky_high', 'splash', 'standard', 'standardold'), - 'webservice' => array('amf'), + 'webservice' => array('amf', 'xmlrpc'), ); if (!isset($plugins[$type])) { @@ -2047,7 +2047,7 @@ class core_plugin_manager { ), 'webservice' => array( - 'rest', 'soap', 'xmlrpc' + 'rest', 'soap' ), 'workshopallocation' => array( diff --git a/lib/classes/plugininfo/webservice.php b/lib/classes/plugininfo/webservice.php index f898155cc6c..1c859cbbb28 100644 --- a/lib/classes/plugininfo/webservice.php +++ b/lib/classes/plugininfo/webservice.php @@ -116,10 +116,6 @@ class webservice extends base { } public function is_uninstall_allowed() { - // The xmlrpc plugin contains webservice_xmlrpc_client (used by core). - if ($this->name == 'xmlrpc') { - return false; - } return true; } } diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index a49de9f17b4..e9751c27541 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -3005,5 +3005,31 @@ privatefiles,moodle|/user/files.php'; upgrade_main_savepoint(true, 2022102800.01); } + if ($oldversion < 2022110600.00) { + // If webservice_xmlrpc isn't any longer installed, remove its configuration, + // capabilities and presence in other settings. + if (!file_exists($CFG->dirroot . '/webservice/xmlrpc/version.php')) { + // No DB structures to delete in this plugin. + + // Remove capabilities. + capabilities_cleanup('webservice_xmlrpc'); + + // Remove own configuration. + unset_all_config_for_plugin('webservice_xmlrpc'); + + // Remove it from the enabled protocols if it was there. + $protos = get_config('core', 'webserviceprotocols'); + $protoarr = explode(',', $protos); + $protoarr = array_filter($protoarr, function($ele) { + return trim($ele) !== 'xmlrpc'; + }); + $protos = implode(',', $protoarr); + set_config('webserviceprotocols', $protos); + } + + // Main savepoint reached. + upgrade_main_savepoint(true, 2022110600.00); + } + return true; } diff --git a/version.php b/version.php index 227a8c54c58..4329581c986 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2022110400.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2022110600.00; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '4.1dev+ (Build: 20221104)'; // Human-friendly version name diff --git a/webservice/lib.php b/webservice/lib.php index 5aa2aaddfed..8ed26c54409 100644 --- a/webservice/lib.php +++ b/webservice/lib.php @@ -898,7 +898,7 @@ class webservice_access_exception extends moodle_exception { /** * Check if a protocol is enabled * - * @param string $protocol name of WS protocol ('rest', 'soap', 'xmlrpc'...) + * @param string $protocol name of WS protocol ('rest', 'soap', ...) * @return bool true if the protocol is enabled */ function webservice_protocol_is_enabled($protocol) { diff --git a/webservice/upgrade.txt b/webservice/upgrade.txt index 2ce39cf58cf..8662cd753ed 100644 --- a/webservice/upgrade.txt +++ b/webservice/upgrade.txt @@ -3,10 +3,15 @@ information provided here is intended especially for developers. This information is intended for authors of webservices, not people writing webservice clients. +=== 4.1 === + +* The XMLRPC webservice (protocol) has been completely removed. It's now available in the plugins directory. + === 4.0 === -* User access related exceptions have been changed to use the moodle_exception class instead of the generic webservice_access_exception, - the main reason for this change is to allow clients to implement some code logic against an access error. +* User access related exceptions have been changed to use the moodle_exception class instead of the + generic webservice_access_exception, the main reason for this change is to allow clients to + implement some code logic against an access error. === 3.11 === diff --git a/webservice/xmlrpc/classes/privacy/provider.php b/webservice/xmlrpc/classes/privacy/provider.php deleted file mode 100644 index aeb67addf4b..00000000000 --- a/webservice/xmlrpc/classes/privacy/provider.php +++ /dev/null @@ -1,46 +0,0 @@ -. - -/** - * Privacy provider implementation for webservice_xmlrpc. - * - * @package webservice_xmlrpc - * @copyright 2018 Mihail Geshoski - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -namespace webservice_xmlrpc\privacy; - -defined('MOODLE_INTERNAL') || die(); - -/** - * Privacy provider implementation for webservice_xmlrpc. - * - * @copyright 2018 Mihail Geshoski - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class provider implements \core_privacy\local\metadata\null_provider { - - /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. - * - * @return string - */ - public static function get_reason() : string { - return 'privacy:metadata'; - } -} diff --git a/webservice/xmlrpc/db/access.php b/webservice/xmlrpc/db/access.php deleted file mode 100644 index 3f4f90e4a72..00000000000 --- a/webservice/xmlrpc/db/access.php +++ /dev/null @@ -1,36 +0,0 @@ -. - - -/** - * XML-RPC server related capabilities - * - * @package webservice_xmlrpc - * @category access - * @copyright 2009 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$capabilities = array( - - 'webservice/xmlrpc:use' => array( - 'captype' => 'read', // in fact this may be considered read and write at the same time - 'contextlevel' => CONTEXT_COURSE, // the context level should be probably CONTEXT_MODULE - 'archetypes' => array( - ), - ), - -); diff --git a/webservice/xmlrpc/lang/en/webservice_xmlrpc.php b/webservice/xmlrpc/lang/en/webservice_xmlrpc.php deleted file mode 100644 index bd0fe747892..00000000000 --- a/webservice/xmlrpc/lang/en/webservice_xmlrpc.php +++ /dev/null @@ -1,29 +0,0 @@ -. - - -/** - * Strings for component 'webservice_xmlrpc', language 'en', branch 'MOODLE_20_STABLE' - * - * @package webservice_xmlrpc - * @category string - * @copyright 2010 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -$string['pluginname'] = 'XML-RPC protocol'; -$string['privacy:metadata'] = 'The XML-RPC protocol plugin does not store any personal data.'; -$string['xmlrpc:use'] = 'Use XML-RPC protocol'; diff --git a/webservice/xmlrpc/lib.php b/webservice/xmlrpc/lib.php deleted file mode 100644 index dc3aef1c1d0..00000000000 --- a/webservice/xmlrpc/lib.php +++ /dev/null @@ -1,138 +0,0 @@ -. - -/** - * Moodle XML-RPC library - * - * @package webservice_xmlrpc - * @copyright 2009 Jerome Mouneyrac - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * Moodle XML-RPC client - * - * @package webservice_xmlrpc - * @copyright 2010 Jerome Mouneyrac - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class webservice_xmlrpc_client { - - /** @var moodle_url The XML-RPC server url. */ - protected $serverurl; - - /** @var string The token for the XML-RPC call. */ - protected $token; - - /** - * Constructor - * - * @param string $serverurl a Moodle URL - * @param string $token the token used to do the web service call - */ - public function __construct($serverurl, $token) { - $this->serverurl = new moodle_url($serverurl); - $this->token = $token; - } - - /** - * Set the token used to do the XML-RPC call - * - * @param string $token the token used to do the web service call - */ - public function set_token($token) { - $this->token = $token; - } - - /** - * Execute client WS request with token authentication - * - * @param string $functionname the function name - * @param array $params An associative array containing the the parameters of the function being called. - * @return mixed The decoded XML RPC response. - * @throws moodle_exception - */ - public function call($functionname, $params = array()) { - global $CFG; - require_once($CFG->libdir . '/filelib.php'); - - if ($this->token) { - $this->serverurl->param('wstoken', $this->token); - } - - $request = $this->encode_request($functionname, $params); - - // Set the headers. - $headers = array( - 'Content-Length' => strlen($request), - 'Content-Type' => 'text/xml; charset=utf-8', - 'Host' => $this->serverurl->get_host(), - 'User-Agent' => 'Moodle XML-RPC Client/1.0', - ); - - // Get the response. - $response = download_file_content($this->serverurl->out(false), $headers, $request); - - // Decode the response. - $result = $this->decode_response($response); - if (is_array($result) && xmlrpc_is_fault($result)) { - throw new Exception($result['faultString'], $result['faultCode']); - } - - return $result; - } - - /** - * Generates XML for a method request. - * - * @param string $functionname Name of the method to call. - * @param mixed $params Method parameters compatible with the method signature. - * @return string - */ - protected function encode_request($functionname, $params) { - - $outputoptions = array( - 'encoding' => 'utf-8', - 'escaping' => 'markup', - ); - - // See MDL-53962 - needed for backwards compatibility on <= 3.0. - $params = array_values($params); - - return xmlrpc_encode_request($functionname, $params, $outputoptions); - } - - /** - * Parses and decodes the response XML - * - * @param string $response - * @return array - */ - protected function decode_response($response) { - // XMLRPC server in Moodle encodes response using function xmlrpc_encode_request() with method==null - // see {@link webservice_xmlrpc_server::prepare_response()} . We should use xmlrpc_decode_request() for decoding too. - $method = null; - $encoding = null; - if (preg_match('/^<\?xml version="1.0" encoding="([^"]*)"\?>/', $response, $matches)) { - // Sometimes xmlrpc_decode_request() fails to recognise encoding, let's help it. - $encoding = $matches[1]; - } - $r = xmlrpc_decode_request($response, $method, $encoding); - return $r; - } -} diff --git a/webservice/xmlrpc/locallib.php b/webservice/xmlrpc/locallib.php deleted file mode 100644 index 92203e70eb0..00000000000 --- a/webservice/xmlrpc/locallib.php +++ /dev/null @@ -1,230 +0,0 @@ -. - - -/** - * XML-RPC web service implementation classes and methods. - * - * @package webservice_xmlrpc - * @copyright 2009 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require_once("$CFG->dirroot/webservice/lib.php"); - -/** - * XML-RPC service server implementation. - * - * @package webservice_xmlrpc - * @copyright 2009 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class webservice_xmlrpc_server extends webservice_base_server { - - /** @var string $response The XML-RPC response string. */ - private $response; - - /** - * Contructor - * - * @param string $authmethod authentication method of the web service (WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN, ...) - */ - public function __construct($authmethod) { - parent::__construct($authmethod); - $this->wsname = 'xmlrpc'; - } - - /** - * This method parses the request input, it needs to get: - * 1/ user authentication - username+password or token - * 2/ function name - * 3/ function parameters - */ - protected function parse_request() { - // Retrieve and clean the POST/GET parameters from the parameters specific to the server. - parent::set_web_service_call_settings(); - - if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { - $this->username = isset($_GET['wsusername']) ? $_GET['wsusername'] : null; - $this->password = isset($_GET['wspassword']) ? $_GET['wspassword'] : null; - } else { - $this->token = isset($_GET['wstoken']) ? $_GET['wstoken'] : null; - } - - // Get the XML-RPC request data. - $rawpostdata = $this->fetch_input_content(); - $methodname = null; - - // Decode the request to get the decoded parameters and the name of the method to be called. - $decodedparams = xmlrpc_decode_request($rawpostdata, $methodname, 'UTF-8'); - $methodinfo = external_api::external_function_info($methodname); - $methodparams = array_keys($methodinfo->parameters_desc->keys); - $methodvariables = []; - - // Add the decoded parameters to the methodvariables array. - if (is_array($decodedparams)) { - foreach ($decodedparams as $index => $param) { - // See MDL-53962 - XML-RPC requests will usually be sent as an array (as in, one with indicies). - // We need to use a bit of "magic" to add the correct index back. Zend used to do this for us. - $methodvariables[$methodparams[$index]] = $param; - } - } - - $this->functionname = $methodname; - $this->parameters = $methodvariables; - } - - /** - * Fetch content from the client. - * - * @return string - */ - protected function fetch_input_content() { - return file_get_contents('php://input'); - } - - /** - * Prepares the response. - */ - protected function prepare_response() { - try { - if (!empty($this->function->returns_desc)) { - $validatedvalues = external_api::clean_returnvalue($this->function->returns_desc, $this->returns); - $encodingoptions = array( - "encoding" => "UTF-8", - "verbosity" => "no_white_space", - // See MDL-54868. - "escaping" => ["markup"] - ); - // We can now convert the response to the requested XML-RPC format. - $this->response = xmlrpc_encode_request(null, $validatedvalues, $encodingoptions); - } - } catch (invalid_response_exception $ex) { - $this->response = $this->generate_error($ex); - } - } - - /** - * Send the result of function call to the WS client. - */ - protected function send_response() { - $this->prepare_response(); - $this->send_headers(); - echo $this->response; - } - - /** - * Send the error information to the WS client. - * - * @param Exception $ex - */ - protected function send_error($ex = null) { - $this->response = $this->generate_error($ex); - $this->send_headers(); - echo $this->response; - } - - /** - * Sends the headers for the XML-RPC response. - */ - protected function send_headers() { - // Standard headers. - header('HTTP/1.1 200 OK'); - header('Connection: close'); - header('Content-Length: ' . strlen($this->response)); - header('Content-Type: text/xml; charset=utf-8'); - header('Date: ' . gmdate('D, d M Y H:i:s', 0) . ' GMT'); - header('Server: Moodle XML-RPC Server/1.0'); - // Other headers. - header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0'); - header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT'); - header('Pragma: no-cache'); - header('Accept-Ranges: none'); - // Allow cross-origin requests only for Web Services. - // This allow to receive requests done by Web Workers or webapps in different domains. - header('Access-Control-Allow-Origin: *'); - } - - /** - * Generate the XML-RPC fault response. - * - * @param Exception|Throwable $ex The exception. - * @param int $faultcode The faultCode to be included in the fault response - * @return string The XML-RPC fault response xml containing the faultCode and faultString. - */ - protected function generate_error($ex, $faultcode = 404) { - $error = $ex->getMessage(); - - if (!empty($ex->errorcode)) { - // The faultCode must be an int, so we obtain a hash of the errorcode then get an integer value of the hash. - $faultcode = base_convert(md5($ex->errorcode), 16, 10); - - // We strip the $code to 8 digits (and hope for no error code collisions). - // Collisions should be pretty rare, and if needed the client can retrieve - // the accurate errorcode from the last | in the exception message. - $faultcode = substr($faultcode, 0, 8); - - // Add the debuginfo to the exception message if debuginfo must be returned. - if (debugging() and isset($ex->debuginfo)) { - $error .= ' | DEBUG INFO: ' . $ex->debuginfo . ' | ERRORCODE: ' . $ex->errorcode; - } else { - $error .= ' | ERRORCODE: ' . $ex->errorcode; - } - } - - $fault = array( - 'faultCode' => (int) $faultcode, - 'faultString' => $error - ); - - $encodingoptions = array( - "encoding" => "UTF-8", - "verbosity" => "no_white_space", - // See MDL-54868. - "escaping" => ["markup"] - ); - - return xmlrpc_encode_request(null, $fault, $encodingoptions); - } -} - -/** - * XML-RPC test client class - * - * @package webservice_xmlrpc - * @copyright 2009 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class webservice_xmlrpc_test_client implements webservice_test_client_interface { - /** - * Execute test client WS request - * @param string $serverurl server url (including token parameter or username/password parameters) - * @param string $function function name - * @param array $params parameters of the called function - * @return mixed - */ - public function simpletest($serverurl, $function, $params) { - global $CFG; - - $url = new moodle_url($serverurl); - $token = $url->get_param('wstoken'); - require_once($CFG->dirroot . '/webservice/xmlrpc/lib.php'); - $client = new webservice_xmlrpc_client($serverurl, $token); - return $client->call($function, $params); - } -} diff --git a/webservice/xmlrpc/server.php b/webservice/xmlrpc/server.php deleted file mode 100644 index 7c4efd555d7..00000000000 --- a/webservice/xmlrpc/server.php +++ /dev/null @@ -1,57 +0,0 @@ -. - - -/** - * XML-RPC web service entry point. The authentication is done via tokens. - * - * @package webservice_xmlrpc - * @copyright 2009 Jerome Mouneyrac - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * NO_DEBUG_DISPLAY - disable moodle specific debug messages and any errors in output - */ -define('NO_DEBUG_DISPLAY', true); - -define('WS_SERVER', true); - -require('../../config.php'); -require_once("$CFG->dirroot/webservice/xmlrpc/locallib.php"); - -if (!webservice_protocol_is_enabled('xmlrpc')) { - debugging('The server died because the web services or the XMLRPC protocol are not enable', - DEBUG_DEVELOPER); - die; -} - -$server = new webservice_xmlrpc_server(WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN); -$server->run(); -die; - -/** - * Raises Early WS Exception in XMLRPC format. - * - * @param Exception $ex Raised exception. - */ -function raise_early_ws_exception(Exception $ex): void { - global $CFG; - require_once("$CFG->dirroot/webservice/xmlrpc/locallib.php"); - $server = new webservice_xmlrpc_server(WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN); - $server->exception_handler($ex); -} - diff --git a/webservice/xmlrpc/simpleserver.php b/webservice/xmlrpc/simpleserver.php deleted file mode 100644 index b1f08557a35..00000000000 --- a/webservice/xmlrpc/simpleserver.php +++ /dev/null @@ -1,44 +0,0 @@ -. - - -/** - * XML-RPC web service entry point. The authentication is done via username/password. - * - * @package webservice_xmlrpc - * @copyright 2009 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * NO_DEBUG_DISPLAY - disable moodle specific debug messages and any errors in output - */ -define('NO_DEBUG_DISPLAY', true); - -define('WS_SERVER', true); - -require('../../config.php'); -require_once("$CFG->dirroot/webservice/xmlrpc/locallib.php"); - -if (!webservice_protocol_is_enabled('xmlrpc')) { - die; -} - -$server = new webservice_xmlrpc_server(WEBSERVICE_AUTHMETHOD_USERNAME); -$server->run(); -die; - - diff --git a/webservice/xmlrpc/tests/fixtures/array_response.xml b/webservice/xmlrpc/tests/fixtures/array_response.xml deleted file mode 100644 index fb44121e61e..00000000000 --- a/webservice/xmlrpc/tests/fixtures/array_response.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - 1 - - - Test string - - - 3.1416 - - - - - - - diff --git a/webservice/xmlrpc/tests/fixtures/fault_response.xml b/webservice/xmlrpc/tests/fixtures/fault_response.xml deleted file mode 100644 index ff90ff15814..00000000000 --- a/webservice/xmlrpc/tests/fixtures/fault_response.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - faultCode - - 23604497 - - - - faultString - - Can not find data record in database table external_functions. | DEBUG INFO: SELECT * FROM {external_functions} WHERE name = ? [array ( 0 => 'core_course_get_course', )] | ERRORCODE: invalidrecord - - - - - - diff --git a/webservice/xmlrpc/tests/fixtures/value_response.xml b/webservice/xmlrpc/tests/fixtures/value_response.xml deleted file mode 100644 index daa29c62b3b..00000000000 --- a/webservice/xmlrpc/tests/fixtures/value_response.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - 1 - - - - diff --git a/webservice/xmlrpc/tests/lib_test.php b/webservice/xmlrpc/tests/lib_test.php deleted file mode 100644 index be5d3c89610..00000000000 --- a/webservice/xmlrpc/tests/lib_test.php +++ /dev/null @@ -1,218 +0,0 @@ -. - -/** - * Unit tests for the XML-RPC web service. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2015 Jun Pataleta - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -namespace webservice_xmlrpc; - -defined('MOODLE_INTERNAL') || die(); - -global $CFG; -require_once($CFG->dirroot . '/webservice/xmlrpc/lib.php'); - -/** - * Unit tests for the XML-RPC web service. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2015 Jun Pataleta - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class lib_test extends \advanced_testcase { - - /** - * Setup. - */ - public function setUp(): void { - $this->resetAfterTest(); - - // All tests require xmlrpc. Skip tests, if xmlrpc is not installed. - if (!function_exists('xmlrpc_decode')) { - $this->markTestSkipped('XMLRPC is not installed.'); - } - } - - /** - * Test for array response. - */ - public function test_client_with_array_response() { - global $CFG; - - $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken'); - $mockresponse = file_get_contents($CFG->dirroot . '/webservice/xmlrpc/tests/fixtures/array_response.xml'); - $client->set_mock_response($mockresponse); - $result = $client->call('testfunction'); - $this->assertEquals(xmlrpc_decode($mockresponse), $result); - } - - /** - * Test for value response. - */ - public function test_client_with_value_response() { - global $CFG; - - $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken'); - $mockresponse = file_get_contents($CFG->dirroot . '/webservice/xmlrpc/tests/fixtures/value_response.xml'); - $client->set_mock_response($mockresponse); - $result = $client->call('testfunction'); - $this->assertEquals(xmlrpc_decode($mockresponse), $result); - } - - /** - * Test for fault response. - */ - public function test_client_with_fault_response() { - global $CFG; - - $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken'); - $mockresponse = file_get_contents($CFG->dirroot . '/webservice/xmlrpc/tests/fixtures/fault_response.xml'); - $client->set_mock_response($mockresponse); - $this->expectException('\moodle_exception'); - $client->call('testfunction'); - } - - /** - * Test the XML-RPC request encoding. - */ - public function test_encode_request() { - - $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken'); - - // Encode the request with the proper encoding and escaping options. - $xml = $client->encode_request('do_it', ['foo' => 'ŠČŘŽÝÁÍÉ']); - - // Assert that decoding with explicit encoding will work. This appeared - // to fail if the markup escaping was not set. - $this->assertEquals(['ŠČŘŽÝÁÍÉ'], xmlrpc_decode($xml, 'UTF-8')); - - // Decoding also works with our wrapper method. - $this->assertEquals(['ŠČŘŽÝÁÍÉ'], $client->decode_response($xml)); - - // Our experiments show that even with default/implicit encoding, - // requests encoded with markup escaping set are also decoded - // correctly. This is known to be used in some servers so we test it - // here, too. - // However, this does not work for all strings, see next test. - $this->assertEquals(['ŠČŘŽÝÁÍÉ'], xmlrpc_decode($xml)); - } - - /** - * Test the XML-RPC response decoding - */ - public function test_decode_response() { - $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken'); - - $teststring = 'Recherche thématique:Villes & Développement durable'; - - // Encode the string with the proper encoding and escaping options. Assert that decoding will work. - $xml = $client->encode_request('do_it', [$teststring]); - $this->assertEquals([$teststring], $client->decode_response($xml)); - // For this particular string bare decoding function does not work. - // It can't really be explained why it works for the string 'ŠČŘŽÝÁÍÉ' in the previous test but not this one. - // Symbol é comes as chr(233) . It looks like 'Recherche th�matique:Villes & D�veloppement durable'. - $this->assertEquals([preg_replace('/é/', chr(233), $teststring)], xmlrpc_decode($xml)); - - // Encode the string without any options (default encoding "iso-8859-1" is used). Assert that decoding will work. - $xml = xmlrpc_encode_request('do_it', [$teststring]); - $this->assertEquals([$teststring], $client->decode_response($xml)); - $this->assertEquals([$teststring], xmlrpc_decode($xml)); - - // Another example of the string where bare xmlrpc_decode() does not work but our wrapper does. - $teststring = 'Formación Docente'; - - $xml = $client->encode_request('do_it', [$teststring]); - $this->assertEquals([$teststring], $client->decode_response($xml)); - // Bare decoding function xmlrpc_decode() does not work. - // Symbol ó comes as chr(243), it looks like 'Formaci�n Docente'. - $this->assertEquals([preg_replace('/ó/', chr(243), $teststring)], xmlrpc_decode($xml)); - } -} - -/** - * Class webservice_xmlrpc_client_mock. - * - * Mock class that returns the processed XML-RPC response. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2015 Jun Pataleta - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class webservice_xmlrpc_client_mock extends \webservice_xmlrpc_client { - - /** @var string The mock XML-RPC response string. */ - private $mockresponse; - - /** - * XML-RPC mock response setter. - * - * @param string $mockresponse - */ - public function set_mock_response($mockresponse) { - $this->mockresponse = $mockresponse; - } - - /** - * Since the call method uses download_file_content and it is hard to make an actual call to a web service, - * we'll just have to simulate the receipt of the response from the server using the mock response so we - * can test the processing result of this method. - * - * @param string $functionname the function name - * @param array $params the parameters of the function - * @return mixed The decoded XML RPC response. - * @throws \moodle_exception - */ - public function call($functionname, $params = array()) { - // Get the response. - $response = $this->mockresponse; - - // This is the part of the code in webservice_xmlrpc_client::call() what we would like to test. - // Decode the response. - $result = xmlrpc_decode($response); - if (is_array($result) && xmlrpc_is_fault($result)) { - throw new \moodle_exception($result['faultString']); - } - - return $result; - } - - /** - * Allows to test the request encoding. - * - * @param string $functionname Name of the method to call. - * @param mixed $params Method parameters compatible with the method signature. - * @return string - */ - public function encode_request($functionname, $params) { - return parent::encode_request($functionname, $params); - } - - /** - * Allows to test the response decoding. - * - * @param string $response - * @return array - */ - public function decode_response($response) { - return parent::decode_response($response); - } -} diff --git a/webservice/xmlrpc/tests/locallib_test.php b/webservice/xmlrpc/tests/locallib_test.php deleted file mode 100644 index cba89d2e8f1..00000000000 --- a/webservice/xmlrpc/tests/locallib_test.php +++ /dev/null @@ -1,163 +0,0 @@ -. - -/** - * Unit tests for the XML-RPC web service server. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2016 Cameron Ball - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -namespace webservice_xmlrpc; - -defined('MOODLE_INTERNAL') || die(); - -global $CFG; -require_once($CFG->dirroot . '/webservice/xmlrpc/locallib.php'); - -/** - * Unit tests for the XML-RPC web service server. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2016 Cameron Ball - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class locallib_test extends \advanced_testcase { - - /** - * Setup. - */ - public function setUp(): void { - if (!function_exists('xmlrpc_decode')) { - $this->markTestSkipped('XMLRPC is not installed.'); - } - } - - /** - * Test that the response generated is correct - * - * There is a bug in PHP that causes the xml_rpc library to - * incorrectly escape multibyte characters. See https://bugs.php.net/bug.php?id=41650 - * - * @dataProvider prepare_response_provider - * @param string $returnsdesc Webservice function return description - * @param string $returns Webservice function description - * @param string $expected The expected XML-RPC response - */ - public function test_prepare_response($returnsdesc, $returns, $expected) { - $server = $this->getMockBuilder('webservice_xmlrpc_server') - ->disableOriginalConstructor() - ->onlyMethods([]) - ->getMock(); - - $rc = new \ReflectionClass('webservice_xmlrpc_server'); - $rcm = $rc->getMethod('prepare_response'); - $rcm->setAccessible(true); - - $func = $rc->getProperty('function'); - $func->setAccessible(true); - $func->setValue($server, (object) ['returns_desc' => new \external_value(PARAM_RAW, $returnsdesc, VALUE_OPTIONAL)]); - - $ret = $rc->getProperty('returns'); - $ret->setAccessible(true); - $ret->setValue($server, $returns); - - $rcm->invokeArgs($server, []); - $response = $rc->getProperty('response'); - $response->setAccessible(true); - - $this->assertEquals($expected, $response->getValue($server)); - } - - /** - * Test that the response generated is correct - * - * There is a bug in PHP that causes the xml_rpc library to - * incorrectly escape multibyte characters. See https://bugs.php.net/bug.php?id=41650 - * - * @dataProvider generate_error_provider - * @param Exception $exception An exception to be provided to generate_error - * @param string $code An error code to be provided to generate_error - * @param string $expected The expected XML-RPC response - */ - public function test_generate_error($exception, $code, $expected) { - $server = $this->getMockBuilder('webservice_xmlrpc_server') - ->disableOriginalConstructor() - ->onlyMethods([]) - ->getMock(); - - $rc = new \ReflectionClass('webservice_xmlrpc_server'); - $rcm = $rc->getMethod('generate_error'); - $rcm->setAccessible(true); - - if ($code === null) { - $result = $rcm->invokeArgs($server, [$exception]); - } else { - $result = $rcm->invokeArgs($server, [$exception, $code]); - } - $this->assertEquals($expected, $result); - } - - /** - * Data provider for the prepare_response testcase - * - * @return array of testcases - */ - public function prepare_response_provider() { - return [ - 'Description written with Latin script' => [ - 'Ennyn Durin, Aran Moria: pedo mellon a minno', - 'Mellon!', - 'Mellon!' - . '' - ], - 'Description with non-Latin glyphs' => [ - 'What biscuits do you have?', - // V Unicode 9! V. - '😂🤵😂 𝒪𝓃𝓁𝓎 𝓉𝒽𝑒 𝒻𝒾𝓃𝑒𝓈𝓉 𝐼𝓉𝒶𝓁𝒾𝒶𝓃 𝒷𝒾𝓈𝒸𝓊𝒾𝓉𝓈 😂🤵😂', - '' - . '😂🤵😂 𝒪𝓃𝓁𝓎 𝓉𝒽𝑒 𝒻𝒾𝓃𝑒𝓈𝓉 𝐼𝓉𝒶𝓁𝒾𝒶𝓃 𝒷𝒾𝓈𝒸𝓊𝒾𝓉𝓈 😂🤵😂' - ] - ]; - } - - /** - * Data provider for the generate_error testcase - * - * @return array of testcases - */ - public function generate_error_provider() { - return [ - 'Standard exception with default faultcode' => [ - new \Exception(), - null, - 'faultCode404faultString' - ], - 'Standard exception with default faultcode and exception content' => [ - new \Exception('PC LOAD LETTER'), - null, - 'faultCode404faultStringPC LOAD LETTER' - ], - 'Standard exception with really messed up non-Latin glyphs' => [ - new \Exception('P̫̬̳̫̓͊̇r̨͎̜ͧa͚̬̙̺͎̙ͬẏ͎̲̦̲e̶̞͎͙̻͐̉r͙̙ͮ̓̈ͧ̔̃ ̠ͨ́ͭ̎̎̇̿n̗̥̞͗o̼̖͛̂̒̿ͮ͘t̷̞͎̘̘̝̥̲͂̌ͭ ͕̹͚̪͖̖̊̆́̒ͫ̓̀fͤͦͭͥ͊ͩo̼̱̻̹͒̿͒u̡͕̞͕̜̠͕ͥͭ̈̄̈́͐ń̘̼̇͜d̸̰̻͎͉̱̰̥̿͒'), - null, - 'faultCode404faultStringP̫̬̳̫̓͊̇r̨͎̜ͧa͚̬̙̺͎̙ͬẏ͎̲̦̲e̶̞͎͙̻͐̉r͙̙ͮ̓̈ͧ̔̃ ̠ͨ́ͭ̎̎̇̿n̗̥̞͗o̼̖͛̂̒̿ͮ͘t̷̞͎̘̘̝̥̲͂̌ͭ ͕̹͚̪͖̖̊̆́̒ͫ̓̀fͤͦͭͥ͊ͩo̼̱̻̹͒̿͒u̡͕̞͕̜̠͕ͥͭ̈̄̈́͐ń̘̼̇͜d̸̰̻͎͉̱̰̥̿͒' - ] - ]; - } -} diff --git a/webservice/xmlrpc/tests/xmlrpc_server_test.php b/webservice/xmlrpc/tests/xmlrpc_server_test.php deleted file mode 100644 index 7e68074a291..00000000000 --- a/webservice/xmlrpc/tests/xmlrpc_server_test.php +++ /dev/null @@ -1,114 +0,0 @@ -. - -/** - * Unit tests for the XML-RPC web service server. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -global $CFG; -require_once($CFG->dirroot . '/webservice/xmlrpc/locallib.php'); - -/** - * Unit tests for the XML-RPC web service server. - * - * @package webservice_xmlrpc - * @category test - * @copyright 2016 Andrew Nicols - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class xmlrpc_server_test extends advanced_testcase { - - /** - * Setup. - */ - public function setUp(): void { - if (!function_exists('xmlrpc_decode')) { - $this->markTestSkipped('XMLRPC is not installed.'); - } - } - - /** - * Test parameter parsing. - * - * @dataProvider parse_request_provider - * @param string $input The XML-RPC request - * @param string $expectfunction The expected value for the function after decoding the request - * @param array $expectparams The expected value for the params after decoding the request - */ - public function test_parse_request($input, $expectfunction, $expectparams) { - $server = $this->getMockBuilder('\webservice_xmlrpc_server') - ->onlyMethods(['fetch_input_content']) - ->disableOriginalConstructor() - ->getMock(); - - $server->method('fetch_input_content') - ->willReturn($input); - - $rc = new \ReflectionClass('\webservice_xmlrpc_server'); - $rcm = $rc->getMethod('parse_request'); - $rcm->setAccessible(true); - $rcm->invoke($server); - - $rcp = $rc->getProperty('functionname'); - $rcp->setAccessible(true); - $this->assertEquals($expectfunction, $rcp->getValue($server)); - - $rcp = $rc->getProperty('parameters'); - $rcp->setAccessible(true); - $this->assertEquals($expectparams, $rcp->getValue($server)); - } - - /** - * Data provider for testing parse_request. - * - * @return array - */ - public function parse_request_provider() { - $xml = ''; - - // This valid webservice call has one required param ('component'), and one optional param ('lang'). - $validmethod = 'core_get_component_strings'; - $requiredparams = 'moodle'; - $allparams = 'moodleen' - . ''; - $requiredparamsnonlatin = 'ᛞᛁᛞᛃᛟᚢᚲᚾᛟᚹᛈᚺᛈᛋᚢᛈᛈᛟᚱᛏᛋᚢᛏᚠ8ᚡᚨᚱᛁᚨᛒᛚᛖᚾᚨᛗᛖᛋ'; - - return [ - 'Valid method, required params only' => [ - "{$xml}{$validmethod}{$requiredparams}", - 'core_get_component_strings', - ['component' => 'moodle'], - ], - 'Valid method, all params' => [ - "{$xml}{$validmethod}{$allparams}", - 'core_get_component_strings', - ['component' => 'moodle', 'lang' => 'en'], - ], - 'Valid method required params only (non Latin)' => [ - "{$xml}{$validmethod}{$requiredparamsnonlatin}", - 'core_get_component_strings', - ['component' => 'ᛞᛁᛞᛃᛟᚢᚲᚾᛟᚹᛈᚺᛈᛋᚢᛈᛈᛟᚱᛏᛋᚢᛏᚠ8ᚡᚨᚱᛁᚨᛒᛚᛖᚾᚨᛗᛖᛋ'], - ], - ]; - } -} diff --git a/webservice/xmlrpc/version.php b/webservice/xmlrpc/version.php deleted file mode 100644 index dd20d5ab6b8..00000000000 --- a/webservice/xmlrpc/version.php +++ /dev/null @@ -1,30 +0,0 @@ -. - - -/** - * Version details - * - * @package webservice_xmlrpc - * @copyright 2009 Petr Skodak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -$plugin->version = 2022041900; // The current plugin version (Date: YYYYMMDDXX). -$plugin->requires = 2022041200; // Requires this Moodle version. -$plugin->component = 'webservice_xmlrpc'; // Full name of the plugin (used for diagnostics)