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
 * LTI web service endpoints
19
 *
20
 * @package mod_lti
21
 * @copyright  Copyright (c) 2011 Moodlerooms Inc. (http://www.moodlerooms.com)
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 * @author     Chris Scribner
24
 */
25
 
26
define('NO_DEBUG_DISPLAY', true);
27
define('NO_MOODLE_COOKIES', true);
28
 
29
require_once(__DIR__ . "/../../config.php");
30
require_once($CFG->dirroot.'/mod/lti/locallib.php');
31
require_once($CFG->dirroot.'/mod/lti/servicelib.php');
32
 
33
// TODO: Switch to core oauthlib once implemented - MDL-30149.
34
use mod_lti\service_exception_handler;
35
use moodle\mod\lti as lti;
36
use ltiservice_basicoutcomes\local\service\basicoutcomes;
37
 
38
$rawbody = file_get_contents("php://input");
39
 
40
$logrequests  = lti_should_log_request($rawbody);
41
$errorhandler = new service_exception_handler($logrequests);
42
 
43
// Register our own error handler so we can always send valid XML response.
44
set_exception_handler(array($errorhandler, 'handle'));
45
 
46
if ($logrequests) {
47
    lti_log_request($rawbody);
48
}
49
 
50
$ok = true;
51
$type = null;
52
$toolproxy = false;
53
 
54
$consumerkey = lti\get_oauth_key_from_headers(null, array(basicoutcomes::SCOPE_BASIC_OUTCOMES));
55
if ($consumerkey === false) {
56
    throw new Exception('Missing or invalid consumer key or access token.');
57
} else if (is_string($consumerkey)) {
58
    $toolproxy = lti_get_tool_proxy_from_guid($consumerkey);
59
    if ($toolproxy !== false) {
60
        $secrets = array($toolproxy->secret);
61
    } else if (!empty($tool)) {
62
        $secrets = array($typeconfig['password']);
63
    } else {
64
        $secrets = lti_get_shared_secrets_by_key($consumerkey);
65
    }
66
    $sharedsecret = lti_verify_message($consumerkey, lti_get_shared_secrets_by_key($consumerkey), $rawbody);
67
    if ($sharedsecret === false) {
68
        throw new Exception('Message signature not valid');
69
    }
70
}
71
 
72
// TODO MDL-46023 Replace this code with a call to the new library.
73
$xml = simplexml_load_string($rawbody);
74
if (!$xml) {
75
    throw new Exception('Invalid XML content');
76
}
77
 
78
$body = $xml->imsx_POXBody;
79
foreach ($body->children() as $child) {
80
    $messagetype = $child->getName();
81
}
82
 
83
// We know more about the message, update error handler to send better errors.
84
$errorhandler->set_message_id(lti_parse_message_id($xml));
85
$errorhandler->set_message_type($messagetype);
86
 
87
switch ($messagetype) {
88
    case 'replaceResultRequest':
89
        $parsed = lti_parse_grade_replace_message($xml);
90
 
91
        $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid));
92
 
93
        if (!lti_accepts_grades($ltiinstance)) {
94
            throw new Exception('Tool does not accept grades');
95
        }
96
 
97
        lti_verify_sourcedid($ltiinstance, $parsed);
98
        lti_set_session_user($parsed->userid);
99
 
100
        $gradestatus = lti_update_grade($ltiinstance, $parsed->userid, $parsed->launchid, $parsed->gradeval);
101
 
102
        if (!$gradestatus) {
103
            throw new Exception('Grade replace response');
104
        }
105
 
106
        $responsexml = lti_get_response_xml(
107
                'success',
108
                'Grade replace response',
109
                $parsed->messageid,
110
                'replaceResultResponse'
111
        );
112
 
113
        echo $responsexml->asXML();
114
 
115
        break;
116
 
117
    case 'readResultRequest':
118
        $parsed = lti_parse_grade_read_message($xml);
119
 
120
        $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid));
121
 
122
        if (!lti_accepts_grades($ltiinstance)) {
123
            throw new Exception('Tool does not accept grades');
124
        }
125
 
126
        // Getting the grade requires the context is set.
127
        $context = context_course::instance($ltiinstance->course);
128
        $PAGE->set_context($context);
129
 
130
        lti_verify_sourcedid($ltiinstance, $parsed);
131
 
132
        $grade = lti_read_grade($ltiinstance, $parsed->userid);
133
 
134
        $responsexml = lti_get_response_xml(
135
                'success',  // Empty grade is also 'success'.
136
                'Result read',
137
                $parsed->messageid,
138
                'readResultResponse'
139
        );
140
 
141
        $node = $responsexml->imsx_POXBody->readResultResponse;
142
        $node = $node->addChild('result')->addChild('resultScore');
143
        $node->addChild('language', 'en');
144
        $node->addChild('textString', isset($grade) ? $grade : '');
145
 
146
        echo $responsexml->asXML();
147
 
148
        break;
149
 
150
    case 'deleteResultRequest':
151
        $parsed = lti_parse_grade_delete_message($xml);
152
 
153
        $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid));
154
 
155
        if (!lti_accepts_grades($ltiinstance)) {
156
            throw new Exception('Tool does not accept grades');
157
        }
158
 
159
        lti_verify_sourcedid($ltiinstance, $parsed);
160
        lti_set_session_user($parsed->userid);
161
 
162
        $gradestatus = lti_delete_grade($ltiinstance, $parsed->userid);
163
 
164
        if (!$gradestatus) {
165
            throw new Exception('Grade delete request');
166
        }
167
 
168
        $responsexml = lti_get_response_xml(
169
                'success',
170
                'Grade delete request',
171
                $parsed->messageid,
172
                'deleteResultResponse'
173
        );
174
 
175
        echo $responsexml->asXML();
176
 
177
        break;
178
 
179
    default:
180
        // Fire an event if we get a web service request which we don't support directly.
181
        // This will allow others to extend the LTI services, which I expect to be a common
182
        // use case, at least until the spec matures.
183
        $data = new stdClass();
184
        $data->body = $rawbody;
185
        $data->xml = $xml;
186
        $data->messageid = lti_parse_message_id($xml);
187
        $data->messagetype = $messagetype;
188
        $data->consumerkey = $consumerkey;
189
        $data->sharedsecret = $sharedsecret;
190
        $eventdata = array();
191
        $eventdata['other'] = array();
192
        $eventdata['other']['messageid'] = $data->messageid;
193
        $eventdata['other']['messagetype'] = $messagetype;
194
        $eventdata['other']['consumerkey'] = $consumerkey;
195
 
196
        // Before firing the event, allow subplugins a chance to handle.
197
        if (lti_extend_lti_services($data)) {
198
            break;
199
        }
200
 
201
        // If an event handler handles the web service, it should set this global to true
202
        // So this code knows whether to send an "operation not supported" or not.
203
        global $ltiwebservicehandled;
204
        $ltiwebservicehandled = false;
205
 
206
        try {
207
            $event = \mod_lti\event\unknown_service_api_called::create($eventdata);
208
            $event->set_message_data($data);
209
            $event->trigger();
210
        } catch (Exception $e) {
211
            $ltiwebservicehandled = false;
212
        }
213
 
214
        if (!$ltiwebservicehandled) {
215
            $responsexml = lti_get_response_xml(
216
                'unsupported',
217
                'unsupported',
218
                 lti_parse_message_id($xml),
219
                 $messagetype
220
            );
221
 
222
            echo $responsexml->asXML();
223
        }
224
 
225
        break;
226
}