Removing user counting from iTop (to put it in itop-system-information)

This commit is contained in:
jf-cbd
2026-06-11 16:25:20 +02:00
parent 2803c296be
commit 1e7238a791
2 changed files with 47 additions and 304 deletions

View File

@@ -46,6 +46,13 @@ use utils;
*/
class UserRightsTest extends ItopDataTestCase
{
public function setUp(): void
{
parent::setUp();
utils::GetConfig()->SetModuleSetting('authent-local', 'password_validation.pattern', '');
}
public static $aClasses = [
'FunctionalCI' => ['class' => 'FunctionalCI', 'attcode' => 'name'],
'URP_UserProfile' => ['class' => 'URP_UserProfile', 'attcode' => 'reason'],
@@ -54,11 +61,24 @@ class UserRightsTest extends ItopDataTestCase
'ModuleInstallation' => ['class' => 'ModuleInstallation', 'attcode' => 'name'],
];
public function setUp(): void
/**
* @param string $sLoginPrefix
* @param int $iProfileId initial profile
*
* @return \DBObject
* @throws \CoreException
* @throws \Exception
*/
protected function CreateUniqueUserAndLogin(string $sLoginPrefix, int $iProfileId): DBObject
{
parent::setUp();
static $iCount = 0;
$sLogin = $sLoginPrefix.$iCount;
$iCount++;
utils::GetConfig()->SetModuleSetting('authent-local', 'password_validation.pattern', '');
$oUser = self::CreateUser($sLogin, $iProfileId);
$_SESSION = [];
UserRights::Login($sLogin);
return $oUser;
}
/**
@@ -209,26 +229,19 @@ class UserRightsTest extends ItopDataTestCase
$this->assertEquals($aClassActionResult['res'], $bRes);
}
/**
* @param string $sLoginPrefix
* @param int $iProfileId initial profile
/*
* FunctionalCI => bizmodel searchable
* UserRequest => bizmodel searchable requestmgmt
* URP_UserProfile => addon/userrights
* UserLocal => addon/authentication
* ModuleInstallation => core view_in_gui
*
* Profiles:
* 1 - Administrator
* 2 - User Portal
* 3 - Configuration manager
*
* @return \DBObject
* @throws \CoreException
* @throws \Exception
*/
protected function CreateUniqueUserAndLogin(string $sLoginPrefix, int $iProfileId): DBObject
{
static $iCount = 0;
$sLogin = $sLoginPrefix.$iCount;
$iCount++;
$oUser = self::CreateUser($sLogin, $iProfileId);
$_SESSION = [];
UserRights::Login($sLogin);
return $oUser;
}
public function ActionAllowedProvider(): array
{
return [
@@ -276,20 +289,6 @@ class UserRightsTest extends ItopDataTestCase
];
}
/*
* FunctionalCI => bizmodel searchable
* UserRequest => bizmodel searchable requestmgmt
* URP_UserProfile => addon/userrights
* UserLocal => addon/authentication
* ModuleInstallation => core view_in_gui
*
* Profiles:
* 1 - Administrator
* 2 - User Portal
* 3 - Configuration manager
*
*/
/** Test IsActionAllowedOnAttribute
*
* @dataProvider ActionAllowedOnAttributeProvider
@@ -309,6 +308,14 @@ class UserRightsTest extends ItopDataTestCase
$this->assertEquals($aClassActionResult['res'], $bRes);
}
/*
* FunctionalCI => bizmodel searchable
* UserRequest => bizmodel searchable requestmgmt
* URP_UserProfile => addon/userrights grant_by_profile
* UserLocal => addon/authentication grant_by_profile
* ModuleInstallation => core view_in_gui
*
*/
public function ActionAllowedOnAttributeProvider(): array
{
return [
@@ -335,15 +342,6 @@ class UserRightsTest extends ItopDataTestCase
];
}
/*
* FunctionalCI => bizmodel searchable
* UserRequest => bizmodel searchable requestmgmt
* URP_UserProfile => addon/userrights grant_by_profile
* UserLocal => addon/authentication grant_by_profile
* ModuleInstallation => core view_in_gui
*
*/
/**
* @dataProvider UserCannotLoseConsoleAccessProvider
*
@@ -487,7 +485,6 @@ class UserRightsTest extends ItopDataTestCase
$oUser->DBInsert();
}
public function PrivilegedUsersMustHaveBackofficeAccessProvider(): array
{
return [
@@ -497,7 +494,6 @@ class UserRightsTest extends ItopDataTestCase
];
}
public function testNonPrivilegedUsersCanBeDeniedFromBackoffice()
{
$oUser = $this->GivenUserWithProfiles('test1', [5, 2]);
@@ -533,7 +529,6 @@ class UserRightsTest extends ItopDataTestCase
'with Admins hidden' => [true],
];
}
/**
* @dataProvider NonAdminCannotListAdminProfilesProvider
*/
@@ -580,12 +575,6 @@ class UserRightsTest extends ItopDataTestCase
);
}
public function FindUserAndAssertItHasBeenFound($sLogin, $iExpectedKey)
{
$oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]);
static::assertIsDBObject(\User::class, $iExpectedKey, $oUser, 'FindUser should return the User object corresponding to the login');
}
public function testFindUser_ExistingExternalUser()
{
$sLogin = 'AnExternalUser'.uniqid();
@@ -621,6 +610,11 @@ class UserRightsTest extends ItopDataTestCase
);
}
public function FindUserAndAssertItHasBeenFound($sLogin, $iExpectedKey)
{
$oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]);
static::assertIsDBObject(\User::class, $iExpectedKey, $oUser, 'FindUser should return the User object corresponding to the login');
}
public function FindUserAndAssertItWasNotFound($sLogin)
{
$oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]);

