253 lines
7.8 KiB
PHP
253 lines
7.8 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; under version 2
|
||
|
* of the License (non-upgradable).
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* Copyright (c) 2017-2020 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
|
||
|
*/
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace oat\taoLti\models\classes\user;
|
||
|
|
||
|
use common_Exception;
|
||
|
use Exception;
|
||
|
use oat\generis\model\GenerisRdf;
|
||
|
use oat\oatbox\event\EventManager;
|
||
|
use oat\oatbox\service\ConfigurableService;
|
||
|
use oat\taoLti\models\classes\LtiLaunchData;
|
||
|
use oat\oatbox\mutex\LockTrait;
|
||
|
use oat\taoLti\models\classes\user\events\dispatcher\LtiUserEventDispatcher;
|
||
|
use oat\taoLti\models\classes\user\events\LtiUserCreatedEvent;
|
||
|
use oat\taoLti\models\classes\user\events\LtiUserUpdatedEvent;
|
||
|
|
||
|
/**
|
||
|
* Lti user service, allow us to find or spawn a lti user based on launch data
|
||
|
*
|
||
|
* @access public
|
||
|
* @author Antoine Antoine, <joel@taotesting.com>
|
||
|
* @package taoLti
|
||
|
*/
|
||
|
abstract class LtiUserService extends ConfigurableService
|
||
|
{
|
||
|
use LockTrait;
|
||
|
|
||
|
const SERVICE_ID = 'taoLti/LtiUserService';
|
||
|
|
||
|
const OPTION_FACTORY_LTI_USER = 'factoryLtiUser';
|
||
|
|
||
|
const PROPERTY_USER_LTICONSUMER = 'http://www.tao.lu/Ontologies/TAOLTI.rdf#UserConsumer';
|
||
|
|
||
|
const PROPERTY_USER_LTIKEY = 'http://www.tao.lu/Ontologies/TAOLTI.rdf#UserKey';
|
||
|
|
||
|
/**
|
||
|
* Returns the existing tao User that corresponds to
|
||
|
* the LTI request or spawns it
|
||
|
*
|
||
|
* @param LtiLaunchData $launchData
|
||
|
* @return LtiUser
|
||
|
* @throws common_Exception
|
||
|
* @throws \common_exception_Error
|
||
|
* @throws \core_kernel_users_CacheException
|
||
|
* @throws \core_kernel_users_Exception
|
||
|
* @throws \oat\taoLti\models\classes\LtiVariableMissingException
|
||
|
*/
|
||
|
public function findOrSpawnUser(LtiLaunchData $launchData)
|
||
|
{
|
||
|
$lock = $this->createLock(__METHOD__ . $launchData->getUserID() . $launchData->getLtiConsumer()->getUri(), 30);
|
||
|
$lock->acquire(true);
|
||
|
|
||
|
try {
|
||
|
$taoUser = $this->findUser($launchData);
|
||
|
if ($taoUser === null) {
|
||
|
$taoUser = $this->spawnUser($launchData);
|
||
|
|
||
|
$this->getLtiUserEventDispatcher()->dispatch($taoUser);
|
||
|
}
|
||
|
} finally {
|
||
|
$lock->release();
|
||
|
}
|
||
|
|
||
|
return $taoUser;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Searches if this user was already created in TAO
|
||
|
*
|
||
|
* @param LtiLaunchData $ltiContext
|
||
|
* @return LtiUser
|
||
|
* @throws common_Exception
|
||
|
* @throws \common_exception_Error
|
||
|
* @throws \core_kernel_users_CacheException
|
||
|
* @throws \core_kernel_users_Exception
|
||
|
* @throws \oat\taoLti\models\classes\LtiVariableMissingException
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function findUser(LtiLaunchData $ltiContext)
|
||
|
{
|
||
|
$ltiConsumer = $ltiContext->getLtiConsumer();
|
||
|
$taoUserId = $this->getUserIdentifier($ltiContext->getUserID(), $ltiConsumer->getUri());
|
||
|
if (is_null($taoUserId)) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
$ltiUser = $this->createLtiUser($ltiContext, $taoUserId);
|
||
|
|
||
|
\common_Logger::t("LTI User '" . $ltiUser->getIdentifier() . "' found.");
|
||
|
|
||
|
$this->updateUser($ltiUser, $ltiContext);
|
||
|
|
||
|
return $ltiUser;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param LtiUser $user
|
||
|
* @param LtiLaunchData $ltiContext
|
||
|
* @return mixed
|
||
|
*/
|
||
|
abstract protected function updateUser(LtiUserInterface $user, LtiLaunchData $ltiContext);
|
||
|
|
||
|
/**
|
||
|
* Find the tao user identifier related to a lti user id and a consumer
|
||
|
* @param string $ltiUserId
|
||
|
* @param \core_kernel_classes_Resource $consumer
|
||
|
* @return mixed
|
||
|
*/
|
||
|
abstract public function getUserIdentifier($ltiUserId, $consumer);
|
||
|
|
||
|
/**
|
||
|
* Creates a new LTI User with the absolute minimum of required informations
|
||
|
*
|
||
|
* @param LtiLaunchData $ltiContext
|
||
|
* @return LtiUserInterface
|
||
|
* @throws common_Exception
|
||
|
* @throws \common_exception_Error
|
||
|
* @throws \core_kernel_users_CacheException
|
||
|
* @throws \core_kernel_users_Exception
|
||
|
* @throws \oat\taoLti\models\classes\LtiVariableMissingException
|
||
|
* @throws Exception
|
||
|
*/
|
||
|
public function spawnUser(LtiLaunchData $ltiContext)
|
||
|
{
|
||
|
//@TODO create LtiUser after create and save in db.
|
||
|
$userId = $ltiContext->getUserID();
|
||
|
|
||
|
$ltiUser = $this->createLtiUser($ltiContext, $userId);
|
||
|
|
||
|
$this->updateUser($ltiUser, $ltiContext);
|
||
|
|
||
|
return $ltiUser;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the user information from the tao user identifier
|
||
|
* @param string $taoUserId
|
||
|
* @return array structure that represent the user
|
||
|
* [
|
||
|
* 'http://www.tao.lu/Ontologies/generis.rdf#userRoles' => ['firstRole', 'secondRole'],
|
||
|
* 'http://www.tao.lu/Ontologies/generis.rdf#userUILg' => 'en-US',
|
||
|
* 'http://www.tao.lu/Ontologies/generis.rdf#userFirstName' => 'firstname,
|
||
|
* 'http://www.tao.lu/Ontologies/generis.rdf#userLastName' => 'lastname',
|
||
|
* 'http://www.tao.lu/Ontologies/generis.rdf#userMail' => 'test@test.com',
|
||
|
* 'http://www.w3.org/2000/01/rdf-schema#label' => 'label'
|
||
|
* ]
|
||
|
*/
|
||
|
abstract public function getUserDataFromId($taoUserId);
|
||
|
|
||
|
/**
|
||
|
* @param array $userData
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getUserName(array $userData)
|
||
|
{
|
||
|
$firstName = $this->getFirstName($userData);
|
||
|
$lastName = $this->getLastName($userData);
|
||
|
|
||
|
$userName = trim($firstName . ' ' . $lastName);
|
||
|
|
||
|
return $userName;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $userData
|
||
|
* @return mixed|string
|
||
|
*/
|
||
|
public function getLastName(array $userData)
|
||
|
{
|
||
|
return isset($userData[GenerisRdf::PROPERTY_USER_LASTNAME])
|
||
|
? $userData[GenerisRdf::PROPERTY_USER_LASTNAME]
|
||
|
: '';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array $userData
|
||
|
* @return string
|
||
|
*/
|
||
|
public function getFirstName(array $userData)
|
||
|
{
|
||
|
return isset($userData[GenerisRdf::PROPERTY_USER_FIRSTNAME])
|
||
|
? $userData[GenerisRdf::PROPERTY_USER_FIRSTNAME]
|
||
|
: '';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param LtiLaunchData $ltiContext
|
||
|
* @param string $userId
|
||
|
* @return LtiUserInterface
|
||
|
* @throws common_Exception
|
||
|
*/
|
||
|
protected function createLtiUser(LtiLaunchData $ltiContext, $userId)
|
||
|
{
|
||
|
return $this->getLtiUserFactory()->create($ltiContext, $userId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return LtiUserFactoryInterface
|
||
|
* @throws common_Exception
|
||
|
*/
|
||
|
protected function getLtiUserFactory()
|
||
|
{
|
||
|
$ltiUserFactory = $this->getServiceLocator()->get($this->getOption(static::OPTION_FACTORY_LTI_USER));
|
||
|
if (!$ltiUserFactory instanceof LtiUserFactoryInterface) {
|
||
|
throw new common_Exception('Lti Factory it is not a LtiUserFactoryInterface');
|
||
|
}
|
||
|
|
||
|
return $ltiUserFactory;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return EventManager
|
||
|
*/
|
||
|
protected function getEventManager()
|
||
|
{
|
||
|
return $this->getServiceLocator()->get(EventManager::SERVICE_ID);
|
||
|
}
|
||
|
|
||
|
protected function userUpdatedEvent($userId)
|
||
|
{
|
||
|
$this->getEventManager()->trigger(new LtiUserUpdatedEvent($userId));
|
||
|
}
|
||
|
|
||
|
protected function userCreatedEvent($userId)
|
||
|
{
|
||
|
$this->getEventManager()->trigger(new LtiUserCreatedEvent($userId));
|
||
|
}
|
||
|
|
||
|
private function getLtiUserEventDispatcher(): LtiUserEventDispatcher
|
||
|
{
|
||
|
return $this->getServiceLocator()->get(LtiUserEventDispatcher::class);
|
||
|
}
|
||
|
}
|