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