Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 service_base
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
    abstract public 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
}