LTI Allow create tools when there is no key/secret available for launch - refs BT#13469

pull/2731/head
Angel Fernando Quiroz Campos 7 years ago
parent 585ea84fba
commit b8bb53d154
  1. 6
      plugin/ims_lti/Entity/ImsLtiTool.php
  2. 44
      plugin/ims_lti/ImsLtiPlugin.php
  3. 12
      plugin/ims_lti/README.md
  4. 36
      plugin/ims_lti/configure.php
  5. 35
      plugin/ims_lti/create.php
  6. 16
      plugin/ims_lti/edit.php
  7. 32
      plugin/ims_lti/form.php
  8. 2
      plugin/ims_lti/lang/english.php
  9. 2
      plugin/ims_lti/lang/spanish.php
  10. 4
      plugin/ims_lti/src/Form/FrmAdd.php
  11. 4
      plugin/ims_lti/src/Form/FrmEdit.php

@ -45,13 +45,13 @@ class ImsLtiTool
/**
* @var string
*
* @ORM\Column(name="consumer_key", type="string")
* @ORM\Column(name="consumer_key", type="string", nullable=true)
*/
private $consumerKey = '';
/**
* @var string
*
* @ORM\Column(name="shared_secret", type="string")
* @ORM\Column(name="shared_secret", type="string", nullable=true)
*/
private $sharedSecret = '';
/**
@ -117,6 +117,8 @@ class ImsLtiTool
$this->gradebookEval =null;
$this->privacy = null;
$this->children = new ArrayCollection();
$this->consumerKey = null;
$this->sharedSecret = null;
}
/**

@ -125,8 +125,8 @@ class ImsLtiPlugin extends Plugin
name VARCHAR(255) NOT NULL,
description LONGTEXT DEFAULT NULL,
launch_url VARCHAR(255) NOT NULL,
consumer_key VARCHAR(255) NOT NULL,
shared_secret VARCHAR(255) NOT NULL,
consumer_key VARCHAR(255) DEFAULT NULL,
shared_secret VARCHAR(255) DEFAULT NULL,
custom_params LONGTEXT DEFAULT NULL,
active_deep_linking TINYINT(1) DEFAULT \'0\' NOT NULL,
privacy LONGTEXT DEFAULT NULL,
@ -466,4 +466,44 @@ class ImsLtiPlugin extends Plugin
return !empty($tool);
}
/**
* @param string $configUrl
*
* @return string
* @throws Exception
*/
public function getLaunchUrlFromCartridge($configUrl)
{
$options = [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_POST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_ENCODING => '',
CURLOPT_SSL_VERIFYPEER => false,
];
$ch = curl_init($configUrl);
curl_setopt_array($ch, $options);
$content = curl_exec($ch);
$errno = curl_errno($ch);
curl_close($ch);
if ($errno !== 0) {
throw new Exception($this->get_lang('NoAccessToUrl'));
}
$xml = new SimpleXMLElement($content);
$result = $xml->xpath('blti:launch_url');
if (empty($result)) {
throw new Exception($this->get_lang('LaunchUrlNotFound'));
}
$launchUrl = $result[0];
return (string) $launchUrl;
}
}

@ -1,7 +1,7 @@
IMS/LTI plugin
===
Version 1.3 (beta)
Version 1.4 (beta)
This plugin is meant to be later integrated into Chamilo (in a major version
release).
@ -33,6 +33,9 @@ external tool.
**v1.3**
* Privacy settings added. Allow to indicate id the launcher's data
should be sent in request.
**v1.4**
* Allow create external tools when there is no key/secret available for launch
# Installation
@ -75,3 +78,10 @@ CREATE INDEX IDX_C5E47F7C727ACA70 ON plugin_ims_lti_tool (parent_id);
```sql
ALTER TABLE plugin_ims_lti_tool ADD privacy LONGTEXT DEFAULT NULL;
```
**To v.4**
```sql
ALTER TABLE plugin_ims_lti_tool
CHANGE consumer_key consumer_key VARCHAR(255) DEFAULT NULL,
CHANGE shared_secret shared_secret VARCHAR(255) DEFAULT NULL;
```