View File

@@ -1,251 +0,0 @@
<?php
namespace Users;
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
use Combodo\iTop\Users\ITopUserCountingRepository;
use MetaModel;
use User;
class ITopUserCountingRepositoryTest extends ItopDataTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->CreateReadOnlyUsers();
$this->CreateDisabledUsers();
$this->CreatePortalUsers();
if (MetaModel::IsValidClass('UserToken')) {
$this->CreateTokenUsers();
}
$this->CreateConsoleUsers();
$this->CreateBusinessPartnerUser();
}
private function CreateReadOnlyUsers()
{
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Configuration ReadOnly']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Ticket ReadOnly']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Service Catalog ReadOnly']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Configuration ReadOnly', 'Portal user']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Ticket ReadOnly', 'Portal user']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Service Catalog ReadOnly', 'Portal user']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Configuration ReadOnly', 'Ticket ReadOnly']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Ticket ReadOnly', 'Service Catalog ReadOnly']);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Configuration ReadOnly', 'Ticket ReadOnly', 'Service Catalog ReadOnly']);
}
private function CreateDisabledUsers()
{
$iDisabledUser = $this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Configuration Manager'], bReturnLogin: false);
$oUser = \MetaModel::GetObject('User', $iDisabledUser);
$oUser->Set('status', 'disabled');
$oUser->DBUpdate();
$iDisabledReadOnlyUser = $this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Ticket ReadOnly'], bReturnLogin: false);
$oUser = \MetaModel::GetObject('User', $iDisabledReadOnlyUser);
$oUser->Set('status', 'disabled');
$oUser->DBUpdate();
}
private function CreatePortalUsers()
{
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Portal user'], false);
$iDisabledPortalUser = $this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Portal user'], bReturnLogin: false);
$oUser = \MetaModel::GetObject('User', $iDisabledPortalUser);
$oUser->Set('status', 'disabled');
$oUser->DBUpdate();
}
private function CreateTokenUsers()
{
$this->GivenTokenUserInDB(['Configuration Manager'], false);
$this->GivenTokenUserInDB(['Portal user'], false);
$this->GivenTokenUserInDB(['Configuration ReadOnly'], false);
}
private function CreateConsoleUsers()
{
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Configuration Manager'], bReturnLogin: false);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Administrator'], bReturnLogin: false);
}
private function CreateBusinessPartnerUser()
{
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Business partner user'], bReturnLogin: false);
$this->GivenUserInDB('qpf_z17H3232*"ré$"é', ['Business partner user'], bReturnLogin: false);
}
/**
* @throws \CoreUnexpectedValue
* @throws \DictExceptionMissingString
* @throws \CoreException
* @throws \MySQLException
* @throws \Exception
*/
public function testNotDuplicateInDifferentCountsCategories(): void
{
$oITopUserRepository = new ITopUserCountingRepository();
$aCountedUsers = [
'console' => $oITopUserRepository->GetConsoleUsers(),
'portal' => $oITopUserRepository->GetPortalUsers(),
'disabled' => $oITopUserRepository->GetDisabledUsers(),
'readonly' => $oITopUserRepository->GetReadOnlyUsers(),
'businesspartner' => $oITopUserRepository->GetBusinessPartnerUsers(),
];
if (MetaModel::IsValidClass('UserToken')) {
$aCountedUsers['application'] = $oITopUserRepository->GetApplicationUsers();
}
$aCountedUserFormated = [];
foreach ($aCountedUsers as $sCountedCategory => $aUsers) {
foreach ($aUsers as $oUser) {
$sUserId = (string) $oUser->GetKey();
$aCountedUserFormated[$sUserId][$sCountedCategory] = true;
}
}
$aDuplicates = [];
foreach ($aCountedUserFormated as $sUserId => $aCountedCategory) {
$aCountedCategoryName = array_keys($aCountedCategory);
if (count($aCountedCategoryName) > 1) {
sort($aCountedCategoryName);
$aDuplicates[] = sprintf('User #%s appears in: %s', $sUserId, implode(', ', $aCountedCategoryName));
}
}
$this->assertEmpty(
$aDuplicates,
"Some users are counted in multiple categories:\n- ".implode("\n- ", $aDuplicates)
);
}
public function testAllUsersAreCounted()
{
$oITopUserRepository = new ITopUserCountingRepository();
$aConsoleUsers = $oITopUserRepository->GetConsoleUsers();
$aPortalUsers = $oITopUserRepository->GetPortalUsers();
$aDisabledUsers = $oITopUserRepository->GetDisabledUsers();
$aReadOnlyUsers = $oITopUserRepository->GetReadOnlyUsers();
$aApplicationUsers = $oITopUserRepository->GetApplicationUsers() ?? [];
$aBusinessPartnerUsers = $oITopUserRepository->GetBusinessPartnerUsers();
$aAllUsersFromMergedCounts = array_merge($aConsoleUsers, $aPortalUsers, $aDisabledUsers, $aReadOnlyUsers, $aApplicationUsers, $aBusinessPartnerUsers);
$aAllUsersFromOQL = $oITopUserRepository->GetAllUsers();
$this->assertEmpty( // asserts that all users are in both arrays
array_merge(
array_diff(
$aAllUsersFromMergedCounts,
$aAllUsersFromOQL
),
array_diff(
$aAllUsersFromOQL,
$aAllUsersFromMergedCounts
)
)
);
// check for cardinality
$aMergedCountingUsersIds = [];
foreach ($aAllUsersFromMergedCounts as $oUser) {
$aMergedCountingUsersIds[] = (int) $oUser->GetKey();
}
$aOqlUsersIds = [];
foreach ($aAllUsersFromOQL as $oUser) {
$aOqlUsersIds[] = (int) $oUser->GetKey();
}
sort($aMergedCountingUsersIds, SORT_NUMERIC);
sort($aOqlUsersIds, SORT_NUMERIC);
$this->assertSame($aOqlUsersIds, $aMergedCountingUsersIds);
}
public function testAllCountedUsersAreUsersObjects()
{
$oITopUserRepository = new ITopUserCountingRepository();
$aConsoleUsers = $oITopUserRepository->GetConsoleUsers();
$aPortalUsers = $oITopUserRepository->GetPortalUsers();
$aDisabledUsers = $oITopUserRepository->GetDisabledUsers();
$aReadOnlyUsers = $oITopUserRepository->GetReadOnlyUsers();
$aApplicationUsers = $oITopUserRepository->GetApplicationUsers() ?? [];
$aBusinessPartnerUsers = $oITopUserRepository->GetBusinessPartnerUsers();
$aCountedUsers = array_merge($aConsoleUsers, $aPortalUsers, $aDisabledUsers, $aReadOnlyUsers, $aApplicationUsers, $aBusinessPartnerUsers);
foreach ($aCountedUsers as $oUser) {
$this->assertInstanceOf(User::class, $oUser);
}
}
/**
* @param array $aProfilesList
* @param $sExpectedCategorie
*
* @return void
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \DictExceptionMissingString
* @throws \MySQLException
* @dataProvider RealUseCasesDataProvider
*/
public function testRealUseCases(array $aProfilesList, $sExpectedCategorie)
{
$iUser = $this->GivenUserInDB('<_ç"éue"ç_u', $aProfilesList, bReturnLogin: false);
$oUser = \MetaModel::GetObject('User', $iUser);
\UserRights::Login($oUser->Get('login')); // work around since user needs to be logged in in IsActionAllowed
$oITopUserRepository = new ITopUserCountingRepository();
$aUsers = match ($sExpectedCategorie) {
'console' => $oITopUserRepository->GetConsoleUsers(),
'readonly' => $oITopUserRepository->GetReadOnlyUsers(),
'disabled' => $oITopUserRepository->GetDisabledUsers(),
'portal' => $oITopUserRepository->GetPortalUsers(),
'application' => $oITopUserRepository->GetApplicationUsers(),
'businesspartner' => $oITopUserRepository->GetBusinessPartnerUsers(),
default => throw new \InvalidArgumentException(sprintf('Unexpected category %s', $sExpectedCategorie)),
};
$bUserInCorrectCategory = false;
foreach ($aUsers as $oUserInCategory) {
if ($oUserInCategory->GetKey() === $oUser->GetKey()) {
$bUserInCorrectCategory = true;
}
}
$this->assertTrue($bUserInCorrectCategory, 'User with profiles '.implode(', ', $aProfilesList).' should be counted as '.$sExpectedCategorie.' user');
}
public function RealUseCasesDataProvider()
{
return [
'User with profiles Support Agent and Configuration ReadOnly' => [
'profiles' => ['Support Agent', 'Configuration ReadOnly'],
'expected category' => 'console',
],
'User with profiles Configuration ReadOnly and Service Catalog ReadOnly' => [
'profiles' => ['Configuration ReadOnly', 'Service Catalog ReadOnly'],
'expected category' => 'readonly',
],
'User with profiles Portal user and Service Catalog ReadOnly' => [
'profiles' => ['Portal user', 'Service Catalog ReadOnly'],
'expected category' => 'portal',
],
'User with profiles Support Agent and Portal user' => [
'profiles' => ['Support Agent', 'Portal user'],
'expected category' => 'portal',
],
'User with profiles Configuration Manager and Ticket ReadOnly' => [
'profiles' => ['Configuration Manager', 'Ticket ReadOnly'],
'expected category' => 'console',
],
];
}
}