Plugin : Improve library , feedbacks from PR1

pull/3914/head
Christian 4 years ago
parent efc6b431c4
commit fd2a1bcf3e
  1. 131
      plugin/lti_provider/Entity/PlatformKey.php
  2. 56
      plugin/lti_provider/LtiProviderPlugin.php
  3. 12
      plugin/lti_provider/README.md
  4. 24
      plugin/lti_provider/db/configs/local.json
  5. 65
      plugin/lti_provider/db/demo_database.php
  6. 50
      plugin/lti_provider/db/lti13_cache.php
  7. 39
      plugin/lti_provider/db/lti13_cookie.php
  8. 75
      plugin/lti_provider/db/lti13_database.php
  9. 2
      plugin/lti_provider/delete.php
  10. 2
      plugin/lti_provider/edit.php
  11. 27
      plugin/lti_provider/keys/platform.key
  12. 27
      plugin/lti_provider/keys/private.key
  13. 9
      plugin/lti_provider/keys/public.key
  14. 5
      plugin/lti_provider/lang/english.php
  15. 29
      plugin/lti_provider/lang/french.php
  16. 29
      plugin/lti_provider/lang/spanish.php
  17. 2
      plugin/lti_provider/src/Form/FrmEdit.php
  18. 31
      plugin/lti_provider/src/LtiProvider.php
  19. 2
      plugin/lti_provider/web/api/ags/results.json
  20. 29
      plugin/lti_provider/web/api/score.php
  21. 24
      plugin/lti_provider/web/api/scoreboard.php
  22. 18
      plugin/lti_provider/web/configure.php
  23. 12
      plugin/lti_provider/web/game.php
  24. 3
      plugin/lti_provider/web/login.php
  25. 10
      plugin/lti_provider/web/view/game.tpl

@ -0,0 +1,131 @@
<?php
/* For licensing terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\LtiProvider;
use Doctrine\ORM\Mapping as ORM;
/**
* Class Platform
*
* @package Chamilo\PluginBundle\Entity\LtiProvider
*
* @ORM\Table(name="plugin_lti_provider_platform_key")
* @ORM\Entity()
*/
class PlatformKey
{
/**
* @var string
*
* @ORM\Column(name="public_key", type="text")
*/
public $publicKey;
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="kid", type="string")
*/
private $kid;
/**
* @var string
*
* @ORM\Column(name="private_key", type="text")
*/
private $privateKey;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* @param int $id
*
* @return Platform
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
*
* Get kid.
*
* @return string
*/
public function getKid()
{
return $this->kid;
}
/**
* Set kid.
*
* @param string $kid
*/
public function setKid($kid)
{
$this->kid = $kid;
}
/**
* Get privateKey.
*
* @return string
*/
public function getPrivateKey()
{
return $this->privateKey;
}
/**
* Set privateKey.
*
* @param string $privateKey
*
* @return Platform
*/
public function setPrivateKey($privateKey)
{
$this->privateKey = $privateKey;
return $this;
}
/**
* @return string
*/
public function getPublicKey()
{
return $this->publicKey;
}
/**
* @param string $publicKey
*/
public function setPublicKey(string $publicKey)
{
$this->publicKey = $publicKey;
}
}

@ -1,7 +1,7 @@
<?php <?php
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
use Chamilo\PluginBundle\Entity\LtiProvider\Platform; use Chamilo\PluginBundle\Entity\LtiProvider\PlatformKey;
use Doctrine\DBAL\DBALException; use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
@ -23,9 +23,14 @@ class LtiProviderPlugin extends Plugin
{ {
$version = '1.0'; $version = '1.0';
$author = 'Christian Beeznest'; $author = 'Christian Beeznest';
$publicKey = $this->getPublicKey(); $publicKey = $this->getPublicKey();
$message = Display::return_message($this->get_lang('description')); $message = Display::return_message($this->get_lang('description'));
if (empty($publicKey)) {
$publicKey = $this->get_lang('GenerateKeyPairInfo');
}
$pkHtml = '<div class="form-group "> $pkHtml = '<div class="form-group ">
<label for="lti_provider_public_key" class="col-sm-2 control-label">'.$this->get_lang('public_key').'</label> <label for="lti_provider_public_key" class="col-sm-2 control-label">'.$this->get_lang('public_key').'</label>
<div class="col-sm-8"> <div class="col-sm-8">
@ -103,6 +108,33 @@ class LtiProviderPlugin extends Plugin
*/ */
public function performActionsAfterConfigure() public function performActionsAfterConfigure()
{ {
$em = Database::getManager();
/** @var PlatformKey $platformKey */
$platformKey = $em
->getRepository('ChamiloPluginBundle:LtiProvider\PlatformKey')
->findOneBy([]);
if ($this->get('enabled') === 'true') {
if (!$platformKey) {
$platformKey = new PlatformKey();
}
$keyPair = self::generatePlatformKeys();
$platformKey->setKid($keyPair['kid']);
$platformKey->publicKey = $keyPair['public'];
$platformKey->setPrivateKey($keyPair['private']);
$em->persist($platformKey);
} else {
if ($platformKey) {
$em->remove($platformKey);
}
}
$em->flush();
return $this; return $this;
} }
@ -152,6 +184,13 @@ class LtiProviderPlugin extends Plugin
deployment_id varchar(255) NOT NULL, deployment_id varchar(255) NOT NULL,
PRIMARY KEY(id) PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB", ) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB",
"CREATE TABLE plugin_lti_provider_platform_key (
id INT AUTO_INCREMENT NOT NULL,
kid VARCHAR(255) NOT NULL,
public_key LONGTEXT NOT NULL,
private_key LONGTEXT NOT NULL,
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB"
]; ];
foreach ($queries as $query) { foreach ($queries as $query) {
@ -169,6 +208,7 @@ class LtiProviderPlugin extends Plugin
private function dropPluginTables() private function dropPluginTables()
{ {
Database::query("DROP TABLE IF EXISTS plugin_lti_provider_platform"); Database::query("DROP TABLE IF EXISTS plugin_lti_provider_platform");
Database::query("DROP TABLE IF EXISTS plugin_lti_provider_platform_key");
return true; return true;
} }
@ -242,9 +282,19 @@ class LtiProviderPlugin extends Plugin
]; ];
} }
/**
* Get the public key
*
* @return string
*/
public function getPublicKey() { public function getPublicKey() {
$keyPath = __DIR__.'/keys/public.key'; $publicKey = '';
$publicKey = file_get_contents($keyPath); $platformKey = Database::getManager()
->getRepository('ChamiloPluginBundle:LtiProvider\PlatformKey')
->findOneBy([]);
if ($platformKey) {
$publicKey = $platformKey->getPublicKey();
}
return $publicKey; return $publicKey;
} }