@ -49,15 +49,6 @@ switch ($action) {
->setDescription(
empty($formValues['description']) ? null : $formValues['description']
)
->setLaunchUrl(
$baseTool ? $baseTool->getLaunchUrl() : $formValues['launch_url']
)
->setConsumerKey(
$baseTool ? $baseTool->getConsumerKey() : $formValues['consumer_key']
)
->setSharedSecret(
$baseTool ? $baseTool->getSharedSecret() : $formValues['shared_secret']
)
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
@ -69,6 +60,33 @@ switch ($action) {
!empty($formValues['share_picture'])
);
if ($baseTool) {
$tool
->setLaunchUrl($baseTool->getLaunchUrl())
->setConsumerKey($baseTool->getConsumerKey())
->setSharedSecret($baseTool->getSharedSecret());
} else {
if (empty($formValues['consumer_key']) && empty($formValues['shared_secret'])) {
try {
$launchUrl = $plugin->getLaunchUrlFromCartridge($formValues['launch_url']);
} catch (Exception $e) {
Display::addFlash(
Display::return_message($e->getMessage(), 'error')
);
header('Location: '.api_get_self().'?'.api_get_cidreq());
exit;
}
$tool->setLaunchUrl($launchUrl);
} else {
$tool
->setLaunchUrl($formValues['launch_url'])
->setConsumerKey($formValues['consumer_key'])
->setSharedSecret($formValues['shared_secret']);
}
}
if (null === $baseTool ||
($baseTool && !$baseTool->isActiveDeepLinking())
) {

@ -21,11 +21,12 @@ if ($form->validate()) {
$externalTool = new ImsLtiTool();
$externalTool
->setName($formValues['name'])
->setDescription($formValues['description'])
->setLaunchUrl($formValues['launch_url'])
->setConsumerKey($formValues['consumer_key'])
->setSharedSecret($formValues['shared_secret'])
->setCustomParams($formValues['custom_params'])
->setDescription(
empty($formValues['description']) ? null : $formValues['description']
)
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
->setCourse(null)
->setActiveDeepLinking(
isset($formValues['deep_linking'])
@ -36,6 +37,30 @@ if ($form->validate()) {
isset($formValues['share_picture'])
);
if (empty($formValues['consumer_key']) && empty($formValues['shared_secret'])) {
try {
$launchUrl = $plugin->getLaunchUrlFromCartridge($formValues['launch_url']);
} catch (Exception $e) {
Display::addFlash(
Display::return_message($e->getMessage(), 'error')
);
header('Location: '.api_get_path(WEB_PLUGIN_PATH).'ims_lti/admin.php');
exit;
}
$externalTool->setLaunchUrl($launchUrl);
} else {
$externalTool
->setLaunchUrl($formValues['launch_url'])
->setConsumerKey(
empty($formValues['consumer_key']) ? null : $formValues['consumer_key']
)
->setSharedSecret(
empty($formValues['shared_secret']) ? null : $formValues['shared_secret']
);
}
$em->persist($externalTool);
$em->flush();

@ -37,8 +37,12 @@ if ($form->validate()) {
$tool
->setName($formValues['name'])
->setDescription($formValues['description'])
->setCustomParams($formValues['custom_params'])
->setDescription(
empty($formValues['description']) ? null : $formValues['description']
)
->setCustomParams(
empty($formValues['custom_params']) ? null : $formValues['custom_params']
)
->setPrivacy(
!empty($formValues['share_name']),
!empty($formValues['share_email']),
@ -48,8 +52,12 @@ if ($form->validate()) {
if (null === $tool->getParent()) {
$tool
->setLaunchUrl($formValues['launch_url'])
->setConsumerKey($formValues['consumer_key'])
->setSharedSecret($formValues['shared_secret']);
->setConsumerKey(
empty($formValues['consumer_key']) ? null : $formValues['consumer_key']
)
->setSharedSecret(
empty($formValues['shared_secret']) ? null : $formValues['shared_secret']
);
}
if (null === $tool->getParent() ||

@ -112,19 +112,23 @@ $params['tool_consumer_instance_contact_email'] = api_get_setting('emailAdminist
$params += $tool->parseCustomParams();
$oauth = new OAuthSimple(
$tool->getConsumerKey(),
$tool->getSharedSecret()
);
$oauth->setAction('post');
$oauth->setSignatureMethod('HMAC-SHA1');
$oauth->setParameters($params);
$result = $oauth->sign(array(
'path' => $tool->getLaunchUrl(),
'parameters' => array(
'oauth_callback' => 'about:blank'
)
));
if (!empty($tool->getConsumerKey()) && !empty($tool->getSharedSecret())) {
$oauth = new OAuthSimple(
$tool->getConsumerKey(),
$tool->getSharedSecret()
);
$oauth->setAction('post');
$oauth->setSignatureMethod('HMAC-SHA1');
$oauth->setParameters($params);
$result = $oauth->sign(array(
'path' => $tool->getLaunchUrl(),
'parameters' => array(
'oauth_callback' => 'about:blank'
)
));
$params = $result['parameters'];
}
?>
<!DOCTYPE html>
<html>
@ -135,7 +139,7 @@ $result = $oauth->sign(array(
<form action="<?php echo $tool->getLaunchUrl() ?>" name="ltiLaunchForm" method="post"
encType="application/x-www-form-urlencoded">
<?php
foreach ($result["parameters"] as $key => $values) { //Dump parameters
foreach ($params as $key => $values) {
echo '<input type="hidden" name="'.$key.'" value="'.htmlspecialchars($values).'" />'.PHP_EOL;
}
?>

@ -36,3 +36,5 @@ $strings['ShareLauncherPicture'] = 'Share launcher\'s picture';
$strings['NoTool'] = 'Tool not exists';
$strings['ToolAddedOnCourseX'] = 'Tool addeed on course <strong>%s</strong>.';
$strings['SupportDeppLinkingHelp'] = 'Contact your Tool Provider to verify if Deep Linking support is mandatory';
$strings['NoAccessToUrl'] = 'No access to URL';
$strings['LaunchUrlNotFound'] = 'Launch URL not found';

@ -36,3 +36,5 @@ $strings['ShareLauncherPicture'] = 'Enviar la foto del usuario';
$strings['NoTool'] = 'La herramienta no existe';
$strings['ToolAddedOnCourseX'] = 'Herramienta agregada en el curso <strong>%s</strong>.';
$strings['SupportDeppLinkingHelp'] = 'Contacte a su Proveedor de Herramienta para verificar si el soporte a Deep Linking es obligatorio';
$strings['NoAccessToUrl'] = 'Sin acceso a la URL';
$strings['LaunchUrlNotFound'] = 'URL de lanzamiento no encontrada';

@ -43,8 +43,8 @@ class FrmAdd extends FormValidator
if (null === $this->baseTool) {
$this->addUrl('launch_url', $plugin->get_lang('LaunchUrl'), true);
$this->addText('consumer_key', $plugin->get_lang('ConsumerKey'));
$this->addText('shared_secret', $plugin->get_lang('SharedSecret'));
$this->addText('consumer_key', $plugin->get_lang('ConsumerKey'), false);
$this->addText('shared_secret', $plugin->get_lang('SharedSecret'), false);
}
$this->addButtonAdvancedSettings('lti_adv');

@ -60,8 +60,8 @@ class FrmEdit extends FormValidator
if (null === $parent) {
$this->addUrl('launch_url', $plugin->get_lang('LaunchUrl'), true);
$this->addText('consumer_key', $plugin->get_lang('ConsumerKey'));
$this->addText('shared_secret', $plugin->get_lang('SharedSecret'));
$this->addText('consumer_key', $plugin->get_lang('ConsumerKey'), false);
$this->addText('shared_secret', $plugin->get_lang('SharedSecret'), false);
}
$this->addButtonAdvancedSettings('lti_adv');

Loading…
Cancel
Save