Plugin - Allow to use jwks url in client LTI - refs BT#20451

pull/4506/head
Christian 3 years ago
parent e6ef1eb41b
commit 1f8c92fe9b
  1. 33
      plugin/ims_lti/Entity/ImsLtiTool.php
  2. 29
      plugin/ims_lti/ImsLtiPlugin.php
  3. 1
      plugin/ims_lti/create.php
  4. 1
      plugin/ims_lti/edit.php
  5. 4
      plugin/ims_lti/lang/english.php
  6. 4
      plugin/ims_lti/lang/french.php
  7. 4
      plugin/ims_lti/lang/spanish.php
  8. 20
      plugin/ims_lti/src/Form/FrmAdd.php
  9. 17
      plugin/ims_lti/src/Form/FrmEdit.php
  10. 2
      plugin/ims_lti/src/ImsLti.php
  11. 3
      plugin/ims_lti/start.php

@ -134,6 +134,13 @@ class ImsLtiTool
*/
private $redirectUrl;
/**
* @var string|null
*
* @ORM\Column(name="jwks_url", type="string", nullable=true)
*/
private $jwksUrl;
/**
* @var array
*
@ -183,7 +190,7 @@ class ImsLtiTool
$this->consumerKey = null;
$this->sharedSecret = null;
$this->lineItems = new ArrayCollection();
$this->version = \ImsLti::V_1P1;
$this->version = \ImsLti::V_1P3;
$this->launchPresentation = [
'document_target' => 'iframe',
];
@ -626,6 +633,30 @@ class ImsLtiTool
return $this;
}
/**
* Get jwksUrl.
*
* @return string|null
*/
public function getJwksUrl()
{
return $this->jwksUrl;
}
/**
* Set jwksUrl.
*
* @param string|null $jwksUrl
*
* @return ImsLtiTool
*/
public function setJwksUrl($jwksUrl)
{
$this->jwksUrl = $jwksUrl;
return $this;
}
/**
* Get clientId.
*

@ -11,6 +11,7 @@ use Chamilo\PluginBundle\Entity\ImsLti\Platform;
use Chamilo\PluginBundle\Entity\ImsLti\Token;
use Chamilo\UserBundle\Entity\User;
use Doctrine\ORM\Tools\SchemaTool;
use Firebase\JWT\JWK;
/**
* Description of MsiLti.
@ -583,6 +584,34 @@ class ImsLtiPlugin extends Plugin
});
}
/**
* It gets the public key from jwks or rsa keys.
*
* @param ImsLtiTool $tool
*
* @return mixed|string|null
*/
public static function getToolPublicKey(ImsLtiTool $tool)
{
$publicKey = '';
if (!empty($tool->getJwksUrl())) {
$publicKeySet = json_decode(file_get_contents($tool->getJwksUrl()), true);
$pk = [];
foreach ($publicKeySet['keys'] as $key) {
$pk = openssl_pkey_get_details(
JWK::parseKeySet(['keys' => [$key]])[$key['kid']]
);
}
if (!empty($pk)) {
$publicKey = $pk['key'];
}
} else {
$publicKey = $tool->publicKey;
};
return $publicKey;
}
/**
* @return string
*/

@ -57,6 +57,7 @@ if ($form->validate()) {
'ags' => $formValues['1p3_ags'],
]
)
->setJwksUrl($formValues['jwks_url'])
->publicKey = $formValues['public_key'];
} else {
if (empty($formValues['consumer_key']) && empty($formValues['shared_secret'])) {

@ -73,6 +73,7 @@ if ($form->validate()) {
'nrps' => $formValues['1p3_nrps'],
]
)
->setJwksUrl($formValues['jwks_url'])
->publicKey = $formValues['public_key'];
}

@ -49,6 +49,10 @@ $strings['PublicKey'] = 'Public key';
$strings['PrivateKey'] = 'Private key';
$strings['PlatformDateUpdated'] = 'Platform data updated';
$strings['LtiVersion'] = 'LTI Version';
$strings['PublicKeyType'] = 'Public key type';
$strings['KeySetUrl'] = 'Keyset URL';
$strings['RsaKey'] = 'RSA key';
$strings['PublicKeyset'] = 'Jwks URL';
$strings['LoginUrl'] = 'Login URL';
$strings['RedirectUrl'] = 'Redirect URL';
$strings['AssigmentAndGradesService'] = 'Assigment and Grades Service';

@ -49,6 +49,10 @@ $strings['PublicKey'] = 'Clef publique';
$strings['PrivateKey'] = 'Clef privée';
$strings['PlatformDateUpdated'] = 'Données de la plateforme mises à jour';
$strings['LtiVersion'] = 'Version LTI';
$strings['PublicKeyType'] = 'Type de clé publique';
$strings['KeySetUrl'] = 'URL du jeu de clés';
$strings['RsaKey'] = 'Clé RSA';
$strings['PublicKeyset'] = 'URL de Jwks';
$strings['LoginUrl'] = 'URL de connexion';
$strings['RedirectUrl'] = 'URL de redirection';
$strings['AssigmentAndGradesService'] = 'Service de travaux et notes';

