From 15900720c8e19d8b5b93d819474c3b027adc00bb Mon Sep 17 00:00:00 2001 From: odain Date: Fri, 1 Sep 2023 15:33:42 +0200 Subject: [PATCH] 5324-handle forgotten usecases --- .../src/UserProfilesEventListener.php | 291 +++++++++++++----- .../UserProfilesEventListenerTest.php | 210 +++++++------ 2 files changed, 324 insertions(+), 177 deletions(-) diff --git a/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php b/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php index 1da291fdc9..c4ab5088b7 100644 --- a/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php +++ b/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php @@ -41,19 +41,27 @@ class UserProfilesEventListener implements iEventServiceSetup return; } - $callback = [$this, 'OnUserProfileLinkChange']; $aEventSource = [\User::class, \UserExternal::class, \UserInternal::class]; - EventService::RegisterListener( EVENT_DB_BEFORE_WRITE, - $callback, + [$this, 'OnUserEdition'], $aEventSource ); EventService::RegisterListener( - EVENT_DB_LINKS_CHANGED, - $callback, - $aEventSource + EVENT_DB_BEFORE_WRITE, + [ $this, 'OnUserProfileEdition' ], + [ \URP_UserProfile::class ], + [], + null + ); + + EventService::RegisterListener( + EVENT_DB_CHECK_TO_DELETE, + [ $this, 'OnUserProfileLinkDeletion' ], + [ \URP_UserProfile::class ], + [], + null ); } @@ -62,12 +70,13 @@ class UserProfilesEventListener implements iEventServiceSetup return $this->bIsRepairmentEnabled; } - public function OnUserProfileLinkChange(EventData $oEventData): void { + + public function OnUserEdition(EventData $oEventData): void { /** @var \User $oObject */ $oUser = $oEventData->Get('object'); try { - $this->RepairProfiles($oUser); + $this->ValidateThenRepairOrWarn($oUser); } catch (Exception $e) { IssueLog::Error('Exception occurred on RepairProfiles', LogChannels::DM_CRUD, [ 'user_class' => get_class($oUser), @@ -75,9 +84,119 @@ class UserProfilesEventListener implements iEventServiceSetup 'exception_message' => $e->getMessage(), 'exception_stacktrace' => $e->getTraceAsString(), ]); + if ($e instanceof \CoreCannotSaveObjectException){ + throw $e; + } } } + public function OnUserProfileEdition(EventData $oEventData): void { + $oURP_UserProfile = $oEventData->Get('object'); + + try { + $iUserId = $oURP_UserProfile->Get('userid'); + $oUser = \MetaModel::GetReentranceObjectByChildClass(\User::class, $iUserId); + if (false !== $oUser){ + //user edition: handled by other event + return; + } + + $oUser = \MetaModel::GetObject(\User::class, $iUserId); + $aChanges = $oURP_UserProfile->ListChanges(); + if (array_key_exists('userid', $aChanges)) { + $iUserId = $oURP_UserProfile->GetOriginal('userid'); + $oPreviousUser = \MetaModel::GetObject(\User::class, $iUserId); + + $oProfileLinkSet = $oPreviousUser->Get('profile_list'); + $oProfileLinkSet->Rewind(); + $iCount = 0; + while ($oCurrentURP_UserProfile = $oProfileLinkSet->Fetch()) { + if ($oCurrentURP_UserProfile->Get('userid') !== $oCurrentURP_UserProfile->GetOriginal('userid')) { + $sRemovedProfileId = $oCurrentURP_UserProfile->GetOriginal('profileid'); + continue; + } + + $iCount++; + if ($iCount > 1){ + //more than one profile: no repairment needed + return; + } + $sSingleProfileName = $oCurrentURP_UserProfile->Get('profile'); + } + $this->RepairProfileChangesOrWarn($oPreviousUser, $sSingleProfileName, $oURP_UserProfile, $sRemovedProfileId); + } else if (array_key_exists('profileid', $aChanges)){ + $oCurrentUserProfileSet = $oUser->Get('profile_list'); + if ($oCurrentUserProfileSet->Count() === 1){ + $oProfile = $oCurrentUserProfileSet->Fetch(); + + $this->RepairProfileChangesOrWarn($oUser, $oProfile->Get('profile'), $oURP_UserProfile, $oProfile->GetOriginal("profileid")); + } + } + } catch (Exception $e) { + IssueLog::Error('OnUserProfileEdition Exception', LogChannels::DM_CRUD, [ + 'user_id' => $iUserId, + 'lnk_id' => $oURP_UserProfile->GetKey(), + 'exception_message' => $e->getMessage(), + 'exception_stacktrace' => $e->getTraceAsString(), + ]); + if ($e instanceof \CoreCannotSaveObjectException){ + throw $e; + } + } + } + + public function OnUserProfileLinkDeletion(EventData $oEventData): void { + $oURP_UserProfile = $oEventData->Get('object'); + + try { + $iUserId = $oURP_UserProfile->Get('userid'); + $oUser = \MetaModel::GetReentranceObjectByChildClass(\User::class, $iUserId); + if (false !== $oUser){ + //user edition: handled by other event + return; + } + + $oUser = \MetaModel::GetObject(\User::class, $iUserId); + + /** @var \DeletionPlan $oDeletionPlan */ + $oDeletionPlan = $oEventData->Get('deletion_plan'); + $aDeletedURP_UserProfiles = []; + if (! is_null($oDeletionPlan)){ + $aListDeletes = $oDeletionPlan->ListDeletes(); + if (array_key_exists(\URP_UserProfile::class, $aListDeletes)) { + foreach ($aListDeletes[\URP_UserProfile::class] as $iId => $aDeletes) { + $aDeletedURP_UserProfiles []= $iId; + } + } + } + + $oProfileLinkSet = $oUser->Get('profile_list'); + $oProfileLinkSet->Rewind(); + $iCount = 0; + while ($oCurrentURP_UserProfile = $oProfileLinkSet->Fetch()) { + if (in_array($oCurrentURP_UserProfile->GetKey(), $aDeletedURP_UserProfiles)) { + continue; + } + $iCount++; + if ($iCount > 1){ + //more than one profile: no repairment needed + return; + } + $sSingleProfileName = $oCurrentURP_UserProfile->Get('profile'); + } + + $this->RepairProfileChangesOrWarn($oUser, $sSingleProfileName, $oURP_UserProfile, $oURP_UserProfile->Get('profileid'), true); + } catch (Exception $e) { + IssueLog::Error('OnUserProfileLinkDeletion Exception', LogChannels::DM_CRUD, [ + 'user_id' => $iUserId, + 'profile_id' => $oURP_UserProfile->Get('profileid'), + 'exception_message' => $e->getMessage(), + 'exception_stacktrace' => $e->getTraceAsString(), + ]); + } + } + + /** * @param $aPortalDispatcherData: passed only for testing purpose * @@ -125,83 +244,113 @@ class UserProfilesEventListener implements iEventServiceSetup return; } + + $this->FetchRepairingProfileIds($aNonStandaloneProfiles); + } + + public function FetchRepairingProfileIds(array $aNonStandaloneProfiles) : void { + $aProfiles = []; try { - $this->FetchRepairingProfileIds($aNonStandaloneProfiles); + $aProfilesToSearch = array_unique(array_values($aNonStandaloneProfiles)); + if(($iIndex = array_search(null, $aProfilesToSearch)) !== false) { + unset($aProfilesToSearch[$iIndex]); + } + + if (1 === count($aProfilesToSearch)){ + $sInCondition = sprintf('"%s"', array_pop($aProfilesToSearch)); + } else { + $sInCondition = sprintf('"%s"', implode('","', $aProfilesToSearch)); + } + + $sOql = "SELECT URP_Profiles WHERE name IN ($sInCondition)"; + $oSearch = \DBSearch::FromOQL($sOql); + $oSearch->AllowAllData(); + $oSet = new \DBObjectSet($oSearch); + while(($oProfile = $oSet->Fetch()) != null) { + $sProfileName = $oProfile->Get('name'); + $aProfiles[$sProfileName] = $oProfile->GetKey(); + } + + $this->aNonStandaloneProfilesMap = []; + foreach ($aNonStandaloneProfiles as $sNonStandaloneProfileName => $sRepairProfileName) { + if (is_null($sRepairProfileName)) { + $this->aNonStandaloneProfilesMap[$sNonStandaloneProfileName] = null; + continue; + } + + if (! array_key_exists($sRepairProfileName, $aProfiles)) { + throw new \Exception(sprintf("%s is badly configured. profile $sRepairProfileName does not exist.", self::USERPROFILE_REPAIR_ITOP_PARAM_NAME)); + } + + $this->aNonStandaloneProfilesMap[$sNonStandaloneProfileName] = $aProfiles[$sRepairProfileName]; + } + + $this->bIsRepairmentEnabled = true; } catch (\Exception $e) { IssueLog::Error('Exception when searching user portal profile', LogChannels::DM_CRUD, [ 'exception_message' => $e->getMessage(), 'exception_stacktrace' => $e->getTraceAsString(), + 'aProfiles' => $aProfiles, + 'aNonStandaloneProfiles' => $aNonStandaloneProfiles, ]); $this->bIsRepairmentEnabled = false; - return; - } - - $this->bIsRepairmentEnabled = true; - } - - public function FetchRepairingProfileIds(array $aNonStandaloneProfiles) : void { - $aProfilesToSearch = array_unique(array_values($aNonStandaloneProfiles)); - if(($iIndex = array_search(null, $aProfilesToSearch)) !== false) { - unset($aProfilesToSearch[$iIndex]); - } - - if (1 === count($aProfilesToSearch)){ - $sInCondition = sprintf('"%s"', array_pop($aProfilesToSearch)); - } else { - $sInCondition = sprintf('"%s"', implode('","', $aProfilesToSearch)); - } - - $sOql = "SELECT URP_Profiles WHERE name IN ($sInCondition)"; - $oSearch = \DBSearch::FromOQL($sOql); - $oSearch->AllowAllData(); - $oSet = new \DBObjectSet($oSearch); - $aProfiles = []; - while(($oProfile = $oSet->Fetch()) != null) { - $sProfileName = $oProfile->Get('name'); - $aProfiles[$sProfileName] = $oProfile->GetKey(); - } - - $this->aNonStandaloneProfilesMap = []; - foreach ($aNonStandaloneProfiles as $sNonStandaloneProfileName => $sRepairProfileName) { - if (is_null($sRepairProfileName)) { - $this->aNonStandaloneProfilesMap[$sNonStandaloneProfileName] = null; - continue; - } - - if (!array_key_exists($sRepairProfileName, $aProfiles)) { - throw new \Exception(sprintf("%s is badly configured. profile $sRepairProfileName does not exist.", self::USERPROFILE_REPAIR_ITOP_PARAM_NAME)); - } - - $this->aNonStandaloneProfilesMap[$sNonStandaloneProfileName] = $aProfiles[$sRepairProfileName]; } } - public function RepairProfiles(?\User $oUser) : void + public function ValidateThenRepairOrWarn(\User $oUser) : void { - if (!is_null($oUser)) - { - $oCurrentUserProfileSet = $oUser->Get('profile_list'); - if ($oCurrentUserProfileSet->Count() === 1){ - $oProfile = $oCurrentUserProfileSet->Fetch(); - $sSingleProfileName = $oProfile->Get('profile'); + $oCurrentUserProfileSet = $oUser->Get('profile_list'); + if ($oCurrentUserProfileSet->Count() === 1){ + $oProfile = $oCurrentUserProfileSet->Fetch(); - if (array_key_exists($sSingleProfileName, $this->aNonStandaloneProfilesMap)) { - $sRepairingProfileId = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; - if (is_null($sRepairingProfileId)){ - //Notify current user via session messages that there will be an issue - //Without preventing from commiting - $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName); - $oUser::SetSessionMessage(get_class($oUser), $oUser->GetKey(), 1, $sMessage, 'WARNING', 1); - } else { - //Completing profiles profiles by adding repairing one : by default portal user to a power portal user - $oUserProfile = new \URP_UserProfile(); - $oUserProfile->Set('profileid', $sRepairingProfileId); - $oCurrentUserProfileSet->AddItem($oUserProfile); - $oUser->Set('profile_list', $oCurrentUserProfileSet); - } - } + $this->RepairUserChangesOrWarn($oUser, $oProfile->Get('profile')); + } + } + + public function RepairUserChangesOrWarn(\User $oUser, string $sSingleProfileName) : void { + if (array_key_exists($sSingleProfileName, $this->aNonStandaloneProfilesMap)) { + $sRepairingProfileId = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; + if (is_null($sRepairingProfileId)){ + //Notify current user via session messages that there will be an issue + //Without preventing from commiting + $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName); + //$oUser::SetSessionMessage(get_class($oUser), $oUser->GetKey(), 1, $sMessage, 'WARNING', 1); + throw new \CoreCannotSaveObjectException(array('issues' => [$sMessage], 'class' => get_class($oUser), 'id' => $oUser->GetKey())); + } else { + //Completing profiles profiles by adding repairing one : by default portal user to a power portal user + $oUserProfile = new \URP_UserProfile(); + $oUserProfile->Set('profileid', $sRepairingProfileId); + $oCurrentUserProfileSet = $oUser->Get('profile_list'); + $oCurrentUserProfileSet->AddItem($oUserProfile); + $oUser->Set('profile_list', $oCurrentUserProfileSet); } } } + public function RepairProfileChangesOrWarn(\User $oUser, string $sSingleProfileName, \URP_UserProfile $oURP_UserProfile, string $sRemovedProfileId, $bIsRemoval=false) : void { + if (array_key_exists($sSingleProfileName, $this->aNonStandaloneProfilesMap)) { + $sRepairingProfileId = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; + if (is_null($sRepairingProfileId) + || ($sRepairingProfileId === $sRemovedProfileId) //cannot repair by readding same remove profile as it will raise uniqueness rule + ){ + //Notify current user via session messages that there will be an issue + //Without preventing from commiting + $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName); + //$oURP_UserProfile::SetSessionMessage(get_class($oURP_UserProfile), $oURP_UserProfile->GetKey(), 1, $sMessage, 'WARNING', 1); + if ($bIsRemoval){ + $oURP_UserProfile->AddDeleteIssue($sMessage); + } else { + throw new \CoreCannotSaveObjectException(array('issues' => [$sMessage], 'class' => get_class($oURP_UserProfile), 'id' => $oURP_UserProfile->GetKey())); + } + } else { + //Completing profiles profiles by adding repairing one : by default portal user to a power portal user + $oUserProfile = new \URP_UserProfile(); + $oUserProfile->Set('profileid', $sRepairingProfileId); + $oCurrentUserProfileSet = $oUser->Get('profile_list'); + $oCurrentUserProfileSet->AddItem($oUserProfile); + $oUser->Set('profile_list', $oCurrentUserProfileSet); + $oUser->DBWrite(); + } + } + } } diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-profiles-itil/UserProfilesEventListenerTest.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-profiles-itil/UserProfilesEventListenerTest.php index a1e1e7e6bc..d791c64ca1 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-profiles-itil/UserProfilesEventListenerTest.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-profiles-itil/UserProfilesEventListenerTest.php @@ -65,14 +65,14 @@ class UserProfilesEventListenerTest extends ItopDataTestCase 'Portal user', ] ], - 'Portal power user + Support Agent => profiles untouched' => [ + 'Portal power user + Configuration Manager => profiles untouched' => [ 'aAssociatedProfilesBeforeUserCreation' => [ 'Portal power user', - 'Support Agent', + 'Configuration Manager', ], 'aExpectedAssociatedProfilesAfterUserCreation'=> [ 'Portal power user', - 'Support Agent', + 'Configuration Manager', ] ], ]; @@ -89,7 +89,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser->Set('login', $sLogin); $oUser->Set('password', 'ABCD1234@gabuzomeu'); $oUser->Set('language', 'EN US'); - $this->commonUserCreation($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); + $this->commonUserCreationTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); } /** @@ -103,7 +103,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser->Set('login', $sLogin); $oUser->Set('password', 'ABCD1234@gabuzomeu'); $oUser->Set('language', 'EN US'); - $this->commonUserUpdate($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); + $this->commonUserUpdateTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); } /** @@ -115,7 +115,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser = new \UserLDAP(); $sLogin = 'testUserLDAPCreationWithPortalPowerUserProfile-'.uniqid(); $oUser->Set('login', $sLogin); - $this->commonUserCreation($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); + $this->commonUserCreationTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); } /** @@ -127,7 +127,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser = new \UserLDAP(); $sLogin = 'testUserLDAPUpdateWithPortalPowerUserProfile-'.uniqid(); $oUser->Set('login', $sLogin); - $this->commonUserUpdate($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); + $this->commonUserUpdateTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); } /** @@ -139,7 +139,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser = new \UserExternal(); $sLogin = 'testUserLDAPCreationWithPortalPowerUserProfile-'.uniqid(); $oUser->Set('login', $sLogin); - $this->commonUserCreation($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); + $this->commonUserCreationTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); } /** @@ -151,7 +151,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser = new \UserExternal(); $sLogin = 'testUserLDAPUpdateWithPortalPowerUserProfile-'.uniqid(); $oUser->Set('login', $sLogin); - $this->commonUserUpdate($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); + $this->commonUserUpdateTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation); } public function CreateUserForProfileTesting(\User $oUserToCreate, array $aAssociatedProfilesBeforeUserCreation, $bDbInsert=true) : array @@ -189,16 +189,16 @@ class UserProfilesEventListenerTest extends ItopDataTestCase return [ $sId, $aProfiles]; } - public function commonUserCreation($oUserToCreate, $aAssociatedProfilesBeforeUserCreation, + public function commonUserCreationTest($oUserToCreate, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation, $bTestUserItopAccess=true) { $sUserClass = get_class($oUserToCreate); list ($sId, $aProfiles) = $this->CreateUserForProfileTesting($oUserToCreate, $aAssociatedProfilesBeforeUserCreation); - $this->CheckProfilesAreOk($sUserClass, $sId, $aExpectedAssociatedProfilesAfterUserCreation, $bTestUserItopAccess); + $this->CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sId, $aExpectedAssociatedProfilesAfterUserCreation, $bTestUserItopAccess); } - public function CheckProfilesAreOk($sUserClass, $sId, $aExpectedAssociatedProfilesAfterUserCreation, $bTestUserItopAccess=true){ + public function CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sId, $aExpectedAssociatedProfilesAfterUserCreation, $bTestItopConnection=true){ $oUser = \MetaModel::GetObject($sUserClass, $sId); $oUserProfileList = $oUser->Get('profile_list'); $aProfilesAfterCreation=[]; @@ -211,7 +211,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase "profile \'$sExpectedProfileName\' should be asociated to user after creation. " . var_export($aProfilesAfterCreation, true) ); } - if (! $bTestUserItopAccess){ + if (! $bTestItopConnection){ return; } @@ -233,7 +233,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $_SESSION = []; } - public function commonUserUpdate($oUserToCreate, $aAssociatedProfilesBeforeUserCreation, + public function commonUserUpdateTest($oUserToCreate, $aAssociatedProfilesBeforeUserCreation, $aExpectedAssociatedProfilesAfterUserCreation) { $sUserClass = get_class($oUserToCreate); @@ -256,11 +256,14 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUserToUpdate->Set('profile_list', $oProfileList); $oUserToUpdate->DBWrite(); - $this->CheckProfilesAreOk($sUserClass, $sId, $aExpectedAssociatedProfilesAfterUserCreation); + $this->CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sId, $aExpectedAssociatedProfilesAfterUserCreation); } - public function testUpdateUserExternalProfilesViaLinks(){ - $aInitialProfiles = [ "Administrator", "Portal power user"]; + /** + * @dataProvider ProfilesLinksProvider + */ + public function testProfilesLinksDBDelete(string $sProfileNameToRemove, $bRaiseException=false){ + $aInitialProfiles = [ $sProfileNameToRemove, "Portal power user"]; $oUser = new \UserExternal(); $sLogin = 'testUserLDAPUpdateWithPortalPowerUserProfile-'.uniqid(); @@ -269,70 +272,66 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $sUserClass = get_class($oUser); list ($sId, $aProfiles) = $this->CreateUserForProfileTesting($oUser, $aInitialProfiles); + if ($bRaiseException){ + $this->expectException(\DeleteException::class); + } + $aURPUserProfileByUser = $this->GetURPUserProfileByUser($sId); - $sProfileNameToRemove = "Administrator"; if (array_key_exists($sProfileNameToRemove, $aURPUserProfileByUser)){ $oURPUserProfile = $aURPUserProfileByUser[$sProfileNameToRemove]; $oURPUserProfile->DBDelete(); } - $aExpectedProfilesAfterUpdate = ["Portal power user", "Portal user"]; - $this->CheckProfilesAreOk($sUserClass, $sId, $aExpectedProfilesAfterUpdate); + if (! $bRaiseException) { + $aExpectedProfilesAfterUpdate = ["Portal power user", "Portal user"]; + $this->CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sId, $aExpectedProfilesAfterUpdate); + } } - public function BulkUpdateUserExternalProfilesViaLinksProvider(){ + /** + * @dataProvider ProfilesLinksProvider + */ + public function testProfilesLinksEdit_ChangeProfileId(string $sInitialProfile, $bRaiseException=false){ + $oUser = new \UserExternal(); + $sLogin = 'testUserLDAPUpdateWithPortalPowerUserProfile-'.uniqid(); + $oUser->Set('login', $sLogin); + + $sUserClass = get_class($oUser); + list ($sId, $aProfiles) = $this->CreateUserForProfileTesting($oUser, [$sInitialProfile]); + + $oURP_Profile = \MetaModel::GetObjectByColumn("URP_Profiles", "name", "Portal power user"); + + $aURPUserProfileByUser = $this->GetURPUserProfileByUser($sId); + + if ($bRaiseException){ + $this->expectException(\CoreCannotSaveObjectException::class); + } + + if (array_key_exists($sInitialProfile, $aURPUserProfileByUser)){ + $oURPUserProfile = $aURPUserProfileByUser[$sInitialProfile]; + $oURPUserProfile->Set('profileid', $oURP_Profile->GetKey()); + $oURPUserProfile->DBWrite(); + } + + if (!$bRaiseException) { + $aExpectedProfilesAfterUpdate = ["Portal power user", "Portal user"]; + $this->CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sId, $aExpectedProfilesAfterUpdate); + } + } + + public function ProfilesLinksProvider() { return [ - 'user profiles REPAIR 1' => [ - "aInitialProfiles" => [ "Administrator"], - "aOperation" => [ - '-Administrator', - '+Portal power user', - ], - "aExpectedProfilesAfterUpdate" => ["Portal power user", "Portal user"], - ], - 'user profiles REPAIR 2' => [ - "aInitialProfiles" => [ "Administrator"], - "aOperation" => [ - '+Portal power user', - '-Administrator', - ], - "aExpectedProfilesAfterUpdate" => ["Portal power user", "Portal user"], - ], - 'user profiles REPAIR 3' => [ - "aInitialProfiles" => [ "Administrator", "Portal power user"], - "aOperation" => [ - '-Administrator', - ], - "aExpectedProfilesAfterUpdate" => ["Portal power user", "Portal user"], - ], - 'NOTHING DONE with 1 profile' => [ - "aInitialProfiles" => [ "Administrator", "Portal power user"], - "aOperation" => [ - '-Portal power user', - ], - "aExpectedProfilesAfterUpdate" => ["Administrator"], - ], - 'NOTHING DONE with 2 profiles including power...' => [ - "aInitialProfiles" => [ "Administrator"], - "aOperation" => [ - '+Portal power user', - ], - "aExpectedProfilesAfterUpdate" => ["Administrator", "Portal power user"], - ], - 'NOTHING DONE with 2 profiles including power again ...' => [ - "aInitialProfiles" => [ "Portal user"], - "aOperation" => [ - '+Portal power user', - ], - "aExpectedProfilesAfterUpdate" => ["Portal user", "Portal power user"], - ], + "Administrator" => [ "sProfileNameToMove" => "Administrator" ], + "Portal user" => [ "sProfileNameToMove" => "Portal user", "bRaiseException" => true ], ]; } /** - * @dataProvider BulkUpdateUserExternalProfilesViaLinksProvider + * @dataProvider ProfilesLinksProvider */ - public function testBulkUpdateUserExternalProfilesViaLinks($aInitialProfiles, $aOperation, $aExpectedProfilesAfterUpdate){ + public function testProfilesLinksEdit_ChangeUserId($sProfileNameToMove, $bRaiseException=false){ + $aInitialProfiles = [ $sProfileNameToMove, "Portal power user"]; + $oUser = new \UserExternal(); $sLogin = 'testUserLDAPUpdateWithPortalPowerUserProfile-'.uniqid(); $oUser->Set('login', $sLogin); @@ -340,31 +339,29 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $sUserClass = get_class($oUser); list ($sId, $aProfiles) = $this->CreateUserForProfileTesting($oUser, $aInitialProfiles); - \cmdbAbstractObject::SetEventDBLinksChangedBlocked(true); + $oUser = new \UserExternal(); + $sLogin = 'testUserLDAPUpdateWithPortalPowerUserProfile-'.uniqid(); + $oUser->Set('login', $sLogin); + list ($sAnotherUserId, $aProfiles) = $this->CreateUserForProfileTesting($oUser, ["Configuration Manager"]); - $aURPUserProfileByUser = $this->GetURPUserProfileByUser($sId); - foreach ($aOperation as $sOperation){ - $sOp = substr($sOperation,0, 1); - $sProfileName = substr($sOperation,1); - - if ($sOp === "-"){ - if (array_key_exists($sProfileName, $aURPUserProfileByUser)){ - $oURPUserProfile = $aURPUserProfileByUser[$sProfileName]; - $oURPUserProfile->DBDelete(); - } - } else { - $oAdminUrpProfile = new URP_UserProfile(); - $oProfile = $aProfiles[$sProfileName]; - $oAdminUrpProfile->Set('profileid', $oProfile->GetKey()); - $oAdminUrpProfile->Set('userid', $sId); - $oAdminUrpProfile->DBInsert(); - } + if ($bRaiseException){ + $this->expectException(\CoreCannotSaveObjectException::class); } - \cmdbAbstractObject::SetEventDBLinksChangedBlocked(false); - \cmdbAbstractObject::FireEventDbLinksChangedForAllObjects(); + $aURPUserProfileByUser = $this->GetURPUserProfileByUser($sId); + if (array_key_exists($sProfileNameToMove, $aURPUserProfileByUser)){ + $oURPUserProfile = $aURPUserProfileByUser[$sProfileNameToMove]; + $oURPUserProfile->Set('userid', $sAnotherUserId); + $oURPUserProfile->DBWrite(); + } - $this->CheckProfilesAreOk($sUserClass, $sId, $aExpectedProfilesAfterUpdate); + if (! $bRaiseException) { + $aExpectedProfilesAfterUpdate = [$sProfileNameToMove, "Configuration Manager"]; + $this->CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sAnotherUserId, $aExpectedProfilesAfterUpdate); + + $aExpectedProfilesAfterUpdate = ["Portal power user", "Portal user"]; + $this->CheckProfilesAreOkAndThenConnectToITop($sUserClass, $sId, $aExpectedProfilesAfterUpdate); + } } private function GetURPUserProfileByUser($iUserId) : array { @@ -461,7 +458,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase public function testInit_ConfWithOneWarningProfile() { \MetaModel::GetConfig()->Set(UserProfilesEventListener::USERPROFILE_REPAIR_ITOP_PARAM_NAME, - ['Change Supervisor' => 'Administrator', 'Portal power user' => null] + ['Ticket Manager' => 'Administrator', 'Portal power user' => null] ); $oUserProfilesEventListener = new UserProfilesEventListener(); $oUserProfilesEventListener->Init(); @@ -470,7 +467,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase public function testInit_ConfWithFurtherWarningProfiles() { \MetaModel::GetConfig()->Set(UserProfilesEventListener::USERPROFILE_REPAIR_ITOP_PARAM_NAME, - ['Change Supervisor' => null, 'Portal power user' => null] + ['Ticket Manager' => null, 'Portal power user' => null] ); $oUserProfilesEventListener = new UserProfilesEventListener(); $oUserProfilesEventListener->Init(); @@ -479,7 +476,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase public function testInit_ConfWithFurtherWarningProfilesAndOneRepairment() { \MetaModel::GetConfig()->Set(UserProfilesEventListener::USERPROFILE_REPAIR_ITOP_PARAM_NAME, - ['Portal power user' => null, 'Change Supervisor' => null, 'Administrator' => "REST Services User"] + ['Portal power user' => null, 'Ticket Manager' => null, 'Administrator' => "Configuration Manager"] ); $oUserProfilesEventListener = new UserProfilesEventListener(); $oUserProfilesEventListener->Init(); @@ -495,14 +492,14 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser->Set('language', 'EN US'); \MetaModel::GetConfig()->Set(UserProfilesEventListener::USERPROFILE_REPAIR_ITOP_PARAM_NAME, - ['Portal power user' => 'Change Supervisor'] + ['Portal power user' => 'Ticket Manager'] ); $oUserProfilesEventListener = new UserProfilesEventListener(); $oUserProfilesEventListener->Init(); $this->assertTrue($oUserProfilesEventListener->IsRepairmentEnabled()); $this->CreateUserForProfileTesting($oUser, ['Portal power user'], false); - $oUserProfilesEventListener->RepairProfiles($oUser); + $oUserProfilesEventListener->ValidateThenRepairOrWarn($oUser); $oUserProfileList = $oUser->Get('profile_list'); $aProfilesAfterCreation=[]; @@ -510,7 +507,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $aProfilesAfterCreation[] = $oProfile->Get('profile'); } - $this->assertContains('Change Supervisor', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); + $this->assertContains('Ticket Manager', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); $this->assertContains('Portal power user', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); } @@ -518,8 +515,8 @@ class UserProfilesEventListenerTest extends ItopDataTestCase { \MetaModel::GetConfig()->Set(UserProfilesEventListener::USERPROFILE_REPAIR_ITOP_PARAM_NAME, [ - 'Administrator' => 'REST Services User', - 'Portal power user' => 'Change Supervisor' + 'Administrator' => 'Configuration Manager', + 'Portal power user' => 'Ticket Manager' ] ); $oUserProfilesEventListener = new UserProfilesEventListener(); @@ -532,7 +529,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser->Set('password', 'ABCD1234@gabuzomeu'); $oUser->Set('language', 'EN US'); $this->CreateUserForProfileTesting($oUser, ['Portal power user'], false); - $oUserProfilesEventListener->RepairProfiles($oUser); + $oUserProfilesEventListener->ValidateThenRepairOrWarn($oUser); $oUserProfileList = $oUser->Get('profile_list'); $aProfilesAfterCreation=[]; @@ -540,7 +537,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $aProfilesAfterCreation[] = $oProfile->Get('profile'); } - $this->assertContains('Change Supervisor', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); + $this->assertContains('Ticket Manager', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); $this->assertContains('Portal power user', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); $oUser2 = new \UserLocal(); @@ -550,7 +547,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUser2->Set('language', 'EN US'); $this->CreateUserForProfileTesting($oUser2, ['Administrator'], false); - $oUserProfilesEventListener->RepairProfiles($oUser2); + $oUserProfilesEventListener->ValidateThenRepairOrWarn($oUser2); $oUserProfileList = $oUser2->Get('profile_list'); $aProfilesAfterCreation=[]; @@ -559,7 +556,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase } $this->assertContains('Administrator', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); - $this->assertContains('REST Services User', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); + $this->assertContains('Configuration Manager', $aProfilesAfterCreation, var_export($aProfilesAfterCreation, true)); } public function testUserCreationWithWarningMessageConf() @@ -571,11 +568,9 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oAdminUser->Set('password', 'ABCD1234@gabuzomeu'); $oAdminUser->Set('language', 'EN US'); $aAssociatedProfilesBeforeUserCreation = ['Administrator']; - $this->commonUserCreation($oAdminUser, $aAssociatedProfilesBeforeUserCreation, $aAssociatedProfilesBeforeUserCreation, false); + $this->commonUserCreationTest($oAdminUser, $aAssociatedProfilesBeforeUserCreation, $aAssociatedProfilesBeforeUserCreation, false); UserRights::Login($oAdminUser->Get('login')); - - $aAssociatedProfilesBeforeUserCreation = [ 'Portal power user' ]; @@ -594,8 +589,11 @@ class UserProfilesEventListenerTest extends ItopDataTestCase $oUserProfilesEventListener = new UserProfilesEventListener(); $oUserProfilesEventListener->RegisterEventsAndListeners(); - $this->commonUserCreation($oUser, $aAssociatedProfilesBeforeUserCreation, $aAssociatedProfilesBeforeUserCreation, false); - $aObjMessages = Session::Get('obj_messages'); + $this->expectException(\CoreCannotSaveObjectException::class); + + $this->commonUserCreationTest($oUser, $aAssociatedProfilesBeforeUserCreation, $aAssociatedProfilesBeforeUserCreation, false); + + /*$aObjMessages = Session::Get('obj_messages'); $this->assertNotEmpty($aObjMessages); $sKey = sprintf("%s::%s", get_class($oUser), $oUser->GetKey()); $this->assertTrue(array_key_exists($sKey, $aObjMessages)); @@ -608,7 +606,7 @@ class UserProfilesEventListenerTest extends ItopDataTestCase ] ]; $this->assertEquals($aExpectedMessages, array_values($aObjMessages[$sKey]), var_export($aObjMessages[$sKey], true)); - +*/ $_SESSION = []; } }