@ -17,6 +17,8 @@ In this case Chamilo is used as provider , this plugin allows a student inside a
4. Add the LTI connection details to try out this app (Configure page) 4. Add the LTI connection details to try out this app (Configure page)
5. To configure the Platforms LMS for registration and deployment 5. To configure the Platforms LMS for registration and deployment
# DB tables
## v1.0 ## v1.0
```sql ```sql
CREATE TABLE plugin_lti_provider_platform ( CREATE TABLE plugin_lti_provider_platform (
@ -29,5 +31,13 @@ CREATE TABLE plugin_lti_provider_platform (
key_set_url varchar(255) NOT NULL, key_set_url varchar(255) NOT NULL,
deployment_id varchar(255) NOT NULL, deployment_id varchar(255) NOT NULL,
PRIMARY KEY(id) PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB ) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB;
CREATE TABLE plugin_lti_provider_platform_key (
id INT AUTO_INCREMENT NOT NULL,
kid VARCHAR(255) NOT NULL,
public_key LONGTEXT NOT NULL,
private_key LONGTEXT NOT NULL,
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8 COLLATE `utf8_unicode_ci` ENGINE = InnoDB;
``` ```

@ -1,24 +0,0 @@
{
"https://testing3.beeznest.com": {
"client_id": "44WGA9lh8fmsRITfBac4",
"auth_login_url": "https://testing3.beeznest.com/plugin/ims_lti/auth.php",
"auth_token_url": "https://testing3.beeznest.com/plugin/ims_lti/token.php",
"key_set_url": "https://testing3.beeznest.com/plugin/ims_lti/jwks.php",
"private_key_file": "/keys/private.key",
"kid": "51dadff927d803c965f6",
"deployment": [
"8"
]
},
"https://11.chamilo.org": {
"client_id": "RcHE5hk5ruI9sOr9t0UN",
"auth_login_url": "https://11.chamilo.org/plugin/ims_lti/auth.php",
"auth_token_url": "https://11.chamilo.org/plugin/ims_lti/token.php",
"key_set_url": "https://11.chamilo.org/plugin/ims_lti/jwks.php",
"private_key_file": "/keys/private.key",
"kid": "e52a3d2435f9e5071e3e",
"deployment": [
"183"
]
}
}

@ -1,65 +0,0 @@
<?php
/* For license terms, see /license.txt */
require_once __DIR__ . '/../vendor/autoload.php';
use \IMSGlobal\LTI;
class Demo_Database implements LTI\Database
{
public function find_registration_by_issuer($iss) {
$lti_customers = $this->get_lti_connection();
if (empty($lti_customers[$iss])) {
return false;
}
return LTI\LTI_Registration::new()
->set_auth_login_url($lti_customers[$iss]['auth_login_url'])
->set_auth_token_url($lti_customers[$iss]['auth_token_url'])
->set_auth_server($lti_customers[$iss]['auth_token_url'])
->set_client_id($lti_customers[$iss]['client_id'])
->set_key_set_url($lti_customers[$iss]['key_set_url'])
->set_kid($lti_customers[$iss]['kid'])
->set_issuer($iss)
->set_tool_private_key(file_get_contents($lti_customers[$iss]['private_key_file']));
}
public function find_deployment($iss, $deployment_id) {
if (!in_array($deployment_id, $_SESSION['iss'][$iss]['deployment'])) {
return false;
}
return LTI\LTI_Deployment::new()
->set_deployment_id($deployment_id);
}
private function get_lti_connection() {
$keyPath = api_get_path(SYS_PLUGIN_PATH).'/lti_provider/keys/private.key';
$em = Database::getManager();
$platforms = $em->getRepository('ChamiloPluginBundle:LtiProvider\Platform')->findAll();
$lti_customers = [];
foreach ($platforms as $platform) {
$issuer = $platform->getIssuer();
$lti_customers[$issuer] = [
'client_id' => $platform->getClientId(),
'auth_login_url' => $platform->getAuthLoginUrl(),
'auth_token_url' => $platform->getAuthTokenUrl(),
'key_set_url' => $platform->getKeySetUrl(),
'private_key_file' => $keyPath,
'kid' => $platform->getKid(),
'deployment' => [$platform->getDeploymentId()]
];
}
$_SESSION['iss'] = [];
if (!empty($lti_customers)) {
$_SESSION['iss'] = array_merge($_SESSION['iss'], $lti_customers);
}
return $lti_customers;
}
private function private_key($iss) {
return file_get_contents($_SESSION['iss'][$iss]['private_key_file']);
}
}

@ -0,0 +1,50 @@
<?php
/* For license terms, see /license.txt */
use Packback\Lti1p3\Interfaces\Cache as Lti1p3Cache;
class Lti13Cache implements Lti1p3Cache
{
public const NONCE_PREFIX = 'nonce_';
private $cache;
public function getLaunchData($key) {
$this->loadCache();
return $this->cache[$key];
}
public function cacheLaunchData($key, $jwt_body) {
$this->cache[$key] = $jwt_body;
$this->saveCache();
return $this;
}
public function cacheNonce($nonce) {
$this->cache['nonce'][$nonce] = true;
$this->saveCache();
return $this;
}
public function checkNonce($nonce) {
$this->loadCache();
if (!isset($this->cache['nonce'][$nonce])) {
return false;
}
return true;
}
private function loadCache() {
$cache = file_get_contents(sys_get_temp_dir() . '/lti_cache.txt');
if (empty($cache)) {
file_put_contents(sys_get_temp_dir() . '/lti_cache.txt', '{}');
$this->cache = [];
}
$this->cache = json_decode($cache, true);
}
private function saveCache() {
file_put_contents(sys_get_temp_dir() . '/lti_cache.txt', json_encode($this->cache));
}
}

@ -0,0 +1,39 @@
<?php
/* For license terms, see /license.txt */
use Packback\Lti1p3\Interfaces\Cookie as Lti1p3Cookie;
class Lti13Cookie implements Lti1p3Cookie
{
public function getCookie($name)
{
if (isset($_COOKIE[$name])) {
return $_COOKIE[$name];
}
// Look for backup cookie if same site is not supported by the user's browser.
if (isset($_COOKIE["LEGACY_" . $name])) {
return $_COOKIE["LEGACY_" . $name];
}
return false;
}
public function setCookie($name, $value, $exp = 3600, $options = []): self
{
$cookie_options = [
'expires' => time() + $exp
];
// SameSite none and secure will be required for tools to work inside iframes
/*$same_site_options = [
'samesite' => 'None',
'secure' => false,
'httponly' => true
];*/
setcookie($name, $value, array_merge($cookie_options, $same_site_options, $options));
// Set a second fallback cookie in the event that "SameSite" is not supported
setcookie("LEGACY_" . $name, $value, array_merge($cookie_options, $options));
return $this;
}
}

@ -0,0 +1,75 @@
<?php
/* For license terms, see /license.txt */
use Chamilo\PluginBundle\Entity\LtiProvider\Platform;
use Chamilo\PluginBundle\Entity\LtiProvider\PlatformKey;
use ChamiloSession as Session;
use Packback\Lti1p3;
use Packback\Lti1p3\Interfaces;
use Packback\Lti1p3\LtiRegistration;
use Packback\Lti1p3\LtiDeployment;
use Packback\Lti1p3\OidcException;
class Lti13Database implements Interfaces\Database
{
public function findRegistrationByIssuer($iss, $clientId = null) {
$ltiCustomers = $this->getLtiConnection();
if (empty($ltiCustomers[$iss])) {
return false;
}
if (!isset($clientId)) {
$clientId = $ltiCustomers[$iss]['client_id'];
}
return LtiRegistration::new()
->setAuthLoginUrl($ltiCustomers[$iss]['auth_login_url'])
->setAuthTokenUrl($ltiCustomers[$iss]['auth_token_url'])
->setClientId($clientId)
->setKeySetUrl($ltiCustomers[$iss]['key_set_url'])
->setKid($ltiCustomers[$iss]['kid'])
->setIssuer($iss)
->setToolPrivateKey($this->getPrivateKey());
}
public function findDeployment($iss, $deploymentId, $clientId = null) {
if (!in_array($deploymentId, $_SESSION['iss'][$iss]['deployment'])) {
return false;
}
return LtiDeployment::new()
->setDeploymentId($deploymentId);
}
private function getLtiConnection() {
$em = Database::getManager();
$platforms = $em->getRepository('ChamiloPluginBundle:LtiProvider\Platform')->findAll();
$ltiCustomers = [];
foreach ($platforms as $platform) {
$issuer = $platform->getIssuer();
$ltiCustomers[$issuer] = [
'client_id' => $platform->getClientId(),
'auth_login_url' => $platform->getAuthLoginUrl(),
'auth_token_url' => $platform->getAuthTokenUrl(),
'key_set_url' => $platform->getKeySetUrl(),
'kid' => $platform->getKid(),
'deployment' => [$platform->getDeploymentId()]
];
}
Session::write('iss', $ltiCustomers);
return $ltiCustomers;
}
private function getPrivateKey() {
$privateKey = '';
$platformKey = Database::getManager()
->getRepository('ChamiloPluginBundle:LtiProvider\PlatformKey')
->findOneBy([]);
if ($platformKey) {
$privateKey = $platformKey->getPrivateKey();
}
return $privateKey;
}
}

@ -13,7 +13,7 @@ if (!isset($_REQUEST['id'])) {
api_not_allowed(true); api_not_allowed(true);
} }
$platformId = intval($_REQUEST['id']); $platformId = (int)$_REQUEST['id'];
$plugin = LtiProviderPlugin::create(); $plugin = LtiProviderPlugin::create();
$em = Database::getManager(); $em = Database::getManager();

@ -14,7 +14,7 @@ if (!isset($_REQUEST['id'])) {
api_not_allowed(true); api_not_allowed(true);
} }
$platformId = intval($_REQUEST['id']); $platformId = (int)$_REQUEST['id'];
$plugin = LtiProviderPlugin::create(); $plugin = LtiProviderPlugin::create();
$em = Database::getManager(); $em = Database::getManager();

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA8osiSa75nmqmakwNNocLA2N2huWM9At/tjSZOFX1r4+PDclS
zxhMw+ZcgHH+E/05Ec6Vcfd75i8Z+Bxu4ctbYk2FNIvRMN5UgWqxZ5Pf70n8UFxj
GqdwhUA7/n5KOFoUd9F6wLKa6Oh3OzE6v9+O3y6qL40XhZxNrJjCqxSEkLkOK3xJ
0J2npuZ59kipDEDZkRTWz3al09wQ0nvAgCc96DGH+jCgy0msA0OZQ9SmDE9CCMbD
T86ogLugPFCvo5g5zqBBX9Ak3czsuLS6Ni9Wco8ZSxoaCIsPXK0RJpt6Jvbjclqb
4imsobifxy5LsAV0l/weNWmU2DpzJsLgeK6VVwIDAQABAoIBAQC2R1RUdfjJUrOQ
rWk8so7XVBfO15NwEXhAkhUYnpmPAF/tZ4EhfMysaWLZcVIW6bbLKCtuRCVMX9ev
fIbkkLU0ErhqPi3QATcXL/z1r8+bAUprhpNAg9fvfM/ZukXDRged6MPNMC11nseE
p8HUU4oHNwXVyL6FvmstrHyYoEnkjIiMk34O2MFjAavoIJhM0gkoXVnxRP5MNi1n
GPVhK+TfZyRri20x1Rh3CsIq36PUyxCICWkD7jftLGqVdQBfuii600LP5v7nuHz9
LDsCeY7xRJu0eLdDk7/9ukb8fuq6/+3VYMYChYWvpw4DaH8qDHxZfWzMyaI489ma
l27lhgdxAoGBAPkxH6WuZM/GOowjySuruRjAVyJ4stfe9l/x8MrqnFA2Q8stqK69
60Y9LDrSaAx7QutvzZ64br2WMlvnGdJw868z4/JmvoAqW3IHUXzqRAHgOk/8Y3ze
Sjd7t3R0O3v6qAbQjyRYYgfAMZo7PzXW8FKNGsakAedEKW0b94HYndKpAoGBAPkr
grtARp2nnd1WGuxgQMjX++HjT0p9x7fTMCtfvYhZguU9AlCx53VHFeGc6fqsDkUm
BFv0dqMnw0TPzEQqLElBIh87TGS4JSXmcbQcejIx+ry2kMFuyMZIPuvZCnLfB/d7
Qu2DU6mdeIBME/8AX5kBqn1ekddioESdSkHkkif/AoGAaPCeAjjZ7YHuP/wGCOUN
UvYU+8hWkIAtwyPxIpMAdusTS6oTwlrqjK7QRIk9FhyGhv2TWwcSY7avyHIfNrco
eBzjHr7T9MdhsTiRwYgqUZvrEqoX/4rhOFJaZKlaL5DUV+JWlZi+18LBYNEYgoTc
ufcAUqzYvFrBE1jWt5DQjdkCgYATs6sMn1J2GNDUtYA/fITi3KEgBVc5rqRiFqLS
aymTZHCDK8XJF6gTj+FdC4k8tuoR8aWal8Phtr0r7bpbEXKbADlwesHZnO3jB0uq
UC4hVe5biZv8j4P0mbXP9ENtPdFlciuimCW/XaIvktRp71+fu4/9hcLGYxgFFOLQ
PwCHhQKBgGMCxIcueUkLnI9r0KkjtXap9mIgdgERwQPN0Cm9Tx35ZEzRp95kf4C6
MPsVOwZk5gNvvQngx4iaw9fNYG+PF2yNuDZ+EFwI0vpmGCKRQEke9/VCOFucMsjg
jMhbU+jrqRIJKisP7MCE1NRhymCPpQf/stEPl0nS5rj+mZJHQEGq
-----END RSA PRIVATE KEY-----

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyU64VjSdgPqaQp/iaS8EQsCYMBBKFjevaZGraPWGho3H74OY
nuTbfeo3T6ufSNpK7aImM6rgsNqh6/FVYKUyNKcD/2AYkfu8gip3zAHJBONhu0NN
EkyeKx9ugvvrrgiifTDM5JYOyOSYVcVHZhsOASb/+eHvq3VSa/+rbgOnqeq7t2rS
c+Zt/wTWAtY8OIms6uOr8drbHdvDz4+isxlNTBW06ILDLAUS/gH2PDskPJFwAMbn
moXGoU3j5IKiWGASNWCbUAfeiTs7XIFR/bxEvs+oGsn6vUnZV9dJR20aTG3hsR0E
YEVfjzBCBpoK3Jb3RLouLnwkZAteJFmyWqAXAwIDAQABAoIBAEVqnsgjNpjOUbld
ts48h0SZcyFHzLRimVtW/vufhrcJVwNxpoRMOJ/vzwjrDm8pzyKognHYn8h8a8+X
lbBQ5sIfQZKjSXW1j+h2yn6Pswi7e+z+JSqFPxlxqkMCqd+GXLm8xTqhwBFoOluB
PsCn3alqEGTTkzjVqQlSzYOPQRanHWSIqeZ4A5Xs6NbjoGdlV0mJ3GeyvyyoPdl1
KQoyvVws5xrbHeTgDjLM4Kgp5PShTwlo1Cz2Du34cbUrbcXipS2/77aSM/wBAWuh
Sq7gsd0iPvd+CeFHcK2+zUwHrksVp+86NgnL/GbcS8Q5tFMDo1GXOg39pJ/PmYVI
Wp7EoHkCgYEA5r5EA9qCmNkTQdE4kNNl+/zvGdPuzonw7v6356zoET6zntcNcJLC
EJPPPnipHqLYx2k0URGde1Jywn5xMzJ4hmkj1sPZNfrA5cBjA0T711JnLjOGM6QG
EdiQN6GnyWGzHPQUGQlaHKe1u4yNP+T19zWqJCaYa1CxjreBRjPQjF0CgYEA31eg
PNGIPW8SOokVvgd+iI7g2XcYBo7fJX8rDZ+ZA8mSNyYEF2kKECVbfkNMRkEfX2q0
RUsQyA0JVFVegpVPWsQaRNp1kKQUkh3Qr1jYV/hlwZ+dke7fO6bXNIFoiWDEaIqr
UEV2XbsCMWAaieoGRKiBMqxIsXVEVw5NytQ/+t8CgYBx7goZOP/4xl4Kxmo+oBKf
/EB2qT0lf9iVuPFHFAm10hbQW/DH376wfrr6ZotilBejRl/Nk3wFky0UuWfdVpNK
Eonele8fBwPNrVN2Hs6Wf5pwpoIh52AT2bFDtq7o8TOGHUH7JrH2qhxCUWDA5qVH
/ZhXpzLk8f/prtPGvPjBBQKBgQDdE3fhu+cIKLH6j0eeWvy9X/DiUijOFQ59p2uO
iLSGMzkwrcjPA4KaiOAQE72krUHIyW64SJ3L6FubxwVObU2nowX9seE9060pFapE
Z8V/Drpq9vyaP8Fo4rWTm6VGlyrT8K+zPY71KO/6wA6FBco+nC2HY1JxloqXQelv
JLpQMQKBgQCucWu6d68jtPARZgXDsCADZIr0rz6kGPbOY3U/td437BaEZuFEERm0
0rtzbh+JOd0fFPjeOeF2zvXoygKts9eSY4SMIo/0tH+9YniWwlw85Xcez8ryPdGj
Y9cJsEWTvKKlLo2V0vaYQqNJ3qXW6SZkCkg+rwlfMmhNLrIbx7X2DA==
-----END RSA PRIVATE KEY-----

@ -1,9 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyU64VjSdgPqaQp/iaS8E
QsCYMBBKFjevaZGraPWGho3H74OYnuTbfeo3T6ufSNpK7aImM6rgsNqh6/FVYKUy
NKcD/2AYkfu8gip3zAHJBONhu0NNEkyeKx9ugvvrrgiifTDM5JYOyOSYVcVHZhsO
ASb/+eHvq3VSa/+rbgOnqeq7t2rSc+Zt/wTWAtY8OIms6uOr8drbHdvDz4+isxlN
TBW06ILDLAUS/gH2PDskPJFwAMbnmoXGoU3j5IKiWGASNWCbUAfeiTs7XIFR/bxE
vs+oGsn6vUnZV9dJR20aTG3hsR0EYEVfjzBCBpoK3Jb3RLouLnwkZAteJFmyWqAX
AwIDAQAB
-----END PUBLIC KEY-----

@ -3,8 +3,6 @@
$strings['plugin_title'] = 'LTI 1.3 Advantage Provider'; $strings['plugin_title'] = 'LTI 1.3 Advantage Provider';
$strings['plugin_comment'] = 'Simple application developed as a way to demonstrate how to build an IMS LTI tool provider'; $strings['plugin_comment'] = 'Simple application developed as a way to demonstrate how to build an IMS LTI tool provider';
$plugin_info['version'] = '1.0';
$plugin_info['author'] = 'Christian Beeznest';
$strings['description'] = 'The application allows a student inside a course of the platform with external tools which is scored (Assigment and Grade Services) and generating reporting of their members (NRP Services). $strings['description'] = 'The application allows a student inside a course of the platform with external tools which is scored (Assigment and Grade Services) and generating reporting of their members (NRP Services).
Here are your LTI connection details to try out this app:'; Here are your LTI connection details to try out this app:';
$strings['LtiProviderDescription'] = 'First thing you will need is to configure your registration and deployment. To configure your registration $strings['LtiProviderDescription'] = 'First thing you will need is to configure your registration and deployment. To configure your registration
@ -27,4 +25,7 @@ $strings['kid'] = 'kid';
$strings['public_key'] = 'Public key'; $strings['public_key'] = 'Public key';
$strings['name'] = 'Provider name'; $strings['name'] = 'Provider name';
$strings['enabled'] = 'Enabled'; $strings['enabled'] = 'Enabled';
$strings['GenerateKeyPairInfo'] = 'A new private and public key pair will be created when enabling.';
$strings['URLs'] = 'Endpoints Urls';
$strings['PlatformConnectionAdded'] = 'A platform connection is added.';

@ -1,3 +1,30 @@
<?php <?php
/* For license terms, see /license.txt */
$strings['HelloPlugin'] = "Salut!"; $strings['plugin_title'] = 'LTI 1.3 Advantage Provider';
$strings['plugin_comment'] = 'Une application simple développée pour montrer comment créer un outil IMS LTI';
$strings['description'] = 'L\'application permet à un étudiant à l\'intérieur d\'un cours de la plate-forme avec des outils externes qui est noté (Services d\'affectation et de notes) et de générer des rapports de leurs membres (Services NRP).
Voici les détails de votre connexion LTI pour essayer cette application :';
$strings['LtiProviderDescription'] = 'La première chose dont vous aurez besoin est de configurer votre enregistrement et votre déploiement. Pour configurer votre inscription
remplissez le formulaire les valeurs requises pour le déploiement dans votre plateforme';
$strings['ConnectionDetails'] = 'Détails de connexion LTI';
$strings['AddPlatform'] = 'Ajouter une plateforme client';
$strings['EditPlatform'] = 'Modifier la plateforme client';
$strings['PlatformName'] = 'LMS (émetteur)';
$strings['PlatformEdited'] = 'Détails de la plateforme modifiés';
$strings['PlatformDeleted'] = 'Plateforme supprimée';
$strings['client_id'] = 'Client ID';
$strings['launch_url'] = 'Lancer l\'URL';
$strings['login_url'] = 'URL de connexion';
$strings['redirect_url'] = 'URL de redirection';
$strings['auth_login_url'] = 'URL d\'authentification OIDC';
$strings['auth_token_url'] = 'URL du jeton d\'accès OAuth2';
$strings['key_set_url'] = 'URL du jeu de clés';
$strings['deployment_id'] = 'ID de déploiement';
$strings['kid'] = 'kid';
$strings['public_key'] = 'Clé publique';
$strings['name'] = 'Nom du fournisseur';
$strings['enabled'] = 'Enabled';
$strings['GenerateKeyPairInfo'] = 'Une nouvelle paire de clés privée et publique sera créée lors de l\'activation.';
$strings['URLs'] = 'Endpoints Urls';
$strings['PlatformConnectionAdded'] = 'Une connexion de plate-forme est ajoutée.';

@ -1,3 +1,30 @@
<?php <?php
/* For license terms, see /license.txt */
$strings['HelloPlugin'] = "Hola chaval!"; $strings['plugin_title'] = 'Proveedor de ventajas LTI 1.3';
$strings['plugin_comment'] = 'Aplicación simple desarrollada como una forma de demostrar cómo construir un proveedor de herramientas IMS LTI';
$strings['description'] = 'La aplicación permite a un alumno entrar en un curso de la plataforma con herramientas externas que se puntúan (Assigment and Grade Services) y generar informes de sus miembros (NRP Services).
Aquí están los detalles de su conexión LTI para probar esta aplicación: ';
$strings['LtiProviderDescription'] = 'Lo primero que necesitará es configurar su registro y despliegue. Para configurar su registro
complete el formulario con los valores requeridos para el despliegue en su plataforma ';
$strings['ConnectionDetails'] = 'Detalles de la conexión LTI';
$strings['AddPlatform'] = 'Agregar una plataforma de cliente';
$strings['EditPlatform'] = 'Edite la plataforma del cliente';
$strings['PlatformName'] = 'LMS (emisor)';
$strings['PlatformEdited'] = 'Detalles de la plataforma editados';
$strings['PlatformDeleted'] = 'Plataforma eliminada';
$strings['client_id'] = 'ID de cliente';
$strings['launch_url'] = 'URL de lanzamiento';
$strings['login_url'] = 'URL de inicio de sesión';
$strings['redirect_url'] = 'URL de redireccionamiento';
$strings['auth_login_url'] = 'URL de autenticación OIDC';
$strings['auth_token_url'] = 'URL del token de acceso de OAuth2';
$strings['key_set_url'] = 'URL del conjunto de claves';
$strings['deployment_id'] = 'ID de implementación';
$strings['kid'] = 'Kid';
$strings['public_key'] = 'Clave pública';
$strings['name'] = 'Nombre del proveedor';
$strings['enabled'] = 'Habilitado';
$strings['GenerateKeyPairInfo'] = 'Se creará un nuevo par de claves pública y privada cuando se habilite.';
$strings['URLs'] = 'URL de puntos finales';
$strings['PlatformConnectionAdded'] = 'Se agrega una conexión de plataforma.';

@ -39,7 +39,7 @@ class FrmEdit extends FormValidator
*/ */
public function build($globalMode = true) public function build($globalMode = true)
{ {
$plugin = ImsLtiPlugin::create(); $plugin = LtiProviderPlugin::create();
$this->addHeader($plugin->get_lang('ConnectionDetails')); $this->addHeader($plugin->get_lang('ConnectionDetails'));
$this->addText('issuer', $plugin->get_lang('PlatformName')); $this->addText('issuer', $plugin->get_lang('PlatformName'));

@ -1,9 +1,16 @@
<?php <?php
/* For licensing terms, see /license.txt */ /* For licensing terms, see /license.txt */
use \IMSGlobal\LTI; use Packback\Lti1p3;
use Chamilo\PluginBundle\Entity\LtiProvider\Platform;
require_once __DIR__ . '/../db/demo_database.php'; require_once __DIR__ . '/../db/lti13_cookie.php';
require_once __DIR__ . '/../db/lti13_cache.php';
require_once __DIR__ . '/../db/lti13_database.php';
use Packback\Lti1p3\LtiOidcLogin;
use Packback\Lti1p3\LtiMessageLaunch;
/** /**
* Class LtiProvider * Class LtiProvider
@ -15,22 +22,22 @@ class LtiProvider
* Oidc login and register * Oidc login and register
*/ */
public function login($request = null) { public function login($request = null) {
LTI\LTI_OIDC_Login::new(new Demo_Database()) LtiOidcLogin::new(new Lti13Database, new Lti13Cache(), new Lti13Cookie)
->do_oidc_login_redirect(api_get_path(WEB_PLUGIN_PATH). "lti_provider/web/game.php", $request) ->doOidcLoginRedirect(api_get_path(WEB_PLUGIN_PATH). "lti_provider/web/game.php", $request)
->do_redirect(); ->doRedirect();
} }
/** /**
* Lti Message Launch * Lti Message Launch
* @param bool $from_cache * @param bool $fromCache
* @param null $launch_id * @param null $launchId
* return $launch * return $launch
*/ */
public function launch($from_cache = false, $launch_id = null) { public function launch($fromCache = false, $launchId = null) {
if ($from_cache) { if ($fromCache) {
$launch = LTI\LTI_Message_Launch::from_cache($launch_id, new Demo_Database()); $launch = LtiMessageLaunch::fromCache($launchId, new Lti13Database(), new Lti13Cache());
} else { } else {
$launch = LTI\LTI_Message_Launch::new(new Demo_Database())->validate(); $launch = LtiMessageLaunch::new(new Lti13Database(), new Lti13Cache(), new Lti13Cookie)->validate();
} }
return $launch; return $launch;
} }

@ -1 +1 @@
{"CURSO02":{"2":{"score":"2","time":"3","name":"Christian"},"3":{"score":"6","time":"10","name":"Miguel"},"4":{"score":"15","time":"20","name":"Rosa Emerita"}},"CURSOBASE":{"1":{"name":"John","score":"4","time":"6"}},"CURSODECHRISTIAN":{"1":{"name":"Doe admin","score":"5","time":"8"}},"CURSO04":{"2":{"name":"Juan","score":"9","time":"16"}},"CURSO05":{"2":{"name":"Juan","score":"15","time":"22"}}} {"CURSO02":{"2":{"score":"2","time":"3","name":"Christian"},"3":{"score":"6","time":"10","name":"Miguel"},"4":{"score":"15","time":"20","name":"Rosa Emerita"}},"CURSOBASE":{"1":{"name":"John","score":"4","time":"6"}},"CURSODECHRISTIAN":{"1":{"name":"Doe admin","score":"5","time":"8"}},"CURSO04":{"2":{"name":"Juan","score":"9","time":"16"}},"CURSO05":{"2":{"name":"Juan","score":"15","time":"22"}},"CURSO06":{"2":{"name":"Juan","score":"8","time":"10"}}}

@ -2,29 +2,26 @@
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
require_once __DIR__.'/../../../../main/inc/global.inc.php'; require_once __DIR__.'/../../../../main/inc/global.inc.php';
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../../src/LtiProvider.php'; require_once __DIR__ . '/../../src/LtiProvider.php';
use \IMSGlobal\LTI;
$launch = LtiProvider::create()->launch(true, $_REQUEST['launch_id']); $launch = LtiProvider::create()->launch(true, $_REQUEST['launch_id']);
if (!$launch->has_ags()) { if (!$launch->hasAgs()) {
throw new Exception("Don't have grades!"); //throw new Exception("Don't have grades!");
} }
$launch_data = $launch->get_launch_data(); $launchData = $launch->getLaunchData();
$coursecode = $launch_data['https://purl.imsglobal.org/spec/lti/claim/context']['label']; $coursecode = $launchData['https://purl.imsglobal.org/spec/lti/claim/context']['label'];
$userid = $launch_data['sub']; $userid = $launchData['sub'];
$data = array(); $data = array();
$data_file = __DIR__ . '/ags/results.json'; $dataFile = __DIR__ . '/ags/results.json';
$data_content = file_get_contents($data_file); $dataContent = file_get_contents($dataFile);
if (!empty($data_content)) { if (!empty($dataContent)) {
$data = json_decode($data_content, true); $data = json_decode($dataContent, true);
} }
$data[$coursecode][$userid]['name'] = $launch_data['given_name']; $data[$coursecode][$userid]['name'] = $launchData['given_name'];
if (isset($_REQUEST['score'])) { if (isset($_REQUEST['score'])) {
$data[$coursecode][$userid]['score'] = $_REQUEST['score']; $data[$coursecode][$userid]['score'] = $_REQUEST['score'];
} }
@ -33,6 +30,10 @@ if (isset($_REQUEST['time'])) {
$data[$coursecode][$userid]['time'] = $_REQUEST['time']; $data[$coursecode][$userid]['time'] = $_REQUEST['time'];
} }
file_put_contents($data_file, json_encode($data));
if (file_exists($dataFile)) {
@chmod($dataFile, 0775);
}
file_put_contents($dataFile, json_encode($data));
echo '{"success" : true}'; echo '{"success" : true}';
?> ?>

@ -2,31 +2,29 @@
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
require_once __DIR__.'/../../../../main/inc/global.inc.php'; require_once __DIR__.'/../../../../main/inc/global.inc.php';
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../../src/LtiProvider.php'; require_once __DIR__ . '/../../src/LtiProvider.php';
use \IMSGlobal\LTI;
$launch = LtiProvider::create()->launch(true, $_REQUEST['launch_id']); $launch = LtiProvider::create()->launch(true, $_REQUEST['launch_id']);
if (!$launch->has_nrps()) { if (!$launch->hasNrps()) {
//throw new Exception("Don't have names and roles!"); //throw new Exception("Don't have names and roles!");
} }
if (!$launch->has_ags()) { if (!$launch->hasAgs()) {
throw new Exception("Don't have grades!"); //throw new Exception("Don't have grades!");
} }
$launch_data = $launch->get_launch_data(); $launchData = $launch->getLaunchData();
$coursecode = $launch_data['https://purl.imsglobal.org/spec/lti/claim/context']['label']; $coursecode = $launchData['https://purl.imsglobal.org/spec/lti/claim/context']['label'];
$data_file = __DIR__ . '/ags/results.json'; $dataFile = __DIR__ . '/ags/results.json';
$data_content = file_get_contents($data_file); $dataContent = file_get_contents($dataFile);
if (!empty($data_content)) { if (!empty($dataContent)) {
$data = json_decode($data_content, true); $data = json_decode($dataContent, true);
} }
$scoreboard = []; $scoreboard = [];
foreach ($data[$coursecode] as $user_id => $member) { foreach ($data[$coursecode] as $userId => $member) {
$scoreboard[] = array('user_id' => $user_id, 'name' => $member['name'], 'score' => $member['score'], 'time' => $member['time']); $scoreboard[] = array('user_id' => $userId, 'name' => $member['name'], 'score' => $member['score'], 'time' => $member['time']);
} }
echo json_encode($scoreboard); echo json_encode($scoreboard);
?> ?>

@ -2,19 +2,19 @@
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
require_once __DIR__.'/../../../main/inc/global.inc.php'; require_once __DIR__.'/../../../main/inc/global.inc.php';
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../src/LtiProvider.php'; require_once __DIR__ . '/../src/LtiProvider.php';
use \IMSGlobal\LTI; use Packback\Lti1p3;
$launch = LtiProvider::create()->launch(true, $_REQUEST['launch_id']); $launch = LtiProvider::create()->launch(true, $_REQUEST['launch_id']);
if (!$launch->is_deep_link_launch()) { if (!$launch->isDeepLinkLaunch()) {
throw new Exception("Must be a deep link!"); throw new Exception("Must be a deep link!");
} }
$resource = LTI\LTI_Deep_Link_Resource::new()
->set_url(api_get_path(WEB_PLUGIN_PATH)."lti_provider/web/game.php")
->set_custom_params(['difficulty' => $_REQUEST['diff']])
->set_title('Breakout ' . $_REQUEST['diff'] . ' mode!');
$launch->get_deep_link() $resource = LtiDeepLinkResource::new()
->output_response_form([$resource]); ->setUrl(api_get_path(WEB_PLUGIN_PATH)."lti_provider/web/game.php")
->setCustomParams(['difficulty' => $_REQUEST['diff']])
->setTitle('Breakout ' . $_REQUEST['diff'] . ' mode!');
$launch->getDeepLink()
->outputResponseForm([$resource]);

@ -2,25 +2,23 @@
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
require_once __DIR__.'/../../../main/inc/global.inc.php'; require_once __DIR__.'/../../../main/inc/global.inc.php';
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../src/LtiProvider.php'; require_once __DIR__ . '/../src/LtiProvider.php';
use \IMSGlobal\LTI; use Packback\Lti1p3;
$launch = LtiProvider::create()->launch(); $launch = LtiProvider::create()->launch();
$htmlHeadXtra[] = api_get_css( $htmlHeadXtra[] = api_get_css(
api_get_path(WEB_PLUGIN_PATH).'lti_provider/web/static/breakout.css' api_get_path(WEB_PLUGIN_PATH).'lti_provider/web/static/breakout.css'
); );
$template = new Template('Game demo'); $template = new Template('Game demo');
$courseCode = $launch->get_launch_data()['https://purl.imsglobal.org/spec/lti/claim/context']['label']; $courseCode = $launch->getLaunchData()['https://purl.imsglobal.org/spec/lti/claim/context']['label'];
$diff = 'normal'; $diff = 'normal';
if ($launch->is_deep_link_launch()) { if ($launch->isDeepLinkLaunch()) {
$diff = $launch->get_launch_data()['https://purl.imsglobal.org/spec/lti/claim/custom']['difficulty']; $diff = $launch->getLaunchData()['https://purl.imsglobal.org/spec/lti/claim/custom']['difficulty'];
} }
$username = $launch->get_launch_data()['given_name']; $username = $launch->getLaunchData()['given_name'];
$template->assign('launch', $launch); $template->assign('launch', $launch);
$template->assign('courseCode', $courseCode); $template->assign('courseCode', $courseCode);
$template->assign('diff', $diff); $template->assign('diff', $diff);

@ -2,8 +2,7 @@
/* For license terms, see /license.txt */ /* For license terms, see /license.txt */
require_once __DIR__.'/../../../main/inc/global.inc.php'; require_once __DIR__.'/../../../main/inc/global.inc.php';
require_once __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../src/LtiProvider.php'; require_once __DIR__ . '/../src/LtiProvider.php';
use \IMSGlobal\LTI; use Packback\Lti1p3;
LtiProvider::create()->login($_REQUEST); LtiProvider::create()->login($_REQUEST);

@ -1,11 +1,11 @@
<link href="https://fonts.googleapis.com/css?family=Gugi" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Gugi" rel="stylesheet">
{% if launch.is_deep_link_launch %} {% if launch.isDeepLinkLaunch %}
<div class="dl-config"> <div class="dl-config">
<h1>Pick a Difficulty</h1> <h1>Pick a Difficulty</h1>
<ul> <ul>
<li><a href="{{ _p.web_plugin }}lti_provider/web/configure.php?diff=easy&launch_id={{ launch.get_launch_id }}">Easy</a></li> <li><a href="{{ _p.web_plugin }}lti_provider/web/configure.php?diff=easy&launch_id={{ launch.getLaunchId }}">Easy</a></li>
<li><a href="{{ _p.web_plugin }}lti_provider/web/configure.php?diff=normal&launch_id={{ launch.get_launch_id }}">Normal</a></li> <li><a href="{{ _p.web_plugin }}lti_provider/web/configure.php?diff=normal&launch_id={{ launch.getLaunchId }}">Normal</a></li>
<li><a href="{{ _p.web_plugin }}lti_provider/web/configure.php?diff=hard&launch_id={{ launch.get_launch_id }}">Hard</a></li> <li><a href="{{ _p.web_plugin }}lti_provider/web/configure.php?diff=hard&launch_id={{ launch.getLaunchId }}">Hard</a></li>
</ul> </ul>
</div> </div>
{% else %} {% else %}
@ -28,7 +28,7 @@
<script> <script>
var curr_diff = "{{ diff }}"; var curr_diff = "{{ diff }}";
var curr_user_name = "{{ username }}"; var curr_user_name = "{{ username }}";
var launch_id = "{{ launch.get_launch_id }}"; var launch_id = "{{ launch.getLaunchId }}";
</script> </script>
<script type="text/javascript" src="{{ _p.web_plugin }}lti_provider/web/static/breakout.js" charset="utf-8"></script> <script type="text/javascript" src="{{ _p.web_plugin }}lti_provider/web/static/breakout.js" charset="utf-8"></script>

Loading…
Cancel
Save