mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°7398 - be able to add custom data in session files generated by SessionHandler
This commit is contained in:
@@ -1233,6 +1233,14 @@ class Config
|
|||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
],
|
],
|
||||||
|
'sessions_tracking.session_handler_extension' => [
|
||||||
|
'type' => 'string',
|
||||||
|
'description' => 'to store more data in itop session files, set your own iSessionHandlerExtension implementation class in this variable',
|
||||||
|
'default' => '',
|
||||||
|
'value' => '',
|
||||||
|
'source_of_value' => '',
|
||||||
|
'show_in_conf_sample' => false,
|
||||||
|
],
|
||||||
'sessions_tracking.gc_threshold' => [
|
'sessions_tracking.gc_threshold' => [
|
||||||
'type' => 'integer',
|
'type' => 'integer',
|
||||||
'description' => 'fallback in case cron is not active: probability in percent that session files are cleanup during any itop request (100 means always)',
|
'description' => 'fallback in case cron is not active: probability in percent that session files are cleanup during any itop request (100 means always)',
|
||||||
|
|||||||
@@ -525,6 +525,7 @@ return array(
|
|||||||
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectsEvents' => $baseDir . '/sources/Service/TemporaryObjects/TemporaryObjectsEvents.php',
|
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectsEvents' => $baseDir . '/sources/Service/TemporaryObjects/TemporaryObjectsEvents.php',
|
||||||
'Combodo\\iTop\\SessionTracker\\SessionGC' => $baseDir . '/sources/SessionTracker/SessionGC.php',
|
'Combodo\\iTop\\SessionTracker\\SessionGC' => $baseDir . '/sources/SessionTracker/SessionGC.php',
|
||||||
'Combodo\\iTop\\SessionTracker\\SessionHandler' => $baseDir . '/sources/SessionTracker/SessionHandler.php',
|
'Combodo\\iTop\\SessionTracker\\SessionHandler' => $baseDir . '/sources/SessionTracker/SessionHandler.php',
|
||||||
|
'Combodo\\iTop\\SessionTracker\\iSessionHandlerExtension' => $baseDir . '/sources/SessionTracker/iSessionHandlerExtension.php',
|
||||||
'CompileCSSService' => $baseDir . '/application/compilecssservice.class.inc.php',
|
'CompileCSSService' => $baseDir . '/application/compilecssservice.class.inc.php',
|
||||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Config' => $baseDir . '/core/config.class.inc.php',
|
'Config' => $baseDir . '/core/config.class.inc.php',
|
||||||
@@ -1560,6 +1561,7 @@ return array(
|
|||||||
'Sabberworm\\CSS\\Value\\URL' => $vendorDir . '/sabberworm/php-css-parser/src/Value/URL.php',
|
'Sabberworm\\CSS\\Value\\URL' => $vendorDir . '/sabberworm/php-css-parser/src/Value/URL.php',
|
||||||
'Sabberworm\\CSS\\Value\\Value' => $vendorDir . '/sabberworm/php-css-parser/src/Value/Value.php',
|
'Sabberworm\\CSS\\Value\\Value' => $vendorDir . '/sabberworm/php-css-parser/src/Value/Value.php',
|
||||||
'Sabberworm\\CSS\\Value\\ValueList' => $vendorDir . '/sabberworm/php-css-parser/src/Value/ValueList.php',
|
'Sabberworm\\CSS\\Value\\ValueList' => $vendorDir . '/sabberworm/php-css-parser/src/Value/ValueList.php',
|
||||||
|
'SanitizeTrait' => $baseDir . '/core/restservices.class.inc.php',
|
||||||
'ScalarExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
'ScalarExpression' => $baseDir . '/core/oql/expression.class.inc.php',
|
||||||
'ScalarOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
'ScalarOqlExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||||
'ScssPhp\\ScssPhp\\Base\\Range' => $vendorDir . '/scssphp/scssphp/src/Base/Range.php',
|
'ScssPhp\\ScssPhp\\Base\\Range' => $vendorDir . '/scssphp/scssphp/src/Base/Range.php',
|
||||||
@@ -3201,6 +3203,7 @@ return array(
|
|||||||
'iPreferencesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
'iPreferencesExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||||
'iProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
'iProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||||
'iQueryModifier' => $baseDir . '/core/querymodifier.class.inc.php',
|
'iQueryModifier' => $baseDir . '/core/querymodifier.class.inc.php',
|
||||||
|
'iRestInputSanitizer' => $baseDir . '/application/applicationextension.inc.php',
|
||||||
'iRestServiceProvider' => $baseDir . '/application/applicationextension.inc.php',
|
'iRestServiceProvider' => $baseDir . '/application/applicationextension.inc.php',
|
||||||
'iScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
'iScheduledProcess' => $baseDir . '/core/backgroundprocess.inc.php',
|
||||||
'iSelfRegister' => $baseDir . '/core/userrights.class.inc.php',
|
'iSelfRegister' => $baseDir . '/core/userrights.class.inc.php',
|
||||||
|
|||||||
@@ -915,6 +915,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectsEvents' => __DIR__ . '/../..' . '/sources/Service/TemporaryObjects/TemporaryObjectsEvents.php',
|
'Combodo\\iTop\\Service\\TemporaryObjects\\TemporaryObjectsEvents' => __DIR__ . '/../..' . '/sources/Service/TemporaryObjects/TemporaryObjectsEvents.php',
|
||||||
'Combodo\\iTop\\SessionTracker\\SessionGC' => __DIR__ . '/../..' . '/sources/SessionTracker/SessionGC.php',
|
'Combodo\\iTop\\SessionTracker\\SessionGC' => __DIR__ . '/../..' . '/sources/SessionTracker/SessionGC.php',
|
||||||
'Combodo\\iTop\\SessionTracker\\SessionHandler' => __DIR__ . '/../..' . '/sources/SessionTracker/SessionHandler.php',
|
'Combodo\\iTop\\SessionTracker\\SessionHandler' => __DIR__ . '/../..' . '/sources/SessionTracker/SessionHandler.php',
|
||||||
|
'Combodo\\iTop\\SessionTracker\\iSessionHandlerExtension' => __DIR__ . '/../..' . '/sources/SessionTracker/iSessionHandlerExtension.php',
|
||||||
'CompileCSSService' => __DIR__ . '/../..' . '/application/compilecssservice.class.inc.php',
|
'CompileCSSService' => __DIR__ . '/../..' . '/application/compilecssservice.class.inc.php',
|
||||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
||||||
@@ -1950,6 +1951,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Sabberworm\\CSS\\Value\\URL' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/URL.php',
|
'Sabberworm\\CSS\\Value\\URL' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/URL.php',
|
||||||
'Sabberworm\\CSS\\Value\\Value' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/Value.php',
|
'Sabberworm\\CSS\\Value\\Value' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/Value.php',
|
||||||
'Sabberworm\\CSS\\Value\\ValueList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/ValueList.php',
|
'Sabberworm\\CSS\\Value\\ValueList' => __DIR__ . '/..' . '/sabberworm/php-css-parser/src/Value/ValueList.php',
|
||||||
|
'SanitizeTrait' => __DIR__ . '/../..' . '/core/restservices.class.inc.php',
|
||||||
'ScalarExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
'ScalarExpression' => __DIR__ . '/../..' . '/core/oql/expression.class.inc.php',
|
||||||
'ScalarOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
'ScalarOqlExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||||
'ScssPhp\\ScssPhp\\Base\\Range' => __DIR__ . '/..' . '/scssphp/scssphp/src/Base/Range.php',
|
'ScssPhp\\ScssPhp\\Base\\Range' => __DIR__ . '/..' . '/scssphp/scssphp/src/Base/Range.php',
|
||||||
@@ -3591,6 +3593,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'iPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
'iPreferencesExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||||
'iProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
'iProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||||
'iQueryModifier' => __DIR__ . '/../..' . '/core/querymodifier.class.inc.php',
|
'iQueryModifier' => __DIR__ . '/../..' . '/core/querymodifier.class.inc.php',
|
||||||
|
'iRestInputSanitizer' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||||
'iRestServiceProvider' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
'iRestServiceProvider' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||||
'iScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
'iScheduledProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',
|
||||||
'iSelfRegister' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
'iSelfRegister' => __DIR__ . '/../..' . '/core/userrights.class.inc.php',
|
||||||
|
|||||||
@@ -139,23 +139,60 @@ class SessionHandler extends \SessionHandler
|
|||||||
// - Data corruption (not a json / not an array / no previous creation_time key)
|
// - Data corruption (not a json / not an array / no previous creation_time key)
|
||||||
$iCreationTime = time();
|
$iCreationTime = time();
|
||||||
|
|
||||||
|
$aJson=[];
|
||||||
if (! is_null($sPreviousFileVersionContent)) {
|
if (! is_null($sPreviousFileVersionContent)) {
|
||||||
$aJson = json_decode($sPreviousFileVersionContent, true);
|
$aJson = json_decode($sPreviousFileVersionContent, true);
|
||||||
if (is_array($aJson) && array_key_exists('creation_time', $aJson)) {
|
if (is_array($aJson)){
|
||||||
$iCreationTime = $aJson['creation_time'];
|
if (array_key_exists('creation_time', $aJson)) {
|
||||||
|
$iCreationTime = $aJson['creation_time'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IssueLog::Warning(__METHOD__ . ': not a json due (session file corruption?)', null, [ 'sPreviousFileVersionContent' => $sPreviousFileVersionContent ]);
|
||||||
|
$aJson=[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$aData = [
|
||||||
|
'login_mode' => Session::Get('login_mode'),
|
||||||
|
'user_id' => $sUserId,
|
||||||
|
'creation_time' => $iCreationTime,
|
||||||
|
'context' => implode('|', ContextTag::GetStack())
|
||||||
|
];
|
||||||
|
|
||||||
|
$oiSessionHandlerExtension = $this->GetSessionHandlerExtension();
|
||||||
|
if (! is_null($oiSessionHandlerExtension)){
|
||||||
|
$oiSessionHandlerExtension->CompleteSessionData($aJson, $aData);
|
||||||
|
}
|
||||||
|
|
||||||
return json_encode (
|
return json_encode (
|
||||||
[
|
$aData
|
||||||
'login_mode' => Session::Get('login_mode'),
|
|
||||||
'user_id' => $sUserId,
|
|
||||||
'creation_time' => $iCreationTime,
|
|
||||||
'context' => implode('|', ContextTag::GetStack())
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
|
IssueLog::Error(__METHOD__, null, [ 'error' => $e->getMessage() ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function GetSessionHandlerExtension() : ?iSessionHandlerExtension
|
||||||
|
{
|
||||||
|
$sSessionHandlerExtensionClass = utils::GetConfig()->Get('sessions_tracking.session_handler_extension');
|
||||||
|
if (strlen($sSessionHandlerExtensionClass) !=0){
|
||||||
|
try{
|
||||||
|
if (! class_exists($sSessionHandlerExtensionClass)){
|
||||||
|
throw new \Exception("Cannot find class");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var iSessionHandlerExtension $oSessionHandlerExtension */
|
||||||
|
$oSessionHandlerExtension = new $sSessionHandlerExtensionClass;
|
||||||
|
if ($oSessionHandlerExtension instanceof iSessionHandlerExtension){
|
||||||
|
return $oSessionHandlerExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \Exception("Not an instance of iSessionHandlerExtension");
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
IssueLog::Error(__METHOD__ . ': cannot instanciate iSessionHandlerExtension', null, ['sessions_tracking.session_handler_extension' => $sSessionHandlerExtensionClass]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
16
sources/SessionTracker/iSessionHandlerExtension.php
Normal file
16
sources/SessionTracker/iSessionHandlerExtension.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\SessionTracker;
|
||||||
|
|
||||||
|
interface iSessionHandlerExtension {
|
||||||
|
public function __construct();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by SessionHandler to change data stored in iTop session files
|
||||||
|
* @param array $aJson: previous data stored in session file
|
||||||
|
* @param array $aData: usual session data see @SessionHandler
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function CompleteSessionData(array $aJson, array &$aData) : void;
|
||||||
|
}
|
||||||
@@ -3,19 +3,21 @@
|
|||||||
namespace Combodo\iTop\Test\UnitTest\SessionTracker;
|
namespace Combodo\iTop\Test\UnitTest\SessionTracker;
|
||||||
|
|
||||||
use Combodo\iTop\Application\Helper\Session;
|
use Combodo\iTop\Application\Helper\Session;
|
||||||
|
use Combodo\iTop\SessionTracker\iSessionHandlerExtension;
|
||||||
use Combodo\iTop\SessionTracker\SessionHandler;
|
use Combodo\iTop\SessionTracker\SessionHandler;
|
||||||
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
||||||
use ContextTag;
|
use ContextTag;
|
||||||
|
|
||||||
class SessionHandlerTest extends ItopDataTestCase
|
class SessionHandlerTest extends ItopDataTestCase
|
||||||
{
|
{
|
||||||
private $aFiles ;
|
private $aFiles;
|
||||||
private $oTag ;
|
private $oTag;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
$this->aFiles=[];
|
$this->RequireOnceUnitTestFile('./iSessionHandlerExtensionExamples.php');
|
||||||
|
$this->aFiles = [];
|
||||||
$this->oTag = new ContextTag(ContextTag::TAG_REST);
|
$this->oTag = new ContextTag(ContextTag::TAG_REST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,47 +26,53 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
$this->oTag = null;
|
$this->oTag = null;
|
||||||
|
|
||||||
foreach ($this->aFiles as $sFile){
|
foreach ($this->aFiles as $sFile) {
|
||||||
if (is_file($sFile)){
|
if (is_file($sFile)) {
|
||||||
@unlink($sFile);
|
@unlink($sFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function CreateUserAndLogIn() : ? string {
|
private function CreateUserAndLogIn(): ?string
|
||||||
|
{
|
||||||
$_SESSION = [];
|
$_SESSION = [];
|
||||||
$oUser = $this->CreateContactlessUser("admin" . uniqid(), 1, "1234@Abcdefg");
|
$oUser = $this->CreateContactlessUser("admin".uniqid(), 1, "1234@Abcdefg");
|
||||||
|
|
||||||
\UserRights::Login($oUser->Get('login'));
|
\UserRights::Login($oUser->Get('login'));
|
||||||
|
|
||||||
return $oUser->GetKey();
|
return $oUser->GetKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function GenerateSessionContent(SessionHandler $oSessionHandler, ?string $sPreviousFileVersionContent) : ?string {
|
private function GenerateSessionContent(SessionHandler $oSessionHandler, ?string $sPreviousFileVersionContent): ?string
|
||||||
|
{
|
||||||
return $this->InvokeNonPublicMethod(SessionHandler::class, "generate_session_content", $oSessionHandler, $aArgs = [$sPreviousFileVersionContent]);
|
return $this->InvokeNonPublicMethod(SessionHandler::class, "generate_session_content", $oSessionHandler, $aArgs = [$sPreviousFileVersionContent]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @covers SessionHandler::generate_session_content
|
* @covers SessionHandler::generate_session_content
|
||||||
*/
|
*/
|
||||||
public function testGenerateSessionContentNoUserLoggedIn(){
|
public function testGenerateSessionContentNoUserLoggedIn()
|
||||||
|
{
|
||||||
$oSessionHandler = new SessionHandler();
|
$oSessionHandler = new SessionHandler();
|
||||||
$sContent = $this->GenerateSessionContent($oSessionHandler, null);
|
$sContent = $this->GenerateSessionContent($oSessionHandler, null);
|
||||||
$this->assertNull($sContent, "Session content should be null when there is no user logged in");
|
$this->assertNull($sContent, "Session content should be null when there is no user logged in");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GenerateSessionContentCorruptedPreviousFileContentProvider() {
|
public function GenerateSessionContentCorruptedPreviousFileContentProvider()
|
||||||
|
{
|
||||||
return [
|
return [
|
||||||
'not a json' => [ "not a json" ],
|
'not a json' => ["not a json"],
|
||||||
'not an array' => [ json_encode("not an array") ],
|
'not an array' => [json_encode("not an array")],
|
||||||
'array without creation_time key' => [ json_encode([]) ],
|
'array without creation_time key' => [json_encode([])],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers SessionHandler::generate_session_content
|
* @covers SessionHandler::generate_session_content
|
||||||
* @dataProvider GenerateSessionContentCorruptedPreviousFileContentProvider
|
* @dataProvider GenerateSessionContentCorruptedPreviousFileContentProvider
|
||||||
*/
|
*/
|
||||||
public function testGenerateSessionContent_SessionFileRepairment(?string $sFileContent){
|
public function testGenerateSessionContent_SessionFileRepairment(?string $sFileContent)
|
||||||
|
{
|
||||||
$sUserId = $this->CreateUserAndLogIn();
|
$sUserId = $this->CreateUserAndLogIn();
|
||||||
|
|
||||||
$oSessionHandler = new SessionHandler();
|
$oSessionHandler = new SessionHandler();
|
||||||
@@ -84,7 +92,8 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
/*
|
/*
|
||||||
* @covers SessionHandler::generate_session_content
|
* @covers SessionHandler::generate_session_content
|
||||||
*/
|
*/
|
||||||
public function testGenerateSessionContent(){
|
public function testGenerateSessionContent()
|
||||||
|
{
|
||||||
$sUserId = $this->CreateUserAndLogIn();
|
$sUserId = $this->CreateUserAndLogIn();
|
||||||
|
|
||||||
$oSessionHandler = new SessionHandler();
|
$oSessionHandler = new SessionHandler();
|
||||||
@@ -105,33 +114,36 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
|
|
||||||
// Switch context + change user id via impersonation
|
// Switch context + change user id via impersonation
|
||||||
// check it is still tracked in session files
|
// check it is still tracked in session files
|
||||||
$oOtherUser = $this->CreateContactlessUser("admin" . uniqid(), 1, "1234@Abcdefg");
|
$oOtherUser = $this->CreateContactlessUser("admin".uniqid(), 1, "1234@Abcdefg");
|
||||||
$this->assertTrue(\UserRights::Impersonate($oOtherUser->Get('login')), "Failed to execute impersonate on: ".$oOtherUser->Get('login'));
|
$this->assertTrue(\UserRights::Impersonate($oOtherUser->Get('login')), "Failed to execute impersonate on: ".$oOtherUser->Get('login'));
|
||||||
$oTag2 = new ContextTag(ContextTag::TAG_SYNCHRO);
|
$oTag2 = new ContextTag(ContextTag::TAG_SYNCHRO);
|
||||||
$sNewContent = $this->GenerateSessionContent($oSessionHandler, $sFirstContent);
|
$sNewContent = $this->GenerateSessionContent($oSessionHandler, $sFirstContent);
|
||||||
$this->assertNotNull($sNewContent, 'Should not return null');
|
$this->assertNotNull($sNewContent, 'Should not return null');
|
||||||
$aJson = json_decode($sNewContent, true);
|
$aJson = json_decode($sNewContent, true);
|
||||||
$this->assertNotEquals(false, $aJson, 'Should return a valid json string, found: '.$sNewContent);
|
$this->assertNotEquals(false, $aJson, 'Should return a valid json string, found: '.$sNewContent);
|
||||||
$this->assertEquals(ContextTag::TAG_REST . '|' . ContextTag::TAG_SYNCHRO, $aJson['context'] ?? '', "After impersonation, should report the new context tags in [context]: $sNewContent");
|
$this->assertEquals(ContextTag::TAG_REST.'|'.ContextTag::TAG_SYNCHRO, $aJson['context'] ?? '', "After impersonation, should report the new context tags in [context]: $sNewContent");
|
||||||
$this->assertEquals($iFirstSessionCreationTime, $aJson['creation_time'] ?? '', "After impersonation, should still report the the session start timestamp in [creation_time]: $sNewContent");
|
$this->assertEquals($iFirstSessionCreationTime, $aJson['creation_time'] ?? '', "After impersonation, should still report the the session start timestamp in [creation_time]: $sNewContent");
|
||||||
$this->assertEquals('foo_login_mode', $aJson['login_mode'] ?? '', "After impersonation, should still report the login mode in [login_mode]: $sNewContent");
|
$this->assertEquals('foo_login_mode', $aJson['login_mode'] ?? '', "After impersonation, should still report the login mode in [login_mode]: $sNewContent");
|
||||||
$this->assertEquals($oOtherUser->GetKey(), $aJson['user_id'] ?? '', "Should report the impersonate user in [user_id]: $sNewContent");
|
$this->assertEquals($oOtherUser->GetKey(), $aJson['user_id'] ?? '', "Should report the impersonate user in [user_id]: $sNewContent");
|
||||||
}
|
}
|
||||||
|
|
||||||
private function touchSessionFile(SessionHandler $oSessionHandler, $session_id) : ?string {
|
private function touchSessionFile(SessionHandler $oSessionHandler, $session_id): ?string
|
||||||
|
{
|
||||||
$sRes = $this->InvokeNonPublicMethod(SessionHandler::class, "touch_session_file", $oSessionHandler, $aArgs = [$session_id]);
|
$sRes = $this->InvokeNonPublicMethod(SessionHandler::class, "touch_session_file", $oSessionHandler, $aArgs = [$session_id]);
|
||||||
if (!is_null($sRes) && is_file($sRes)) {
|
if (!is_null($sRes) && is_file($sRes)) {
|
||||||
// Record the file for cleanup on tearDown
|
// Record the file for cleanup on tearDown
|
||||||
$this->aFiles[] = $sRes;
|
$this->aFiles[] = $sRes;
|
||||||
}
|
}
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
|
|
||||||
return $sRes;
|
return $sRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @covers SessionHandler::touch_session_file
|
* @covers SessionHandler::touch_session_file
|
||||||
*/
|
*/
|
||||||
public function testTouchSessionFile_NoUserLoggedIn(){
|
public function testTouchSessionFile_NoUserLoggedIn()
|
||||||
|
{
|
||||||
$oSessionHandler = new SessionHandler();
|
$oSessionHandler = new SessionHandler();
|
||||||
$session_id = uniqid();
|
$session_id = uniqid();
|
||||||
$sFile = $this->touchSessionFile($oSessionHandler, $session_id);
|
$sFile = $this->touchSessionFile($oSessionHandler, $session_id);
|
||||||
@@ -143,7 +155,8 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
/*
|
/*
|
||||||
* @covers SessionHandler::touch_session_file
|
* @covers SessionHandler::touch_session_file
|
||||||
*/
|
*/
|
||||||
public function testTouchSessionFile_UserLoggedIn(){
|
public function testTouchSessionFile_UserLoggedIn()
|
||||||
|
{
|
||||||
$sUserId = $this->CreateUserAndLogIn();
|
$sUserId = $this->CreateUserAndLogIn();
|
||||||
Session::Set('login_mode', 'foo_login_mode');
|
Session::Set('login_mode', 'foo_login_mode');
|
||||||
|
|
||||||
@@ -174,7 +187,8 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
/**
|
/**
|
||||||
* @covers SessionHandler::touch_session_file
|
* @covers SessionHandler::touch_session_file
|
||||||
*/
|
*/
|
||||||
public function testTouchSessionFileWithEmptySessionId() {
|
public function testTouchSessionFileWithEmptySessionId()
|
||||||
|
{
|
||||||
$this->CreateUserAndLogIn();
|
$this->CreateUserAndLogIn();
|
||||||
Session::Set('login_mode', 'toto');
|
Session::Set('login_mode', 'toto');
|
||||||
|
|
||||||
@@ -183,32 +197,36 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
$this->assertNull($this->touchSessionFile($oSessionHandler, false), 'Should return null when session id (boolean) false');
|
$this->assertNull($this->touchSessionFile($oSessionHandler, false), 'Should return null when session id (boolean) false');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function GetFilePath(SessionHandler $oSessionHandler, $session_id) : string {
|
private function GetFilePath(SessionHandler $oSessionHandler, $session_id): string
|
||||||
|
{
|
||||||
$sFile = $this->InvokeNonPublicMethod(SessionHandler::class, "get_file_path", $oSessionHandler, $aArgs = [$session_id]);
|
$sFile = $this->InvokeNonPublicMethod(SessionHandler::class, "get_file_path", $oSessionHandler, $aArgs = [$session_id]);
|
||||||
// Record file for cleanup on tearDown
|
// Record file for cleanup on tearDown
|
||||||
$this->aFiles[] = $sFile;
|
$this->aFiles[] = $sFile;
|
||||||
|
|
||||||
return $sFile;
|
return $sFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function GgcWithTimeLimitProvider(){
|
public function GgcWithTimeLimitProvider()
|
||||||
|
{
|
||||||
return [
|
return [
|
||||||
'no cleanup time limit' => [
|
'no cleanup time limit' => [
|
||||||
'iTimeLimit' => -1,
|
'iTimeLimit' => -1,
|
||||||
'iExpectedProcessed' => 2
|
'iExpectedProcessed' => 2,
|
||||||
],
|
],
|
||||||
'cleanup time limit in the pass => first file removed only' => [
|
'cleanup time limit in the pass => first file removed only' => [
|
||||||
'iTimeLimit' => time() - 1,
|
'iTimeLimit' => time() - 1,
|
||||||
'iExpectedProcessed' => 1
|
'iExpectedProcessed' => 1,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers SessionHandler::gc_with_time_limit
|
* @covers SessionHandler::gc_with_time_limit
|
||||||
* @covers SessionHandler::list_session_files
|
* @covers SessionHandler::list_session_files
|
||||||
* @dataProvider GgcWithTimeLimitProvider
|
* @dataProvider GgcWithTimeLimitProvider
|
||||||
*/
|
*/
|
||||||
public function testGgcWithTimeLimit($iTimeLimit, $iExpectedProcessed) {
|
public function testGgcWithTimeLimit($iTimeLimit, $iExpectedProcessed)
|
||||||
|
{
|
||||||
$oSessionHandler = new SessionHandler();
|
$oSessionHandler = new SessionHandler();
|
||||||
//remove all first
|
//remove all first
|
||||||
$oSessionHandler->gc_with_time_limit(-1);
|
$oSessionHandler->gc_with_time_limit(-1);
|
||||||
@@ -218,11 +236,11 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
$iNbExpiredFiles = 2;
|
$iNbExpiredFiles = 2;
|
||||||
$iNbFiles = 5;
|
$iNbFiles = 5;
|
||||||
$iExpiredTimeStamp = time() - $max_lifetime - 1;
|
$iExpiredTimeStamp = time() - $max_lifetime - 1;
|
||||||
for($i=0; $i<$iNbFiles; $i++) {
|
for ($i = 0; $i < $iNbFiles; $i++) {
|
||||||
$sFile = $this->GetFilePath($oSessionHandler, uniqid());
|
$sFile = $this->GetFilePath($oSessionHandler, uniqid());
|
||||||
file_put_contents($sFile, "fakedata");
|
file_put_contents($sFile, "fakedata");
|
||||||
|
|
||||||
if ($iNbExpiredFiles > 0){
|
if ($iNbExpiredFiles > 0) {
|
||||||
$iNbExpiredFiles--;
|
$iNbExpiredFiles--;
|
||||||
touch($sFile, $iExpiredTimeStamp);
|
touch($sFile, $iExpiredTimeStamp);
|
||||||
}
|
}
|
||||||
@@ -230,7 +248,7 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
|
|
||||||
$aFoundSessionFiles = $oSessionHandler->list_session_files();
|
$aFoundSessionFiles = $oSessionHandler->list_session_files();
|
||||||
$this->assertEquals($iNbFiles, sizeof($aFoundSessionFiles), 'list_session_files should reports all files');
|
$this->assertEquals($iNbFiles, sizeof($aFoundSessionFiles), 'list_session_files should reports all files');
|
||||||
foreach ($aFoundSessionFiles as $sFile){
|
foreach ($aFoundSessionFiles as $sFile) {
|
||||||
$this->assertTrue(is_file($sFile), 'list_session_files should return a valid file paths, found: '.$sFile);
|
$this->assertTrue(is_file($sFile), 'list_session_files should return a valid file paths, found: '.$sFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,4 +256,64 @@ class SessionHandlerTest extends ItopDataTestCase
|
|||||||
$this->assertEquals($iExpectedProcessed, $iProcessed, 'gc_with_time_limit should report the count of expired files');
|
$this->assertEquals($iExpectedProcessed, $iProcessed, 'gc_with_time_limit should report the count of expired files');
|
||||||
$this->assertEquals($iNbFiles - $iExpectedProcessed, sizeof($oSessionHandler->list_session_files()), 'gc_with_time_limit should actually remove all processed files');
|
$this->assertEquals($iNbFiles - $iExpectedProcessed, sizeof($oSessionHandler->list_session_files()), 'gc_with_time_limit should actually remove all processed files');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public function testGetSessionHandlerExtension_NoExtension()
|
||||||
|
{
|
||||||
|
\utils::GetConfig()->Set('sessions_tracking.session_handler_extension', '');
|
||||||
|
|
||||||
|
$oSessionHandler = new SessionHandler();
|
||||||
|
$oSessionHandlerExtension = $this->InvokeNonPublicMethod(SessionHandler::class, "GetSessionHandlerExtension", $oSessionHandler);
|
||||||
|
$this->assertNull($oSessionHandlerExtension, "by default no extension");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSessionHandlerExtension_InvalidClassExtension()
|
||||||
|
{
|
||||||
|
\utils::GetConfig()->Set('sessions_tracking.session_handler_extension', 'dddf');
|
||||||
|
|
||||||
|
$oSessionHandler = new SessionHandler();
|
||||||
|
$oSessionHandlerExtension = $this->InvokeNonPublicMethod(SessionHandler::class, "GetSessionHandlerExtension", $oSessionHandler);
|
||||||
|
$this->assertNull($oSessionHandlerExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSessionHandlerExtension_InvalidExtension()
|
||||||
|
{
|
||||||
|
\utils::GetConfig()->Set('sessions_tracking.session_handler_extension', Session::class);
|
||||||
|
|
||||||
|
$oSessionHandler = new SessionHandler();
|
||||||
|
$oSessionHandlerExtension = $this->InvokeNonPublicMethod(SessionHandler::class, "GetSessionHandlerExtension", $oSessionHandler);
|
||||||
|
$this->assertNull($oSessionHandlerExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetSessionHandlerExtension_OK()
|
||||||
|
{
|
||||||
|
\utils::GetConfig()->Set('sessions_tracking.session_handler_extension', 'Combodo\iTop\Test\UnitTest\SessionTracker\BasicSessionHandlerExtension');
|
||||||
|
|
||||||
|
$oSessionHandler = new SessionHandler();
|
||||||
|
$oSessionHandlerExtension = $this->InvokeNonPublicMethod(SessionHandler::class, "GetSessionHandlerExtension", $oSessionHandler);
|
||||||
|
$this->assertNotNull($oSessionHandlerExtension, "by default no extension");
|
||||||
|
$this->assertTrue($oSessionHandlerExtension instanceof iSessionHandlerExtension);
|
||||||
|
$this->assertInstanceOf(BasicSessionHandlerExtension::class, $oSessionHandlerExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGenerateSessionContent_WithAdditionalDataProvidedBySessionHandlerExtension()
|
||||||
|
{
|
||||||
|
\utils::GetConfig()->Set('sessions_tracking.session_handler_extension', 'Combodo\iTop\Test\UnitTest\SessionTracker\BasicSessionHandlerExtension');
|
||||||
|
$sUserId = $this->CreateUserAndLogIn();
|
||||||
|
|
||||||
|
$oSessionHandler = new SessionHandler();
|
||||||
|
Session::Set('login_mode', 'foo_login_mode');
|
||||||
|
|
||||||
|
//first time
|
||||||
|
$sFirstContent = $this->GenerateSessionContent($oSessionHandler, null);
|
||||||
|
$this->assertNotNull($sFirstContent, 'Should not return null');
|
||||||
|
$aJson = json_decode($sFirstContent, true);
|
||||||
|
$this->assertNotEquals(false, $aJson, 'Should return a valid json string, found: '.$sFirstContent);
|
||||||
|
|
||||||
|
$this->assertEquals($sUserId, $aJson['user_id'] ?? '', "Should report the login of the logged in user in [user_id]: $sFirstContent");
|
||||||
|
$this->assertEquals(ContextTag::TAG_REST, $aJson['context'] ?? '', "Should report the context tag(s) in [context]: $sFirstContent");
|
||||||
|
$this->assertIsInt($aJson['creation_time'] ?? '', "Should report the session start timestamp in [creation_time]: $sFirstContent");
|
||||||
|
$this->assertEquals('foo_login_mode', $aJson['login_mode'] ?? '', "Should report the current login mode in [login_mode]: $sFirstContent");
|
||||||
|
|
||||||
|
$this->assertEquals('gabuzomeu', $aJson['shadok'] ?? '', "Should report the current login mode in [shadok]: $sFirstContent");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Test\UnitTest\SessionTracker;
|
||||||
|
|
||||||
|
use Combodo\iTop\SessionTracker\iSessionHandlerExtension;
|
||||||
|
|
||||||
|
class BasicSessionHandlerExtension implements iSessionHandlerExtension {
|
||||||
|
public function __construct(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CompleteSessionData(array $aJson, array &$aData): void
|
||||||
|
{
|
||||||
|
$aData['shadok']='gabuzomeu';
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user