Set('name', 'PHPUnit test'); $oTestObject->Set('org_id', 1); $oTestObject->Set('url', 'https://www.combodo.com'); $oTestObject->DBWrite(); self::assertFalse(CMDBObject::GetCurrentChange()->IsNew(), 'TrackInfo : Current change persisted'); self::assertEquals( $sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : current change created with expected trackinfo' ); //-- new object with non persisted current change $sTrackInfo2 = $sTrackInfo.'_2'; /** @var \CMDBChange $oCustomChange */ $oCustomChange = MetaModel::NewObject('CMDBChange'); $oCustomChange->Set('date', time()); $oCustomChange->Set('userinfo', $sTrackInfo2); CMDBObject::SetCurrentChange($oCustomChange); $oTestObject->Set('url', 'https://fr.wikipedia.org'); $oTestObject->DBUpdate(); self::assertFalse(CMDBObject::GetCurrentChange()->IsNew(), 'SetCurrentChange : Current change persisted'); self::assertEquals( $sTrackInfo2, CMDBObject::GetCurrentChange()->Get('userinfo'), 'SetCurrentChange : current change created with expected trackinfo' ); //-- new object with current change init using helper method $sTrackInfo3 = $sTrackInfo.'_3'; CMDBObject::SetCurrentChangeFromParams($sTrackInfo3); $oTestObject->Set('url', 'https://en.wikipedia.org'); $oTestObject->DBUpdate(); self::assertFalse(CMDBObject::GetCurrentChange()->IsNew(), 'SetCurrentChangeFromParams : Current change persisted'); self::assertEquals( $sTrackInfo3, CMDBObject::GetCurrentChange()->Get('userinfo'), 'SetCurrentChangeFromParams : current change created with expected trackinfo' ); // restore initial conditions $oTestObject->DBDelete(); CMDBObject::SetCurrentChange($oInitialCurrentChange); CMDBObject::SetTrackInfo($sInitialTrackInfo); } public function CurrentChangeUnderImpersonationProvider() { return [ 'no track info' => [ 'sTrackInfo' => null ], 'track info from approvalbase' => [ 'sTrackInfo' => 'ImpersonatedSurName ImpersonatedName Approved on behalf of YYY', 'sExpectedChangeLogWhenImpersonation' => "AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName (ImpersonatedSurName ImpersonatedName Approved on behalf of YYY)", ], ]; } /** * @covers CMDBObject::SetCurrentChange * @since 3.0.1 N°5135 - Impersonate: history of changes versus log entries * * @runInSeparateProcess * @dataProvider CurrentChangeUnderImpersonationProvider */ public function testCurrentChangeUnderImpersonation($sTrackInfo = null, $sExpectedChangeLogWhenImpersonation = null) { $this->CreateTestOrganization(); $sUid = date('dmYHis'); $sAdminLogin = "admin-user-".$sUid; $sImpersonatedLogin = "impersonated-user-".$sUid; $oAdminUser = $this->CreateUserForImpersonation($sAdminLogin, 'Administrator', 'AdminName', 'AdminSurName'); $oImpersonatedUser = $this->CreateUserForImpersonation($sImpersonatedLogin, 'Configuration Manager', 'ImpersonatedName', 'ImpersonatedSurName'); $_SESSION = []; \UserRights::Login($sAdminLogin); // save initial conditions $oInitialCurrentChange = CMDBObject::GetCurrentChange(); $sInitialTrackInfo = CMDBObject::GetTrackInfo(); // reset current change CMDBObject::SetCurrentChange(null); if (is_null($sTrackInfo)) { CMDBObject::SetTrackInfo(null); } else { $sTrackInfo = $this->ReplaceByFriendlyNames($sTrackInfo, $oAdminUser, $oImpersonatedUser); CMDBObject::SetTrackInfo($sTrackInfo); } $this->CreateSimpleObject(); if (is_null($sTrackInfo)) { self::assertEquals( $oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : no impersonation' ); } else { self::assertEquals( $sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : no impersonation' ); } self::assertEquals( $oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'), 'TrackInfo : admin userid' ); \UserRights::Impersonate($sImpersonatedLogin); $this->CreateSimpleObject(); if (is_null($sExpectedChangeLogWhenImpersonation)) { $sExpectedMsg = $this->ReplaceByFriendlyNames("AdminSurName AdminName on behalf of ImpersonatedSurName ImpersonatedName", $oAdminUser, $oImpersonatedUser); self::assertEquals( $sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : impersonation' ); } else { $sExpectedMsg = $this->ReplaceByFriendlyNames($sExpectedChangeLogWhenImpersonation, $oAdminUser, $oImpersonatedUser); self::assertEquals( $sExpectedMsg, CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : impersonation' ); } self::assertEquals( null, CMDBObject::GetCurrentChange()->Get('user_id'), 'TrackInfo : no userid to force userinfo being displayed on UI caselog side' ); \UserRights::Deimpersonate(); $this->CreateSimpleObject(); if (is_null($sTrackInfo)) { self::assertEquals( $oAdminUser->GetFriendlyName(), CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : no impersonation' ); } else { self::assertEquals( $sTrackInfo, CMDBObject::GetCurrentChange()->Get('userinfo'), 'TrackInfo : no impersonation' ); } self::assertEquals( $oAdminUser->GetKey(), CMDBObject::GetCurrentChange()->Get('user_id'), 'TrackInfo : admin userid' ); // restore initial conditions CMDBObject::SetCurrentChange($oInitialCurrentChange); CMDBObject::SetTrackInfo($sInitialTrackInfo); } /** * Data provider for test deletion * N°5547 - Object deletion fails if friendlyname too long * * @return array data */ public function RecordObjDeletionProvider() { return [ 'friendlyname longer than 255 characters which will be truncated on a multi-bytes characters' => [ str_repeat('e', 250), 'šŸ˜šŸ˜‚šŸ¤£šŸ˜ƒšŸ˜„šŸ˜…šŸ˜†šŸ˜—šŸ„°šŸ˜˜šŸ˜šŸ˜ŽšŸ˜‹šŸ˜ŠšŸ˜‰šŸ˜™šŸ˜š', ], 'friendlyname longer than 255 characters which will be truncated after a single byte characters' => [ 'šŸ˜šŸ˜‚šŸ¤£šŸ˜ƒšŸ˜„šŸ˜…šŸ˜†šŸ˜—šŸ„°šŸ˜˜šŸ˜šŸ˜ŽšŸ˜‹šŸ˜ŠšŸ˜‰šŸ˜™šŸ˜š', str_repeat('e', 250), ], ]; } /** * N°5547 - Object deletion fails if friendlyname too long * * @dataProvider RecordObjDeletionProvider * */ public function testRecordObjDeletion(string $sFirstName, string $sName) { $oPerson = MetaModel::NewObject('Person', [ 'first_name' => $sFirstName, 'name' => $sName, 'org_id' => 1, ]); $oPerson->DBWrite(); $bDeletionOK = true; try { $oDeletionPlan = $this->InvokeNonPublicMethod(CMDBObject::class, 'RecordObjDeletion', $oPerson, [$oPerson->GetKey()]); } catch (CoreException $e) { $bDeletionOK = false; } // We don't need to test the result (truncated string), it's already done in \DBObject::SetTrim() with N°3448 $this->assertTrue($bDeletionOK); } private function ReplaceByFriendlyNames($sMessage, $oAdminUser, $oImpersonatedUser): string { $sNewMessage = str_replace('AdminSurName AdminName', $oAdminUser->GetFriendlyName(), $sMessage); $sNewMessage = str_replace('ImpersonatedSurName ImpersonatedName', $oImpersonatedUser->GetFriendlyName(), $sNewMessage); return $sNewMessage; } private function CreateSimpleObject() { /** @var \DocumentWeb $oTestObject */ $oTestObject = MetaModel::NewObject('DocumentWeb'); $oTestObject->Set('name', 'PHPUnit test'); $oTestObject->Set('org_id', $this->getTestOrgId()); $oTestObject->Set('url', 'https://www.combodo.com'); $oTestObject->DBWrite(); } private function CreateUserForImpersonation($sLogin, $sProfileName, $sName, $sSurname): \UserLocal { /** @var \Person $oPerson */ $oPerson = $this->createObject('Person', [ 'name' => $sName, 'first_name' => $sSurname, 'org_id' => $this->getTestOrgId(), ]); $oProfile = \MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", ['name' => $sProfileName], true); /** @var \UserLocal $oUser */ $oUser = $this->CreateUser($sLogin, $oProfile->GetKey(), "1234567Azert@", $oPerson->GetKey()); return $oUser; } }