mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
576 lines
21 KiB
PHP
576 lines
21 KiB
PHP
<?php
|
|
|
|
// Copyright (c) 2010-2024 Combodo SAS
|
|
//
|
|
// This file is part of iTop.
|
|
//
|
|
// iTop is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// iTop 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 Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
|
//
|
|
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: Eric
|
|
* Date: 25/01/2018
|
|
* Time: 11:12
|
|
*/
|
|
|
|
namespace Combodo\iTop\Test\UnitTest\Core;
|
|
|
|
use Combodo\iTop\Test\UnitTest\ItopDataTestCase;
|
|
use CoreCannotSaveObjectException;
|
|
use CoreException;
|
|
use DBObject;
|
|
use DBObjectSearch;
|
|
use DBObjectSet;
|
|
use DeleteException;
|
|
use MetaModel;
|
|
use UserLocal;
|
|
use UserRights;
|
|
use utils;
|
|
|
|
/**
|
|
* @group itopRequestMgmt
|
|
* @group userRights
|
|
* @group defaultProfiles
|
|
*/
|
|
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'],
|
|
'UserLocal' => ['class' => 'UserLocal', 'attcode' => 'login'],
|
|
'UserRequest' => ['class' => 'UserRequest', 'attcode' => 'title'],
|
|
'ModuleInstallation' => ['class' => 'ModuleInstallation', 'attcode' => 'name'],
|
|
];
|
|
|
|
/**
|
|
* @param string $sLoginPrefix
|
|
* @param int $iProfileId initial profile
|
|
*
|
|
* @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;
|
|
}
|
|
|
|
protected function GivenUserWithProfiles(string $sLogin, array $aProfileIds): DBObject
|
|
{
|
|
$oProfiles = new \ormLinkSet(\UserLocal::class, 'profile_list', \DBObjectSet::FromScratch(\URP_UserProfile::class));
|
|
foreach ($aProfileIds as $iProfileId) {
|
|
$oProfiles->AddItem(MetaModel::NewObject('URP_UserProfile', ['profileid' => $iProfileId, 'reason' => 'UNIT Tests']));
|
|
}
|
|
$oUser = MetaModel::NewObject('UserLocal', [
|
|
'login' => $sLogin,
|
|
'password' => 'Password1!',
|
|
'expiration' => UserLocal::EXPIRE_NEVER,
|
|
'profile_list' => $oProfiles,
|
|
]);
|
|
return $oUser;
|
|
}
|
|
|
|
public function testIsLoggedIn()
|
|
{
|
|
$this->assertFalse(UserRights::IsLoggedIn());
|
|
}
|
|
|
|
/**
|
|
* Test Login validation
|
|
*
|
|
* @dataProvider LoginProvider
|
|
*
|
|
* @param $sLogin
|
|
* @param $bResult
|
|
*
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testLogin($sLogin, $bResult)
|
|
{
|
|
$_SESSION = [];
|
|
if ($sLogin == 'admin') {
|
|
// Fixture data required in this case only
|
|
try {
|
|
self::CreateUser('admin', 1);
|
|
} catch (CoreCannotSaveObjectException $e) {
|
|
// The admin account could exist, depending on where and when the test suite is executed
|
|
}
|
|
}
|
|
$this->assertEquals($bResult, UserRights::Login($sLogin));
|
|
$this->assertEquals($bResult, UserRights::IsLoggedIn());
|
|
}
|
|
|
|
public function LoginProvider(): array
|
|
{
|
|
return [
|
|
['admin', true],
|
|
['NotALoginForUnitTests', false],
|
|
['', false],
|
|
];
|
|
}
|
|
|
|
/** Test IsActionAllowed when not logged => always true
|
|
*
|
|
* @dataProvider ActionAllowedNotLoggedProvider
|
|
*
|
|
* @param $aClassAction
|
|
*
|
|
* @throws \CoreException
|
|
*/
|
|
public function testIsActionAllowedNotLogged($aClassAction)
|
|
{
|
|
$bRes = UserRights::IsActionAllowed($aClassAction['class'], $aClassAction['action']) == UR_ALLOWED_YES;
|
|
$this->assertEquals(true, $bRes);
|
|
}
|
|
|
|
public function ActionAllowedNotLoggedProvider(): array
|
|
{
|
|
$aClassActions = [];
|
|
|
|
foreach (array_keys(self::$aClasses) as $sClass) {
|
|
for ($i = 1; $i < 8; $i++) {
|
|
$aClassAction = ['class' => $sClass, 'action' => $i];
|
|
$aClassActions[] = [$aClassAction];
|
|
}
|
|
}
|
|
|
|
return $aClassActions;
|
|
}
|
|
|
|
/**
|
|
* @dataProvider ActionAllowedProvider
|
|
*
|
|
* @param int $iProfileId
|
|
* @param array $aClassActionResult
|
|
*
|
|
* @throws \CoreException
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testIsActionAllowed(int $iProfileId, array $aClassActionResult)
|
|
{
|
|
$this->CreateUniqueUserAndLogin('test1', $iProfileId);
|
|
$bRes = UserRights::IsActionAllowed($aClassActionResult['class'], $aClassActionResult['action']) == UR_ALLOWED_YES;
|
|
$this->assertEquals($aClassActionResult['res'], $bRes);
|
|
}
|
|
|
|
/*
|
|
* 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
|
|
*
|
|
*/
|
|
public function ActionAllowedProvider(): array
|
|
{
|
|
return [
|
|
/* Administrator (7 = UR_ACTION_CREATE) */
|
|
'Administrator FunctionalCI write' => [1, ['class' => 'FunctionalCI', 'action' => 7, 'res' => true]],
|
|
'Administrator UserRequest write' => [1, ['class' => 'UserRequest', 'action' => 7, 'res' => true]],
|
|
'Administrator URP_UserProfile write' => [1, ['class' => 'URP_UserProfile', 'action' => 7, 'res' => true]],
|
|
'Administrator UserLocal write' => [1, ['class' => 'UserLocal', 'action' => 7, 'res' => true]],
|
|
'Administrator ModuleInstallation write' => [1, ['class' => 'ModuleInstallation', 'action' => 7, 'res' => true]],
|
|
|
|
/* User Portal (7 = UR_ACTION_CREATE) */
|
|
'User Portal FunctionalCI write' => [2, ['class' => 'FunctionalCI', 'action' => 7, 'res' => false]],
|
|
'User Portal UserRequest write' => [2, ['class' => 'UserRequest', 'action' => 7, 'res' => true]],
|
|
'User Portal URP_UserProfile write' => [2, ['class' => 'URP_UserProfile', 'action' => 7, 'res' => false]],
|
|
'User Portal UserLocal write' => [2, ['class' => 'UserLocal', 'action' => 7, 'res' => false]],
|
|
'User Portal ModuleInstallation write' => [2, ['class' => 'ModuleInstallation', 'action' => 7, 'res' => false]],
|
|
|
|
/* Configuration manager (7 = UR_ACTION_CREATE) */
|
|
'Configuration manager FunctionalCI write' => [3, ['class' => 'FunctionalCI', 'action' => 7, 'res' => true]],
|
|
'Configuration manager UserRequest write' => [3, ['class' => 'UserRequest', 'action' => 7, 'res' => false]],
|
|
'Configuration manager URP_UserProfile write' => [3, ['class' => 'URP_UserProfile', 'action' => 7, 'res' => false]],
|
|
'Configuration manager UserLocal write' => [3, ['class' => 'UserLocal', 'action' => 7, 'res' => false]],
|
|
'Configuration manager ModuleInstallation write' => [3, ['class' => 'ModuleInstallation', 'action' => 7, 'res' => false]],
|
|
|
|
/* Administrator (1 = UR_ACTION_READ) */
|
|
'Administrator FunctionalCI read' => [1, ['class' => 'FunctionalCI', 'action' => 1, 'res' => true]],
|
|
'Administrator UserRequest read' => [1, ['class' => 'UserRequest', 'action' => 1, 'res' => true]],
|
|
'Administrator URP_UserProfile read' => [1, ['class' => 'URP_UserProfile', 'action' => 1, 'res' => true]],
|
|
'Administrator UserLocal read' => [1, ['class' => 'UserLocal', 'action' => 1, 'res' => true]],
|
|
'Administrator ModuleInstallation read' => [1, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => true]],
|
|
|
|
/* User Portal (1 = UR_ACTION_READ) */
|
|
'User Portal FunctionalCI read' => [2, ['class' => 'FunctionalCI', 'action' => 1, 'res' => true]],
|
|
'User Portal UserRequest read' => [2, ['class' => 'UserRequest', 'action' => 1, 'res' => true]],
|
|
'User Portal URP_UserProfile read' => [2, ['class' => 'URP_UserProfile', 'action' => 1, 'res' => false]],
|
|
'User Portal UserLocal read' => [2, ['class' => 'UserLocal', 'action' => 1, 'res' => false]],
|
|
'User Portal ModuleInstallation read' => [2, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => true]],
|
|
|
|
/* Configuration manager (1 = UR_ACTION_READ) */
|
|
'Configuration manager FunctionalCI read' => [3, ['class' => 'FunctionalCI', 'action' => 1, 'res' => true]],
|
|
'Configuration manager UserRequest read' => [3, ['class' => 'UserRequest', 'action' => 1, 'res' => true]],
|
|
'Configuration manager URP_UserProfile read' => [3, ['class' => 'URP_UserProfile', 'action' => 1, 'res' => false]],
|
|
'Configuration manager UserLocal read' => [3, ['class' => 'UserLocal', 'action' => 1, 'res' => false]],
|
|
'Configuration manager ModuleInstallation read' => [3, ['class' => 'ModuleInstallation', 'action' => 1, 'res' => true]],
|
|
];
|
|
}
|
|
|
|
/** Test IsActionAllowedOnAttribute
|
|
*
|
|
* @dataProvider ActionAllowedOnAttributeProvider
|
|
*
|
|
* @param int $iProfileId
|
|
* @param array $aClassActionResult
|
|
*
|
|
* @throws \CoreException
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testIsActionAllowedOnAttribute(int $iProfileId, array $aClassActionResult)
|
|
{
|
|
$this->CreateUniqueUserAndLogin('test1', $iProfileId);
|
|
$sClass = $aClassActionResult['class'];
|
|
$bRes = UserRights::IsActionAllowedOnAttribute($sClass, self::$aClasses[$sClass]['attcode'], $aClassActionResult['action']) == UR_ALLOWED_YES;
|
|
$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 [
|
|
/* Administrator (2 = UR_ACTION_MODIFY) */
|
|
'Administrator FunctionalCI' => [1, ['class' => 'FunctionalCI', 'action' => 2, 'res' => true]],
|
|
'Administrator UserRequest' => [1, ['class' => 'UserRequest', 'action' => 2, 'res' => true]],
|
|
'Administrator URP_UserProfile' => [1, ['class' => 'URP_UserProfile', 'action' => 2, 'res' => true]],
|
|
'Administrator UserLocal' => [1, ['class' => 'UserLocal', 'action' => 2, 'res' => true]],
|
|
'Administrator ModuleInstallation' => [1, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => true]],
|
|
|
|
/* User Portal (2 = UR_ACTION_MODIFY) */
|
|
'User Portal FunctionalCI' => [2, ['class' => 'FunctionalCI', 'action' => 2, 'res' => false]],
|
|
'User Portal UserRequest' => [2, ['class' => 'UserRequest', 'action' => 2, 'res' => true]],
|
|
'User Portal URP_UserProfile' => [2, ['class' => 'URP_UserProfile', 'action' => 2, 'res' => false]],
|
|
'User Portal UserLocal' => [2, ['class' => 'UserLocal', 'action' => 2, 'res' => false]],
|
|
'User Portal ModuleInstallation' => [2, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => true]],
|
|
|
|
/* Configuration manager (2 = UR_ACTION_MODIFY) */
|
|
'Configuration manager FunctionalCI' => [3, ['class' => 'FunctionalCI', 'action' => 2, 'res' => true]],
|
|
'Configuration manager UserRequest' => [3, ['class' => 'UserRequest', 'action' => 2, 'res' => false]],
|
|
'Configuration manager URP_UserProfile' => [3, ['class' => 'URP_UserProfile', 'action' => 2, 'res' => false]],
|
|
'Configuration manager UserLocal' => [3, ['class' => 'UserLocal', 'action' => 2, 'res' => false]],
|
|
'Configuration manager ModuleInstallation' => [3, ['class' => 'ModuleInstallation', 'action' => 2, 'res' => true]],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider UserCannotLoseConsoleAccessProvider
|
|
*
|
|
* @throws \CoreException
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testUserCannotLoseConsoleAccess(int $iProfileId)
|
|
{
|
|
$oUser = $this->CreateUniqueUserAndLogin('test1', $iProfileId);
|
|
|
|
$this->expectException(CoreCannotSaveObjectException::class);
|
|
$this->expectExceptionMessage('Profile "Portal user" cannot be added it will deny the access to backoffice');
|
|
$this->AddProfileToUser($oUser, 2);
|
|
}
|
|
|
|
public function UserCannotLoseConsoleAccessProvider(): array
|
|
{
|
|
return [
|
|
'Administrator' => [1],
|
|
'SuperUser' => [117],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider UserCannotElevateTheirOwnRightsProvider
|
|
*
|
|
* @throws \CoreException
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testUserCannotElevateTheirOwnRights(int $iCurrentProfileId, int $iElevatedProfileId)
|
|
{
|
|
$oUser = $this->CreateUniqueUserAndLogin('test1', $iCurrentProfileId);
|
|
|
|
$this->expectException(CoreCannotSaveObjectException::class);
|
|
$this->AddProfileToUser($oUser, $iElevatedProfileId);
|
|
}
|
|
|
|
public function UserCannotElevateTheirOwnRightsProvider(): array
|
|
{
|
|
return [
|
|
'Configuration manager to SuperUser' => ['current' => 3, 'added' => 117],
|
|
'Configuration manager to Administrator' => ['current' => 3, 'added' => 1],
|
|
'SuperUser to Administrator' => ['current' => 117, 'added' => 1],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider UserCannotDeleteOwnUserProvider
|
|
*
|
|
* @throws \CoreException
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testUserCannotDeleteOwnUser(int $iProfileId)
|
|
{
|
|
$oUser = $this->CreateUniqueUserAndLogin('test1', $iProfileId);
|
|
|
|
$this->expectException(DeleteException::class);
|
|
$oUser->DBDelete();
|
|
}
|
|
|
|
public function UserCannotDeleteOwnUserProvider(): array
|
|
{
|
|
return [
|
|
'Administrator' => [1],
|
|
'Configuration manager' => [3],
|
|
'SuperUser' => [117],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider UserCannotRemoveOwnContactProvider
|
|
*
|
|
* @param int $iProfileId
|
|
*
|
|
* @throws \CoreException
|
|
* @throws \DictExceptionUnknownLanguage
|
|
* @throws \OQLException
|
|
*/
|
|
public function testUserCannotRemoveOwnContact(int $iProfileId)
|
|
{
|
|
$oUser = $this->CreateUniqueUserAndLogin('test1', $iProfileId);
|
|
|
|
$oUser->Set('contactid', 0);
|
|
$this->expectException(CoreCannotSaveObjectException::class);
|
|
$oUser->DBWrite();
|
|
}
|
|
|
|
public function UserCannotRemoveOwnContactProvider(): array
|
|
{
|
|
return [
|
|
'Administrator' => [1],
|
|
'Configuration manager' => [3],
|
|
'SuperUser' => [117],
|
|
];
|
|
}
|
|
|
|
public function testAdminCannotRemoveOwnAdminProfile()
|
|
{
|
|
$oUser = $this->CreateUniqueUserAndLogin('admin111', 1); // Administrator
|
|
// Keep only the SuperUser profile (remove Administrator profile)
|
|
$this->AddProfileToUser($oUser, 117); // SuperUser profile for the test
|
|
|
|
$this->expectException(CoreCannotSaveObjectException::class);
|
|
$this->expectExceptionMessage('You cannot remove your own Administrator profile. Ask another Administrator to do it for you');
|
|
$this->RemoveProfileFromUser($oUser, 1); // Remove admin profile
|
|
}
|
|
|
|
/**
|
|
* @dataProvider UserCannotLoseUserEditionRightsProvider
|
|
*/
|
|
public function testUserCannotLoseUserEditionRights(int $iProfileId)
|
|
{
|
|
$oUser = $this->CreateUniqueUserAndLogin('configmgr111', $iProfileId); // SuperUser
|
|
$this->AddProfileToUser($oUser, 3);
|
|
|
|
$this->expectException(CoreCannotSaveObjectException::class);
|
|
$this->expectExceptionMessage('You cannot remove your own rights to edit Users');
|
|
$this->RemoveProfileFromUser($oUser, $iProfileId);
|
|
}
|
|
|
|
public function UserCannotLoseUserEditionRightsProvider(): array
|
|
{
|
|
return [
|
|
'Administrator' => [1],
|
|
'SuperUser' => [117],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider PrivilegedUsersMustHaveBackofficeAccessProvider
|
|
*/
|
|
public function testPrivilegedUsersMustHaveBackofficeAccess(int $iProfileId)
|
|
{
|
|
$oUser = $this->GivenUserWithProfiles('test1', [$iProfileId, 2]);
|
|
|
|
$this->expectException(CoreCannotSaveObjectException::class);
|
|
$this->expectExceptionMessage('Profile "Portal user" cannot be given to privileged Users (Administrators, SuperUsers and REST Services Users)');
|
|
$oUser->DBInsert();
|
|
|
|
}
|
|
public function PrivilegedUsersMustHaveBackofficeAccessProvider(): array
|
|
{
|
|
return [
|
|
'killing another administrator' => [1],
|
|
'killing superuser ' => [117],
|
|
'killing Rest User' => [1024],
|
|
|
|
];
|
|
}
|
|
public function testNonPrivilegedUsersCanBeDeniedFromBackoffice()
|
|
{
|
|
$oUser = $this->GivenUserWithProfiles('test1', [5, 2]);
|
|
// No exception expected
|
|
$oUser->DBInsert();
|
|
$this->expectNotToPerformAssertions();
|
|
}
|
|
|
|
/**
|
|
*@dataProvider NonAdminCanListOwnProfilesProvider
|
|
*/
|
|
public function testNonAdminCanListOwnProfiles($bHideAdministrators)
|
|
{
|
|
utils::GetConfig()->Set('security.hide_administrators', $bHideAdministrators);
|
|
$oUser = $this->CreateUniqueUserAndLogin('test1', 2); // portal user
|
|
|
|
// List the link between the User and the Profiles
|
|
$oSearch = new DBObjectSearch('URP_UserProfile');
|
|
$oSearch->AddCondition('userid', $oUser->GetKey());
|
|
$oSet = new DBObjectSet($oSearch);
|
|
$this->assertEquals(1, $oSet->Count());
|
|
|
|
// Get the Profiles as well
|
|
$oSearch = DBObjectSearch::FromOQL('SELECT URP_Profiles JOIN URP_UserProfile ON URP_UserProfile.profileid = URP_Profiles.id WHERE URP_UserProfile.userid='.$oUser->GetKey());
|
|
$oSet = new DBObjectSet($oSearch);
|
|
$this->assertEquals(1, $oSet->Count());
|
|
}
|
|
|
|
public function NonAdminCanListOwnProfilesProvider(): array
|
|
{
|
|
return [
|
|
'with Admins visible' => [false],
|
|
'with Admins hidden' => [true],
|
|
];
|
|
}
|
|
/**
|
|
* @dataProvider NonAdminCannotListAdminProfilesProvider
|
|
*/
|
|
public function testNonAdminCannotListAdminProfiles($bHideAdministrators, $iExpectedCount)
|
|
{
|
|
utils::GetConfig()->Set('security.hide_administrators', $bHideAdministrators);
|
|
|
|
$oUserAdmin = $this->CreateUser('admin1', 1);
|
|
$this->CreateUniqueUserAndLogin('test1', 2); // portal user
|
|
|
|
$oSearch = new DBObjectSearch('URP_UserProfile');
|
|
$oSearch->AddCondition('userid', $oUserAdmin->GetKey());
|
|
$oSet = new DBObjectSet($oSearch);
|
|
$this->assertEquals($iExpectedCount, $oSet->Count(), 'Visibility on Link between User and Administrator Profiles should be controlled by hide_administrators setting');
|
|
// Get the Profiles as well
|
|
$oSearch = DBObjectSearch::FromOQL('SELECT URP_Profiles JOIN URP_UserProfile ON URP_UserProfile.profileid = URP_Profiles.id WHERE URP_UserProfile.userid='.$oUserAdmin->GetKey());
|
|
$oSet = new DBObjectSet($oSearch);
|
|
$this->assertEquals($iExpectedCount, $oSet->Count(), 'Visibility on Administrator Profiles should be controlled by hide_administrators setting');
|
|
}
|
|
|
|
public function NonAdminCannotListAdminProfilesProvider(): array
|
|
{
|
|
return [
|
|
'with Admins visible' => ['hide_administrators' => false, 'visible_objects' => 1],
|
|
'with Admins hidden' => ['hide_administrators' => true, 'visible_objects' => 0],
|
|
];
|
|
}
|
|
|
|
public function testFindUser_ExistingInternalUser()
|
|
{
|
|
$sLogin = 'AnInternalUser'.uniqid();
|
|
$iKey = $this->GivenObjectInDB(\UserLocal::class, ['login' => $sLogin]);
|
|
|
|
$this->assertDBQueryCount(
|
|
1,
|
|
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
|
'A query should be performed the first time FindUser is called'
|
|
);
|
|
|
|
$this->assertDBQueryCount(
|
|
0,
|
|
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
|
'The cache should prevent additional queries on subsequent calls'
|
|
);
|
|
}
|
|
|
|
public function testFindUser_ExistingExternalUser()
|
|
{
|
|
$sLogin = 'AnExternalUser'.uniqid();
|
|
$iKey = $this->GivenObjectInDB(\UserExternal::class, ['login' => $sLogin]);
|
|
|
|
$this->assertDBQueryCount(
|
|
2,
|
|
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
|
'Some queries should be performed the first time FindUser is called'
|
|
);
|
|
|
|
$this->assertDBQueryCount(
|
|
0,
|
|
fn () => $this->FindUserAndAssertItHasBeenFound($sLogin, $iKey),
|
|
'The cache should prevent additional queries on subsequent calls'
|
|
);
|
|
}
|
|
|
|
public function testFindUser_UnknownLogin()
|
|
{
|
|
$sLogin = 'NobodyLogin';
|
|
|
|
$this->assertDBQueryCount(
|
|
2,
|
|
fn () => $this->FindUserAndAssertItWasNotFound($sLogin),
|
|
'Some queries should be performed the first time FindUser is called'
|
|
);
|
|
|
|
$this->assertDBQueryCount(
|
|
0,
|
|
fn () => $this->FindUserAndAssertItWasNotFound($sLogin),
|
|
'The cache should prevent additional queries on subsequent calls'
|
|
);
|
|
}
|
|
|
|
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]);
|
|
static::assertNull($oUser, 'FindUser should return null when the login is unknown');
|
|
}
|
|
}
|