LTI set unique url and sourcedid for services - refs BT#13469

pull/2789/head
Angel Fernando Quiroz Campos 7 years ago
parent c6e5aaef0c
commit 675198f427
  1. 2
      .htaccess
  2. 10
      plugin/ims_lti/form.php
  3. 72
      plugin/ims_lti/outcome_service.php
  4. 1
      plugin/ims_lti/src/ImsLti.php
  5. 15
      plugin/ims_lti/src/ImsLtiServiceDeleteRequest.php
  6. 15
      plugin/ims_lti/src/ImsLtiServiceReadRequest.php
  7. 15
      plugin/ims_lti/src/ImsLtiServiceReplaceRequest.php

@ -70,7 +70,7 @@ RewriteRule ^main/newscorm/(.*)$ main/lp/$1 [QSA,L]
RewriteRule ^service/(\d{1,})$ plugin/buycourses/src/service_information.php?service_id=$1 [L]
# LTI outcome service
RewriteRule ^ims_lti/outcome_service/(\d{1,})$ plugin/ims_lti/outcome_service.php?t=$1 [L]
RewriteRule ^lti/os$ plugin/ims_lti/outcome_service.php [L]
# This rule is very generic and should always remain at the bottom of .htaccess
# http://my.chamilo.net/jdoe to http://my.chamilo.net/user.php?jdoe

