XAPI: Allow set basic auth for LRS - refs BT#16742

pull/3680/head
Angel Fernando Quiroz Campos 5 years ago
parent 6767f13458
commit 81bfbd71e2
  1. 11
      plugin/xapi/lang/english.php
  2. 23
      plugin/xapi/launch/add.php
  3. 21
      plugin/xapi/launch/edit.php
  4. 19
      plugin/xapi/launch/launch.php
  5. 6
      plugin/xapi/launch/tool.php
  6. 40
      plugin/xapi/src/Entity/ToolLaunch.php
  7. 59
      plugin/xapi/src/XApiPlugin.php

@ -7,11 +7,12 @@ $strings['plugin_comment'] = 'Allow to incorporate an Learning Record Store and
$strings[XApiPlugin::SETTING_UUID_NAMESPACE] = 'UUID Namespace';
$strings[XApiPlugin::SETTING_UUID_NAMESPACE.'_help'] = 'Namespace for universally unique identifiers used as statement IDs.'
.'<br>This is automatically by Chamilo LMS. <strong>Don\'t replace it.</strong>';
$strings[XApiPlugin::SETTING_LRS_URL] = 'LRS: URL for API';
$strings[XApiPlugin::SETTING_LRS_URL.'_help'] = 'Sets the LRS base URL.';
$strings[XApiPlugin::SETTING_LRS_AUTH] = 'LRS: Authentication method';
$strings[XApiPlugin::SETTING_LRS_AUTH.'_help'] = 'Sets HTTP authentication credentials.<br>';
$strings[XApiPlugin::SETTING_LRS_AUTH.'_help'] .= 'Choose one auth method: Basic (<code>basic:username:password</code>) or OAuth1 (<code>oauth:key:secret</code>)';
$strings['lrs_url'] = 'LRS endpoint';
$strings['lrs_url_help'] = 'Base URL from the LRS';
$strings['lrs_auth_username'] = 'LRS user';
$strings['lrs_auth_username_help'] = 'Username for basic HTTP authentication';
$strings['lrs_auth_password'] = 'LRS password';
$strings['lrs_auth_password_help'] = 'Password for basic HTTP authentication';
$strings['NoActivities'] = 'No activities added yet';
$strings['ActivityTitle'] = 'Activity';

