MDL-20534 lti: A4, add some todos towards unified Oauth
[moodle.git] / mod / lti / service.php
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/>.
17 /**
18  * MRTODO: Brief description of this file
19  *
20  * @package    mod
21  * @subpackage lti
22  * @copyright  2011 onwards MRTODO
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 require_once(dirname(__FILE__) . "/../../config.php");
27 require_once($CFG->dirroot.'/mod/lti/locallib.php');
28 require_once($CFG->dirroot.'/mod/lti/servicelib.php');
30 // TODO: Switch to core oauthlib once implemented - MDL-30149
31 use moodle\mod\lti as lti;
33 $rawbody = file_get_contents("php://input");
35 foreach (getallheaders() as $name => $value) {
36     if ($name === 'Authorization') {
37         // TODO: Switch to core oauthlib once implemented - MDL-30149
38         $oauthparams = lti\OAuthUtil::split_header($value);
40         $consumerkey = $oauthparams['oauth_consumer_key'];
41         break;
42     }
43 }
45 if (empty($consumerkey)) {
46     throw new Exception('Consumer key is missing.');
47 }
49 $sharedsecret = lti_verify_message($consumerkey, lti_get_shared_secrets_by_key($consumerkey), $rawbody);
51 if ($sharedsecret === false) {
52     throw new Exception('Message signature not valid');
53 }
55 $xml = new SimpleXMLElement($rawbody);
57 $body = $xml->imsx_POXBody;
58 foreach ($body->children() as $child) {
59     $messagetype = $child->getName();
60 }
62 switch ($messagetype) {
63     case 'replaceResultRequest':
64         $parsed = lti_parse_grade_replace_message($xml);
66         $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid));
68         lti_verify_sourcedid($ltiinstance, $parsed);
70         $gradestatus = lti_update_grade($ltiinstance, $parsed->userid, $parsed->launchid, $parsed->gradeval);
72         $responsexml = lti_get_response_xml(
73                 $gradestatus ? 'success' : 'error',
74                 'Grade replace response',
75                 $parsed->messageid,
76                 'replaceResultResponse'
77         );
79         echo $responsexml->asXML();
81         break;
83     case 'readResultRequest':
84         $parsed = lti_parse_grade_read_message($xml);
86         $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid));
88         //Getting the grade requires the context is set
89         $context = get_context_instance(CONTEXT_COURSE, $ltiinstance->course);
90         $PAGE->set_context($context);
92         lti_verify_sourcedid($ltiinstance, $parsed);
94         $grade = lti_read_grade($ltiinstance, $parsed->userid);
96         $responsexml = lti_get_response_xml(
97                 isset($grade) ? 'success' : 'error',
98                 'Result read',
99                 $parsed->messageid,
100                 'readResultResponse'
101         );
103         $node = $responsexml->imsx_POXBody->readResultResponse;
104         $node->addChild('result')->addChild('resultScore')->addChild('textString', isset($grade) ? $grade : '');
106         echo $responsexml->asXML();
108         break;
110     case 'deleteResultRequest':
111         $parsed = lti_parse_grade_delete_message($xml);
113         $ltiinstance = $DB->get_record('lti', array('id' => $parsed->instanceid));
115         lti_verify_sourcedid($ltiinstance, $parsed);
117         $gradestatus = lti_delete_grade($ltiinstance, $parsed->userid);
119         $responsexml = lti_get_response_xml(
120                 $gradestatus ? 'success' : 'error',
121                 'Grade delete request',
122                 $parsed->messageid,
123                 'deleteResultResponse'
124         );
126         echo $responsexml->asXML();
128         break;
130     default:
131         //Fire an event if we get a web service request which we don't support directly.
132         //This will allow others to extend the LTI services, which I expect to be a common
133         //use case, at least until the spec matures.
134         $data = new stdClass();
135         $data->body = $rawbody;
136         $data->xml = $xml;
137         $data->messagetype = $messagetype;
138         $data->consumerkey = $consumerkey;
139         $data->sharedsecret = $sharedsecret;
141         //If an event handler handles the web service, it should set this global to true
142         //So this code knows whether to send an "operation not supported" or not.
143         global $lti_web_service_handled;
144         $lti_web_service_handled = false;
146         events_trigger('lti_unknown_service_api_call', $data);
148         if (!$lti_web_service_handled) {
149             $responsexml = lti_get_response_xml(
150                 'unsupported',
151                 'unsupported',
152                  lti_parse_message_id($xml),
153                  $messagetype
154             );
156             echo $responsexml->asXML();
157         }
159         break;
163 //echo print_r(apache_request_headers(), true);
165 //echo '<br />';
167 //echo file_get_contents("php://input");