@ -49,6 +49,10 @@ $strings['PublicKey'] = 'Llave pública';
$strings['PrivateKey'] = 'Llave privada';
$strings['PlatformDateUpdated'] = 'Datos de la plataforma actualizados.';
$strings['LtiVersion'] = 'Versión LTI';
$strings['PublicKeyType'] = 'Tipo de clave pública';
$strings['KeySetUrl'] = 'KeySet URL';
$strings['RsaKey'] = 'Clave RSA';
$strings['PublicKeyset'] = 'URL de Jwks';
$strings['LoginUrl'] = 'URL de Login';
$strings['RedirectUrl'] = 'URL de redirección';
$strings['AssigmentAndGradesService'] = 'Servicio de tareas y notas';

@ -73,11 +73,24 @@ class FrmAdd extends FormValidator
$this->addText('shared_secret', $plugin->get_lang('SharedSecret'), false);
$this->addHtml('</div>');
$this->addHtml('<div class="'.ImsLti::V_1P3.'" style="display: block;">');
$this->addRadio(
'public_key_type',
$plugin->get_lang('PublicKeyType'),
[
ImsLti::LTI_JWK_KEYSET => $plugin->get_lang('KeySetUrl'),
ImsLti::LTI_RSA_KEY => $plugin->get_lang('RsaKey'),
]
);
$this->addHtml('<div class="'.ImsLti::LTI_JWK_KEYSET.'" style="display: block;">');
$this->addUrl('jwks_url', $plugin->get_lang('PublicKeyset'), false);
$this->addHtml('</div>');
$this->addHtml('<div class="'.ImsLti::LTI_RSA_KEY.'" style="display: none;">');
$this->addTextarea(
'public_key',
$plugin->get_lang('PublicKey'),
['style' => 'font-family: monospace;', 'rows' => 5]
);
$this->addHtml('</div>');
$this->addUrl('login_url', $plugin->get_lang('LoginUrl'), false);
$this->addUrl('redirect_url', $plugin->get_lang('RedirectUrl'), false);
$this->addHtml('</div>');
@ -178,6 +191,7 @@ class FrmAdd extends FormValidator
{
$defaults = [];
$defaults['version'] = ImsLti::V_1P3;
$defaults['public_key_type'] = ImsLti::LTI_JWK_KEYSET;
if ($this->baseTool) {
$defaults['name'] = $this->baseTool->getName();
@ -209,6 +223,12 @@ class FrmAdd extends FormValidator
\$('[name=\"version\"]').on('change', function () {
$('.".ImsLti::V_1P1.", .".ImsLti::V_1P3."').hide();
$('.' + this.value).show();
})
\$('[name=\"public_key_type\"]').on('change', function () {
$('.".ImsLti::LTI_JWK_KEYSET.", .".ImsLti::LTI_RSA_KEY."').hide();
$('[name=\"public_key\"], [name=\"jwks_url\"]').val('');
$('.' + this.value).show();
})
});

@ -82,12 +82,16 @@ class FrmEdit extends FormValidator
} elseif ($this->tool->getVersion() === ImsLti::V_1P3) {
$this->addText('client_id', $plugin->get_lang('ClientId'), true);
$this->freeze(['client_id']);
$this->addTextarea(
'public_key',
$plugin->get_lang('PublicKey'),
['style' => 'font-family: monospace;', 'rows' => 5],
true
);
if (!empty($this->tool->getJwksUrl())) {
$this->addUrl('jwks_url', $plugin->get_lang('PublicKeyset'));
} else {
$this->addTextarea(
'public_key',
$plugin->get_lang('PublicKey'),
['style' => 'font-family: monospace;', 'rows' => 5],
true
);
}
$this->addUrl('login_url', $plugin->get_lang('LoginUrl'));
$this->addUrl('redirect_url', $plugin->get_lang('RedirectUrl'));
}
@ -207,6 +211,7 @@ class FrmEdit extends FormValidator
'version' => $this->tool->getVersion(),
'client_id' => $this->tool->getClientId(),
'public_key' => $this->tool->publicKey,
'jwks_url' => $this->tool->getJwksUrl(),
'login_url' => $this->tool->getLoginUrl(),
'redirect_url' => $this->tool->getRedirectUrl(),
'1p3_ags' => $advServices['ags'],

@ -13,6 +13,8 @@ class ImsLti
{
const V_1P1 = 'lti1p1';
const V_1P3 = 'lti1p3';
const LTI_RSA_KEY = 'rsa_key';
const LTI_JWK_KEYSET = 'jwk_keyset';
/**
* @param Session|null $session Optional.

@ -22,8 +22,9 @@ if (!$tool) {
$imsLtiPlugin = ImsLtiPlugin::create();
$pageTitle = Security::remove_XSS($tool->getName());
$publicKey = ImsLtiPlugin::getToolPublicKey($tool);
$is1p3 = !empty($tool->publicKey) && !empty($tool->getClientId()) &&
$is1p3 = !empty($publicKey) && !empty($tool->getClientId()) &&
!empty($tool->getLoginUrl()) && !empty($tool->getRedirectUrl());
if ($is1p3) {

Loading…
Cancel
Save