Skip to content

Commit

Permalink
LTI Allow create tools when there is no key/secret available for laun…
Browse files Browse the repository at this point in the history
…ch - refs BT#13469
  • Loading branch information
AngelFQC committed Nov 15, 2018
1 parent 585ea84 commit b8bb53d
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 41 deletions.
6 changes: 4 additions & 2 deletions plugin/ims_lti/Entity/ImsLtiTool.php
Expand Up @@ -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 = '';
/**
Expand Down Expand Up @@ -117,6 +117,8 @@ public function __construct()
$this->gradebookEval =null;
$this->privacy = null;
$this->children = new ArrayCollection();
$this->consumerKey = null;
$this->sharedSecret = null;
}

/**
Expand Down
44 changes: 42 additions & 2 deletions plugin/ims_lti/ImsLtiPlugin.php
Expand Up @@ -125,8 +125,8 @@ private function createPluginTables()
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,
Expand Down Expand Up @@ -466,4 +466,44 @@ public static function existsToolInCourse($toolId, Course $course)

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;
}
}
12 changes: 11 additions & 1 deletion plugin/ims_lti/README.md
@@ -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).
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;
```
36 changes: 27 additions & 9 deletions plugin/ims_lti/configure.php
Expand Up @@ -49,15 +49,6 @@
->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']
)
Expand All @@ -69,6 +60,33 @@
!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())
) {
Expand Down
35 changes: 30 additions & 5 deletions plugin/ims_lti/create.php
Expand Up @@ -21,11 +21,12 @@
$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'])
Expand All @@ -36,6 +37,30 @@
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();

Expand Down
16 changes: 12 additions & 4 deletions plugin/ims_lti/edit.php
Expand Up @@ -37,8 +37,12 @@

$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']),
Expand All @@ -48,8 +52,12 @@
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() ||
Expand Down
32 changes: 18 additions & 14 deletions plugin/ims_lti/form.php
Expand Up @@ -112,19 +112,23 @@

$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>
Expand All @@ -135,7 +139,7 @@
<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;
}
?>
Expand Down
2 changes: 2 additions & 0 deletions plugin/ims_lti/lang/english.php
Expand Up @@ -36,3 +36,5 @@
$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';
2 changes: 2 additions & 0 deletions plugin/ims_lti/lang/spanish.php
Expand Up @@ -36,3 +36,5 @@
$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';
4 changes: 2 additions & 2 deletions plugin/ims_lti/src/Form/FrmAdd.php
Expand Up @@ -43,8 +43,8 @@ public function build()

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');
Expand Down
4 changes: 2 additions & 2 deletions plugin/ims_lti/src/Form/FrmEdit.php
Expand Up @@ -60,8 +60,8 @@ public function build($globalMode = true)

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');
Expand Down

0 comments on commit b8bb53d

Please sign in to comment.