<?php // This file is part of BasicLTI4Moodle // // BasicLTI4Moodle is an IMS BasicLTI (Basic Learning Tools for Interoperability) // consumer for Moodle 1.9 and Moodle 2.0. BasicLTI is a IMS Standard that allows web // based learning tools to be easily integrated in LMS as native ones. The IMS BasicLTI // specification is part of the IMS standard Common Cartridge 1.1 Sakai and other main LMS // are already supporting or going to support BasicLTI. This project Implements the consumer // for Moodle. Moodle is a Free Open source Learning Management System by Martin Dougiamas. // BasicLTI4Moodle is a project iniciated and leaded by Ludo(Marc Alier) and Jordi Piguillem // at the GESSI research group at UPC. // SimpleLTI consumer for Moodle is an implementation of the early specification of LTI // by Charles Severance (Dr Chuck) htp://dr-chuck.com , developed by Jordi Piguillem in a // Google Summer of Code 2008 project co-mentored by Charles Severance and Marc Alier. // // BasicLTI4Moodle is copyright 2009 by Marc Alier Forment, Jordi Piguillem and Nikolas Galanis // of the Universitat Politecnica de Catalunya http://www.upc.edu // Contact info: Marc Alier Forment granludo @ gmail.com or marc.alier @ upc.edu // // OAuthBody.php is distributed under the MIT License // // The MIT License // // Copyright (c) 2007 Andy Smith // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // Moodle is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Moodle is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Moodle. If not, see <http://www.gnu.org/licenses/>. namespace moodle\mod\lti;//Using a namespace as the basicLTI module imports classes with the same names defined('MOODLE_INTERNAL') || die; require_once($CFG->dirroot . '/mod/lti/OAuth.php'); require_once($CFG->dirroot . '/mod/lti/TrivialStore.php'); function getOAuthKeyFromHeaders() { $request_headers = OAuthUtil::get_headers(); // print_r($request_headers); if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { $header_parameters = OAuthUtil::split_header($request_headers['Authorization']); // echo("HEADER PARMS=\n"); // print_r($header_parameters); return $header_parameters['oauth_consumer_key']; } return false; } function handleOAuthBodyPOST($oauth_consumer_key, $oauth_consumer_secret, $body, $request_headers = null) { if($request_headers == null){ $request_headers = OAuthUtil::get_headers(); } // Must reject application/x-www-form-urlencoded if (isset($request_headers['Content-type'])) { if ($request_headers['Content-type'] == 'application/x-www-form-urlencoded' ) { throw new Exception("OAuth request body signing must not use application/x-www-form-urlencoded"); } } if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { $header_parameters = OAuthUtil::split_header($request_headers['Authorization']); // echo("HEADER PARMS=\n"); // print_r($header_parameters); $oauth_body_hash = $header_parameters['oauth_body_hash']; // echo("OBH=".$oauth_body_hash."\n"); } if ( ! isset($oauth_body_hash) ) { throw new Exception("OAuth request body signing requires oauth_body_hash body"); } // Verify the message signature $store = new TrivialOAuthDataStore(); $store->add_consumer($oauth_consumer_key, $oauth_consumer_secret); $server = new OAuthServer($store); $method = new OAuthSignatureMethod_HMAC_SHA1(); $server->add_signature_method($method); $request = OAuthRequest::from_request(); try { $server->verify_request($request); } catch (Exception $e) { $message = $e->getMessage(); throw new Exception("OAuth signature failed: " . $message); } $postdata = $body; // echo($postdata); $hash = base64_encode(sha1($postdata, TRUE)); if ( $hash != $oauth_body_hash ) { throw new Exception("OAuth oauth_body_hash mismatch"); } return $postdata; } function sendOAuthBodyPOST($method, $endpoint, $oauth_consumer_key, $oauth_consumer_secret, $content_type, $body) { $hash = base64_encode(sha1($body, TRUE)); $parms = array('oauth_body_hash' => $hash); $test_token = ''; $hmac_method = new OAuthSignatureMethod_HMAC_SHA1(); $test_consumer = new OAuthConsumer($oauth_consumer_key, $oauth_consumer_secret, NULL); $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, $method, $endpoint, $parms); $acc_req->sign_request($hmac_method, $test_consumer, $test_token); $header = $acc_req->to_header(); $header = $header . "\r\nContent-type: " . $content_type . "\r\n"; $params = array('http' => array( 'method' => 'POST', 'content' => $body, 'header' => $header )); $ctx = stream_context_create($params); $fp = @fopen($endpoint, 'rb', false, $ctx); if (!$fp) { throw new Exception("Problem with $endpoint, $php_errormsg"); } $response = @stream_get_contents($fp); if ($response === false) { throw new Exception("Problem reading data from $endpoint, $php_errormsg"); } return $response; }