@ -1,10 +1,10 @@
<?php
/* For license terms, see /license.txt */
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\UserBundle\Entity\User;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CoreBundle\Entity\Session;
use Chamilo\PluginBundle\Entity\ImsLti\ImsLtiTool;
use Chamilo\UserBundle\Entity\User;
require_once __DIR__.'/../../main/inc/global.inc.php';
require './OAuthSimple.php';
@ -60,8 +60,10 @@ if ($tool->isActiveDeepLinking()) {
$toolEval = $tool->getGradebookEval();
if (!empty($toolEval)) {
$params['lis_result_sourcedid'] = $toolEval->getId().':'.$user->getId();
$params['lis_outcome_service_url'] = api_get_path(WEB_PATH).'ims_lti/outcome_service/'.$tool->getId();
$params['lis_result_sourcedid'] = json_encode(
['e' => $toolEval->getId(), 'u' => $user->getId(), 'l' => uniqid(), 'lt' => time()]
);
$params['lis_outcome_service_url'] = api_get_path(WEB_PATH).'lti/os';
$params['lis_person_sourcedid'] = "$platformDomain:$toolUserId";
$params['lis_course_section_sourcedid'] = "$platformDomain:".$course->getId();

@ -8,52 +8,58 @@ require_once './OAuthSimple.php';
header('Content-Type: application/xml');
if (empty($_GET['t'])) {
$url = api_get_path(WEB_PATH).'lti/os';
$em = Database::getManager();
$toolRepo = $em->getRepository('ChamiloPluginBundle:ImsLti\ImsLtiTool');
$headers = OAuthUtil::get_headers();
if (empty($headers['Authorization'])) {
error_log('Authorization header missed');
exit;
}
$em = Database::getManager();
/** @var ImsLtiTool $tool */
$tool = $em->find('ChamiloPluginBundle:ImsLti\ImsLtiTool', (int) $_GET['t']);
$authParams = OAuthUtil::split_header($headers['Authorization']);
if (empty($authParams) || empty($authParams['oauth_consumer_key']) || empty($authParams['oauth_signature'])) {
error_log('Authorization params not found');
if (empty($tool)) {
exit;
}
$body = file_get_contents('php://input');
$bodyHash = OAuthSimple::generateBodyHash($body);
$tools = $toolRepo->findBy(['consumerKey' => $authParams['oauth_consumer_key']]);
$toolIsFound = false;
$url = api_get_path(WEB_PATH).'ims_lti/outcome_service/'.$tool->getId();
$headers = getallheaders();
/** @var ImsLtiTool $tool */
foreach ($tools as $tool) {
$consumer = new OAuthConsumer($tool->getConsumerKey(), $tool->getSharedSecret());
$hmacMethod = new OAuthSignatureMethod_HMAC_SHA1();
$request = OAuthRequest::from_request('POST', $url);
$request->sign_request($hmacMethod, $consumer, '');
$signature = $request->get_parameter('oauth_signature');
if ($signature === $authParams['oauth_signature']) {
$toolIsFound = true;
break;
}
}
$params = OAuthSimple::getAuthorizationParams($headers['Authorization']);
if (false === $toolIsFound) {
error_log('Tool not found. Signature is not valid');
if (empty($params)) {
exit;
}
$oauth = new OAuthSimple(
$params['oauth_consumer_key'],
$tool->getSharedSecret()
);
$oauth->setAction('POST');
$oauth->setSignatureMethod('HMAC-SHA1');
$result = $oauth->sign(
[
'path' => $url,
'parameters' => [
'oauth_body_hash' => $params['oauth_body_hash'],
'oauth_nonce' => $params['oauth_nonce'],
'oauth_timestamp' => $params['oauth_timestamp'],
'oauth_signature_method' => $params['oauth_signature_method'],
],
]
);
$signatureValid = urldecode($result['signature']) == $params['oauth_signature'];
$bodyHashValid = $bodyHash === $params['oauth_body_hash'];
if (!$signatureValid || !$bodyHashValid) {
$body = file_get_contents('php://input');
$bodyHash = base64_encode(sha1($body, true));
if ($bodyHash !== $authParams['oauth_body_hash']) {
error_log('Authorization request not valid');
exit;
}

@ -119,6 +119,7 @@ class ImsLti
'$LineItem.dataSource' => false,
'$Result.sourcedGUID' => ['lis_result_sourcedid'],
'$Result.sourcedId' => ['lis_result_sourcedid'],
'$Result.createdTimestamp' => false,
'$Result.status' => false,
'$Result.resultScore' => false,

@ -26,14 +26,23 @@ class ImsLtiServiceDeleteRequest extends ImsLtiServiceRequest
{
$resultRecord = $this->xmlRequest->resultRecord;
$sourcedId = (string) $resultRecord->sourcedGUID->sourcedId;
$sourcedId = htmlspecialchars_decode($sourcedId);
$sourcedParts = explode(':', $sourcedId);
$sourcedParts = json_decode($sourcedId, true);
if (empty($sourcedParts)) {
$this->statusInfo
->setSeverity(ImsLtiServiceResponseStatus::SEVERITY_ERROR)
->setCodeMajor(ImsLtiServiceResponseStatus::CODEMAJOR_FAILURE);
return;
}
$em = Database::getManager();
/** @var GradebookEvaluation $evaluation */
$evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $sourcedParts[0]);
$evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $sourcedParts['e']);
/** @var User $user */
$user = $em->find('ChamiloUserBundle:User', $sourcedParts[1]);
$user = $em->find('ChamiloUserBundle:User', $sourcedParts['u']);
if (empty($evaluation) || empty($user)) {
$this->statusInfo

@ -26,14 +26,23 @@ class ImsLtiServiceReadRequest extends ImsLtiServiceRequest
{
$resultRecord = $this->xmlRequest->resultRecord;
$sourcedId = (string) $resultRecord->sourcedGUID->sourcedId;
$sourcedId = htmlspecialchars_decode($sourcedId);
$sourcedParts = explode(':', $sourcedId);
$sourcedParts = json_decode($sourcedId, true);
if (empty($sourcedParts)) {
$this->statusInfo
->setSeverity(ImsLtiServiceResponseStatus::SEVERITY_ERROR)
->setCodeMajor(ImsLtiServiceResponseStatus::CODEMAJOR_FAILURE);
return;
}
$em = Database::getManager();
/** @var GradebookEvaluation $evaluation */
$evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $sourcedParts[0]);
$evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $sourcedParts['e']);
/** @var User $user */
$user = $em->find('ChamiloUserBundle:User', $sourcedParts[1]);
$user = $em->find('ChamiloUserBundle:User', $sourcedParts['u']);
if (empty($evaluation) || empty($user)) {
$this->statusInfo

@ -26,6 +26,7 @@ class ImsLtiServiceReplaceRequest extends ImsLtiServiceRequest
{
$resultRecord = $this->xmlRequest->resultRecord;
$sourcedId = (string) $resultRecord->sourcedGUID->sourcedId;
$sourcedId = htmlspecialchars_decode($sourcedId);
$resultScore = (string) $resultRecord->result->resultScore->textString;
if (!is_numeric($resultScore)) {
@ -46,13 +47,21 @@ class ImsLtiServiceReplaceRequest extends ImsLtiServiceRequest
return;
}
$sourcedParts = explode(':', $sourcedId);
$sourcedParts = json_decode($sourcedId, true);
if (empty($sourcedParts)) {
$this->statusInfo
->setSeverity(ImsLtiServiceResponseStatus::SEVERITY_ERROR)
->setCodeMajor(ImsLtiServiceResponseStatus::CODEMAJOR_FAILURE);
return;
}
$em = Database::getManager();
/** @var GradebookEvaluation $evaluation */
$evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $sourcedParts[0]);
$evaluation = $em->find('ChamiloCoreBundle:GradebookEvaluation', $sourcedParts['e']);
/** @var User $user */
$user = $em->find('ChamiloUserBundle:User', $sourcedParts[1]);
$user = $em->find('ChamiloUserBundle:User', $sourcedParts['u']);
if (empty($evaluation) || empty($user)) {
$this->statusInfo

Loading…
Cancel
Save