See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 402] [Versions 39 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 /** 18 * This file contains an abstract definition of an LTI resource 19 * 20 * @package mod_lti 21 * @copyright 2014 Vital Source Technologies http://vitalsource.com 22 * @author Stephen Vickers 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 27 namespace mod_lti\local\ltiservice; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once($CFG->dirroot . '/mod/lti/locallib.php'); 33 34 35 /** 36 * The mod_lti\local\ltiservice\resource_base class. 37 * 38 * @package mod_lti 39 * @since Moodle 2.8 40 * @copyright 2014 Vital Source Technologies http://vitalsource.com 41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 42 */ 43 abstract class resource_base { 44 45 /** HTTP Post method */ 46 const HTTP_POST = 'POST'; 47 /** HTTP Get method */ 48 const HTTP_GET = 'GET'; 49 /** HTTP Put method */ 50 const HTTP_PUT = 'PUT'; 51 /** HTTP Delete method */ 52 const HTTP_DELETE = 'DELETE'; 53 54 /** @var service_base Service associated with this resource. */ 55 private $service; 56 /** @var string Type for this resource. */ 57 protected $type; 58 /** @var string ID for this resource. */ 59 protected $id; 60 /** @var string Template for this resource. */ 61 protected $template; 62 /** @var array Custom parameter substitution variables associated with this resource. */ 63 protected $variables; 64 /** @var array Media types supported by this resource. */ 65 protected $formats; 66 /** @var array HTTP actions supported by this resource. */ 67 protected $methods; 68 /** @var array Template variables parsed from the resource template. */ 69 protected $params; 70 71 72 /** 73 * Class constructor. 74 * 75 * @param service_base $service Service instance 76 */ 77 public function __construct($service) { 78 79 $this->service = $service; 80 $this->type = 'RestService'; 81 $this->id = null; 82 $this->template = null; 83 $this->methods = array(); 84 $this->variables = array(); 85 $this->formats = array(); 86 $this->methods = array(); 87 $this->params = null; 88 89 } 90 91 /** 92 * Get the resource ID. 93 * 94 * @return string 95 */ 96 public function get_id() { 97 98 return $this->id; 99 100 } 101 102 /** 103 * Get the resource template. 104 * 105 * @return string 106 */ 107 public function get_template() { 108 109 return $this->template; 110 111 } 112 113 /** 114 * Get the resource path. 115 * 116 * @return string 117 */ 118 public function get_path() { 119 120 return $this->get_template(); 121 122 } 123 124 /** 125 * Get the resource type. 126 * 127 * @return string 128 */ 129 public function get_type() { 130 131 return $this->type; 132 133 } 134 135 /** 136 * Get the resource's service. 137 * 138 * @return mixed 139 */ 140 public function get_service() { 141 142 return $this->service; 143 144 } 145 146 /** 147 * Get the resource methods. 148 * 149 * @return array 150 */ 151 public function get_methods() { 152 153 return $this->methods; 154 155 } 156 157 /** 158 * Get the resource media types. 159 * 160 * @return array 161 */ 162 public function get_formats() { 163 164 return $this->formats; 165 166 } 167 168 /** 169 * Get the resource template variables. 170 * 171 * @return array 172 */ 173 public function get_variables() { 174 175 return $this->variables; 176 177 } 178 179 /** 180 * Get the resource fully qualified endpoint. 181 * 182 * @return string 183 */ 184 public function get_endpoint() { 185 186 $this->parse_template(); 187 $template = preg_replace('/[\(\)]/', '', $this->get_template()); 188 $url = $this->get_service()->get_service_path() . $template; 189 foreach ($this->params as $key => $value) { 190 $url = str_replace('{' . $key . '}', $value, $url); 191 } 192 $toolproxy = $this->get_service()->get_tool_proxy(); 193 if (!empty($toolproxy)) { 194 $url = str_replace('{config_type}', 'toolproxy', $url); 195 $url = str_replace('{tool_proxy_id}', $toolproxy->guid, $url); 196 } else { 197 $url = str_replace('{config_type}', 'tool', $url); 198 $url = str_replace('{tool_proxy_id}', $this->get_service()->get_type()->id, $url); 199 } 200 201 return $url; 202 203 } 204 205 /** 206 * Execute the request for this resource. 207 * 208 * @param response $response Response object for this request. 209 */ 210 public abstract function execute($response); 211 212 /** 213 * Check to make sure the request is valid. 214 * 215 * @param int $typeid The typeid we want to use 216 * @param string $body Body of HTTP request message 217 * @param string[] $scopes Array of scope(s) required for incoming request 218 * 219 * @return boolean 220 */ 221 public function check_tool($typeid, $body = null, $scopes = null) { 222 223 $ok = $this->get_service()->check_tool($typeid, $body, $scopes); 224 if ($ok) { 225 if ($this->get_service()->get_tool_proxy()) { 226 $toolproxyjson = $this->get_service()->get_tool_proxy()->toolproxy; 227 } 228 if (!empty($toolproxyjson)) { 229 // Check tool proxy to ensure service being requested is included. 230 $toolproxy = json_decode($toolproxyjson); 231 if (!empty($toolproxy) && isset($toolproxy->security_contract->tool_service)) { 232 $contexts = lti_get_contexts($toolproxy); 233 $tpservices = $toolproxy->security_contract->tool_service; 234 foreach ($tpservices as $service) { 235 $fqid = lti_get_fqid($contexts, $service->service); 236 $id = explode('#', $fqid, 2); 237 if ($this->get_id() === $id[1]) { 238 $ok = true; 239 break; 240 } 241 } 242 } 243 if (!$ok) { 244 debugging('Requested service not permitted: ' . $this->get_id(), DEBUG_DEVELOPER); 245 } 246 } else { 247 // Check that the scope required for the service request is included in those granted for the 248 // access token being used. 249 $permittedscopes = $this->get_service()->get_permitted_scopes(); 250 $ok = is_null($permittedscopes) || empty($scopes) || !empty(array_intersect($permittedscopes, $scopes)); 251 } 252 } 253 254 return $ok; 255 256 } 257 258 /** 259 * Check to make sure the request is valid. 260 * 261 * @param string $toolproxyguid Consumer key 262 * @param string $body Body of HTTP request message 263 * 264 * @return boolean 265 * @deprecated since Moodle 3.7 MDL-62599 - please do not use this function any more. 266 * @see resource_base::check_tool() 267 */ 268 public function check_tool_proxy($toolproxyguid, $body = null) { 269 270 debugging('check_tool_proxy() is deprecated to allow LTI 1 connections to support services. ' . 271 'Please use resource_base::check_tool() instead.', DEBUG_DEVELOPER); 272 $ok = false; 273 if ($this->get_service()->check_tool_proxy($toolproxyguid, $body)) { 274 $toolproxyjson = $this->get_service()->get_tool_proxy()->toolproxy; 275 if (empty($toolproxyjson)) { 276 $ok = true; 277 } else { 278 $toolproxy = json_decode($toolproxyjson); 279 if (!empty($toolproxy) && isset($toolproxy->security_contract->tool_service)) { 280 $contexts = lti_get_contexts($toolproxy); 281 $tpservices = $toolproxy->security_contract->tool_service; 282 foreach ($tpservices as $service) { 283 $fqid = lti_get_fqid($contexts, $service->service); 284 $id = explode('#', $fqid, 2); 285 if ($this->get_id() === $id[1]) { 286 $ok = true; 287 break; 288 } 289 } 290 } 291 if (!$ok) { 292 debugging('Requested service not included in tool proxy: ' . $this->get_id()); 293 } 294 } 295 } 296 297 return $ok; 298 299 } 300 301 /** 302 * Check to make sure the request is valid. 303 * 304 * @param int $typeid The typeid we want to use 305 * @param int $contextid The course we are at 306 * @param string $permissionrequested The permission to be checked 307 * @param string $body Body of HTTP request message 308 * 309 * @return boolean 310 * @deprecated since Moodle 3.7 MDL-62599 - please do not use this function any more. 311 * @see resource_base::check_tool() 312 */ 313 public function check_type($typeid, $contextid, $permissionrequested, $body = null) { 314 debugging('check_type() is deprecated to allow LTI 1 connections to support services. ' . 315 'Please use resource_base::check_tool() instead.', DEBUG_DEVELOPER); 316 $ok = false; 317 if ($this->get_service()->check_type($typeid, $contextid, $body)) { 318 $neededpermissions = $this->get_permissions($typeid); 319 foreach ($neededpermissions as $permission) { 320 if ($permission == $permissionrequested) { 321 $ok = true; 322 break; 323 } 324 } 325 if (!$ok) { 326 debugging('Requested service ' . $permissionrequested . ' not included in tool type: ' . $typeid, 327 DEBUG_DEVELOPER); 328 } 329 } 330 return $ok; 331 } 332 333 /** 334 * get permissions from the config of the tool for that resource 335 * 336 * @param int $ltitype Type of LTI 337 * @return array with the permissions related to this resource by the $ltitype or empty if none. 338 * @deprecated since Moodle 3.7 MDL-62599 - please do not use this function any more. 339 * @see resource_base::check_tool() 340 */ 341 public function get_permissions($ltitype) { 342 debugging('get_permissions() is deprecated to allow LTI 1 connections to support services. ' . 343 'Please use resource_base::check_tool() instead.', DEBUG_DEVELOPER); 344 return array(); 345 } 346 347 /** 348 * Parse a value for custom parameter substitution variables. 349 * 350 * @param string $value String to be parsed 351 * 352 * @return string 353 */ 354 public function parse_value($value) { 355 356 return $value; 357 358 } 359 360 /** 361 * Parse the template for variables. 362 * 363 * @return array 364 */ 365 protected function parse_template() { 366 367 if (empty($this->params)) { 368 $this->params = array(); 369 if (!empty($_SERVER['PATH_INFO'])) { 370 $path = explode('/', $_SERVER['PATH_INFO']); 371 $template = preg_replace('/\([0-9a-zA-Z_\-,\/]+\)/', '', $this->get_template()); 372 $parts = explode('/', $template); 373 for ($i = 0; $i < count($parts); $i++) { 374 if ((substr($parts[$i], 0, 1) == '{') && (substr($parts[$i], -1) == '}')) { 375 $value = ''; 376 if ($i < count($path)) { 377 $value = $path[$i]; 378 } 379 $this->params[substr($parts[$i], 1, -1)] = $value; 380 } 381 } 382 } 383 } 384 385 return $this->params; 386 387 } 388 389 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body