diff --git a/plugin/ims_lti/Entity/ImsLtiTool.php b/plugin/ims_lti/Entity/ImsLtiTool.php index 1d4e05f25c..efc4f3c4de 100644 --- a/plugin/ims_lti/Entity/ImsLtiTool.php +++ b/plugin/ims_lti/Entity/ImsLtiTool.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; } /** diff --git a/plugin/ims_lti/ImsLtiPlugin.php b/plugin/ims_lti/ImsLtiPlugin.php index 1f85736fe5..3af28bda0c 100644 --- a/plugin/ims_lti/ImsLtiPlugin.php +++ b/plugin/ims_lti/ImsLtiPlugin.php @@ -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; + } } diff --git a/plugin/ims_lti/README.md b/plugin/ims_lti/README.md index 410de4d699..fb0e907952 100644 --- a/plugin/ims_lti/README.md +++ b/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). @@ -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; +``` diff --git a/plugin/ims_lti/configure.php b/plugin/ims_lti/configure.php index f9eb22f986..67d253beae 100644 --- a/plugin/ims_lti/configure.php +++ b/plugin/ims_lti/configure.php @@ -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()) ) { diff --git a/plugin/ims_lti/create.php b/plugin/ims_lti/create.php index 50f14042b3..7f754d76b3 100644 --- a/plugin/ims_lti/create.php +++ b/plugin/ims_lti/create.php @@ -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(); diff --git a/plugin/ims_lti/edit.php b/plugin/ims_lti/edit.php index 7d562cc5dd..47b279b36b 100644 --- a/plugin/ims_lti/edit.php +++ b/plugin/ims_lti/edit.php @@ -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() || diff --git a/plugin/ims_lti/form.php b/plugin/ims_lti/form.php index ded7e2a42b..2d2ca63d87 100644 --- a/plugin/ims_lti/form.php +++ b/plugin/ims_lti/form.php @@ -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']; +} ?> @@ -135,7 +139,7 @@ $result = $oauth->sign(array(