PageRenderTime 37ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/mod/bigbluebuttonbn/classes/local/proxy/proxy_base.php

https://github.com/mackensen/moodle
PHP | 152 lines | 73 code | 11 blank | 68 comment | 15 complexity | 5e606080e791f59518aa3c17c6dc3ede MD5 | raw file
  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. namespace mod_bigbluebuttonbn\local\proxy;
  17. use mod_bigbluebuttonbn\local\config;
  18. use mod_bigbluebuttonbn\local\exceptions\bigbluebutton_exception;
  19. use mod_bigbluebuttonbn\local\exceptions\server_not_available_exception;
  20. use mod_bigbluebuttonbn\plugin;
  21. use moodle_url;
  22. use SimpleXMLElement;
  23. /**
  24. * The abstract proxy base class.
  25. *
  26. * This class provides common and shared functions used when interacting with
  27. * the BigBlueButton API server.
  28. *
  29. * @package mod_bigbluebuttonbn
  30. * @copyright 2010 onwards, Blindside Networks Inc
  31. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32. * @author Jesus Federico (jesus [at] blindsidenetworks [dt] com)
  33. */
  34. abstract class proxy_base {
  35. /**
  36. * Sometimes the server sends back some error and errorKeys that
  37. * can be converted to Moodle error messages
  38. */
  39. const MEETING_ERROR = [
  40. 'checksumError' => 'index_error_checksum',
  41. 'notFound' => 'general_error_not_found',
  42. 'maxConcurrent' => 'view_error_max_concurrent',
  43. ];
  44. /**
  45. * Returns the right URL for the action specified.
  46. *
  47. * @param string $action
  48. * @param array $data
  49. * @param array $metadata
  50. * @return string
  51. */
  52. protected static function action_url(string $action = '', array $data = [], array $metadata = []): string {
  53. $baseurl = self::sanitized_url() . $action . '?';
  54. $metadata = array_combine(array_map(function($k) {
  55. return 'meta_' . $k;
  56. }, array_keys($metadata)), $metadata);
  57. $params = http_build_query($data + $metadata, '', '&');
  58. return $baseurl . $params . '&checksum=' . sha1($action . $params . self::sanitized_secret());
  59. }
  60. /**
  61. * Makes sure the url used doesn't is in the format required.
  62. *
  63. * @return string
  64. */
  65. protected static function sanitized_url() {
  66. $serverurl = trim(config::get('server_url'));
  67. if (PHPUNIT_TEST) {
  68. $serverurl = (new moodle_url(TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER))->out(false);
  69. }
  70. if (substr($serverurl, -1) == '/') {
  71. $serverurl = rtrim($serverurl, '/');
  72. }
  73. if (substr($serverurl, -4) == '/api') {
  74. $serverurl = rtrim($serverurl, '/api');
  75. }
  76. return $serverurl . '/api/';
  77. }
  78. /**
  79. * Makes sure the shared_secret used doesn't have trailing white characters.
  80. *
  81. * @return string
  82. */
  83. protected static function sanitized_secret(): string {
  84. return trim(config::get('shared_secret'));
  85. }
  86. /**
  87. * Throw an exception if there is a problem in the returned XML value
  88. *
  89. * @param SimpleXMLElement|bool $xml
  90. * @param array|null $additionaldetails
  91. * @throws bigbluebutton_exception
  92. * @throws server_not_available_exception
  93. */
  94. protected static function assert_returned_xml($xml, ?array $additionaldetails = null): void {
  95. if (empty($xml)) {
  96. throw new server_not_available_exception(
  97. 'general_error_no_answer',
  98. plugin::COMPONENT,
  99. (new moodle_url('/admin/settings.php?section=modsettingbigbluebuttonbn'))->out()
  100. );
  101. }
  102. if (is_bool($xml) && $xml) {
  103. // Nothing to do here, this might be a post returning that everything went well.
  104. return;
  105. }
  106. if ((string) $xml->returncode == 'FAILED') {
  107. $messagekey = (string) $xml->messageKey ?? '';
  108. if (!$additionaldetails) {
  109. $additionaldetails = [];
  110. }
  111. $additionaldetails['xmlmessage'] = (string) $xml->message ?? '';
  112. if (empty($messagekey) || empty(self::MEETING_ERROR[$messagekey])) {
  113. $messagekey = 'general_error_unable_connect';
  114. }
  115. throw new bigbluebutton_exception($messagekey, json_encode($additionaldetails));
  116. }
  117. }
  118. /**
  119. * Fetch the XML from an endpoint and test for success.
  120. *
  121. * If the result could not be loaded, or the returncode was not 'SUCCESS', a null value is returned.
  122. *
  123. * @param string $action
  124. * @param array $data
  125. * @param array $metadata
  126. * @return null|bool|SimpleXMLElement
  127. */
  128. protected static function fetch_endpoint_xml(
  129. string $action,
  130. array $data = [],
  131. array $metadata = []
  132. ) {
  133. if (PHPUNIT_TEST && !defined('TEST_MOD_BIGBLUEBUTTONBN_MOCK_SERVER')) {
  134. return true; // In case we still use fetch and mock server is not defined, this prevents
  135. // an error. This can happen if a function from lib.php is called in test from other modules
  136. // for example.
  137. }
  138. $curl = new curl();
  139. return $curl->get(self::action_url($action, $data, $metadata));
  140. }
  141. }