e5920d56585689b4d0b099fb0c9a495d6de9c5fb
[moodle.git] / mod / lti / OAuthBody.php
1 <?php
2 // This file is part of BasicLTI4Moodle
3 //
4 // BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability)
5 // consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web
6 // based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI
7 // specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS
8 // are already supporting or going to support BasicLTI. This project Implements the consumer
9 // for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas.
10 // BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem
11 // at the GESSI research group at UPC.
12 // SimpleLTI consumer for Moodle is an implementation of the early specification of LTI
13 // by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a
14 // Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier.
15 //
16 // BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis
17 // of the Universitat Politecnica de Catalunya http://www.upc.edu
18 // Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu
19 //
20 // OAuthBody.php is distributed under the MIT License
21 //
22 // The MIT License
23 //
24 // Copyright (c) 2007 Andy Smith
25 //
26 // Permission is hereby granted, free of charge, to any person obtaining a copy
27 // of this software and associated documentation files (the "Software"), to deal
28 // in the Software without restriction, including without limitation the rights
29 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30 // copies of the Software, and to permit persons to whom the Software is
31 // furnished to do so, subject to the following conditions:
32 //
33 // The above copyright notice and this permission notice shall be included in
34 // all copies or substantial portions of the Software.
35 //
36 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
42 // THE SOFTWARE.
43 //
44 // Moodle is free software: you can redistribute it and/or modify
45 // it under the terms of the GNU General Public License as published by
46 // the Free Software Foundation, either version 3 of the License, or
47 // (at your option) any later version.
48 //
49 // Moodle is distributed in the hope that it will be useful,
50 // but WITHOUT ANY WARRANTY; without even the implied warranty of
51 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52 // GNU General Public License for more details.
53 //
54 // You should have received a copy of the GNU General Public License
55 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
57 namespace moodle\mod\lti;//Using a namespace as the basicLTI module imports classes with the same names
59 defined('MOODLE_INTERNAL') || die;
61 require_once($CFG->dirroot . '/mod/lti/OAuth.php');
62 require_once($CFG->dirroot . '/mod/lti/TrivialStore.php');
64 function getOAuthKeyFromHeaders()
65 {
66     $request_headers = OAuthUtil::get_headers();
67     // print_r($request_headers);
69     if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
70         $header_parameters = OAuthUtil::split_header($request_headers['Authorization']);
72         // echo("HEADER PARMS=\n");
73         // print_r($header_parameters);
74         return $header_parameters['oauth_consumer_key'];
75     }
76     return false;
77 }
79 function handleOAuthBodyPOST($oauth_consumer_key, $oauth_consumer_secret, $body, $request_headers = null)
80 {
81     if($request_headers == null){
82         $request_headers = OAuthUtil::get_headers();
83     }
85     // Must reject application/x-www-form-urlencoded
86     if ($request_headers['Content-type'] == 'application/x-www-form-urlencoded' ) {
87         throw new Exception("OAuth request body signing must not use application/x-www-form-urlencoded");
88     }
90     if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
91         $header_parameters = OAuthUtil::split_header($request_headers['Authorization']);
93         // echo("HEADER PARMS=\n");
94         // print_r($header_parameters);
95         $oauth_body_hash = $header_parameters['oauth_body_hash'];
96         // echo("OBH=".$oauth_body_hash."\n");
97     }
99     if ( ! isset($oauth_body_hash)  ) {
100         throw new Exception("OAuth request body signing requires oauth_body_hash body");
101     }
103     // Verify the message signature
104     $store = new TrivialOAuthDataStore();
105     $store->add_consumer($oauth_consumer_key, $oauth_consumer_secret);
107     $server = new OAuthServer($store);
109     $method = new OAuthSignatureMethod_HMAC_SHA1();
110     $server->add_signature_method($method);
111     $request = OAuthRequest::from_request();
113     try {
114         $server->verify_request($request);
115     } catch (Exception $e) {
116         $message = $e->getMessage();
117         throw new Exception("OAuth signature failed: " . $message);
118     }
120     $postdata = $body;
121     // echo($postdata);
123     $hash = base64_encode(sha1($postdata, TRUE));
125     if ( $hash != $oauth_body_hash ) {
126         throw new Exception("OAuth oauth_body_hash mismatch");
127     }
129     return $postdata;
132 function sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $body)
134     $hash = base64_encode(sha1($body, TRUE));
136     $parms = array('oauth_body_hash' => $hash);
138     $test_token = '';
139     $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
140     $test_consumer = new OAuthConsumer($oauth_consumer_key, $oauth_consumer_secret, NULL);
142     $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, $method, $endpoint, $parms);
143     $acc_req->sign_request($hmac_method, $test_consumer, $test_token);
145     $header = $acc_req->to_header();
146     $header = $header . "\r\nContent-type: " . $content_type . "\r\n";
148     $params = array('http' => array(
149         'method' => 'POST',
150         'content' => $body,
151         'header' => $header
152         ));
153     $ctx = stream_context_create($params);
154     $fp = @fopen($endpoint, 'rb', false, $ctx);
155     if (!$fp) {
156         throw new Exception("Problem with $endpoint, $php_errormsg");
157     }
158     $response = @stream_get_contents($fp);
159     if ($response === false) {
160         throw new Exception("Problem reading data from $endpoint, $php_errormsg");
161     }
162     return $response;