Differences Between: [Versions 400 and 403] [Versions 401 and 403] [Versions 402 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace mod_bigbluebuttonbn\local\proxy; 18 19 use mod_bigbluebuttonbn\extension; 20 use mod_bigbluebuttonbn\local\config; 21 use mod_bigbluebuttonbn\local\exceptions\bigbluebutton_exception; 22 use mod_bigbluebuttonbn\local\exceptions\server_not_available_exception; 23 use mod_bigbluebuttonbn\plugin; 24 use moodle_url; 25 26 /** 27 * The abstract proxy base class. 28 * 29 * This class provides common and shared functions used when interacting with 30 * the BigBlueButton API server. 31 * 32 * @package mod_bigbluebuttonbn 33 * @copyright 2010 onwards, Blindside Networks Inc 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 * @author Jesus Federico (jesus [at] blindsidenetworks [dt] com) 36 */ 37 abstract class proxy_base { 38 39 /** 40 * Sometimes the server sends back some error and errorKeys that 41 * can be converted to Moodle error messages 42 */ 43 const BBB_TO_MOODLE_ERROR_CODE = [ 44 'checksumError' => 'index_error_checksum', 45 'notFound' => 'general_error_not_found', 46 'maxConcurrent' => 'view_error_max_concurrent', 47 ]; 48 49 /** 50 * Returns the right URL for the action specified. 51 * 52 * @param string $action 53 * @param array $data 54 * @param array $metadata 55 * @param int|null $instanceid 56 * @return string 57 */ 58 protected static function action_url( 59 string $action = '', 60 array $data = [], 61 array $metadata = [], 62 ?int $instanceid = null 63 ): string { 64 $baseurl = self::sanitized_url() . $action . '?'; 65 ['data' => $additionaldata, 'metadata' => $additionalmetadata] = 66 extension::action_url_addons($action, $data, $metadata, $instanceid); 67 $data = array_merge($data, $additionaldata ?? []); 68 $metadata = array_merge($metadata, $additionalmetadata ?? []); 69 70 $metadata = array_combine(array_map(function($k) { 71 return 'meta_' . $k; 72 }, array_keys($metadata)), $metadata); 73 $params = http_build_query($data + $metadata, '', '&'); 74 $checksum = self::get_checksum($action, $params); 75 return $baseurl . $params . '&checksum=' . $checksum; 76 } 77 78 /** 79 * Makes sure the url used doesn't is in the format required. 80 * 81 * @return string 82 */ 83 protected static function sanitized_url(): string { 84 $serverurl = trim(config::get('server_url')); 85 if (PHPUNIT_TEST) { 86 $serverurl = (new moodle_url(TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER))->out(false); 87 } 88 if (substr($serverurl, -1) == '/') { 89 $serverurl = rtrim($serverurl, '/'); 90 } 91 if (substr($serverurl, -4) == '/api') { 92 $serverurl = rtrim($serverurl, '/api'); 93 } 94 return $serverurl . '/api/'; 95 } 96 97 /** 98 * Makes sure the shared_secret used doesn't have trailing white characters. 99 * 100 * @return string 101 */ 102 protected static function sanitized_secret(): string { 103 return trim(config::get('shared_secret')); 104 } 105 106 /** 107 * Throw an exception if there is a problem in the returned XML value 108 * 109 * @param \SimpleXMLElement|bool $xml 110 * @param array|null $additionaldetails 111 * @throws bigbluebutton_exception 112 * @throws server_not_available_exception 113 */ 114 protected static function assert_returned_xml($xml, ?array $additionaldetails = null): void { 115 $messagekey = ''; 116 if (!empty($xml)) { 117 $messagekey = (string) ($xml->messageKey ?? ''); 118 } 119 if (empty($xml) || static::is_known_server_unavailable_errorcode($messagekey)) { 120 $errorcode = self::get_errorcode_from_xml_messagekey($messagekey); 121 throw new server_not_available_exception( 122 $errorcode, 123 plugin::COMPONENT, 124 (new moodle_url('/admin/settings.php?section=modsettingbigbluebuttonbn'))->out(), 125 ); 126 } 127 // If it is a checksum error, this is equivalent to the server not being available. 128 // So we treat it the same way as if there is not answer. 129 if (is_bool($xml) && $xml) { 130 // Nothing to do here, this might be a post returning that everything went well. 131 return; 132 } 133 if ((string) $xml->returncode == 'FAILED') { 134 $errorcode = self::get_errorcode_from_xml_messagekey($messagekey); 135 if (!$additionaldetails) { 136 $additionaldetails = []; 137 } 138 $additionaldetails['xmlmessage'] = (string) $xml->message ?? ''; 139 140 throw new bigbluebutton_exception($errorcode, json_encode($additionaldetails)); 141 } 142 } 143 144 /** 145 * Get Moodle error code from returned Message Key 146 * 147 * @param string $messagekey 148 * @return string 149 */ 150 private static function get_errorcode_from_xml_messagekey(string $messagekey): string { 151 $errorcode = 'general_error_no_answer'; 152 if ($messagekey) { 153 $errorcode = self::BBB_TO_MOODLE_ERROR_CODE[$messagekey] ?? $errorcode; 154 } 155 return $errorcode; 156 } 157 158 /** 159 * Get Moodle error code from returned Message Key 160 * 161 * @param string $messagekey 162 * @return string 163 */ 164 private static function is_known_server_unavailable_errorcode(string $messagekey): string { 165 // For now, only checksumError is supposed to mean that the server is unavailable. 166 // Other errors are recoverable. 167 return in_array($messagekey, ['checksumError']); 168 } 169 170 /** 171 * Fetch the XML from an endpoint and test for success. 172 * 173 * If the result could not be loaded, or the returncode was not 'SUCCESS', a null value is returned. 174 * 175 * @param string $action 176 * @param array $data 177 * @param array $metadata 178 * @param int|null $instanceid 179 * @return null|bool|\SimpleXMLElement 180 */ 181 protected static function fetch_endpoint_xml( 182 string $action, 183 array $data = [], 184 array $metadata = [], 185 ?int $instanceid = null 186 ) { 187 if (PHPUNIT_TEST && !defined('TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER')) { 188 return true; // In case we still use fetch and mock server is not defined, this prevents 189 // an error. This can happen if a function from lib.php is called in test from other modules 190 // for example. 191 } 192 $curl = new curl(); 193 return $curl->get(self::action_url($action, $data, $metadata, $instanceid)); 194 } 195 196 /** 197 * Get checksum 198 * 199 * @param string $action 200 * @param string $params 201 * @return string 202 */ 203 public static function get_checksum(string $action, string $params): string { 204 return hash(config::get('checksum_algorithm'), $action . $params . self::sanitized_secret()); 205 } 206 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body