@ -37,8 +37,16 @@ $frmActivity->addText(
$frmActivity->addText(
'lrs_auth',
[
$plugin->get_lang('lrs_auth'),
$plugin->get_lang('lrs_auth_help'),
$plugin->get_lang('lrs_auth_username'),
$plugin->get_lang('lrs_auth_username_help'),
],
false
);
$frmActivity->addText(
'lrs_auth',
[
$plugin->get_lang('lrs_auth_password'),
$plugin->get_lang('lrs_auth_password_help'),
],
false
);
@ -84,9 +92,14 @@ if ($frmActivity->validate()) {
$toolLaunch->setDescription($values['description']);
}
if (!empty($values['lrs_url']) && !empty($values['lrs_auth'])) {
$toolLaunch->setLrsUrl($values['lrs_url']);
$toolLaunch->setLrsAuth($values['lrs_auth']);
if (!empty($values['lrs_url'])
&& !empty($values['lrs_auth_username'])
&& !empty($values['lrs_auth_password'])
) {
$toolLaunch
->setLrsUrl($values['lrs_url'])
->setLrsAuthUsername($values['lrs_auth_username'])
->setLrsAuthUsername($values['lrs_auth_password']);
}
$em = Database::getManager();

@ -56,8 +56,16 @@ $frmActivity->addText(
$frmActivity->addText(
'lrs_auth',
[
$plugin->get_lang('lrs_auth'),
$plugin->get_lang('lrs_auth_help'),
$plugin->get_lang('lrs_auth_username'),
$plugin->get_lang('lrs_auth_username_help'),
],
false
);
$frmActivity->addText(
'lrs_auth',
[
$plugin->get_lang('lrs_auth_password'),
$plugin->get_lang('lrs_auth_password_help'),
],
false
);
@ -82,8 +90,10 @@ if ($frmActivity->validate()) {
);
if (!empty($values['lrs_url']) && !empty($values['lrs_auth'])) {
$toolLaunch->setLrsUrl($values['lrs_url']);
$toolLaunch->setLrsAuth($values['lrs_auth']);
$toolLaunch
->setLrsUrl($values['lrs_url'])
->setLrsAuthUsername($values['lrs_auth_username'])
->setLrsAuthPassword($values['lrs_auth_password']);
}
$courseTool = $plugin->getCourseToolFromLaunchTool($toolLaunch);
@ -110,7 +120,8 @@ $frmActivity->setDefaults(
'launch_url' => $toolLaunch->getLaunchUrl(),
'allow_multiple_attempts' => $toolLaunch->isAllowMultipleAttempts(),
'lrs_url' => $toolLaunch->getLrsUrl(),
'lrs_auth' => $toolLaunch->getLrsAuth(),
'lrs_auth_username' => $toolLaunch->getLrsAuthUsername(),
'lrs_auth_password' => $toolLaunch->getLrsAuthPassword(),
]
);

@ -57,7 +57,13 @@ $state = new State(
$nowDate = api_get_utc_datetime(null, false, true)->format('c');
try {
$stateDocument = $plugin->getXApiStateClient()->getDocument($state);
$stateDocument = $plugin
->getXApiStateClient(
$toolLaunch->getLrsUrl(),
$toolLaunch->getLrsAuthUsername(),
$toolLaunch->getLrsAuthPassword()
)
->getDocument($state);
$data = $stateDocument->getData()->getData();
@ -111,19 +117,20 @@ try {
exit;
}
$authString = $plugin->get(XApiPlugin::SETTING_LRS_AUTH);
$parts = explode(':', $authString);
$lrsUrl = $toolLaunch->getLrsUrl() ?: $plugin->get(XApiPlugin::SETTING_LRS_URL);
$lrsAuthUsername = $toolLaunch->getLrsAuthUsername() ?: $plugin->get(XApiPlugin::SETTING_LRS_AUTH_USERNAME);
$lrsAuthPassword = $toolLaunch->getLrsAuthPassword() ?: $plugin->get(XApiPlugin::SETTING_LRS_AUTH_PASSWORD);
$activityLaunchUrl = $toolLaunch->getLaunchUrl().'?'
.http_build_query(
[
'endpoint' => $plugin->get(XApiPlugin::SETTING_LRS_URL),
'auth' => 'Basic '.base64_encode("{$parts[1]}:{$parts[2]}"),
'endpoint' => trim($lrsUrl, "/ \t\n\r\0\x0B"),
'auth' => 'Basic '.base64_encode(trim($lrsAuthUsername).':'.trim($lrsAuthPassword)),
'actor' => Serializer::createSerializer()->serialize($actor, 'json'),
'registration' => $attemptId,
'activity_id' => $toolLaunch->getActivityId(),
],
'',
null,
'&',
PHP_QUERY_RFC3986
);

@ -54,7 +54,11 @@ $cidReq = api_get_cidreq();
try {
$stateDocument = $plugin
->getXApiStateClient($toolLaunch->getLrsUrl(), $toolLaunch->getLrsAuth())
->getXApiStateClient(
$toolLaunch->getLrsUrl(),
$toolLaunch->getLrsAuthUsername(),
$toolLaunch->getLrsAuthPassword()
)
->getDocument($state);
} catch (NotFoundException $notFoundException) {
$stateDocument = null;

@ -85,9 +85,15 @@ class ToolLaunch
/**
* @var string|null
*
* @ORM\Column(name="lrs_auth", type="string", nullable=true)
* @ORM\Column(name="lrs_auth_username", type="string", nullable=true)
*/
private $lrsAuth;
private $lrsAuthUsername;
/**
* @var string|null
*
* @ORM\Column(name="lrs_auth_password", type="string", nullable=true)
*/
private $lrsAuthPassword;
/***
* @var \DateTime
*
@ -326,19 +332,39 @@ class ToolLaunch
/**
* @return string|null
*/
public function getLrsAuth(): ?string
public function getLrsAuthUsername(): ?string
{
return $this->lrsAuthUsername;
}
/**
* @param string|null $lrsAuthUsername
*
* @return ToolLaunch
*/
public function setLrsAuthUsername(?string $lrsAuthUsername): ToolLaunch
{
$this->lrsAuthUsername = $lrsAuthUsername;
return $this;
}
/**
* @return string|null
*/
public function getLrsAuthPassword(): ?string
{
return $this->lrsAuth;
return $this->lrsAuthPassword;
}
/**
* @param string|null $lrsAuth
* @param string|null $lrsAuthPassword
*
* @return ToolLaunch
*/
public function setLrsAuth(?string $lrsAuth): ToolLaunch
public function setLrsAuthPassword(?string $lrsAuthPassword): ToolLaunch
{
$this->lrsAuth = $lrsAuth;
$this->lrsAuthPassword = $lrsAuthPassword;
return $this;
}

@ -18,7 +18,8 @@ use Xabbuh\XApi\Client\XApiClientBuilderInterface;
class XApiPlugin extends Plugin implements HookPluginInterface
{
const SETTING_LRS_URL = 'lrs_url';
const SETTING_LRS_AUTH = 'lrs_auth';
const SETTING_LRS_AUTH_USERNAME = 'lrs_auth_username';
const SETTING_LRS_AUTH_PASSWORD = 'lrs_auth_password';
const SETTING_UUID_NAMESPACE = 'uuid_namespace';
const SETTING_LRS_LP_ITEM_ACTIVE = 'lrs_lp_item_viewed_active';
const SETTING_LRS_LP_ACTIVE = 'lrs_lp_end_active';
@ -59,8 +60,11 @@ class XApiPlugin extends Plugin implements HookPluginInterface
];
$settings = [
self::SETTING_UUID_NAMESPACE => 'text',
self::SETTING_LRS_URL => 'text',
self::SETTING_LRS_AUTH => 'text',
self::SETTING_LRS_AUTH_USERNAME => 'text',
self::SETTING_LRS_AUTH_PASSWORD => 'text',
self::SETTING_LRS_LP_ITEM_ACTIVE => 'boolean',
self::SETTING_LRS_LP_ACTIVE => 'boolean',
self::SETTING_LRS_QUIZ_ACTIVE => 'boolean',
@ -194,13 +198,16 @@ class XApiPlugin extends Plugin implements HookPluginInterface
/**
* @param string|null $lrsUrl
* @param string|null $lrsAuth
* @param string|null $lrsAuthUsername
* @param string|null $lrsAuthPassword
*
* @return \Xabbuh\XApi\Client\Api\StateApiClientInterface
*/
public function getXApiStateClient($lrsUrl = null, $lrsAuth = null)
public function getXApiStateClient($lrsUrl = null, $lrsAuthUsername = null, $lrsAuthPassword = null)
{
return $this->createXApiClient($lrsUrl, $lrsAuth)->getStateApiClient();
return $this
->createXApiClient($lrsUrl, $lrsAuthUsername, $lrsAuthPassword)
->getStateApiClient();
}
/**
@ -213,49 +220,25 @@ class XApiPlugin extends Plugin implements HookPluginInterface
/**
* @param string|null $lrsUrl
* @param string|null $lrsAuth
* @param string|null $lrsAuthUsername
* @param string|null $lrsAuthPassword
*
* @return \Xabbuh\XApi\Client\XApiClientInterface
*/
public function createXApiClient($lrsUrl = null, $lrsAuth = null)
private function createXApiClient($lrsUrl = null, $lrsAuthUsername = null, $lrsAuthPassword = null)
{
$baseUrl = $lrsUrl ?: trim($this->get(self::SETTING_LRS_URL), "/ \t\n\r\0\x0B");
$baseUrl = $lrsUrl ?: $this->get(self::SETTING_LRS_URL);
$lrsAuthUsername = $lrsAuthUsername ?: $this->get(self::SETTING_LRS_AUTH_USERNAME);
$lrsAuthPassword = $lrsAuthPassword ?: $this->get(self::SETTING_LRS_AUTH_PASSWORD);
$clientBuilder = new XApiClientBuilder();
$clientBuilder
->setHttpClient(Client::createWithConfig([RequestOptions::VERIFY => false]))
->setRequestFactory(new GuzzleMessageFactory())
->setBaseUrl($baseUrl);
return $this
->setAuthMethodToClient($clientBuilder, $lrsAuth)
->build();
}
/**
* @param \Xabbuh\XApi\Client\XApiClientBuilderInterface $clientBuilder
* @param string|null $lrsAuth
*
* @return \Xabbuh\XApi\Client\XApiClientBuilderInterface
*/
private function setAuthMethodToClient(XApiClientBuilderInterface $clientBuilder, $lrsAuth = null)
{
$authString = $lrsAuth ?: $this->get(self::SETTING_LRS_AUTH);
$parts = explode(':', $authString);
if (!empty($parts)) {
$method = strtolower($parts[0]);
switch ($method) {
case 'basic':
return $clientBuilder->setAuth($parts[1], $parts[2]);
case 'oauth':
return $clientBuilder->setOAuthCredentials($parts[1], $parts[2]);
}
}
->setBaseUrl(trim($baseUrl, "/ \t\n\r\0\x0B"))
->setAuth(trim($lrsAuthUsername), trim($lrsAuthPassword));
return $clientBuilder;
return $clientBuilder->build();
}
/**

Loading…
Cancel
Save