diff --git a/addons/userrights/userrightsprofile.class.inc.php b/addons/userrights/userrightsprofile.class.inc.php index 9463da2034..83b32707f9 100644 --- a/addons/userrights/userrightsprofile.class.inc.php +++ b/addons/userrights/userrightsprofile.class.inc.php @@ -648,7 +648,7 @@ public function GetSelectFilter($oUser, $sClass, $aSettings = array()) $aConditions = array(); // Determine if this class is part of a silo and build the filter for it - $sAttCode = self::GetOwnerOrganizationAttCode($sClass); + $sAttCode = UserRights::GetOwnerOrganizationAttCode($sClass); if (!is_null($sAttCode)) { $aUserOrgs = $this->GetUserOrgs($oUser, $sClass); @@ -835,7 +835,7 @@ public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = n /** @var \DBObjectSet $oInstanceSet */ throw new CoreException(__FUNCTION__.': Expecting object set to be of class '.$sClass.' but it is of class '.$oInstanceSet->GetClass(), ['OQL_Query' => $oInstanceSet->GetFilter()->ToOQL(), 'classes' => $oInstanceSet->GetSelectedClasses()]); } - $sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass); + $sOrgAttCode = UserRights::GetOwnerOrganizationAttCode($sClass); if (!is_null($sOrgAttCode)) { $aUserOrgs = $this->GetUserOrgs($oUser, $sClass); if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) { @@ -927,31 +927,11 @@ public function FlushPrivileges() * @param string $sClass * @return string|null Find out which attribute is corresponding the dimension 'owner org' * returns null if no such attribute has been found (no filtering should occur) + * @deprecated 3.3.0 use @UserRights::GetOwnerOrganizationAttCode instead */ public static function GetOwnerOrganizationAttCode($sClass) { - $sAttCode = null; - - $aCallSpec = array($sClass, 'MapContextParam'); - if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization')) - { - $sAttCode = 'id'; - } - elseif (is_callable($aCallSpec)) - { - $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter - if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - // Skip silently. The data model checker will tell you something about this... - $sAttCode = null; - } - } - elseif(MetaModel::IsValidAttCode($sClass, 'org_id')) - { - $sAttCode = 'org_id'; - } - - return $sAttCode; + return UserRights::GetOwnerOrganizationAttCode($sClass); } /** diff --git a/addons/userrights/userrightsprofile.db.class.inc.php b/addons/userrights/userrightsprofile.db.class.inc.php index 7ae7214b02..ab22fe0f1d 100644 --- a/addons/userrights/userrightsprofile.db.class.inc.php +++ b/addons/userrights/userrightsprofile.db.class.inc.php @@ -778,7 +778,7 @@ public function GetSelectFilter($oUser, $sClass, $aSettings = array()) // Determine how to position the objects of this class // - $sAttCode = self::GetOwnerOrganizationAttCode($sClass); + $sAttCode = UserRights::GetOwnerOrganizationAttCode($sClass); if (is_null($sAttCode)) { // No filtering for this object @@ -909,7 +909,7 @@ public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = n // But currently we are checking wether the objects might be written... // Let's exclude the objects based on the relevant criteria - $sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass); + $sOrgAttCode = UserRights::GetOwnerOrganizationAttCode($sClass); if (!is_null($sOrgAttCode)) { $aUserOrgs = $this->GetUserOrgs($oUser, $sClass); @@ -1015,28 +1015,7 @@ public function FlushPrivileges() */ public static function GetOwnerOrganizationAttCode($sClass) { - $sAttCode = null; - - $aCallSpec = array($sClass, 'MapContextParam'); - if (($sClass == 'Organization') || is_subclass_of($sClass, 'Organization')) - { - $sAttCode = 'id'; - } - elseif (is_callable($aCallSpec)) - { - $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter - if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - // Skip silently. The data model checker will tell you something about this... - $sAttCode = null; - } - } - elseif(MetaModel::IsValidAttCode($sClass, 'org_id')) - { - $sAttCode = 'org_id'; - } - - return $sAttCode; + return UserRights::GetOwnerOrganizationAttCode($sClass);; } /** diff --git a/core/dbobject.class.php b/core/dbobject.class.php index f0030a8606..7559f6a8d1 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -1212,6 +1212,7 @@ final public function DoComputeValues() $oKPI = new ExecutionKPI(); $this->ComputeValues(); $oKPI->ComputeStatsForExtension($this, 'ComputeValues'); + } /** @@ -3663,6 +3664,8 @@ public function DBUpdate() return $this->m_iKey; } + $this->UpdateOrganizationInInlineImages($aChanges); + [$bRes, $aIssues] = $this->CheckToWrite(false); if (!$bRes) { throw new CoreCannotSaveObjectException(['issues' => $aIssues, 'class' => $sClass, 'id' => $this->GetKey()]); @@ -3850,6 +3853,22 @@ public function DBUpdate() return $this->m_iKey; } + public function UpdateOrganizationInInlineImages($aChanges){ + $sClass = get_class($this); + $sOrgAttrCodeForObject = UserRights::GetOwnerOrganizationAttCode( $sClass ); + if (is_null($sOrgAttrCodeForObject)) { + return; + } + if (in_array($sOrgAttrCodeForObject, array_keys($aChanges)) ) { + // Get all current inlineImages + $oSearch = DBObjectSearch::FromOQL("SELECT InlineImage WHERE item_class = :class AND item_id = :item_id"); + $oSet = new DBObjectSet($oSearch, array(), array('class' => $sClass, 'item_id' => $this->GetKey())); + while ($oInlineImage = $oSet->Fetch()) { + $oInlineImage->SetItem($this, true /*updateonchange*/); + } + } + } + /** * @param array $aChanges * diff --git a/core/inlineimage.class.inc.php b/core/inlineimage.class.inc.php index bc59cb7ddd..0d8da86f57 100644 --- a/core/inlineimage.class.inc.php +++ b/core/inlineimage.class.inc.php @@ -101,32 +101,24 @@ public static function MapContextParam($sContextParam) */ public function SetItem(DBObject $oItem, $bUpdateOnChange = false) { - $sClass = get_class($oItem); - $iItemId = $oItem->GetKey(); + $sClass = get_class($oItem); + $iItemId = $oItem->GetKey(); - $this->Set('item_class', $sClass); - $this->Set('item_id', $iItemId); + $this->Set('item_class', $sClass); + $this->Set('item_id', $iItemId); - $aCallSpec = array($sClass, 'MapContextParam'); - if (is_callable($aCallSpec)) - { - $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter - if (MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - $iOrgId = $oItem->Get($sAttCode); - if ($iOrgId > 0) - { - if ($iOrgId != $this->Get('item_org_id')) - { - $this->Set('item_org_id', $iOrgId); - if ($bUpdateOnChange) - { - $this->DBUpdate(); - } - } - } - } - } + $sAttCode = UserRights::GetOwnerOrganizationAttCode( $sClass); + if (is_null($sAttCode)) { + // No need for silos + return; + } + $iOrgId = $oItem->Get($sAttCode); + if ($iOrgId > 0 && $iOrgId != $this->Get('item_org_id')) { + $this->Set('item_org_id', $iOrgId); + if ($bUpdateOnChange) { + $this->DBUpdate(); + } + } } /** @@ -140,36 +132,21 @@ public function SetItem(DBObject $oItem, $bUpdateOnChange = false) */ public function SetDefaultOrgId() { - // First check that the organization CAN be fetched from the target class - // - $sClass = $this->Get('item_class'); - $aCallSpec = array($sClass, 'MapContextParam'); - if (is_callable($aCallSpec)) - { - $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter - if (MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - // Second: check that the organization CAN be fetched from the current user - // - if (MetaModel::IsValidClass('Person')) - { - $aCallSpec = array($sClass, 'MapContextParam'); - if (is_callable($aCallSpec)) - { - $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter - if (MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - // OK - try it - // - $oCurrentPerson = MetaModel::GetObject('Person', UserRights::GetContactId(), false); - if ($oCurrentPerson) - { - $this->Set('item_org_id', $oCurrentPerson->Get($sAttCode)); - } - } - } - } - } + // If the item class has no organization attribute, then no need to set the organization id + if (is_null(UserRights::GetOwnerOrganizationAttCode( $this->Get('item_class')))) { + // No need for silos + return; + } + // get organization attribute code for the person class + $sOrgAttrCodeForPerson = UserRights::GetOwnerOrganizationAttCode('Person'); + if (is_null($sOrgAttrCodeForPerson)) { + // No need for silos + return; + } + + $oCurrentPerson = MetaModel::GetObject('Person', UserRights::GetContactId(), false); + if ($oCurrentPerson) { + $this->Set('item_org_id', $oCurrentPerson->Get($sOrgAttrCodeForPerson)); } } diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index 9152efca54..cd33d3c34c 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -184,7 +184,6 @@ public function MakeSelectFilter($sClass, $aAllowedOrgs, $aSettings = array(), $ $oSearchShares = new DBObjectSearch($sShareClass); $oSearchShares->AllowAllData(); - $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization'); $oOrgField = new FieldExpression('org_id', $sShareClass); $oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr)); $aShared = array(); @@ -2028,6 +2027,33 @@ public static function GetLastLoginStatus() { return self::$m_sLastLoginStatus; } + + + /** + * @param string $sClass + * @return string|null Find out which attribute is corresponding the dimension 'owner org' + * returns null if no such attribute has been found (no filtering should occur) + * @since 3.3.0 + */ + public static function GetOwnerOrganizationAttCode($sClass) + { + $sAttCode = null; + + $aCallSpec = array($sClass, 'MapContextParam'); + if (is_callable($aCallSpec)) { + $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter + if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) { + // Skip silently. The data model checker will tell you something about this... + $sAttCode = null; + } + } + elseif(MetaModel::IsValidAttCode($sClass, 'org_id')) { + $sAttCode = 'org_id'; + } + + return $sAttCode; + } + } /** diff --git a/datamodels/2.x/itop-attachments/datamodel.itop-attachments.xml b/datamodels/2.x/itop-attachments/datamodel.itop-attachments.xml index 0bacc6ed2c..a9bd0dc84f 100755 --- a/datamodels/2.x/itop-attachments/datamodel.itop-attachments.xml +++ b/datamodels/2.x/itop-attachments/datamodel.itop-attachments.xml @@ -160,26 +160,18 @@ $this->Set('item_class', $sClass); $this->Set('item_id', $iItemId); - $aCallSpec = array($sClass, 'MapContextParam'); - if (is_callable($aCallSpec)) - { - $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter - if (MetaModel::IsValidAttCode($sClass, $sAttCode)) - { - $iOrgId = $oItem->Get($sAttCode); - if ($iOrgId > 0) - { - if ($iOrgId != $this->Get('item_org_id')) - { - $this->Set('item_org_id', $iOrgId); - if ($bUpdateOnChange) - { - $this->DBUpdate(); - } - } - } - } + $sAttCode = UserRights::GetOwnerOrganizationAttCode( $sClass); + if (is_null($sAttCode)) { + // No need for silos + return; } + $iOrgId = $oItem->Get($sAttCode); + if ($iOrgId > 0 && $iOrgId != $this->Get('item_org_id')) { + $this->Set('item_org_id', $iOrgId); + if ($bUpdateOnChange) { + $this->DBUpdate(); + } + } }]]> @@ -192,25 +184,16 @@ Overload-ExNihilo Set('item_org_id', $oCurrentPerson->Get($sAttCode)); - } - } - } + // Check that the organization CAN be fetched from the current user + $sOrgAttrCodeForPerson = UserRights::GetOwnerOrganizationAttCode('Person'); + if (is_null($sOrgAttrCodeForPerson)) { + // No need for silos + return; + } + + $oCurrentPerson = MetaModel::GetObject('Person', UserRights::GetContactId(), false); + if ($oCurrentPerson) { + $this->Set('item_org_id', $oCurrentPerson->Get($sOrgAttrCodeForPerson)); } }]]> diff --git a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml index 91e7a445f7..749e4c1ba9 100644 --- a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml +++ b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml @@ -129,7 +129,29 @@ - + + + + true + public + Overload-ExNihilo + + +
diff --git a/datamodels/2.x/itop-structure/module.itop-structure.php b/datamodels/2.x/itop-structure/module.itop-structure.php index fa4b18edff..24817239cc 100644 --- a/datamodels/2.x/itop-structure/module.itop-structure.php +++ b/datamodels/2.x/itop-structure/module.itop-structure.php @@ -142,7 +142,7 @@ public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousV $sPersonClass = 'Person'; $sPersonStateAttCode = MetaModel::GetStateAttributeCode($sPersonClass); - $sPersonOwnerOrgAttCode = UserRightsProfile::GetOwnerOrganizationAttCode($sPersonClass); + $sPersonOwnerOrgAttCode = UserRights::GetOwnerOrganizationAttCode($sPersonClass); $iClassesWithLogCount = 0; $aCreatedTriggerIds = []; @@ -177,7 +177,7 @@ public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousV ); // Filter on class owner org. if any - $sClassOwnerOrgAttCode = UserRightsProfile::GetOwnerOrganizationAttCode($sClass); + $sClassOwnerOrgAttCode = UserRights::GetOwnerOrganizationAttCode($sClass); $oOwnerOrgExpr = empty($sClassOwnerOrgAttCode) ? null : new BinaryExpression( new FieldExpression($sPersonOwnerOrgAttCode), '=', diff --git a/pages/ajax.document.php b/pages/ajax.document.php index 19b321e7a8..d7b68d52f2 100644 --- a/pages/ajax.document.php +++ b/pages/ajax.document.php @@ -25,92 +25,92 @@ if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) && (strlen($_SERVER['HTTP_IF_MODIFIED_SINCE']) > 0)) { - // The content is garanteed to be unmodified since the URL includes a signature based on the contents of the document - header('Last-Modified: Mon, 1 January 2018 00:00:00 GMT', true, 304); // Any date in the past - exit; + // The content is garanteed to be unmodified since the URL includes a signature based on the contents of the document + header('Last-Modified: Mon, 1 January 2018 00:00:00 GMT', true, 304); // Any date in the past + exit; } try { - require_once(APPROOT.'/application/application.inc.php'); - require_once(APPROOT.'/application/startup.inc.php'); - - require_once(APPROOT.'/application/loginwebpage.class.inc.php'); - IssueLog::Trace('----- Request: '.utils::GetRequestUri(), LogChannels::WEB_REQUEST); - - $oPage = new DownloadPage(""); - - $operation = utils::ReadParam('operation', ''); - $sClass = utils::ReadParam('class', 'MissingAjaxParam', false, 'class'); - - switch ($operation) { - case 'download_document': - LoginWebPage::DoLoginEx('backoffice', false); - $id = utils::ReadParam('id', ''); - $sField = utils::ReadParam('field', ''); - if ($sClass == 'Attachment') - { - $iCacheSec = 31556926; // One year ahead: an attachment cannot change - } - else - { - $iCacheSec = (int)utils::ReadParam('cache', 0); - } - if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField)) - { - ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'attachment'); - if ($iCacheSec > 0) - { - $oPage->set_cache($iCacheSec); - // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page - // so we're resetting its value ! (see N°3416) - $oPage->add_http_headers(''); - } - } - break; - - case 'download_inlineimage': - // No login is required because the "secret" protects us - // Benefit: the inline image can be inserted into any HTML (templating = $this->html(public_log)$) - $id = utils::ReadParam('id', ''); - $sSecret = utils::ReadParam('s', ''); - $iCacheSec = 31556926; // One year ahead: an inline image cannot change - if (!empty($id) && !empty($sSecret)) { - ormDocument::DownloadDocument($oPage, 'InlineImage', $id, 'contents', 'inline', 'secret', $sSecret); - $oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec"); - $oPage->add_header("Pragma: cache"); // Reset the value set .... where ? - $oPage->add_header("Expires: "); // Reset the value set in ajax_page - - // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page - // so we're resetting its value ! (see N°3416) - $oPage->add_http_headers(''); - - $oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok - } - break; - - case 'dict': - $sSignature = Utils::ReadParam('s', ''); // Sanitization prevents / and .. - $oPage->SetContentType('text/javascript'); - $oPage->set_cache(86400); // Cache for 24 hours - - // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page - // so we're resetting its value ! (see N°3416) - $oPage->add_http_headers(''); - - $oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js')); - break; - - default: - $oPage->p("Invalid query."); - } - - $oPage->output(); + require_once(APPROOT.'/application/application.inc.php'); + require_once(APPROOT.'/application/startup.inc.php'); + + require_once(APPROOT.'/application/loginwebpage.class.inc.php'); + IssueLog::Trace('----- Request: '.utils::GetRequestUri(), LogChannels::WEB_REQUEST); + + $oPage = new DownloadPage(""); + + $operation = utils::ReadParam('operation', ''); + $sClass = utils::ReadParam('class', 'MissingAjaxParam', false, 'class'); + + switch ($operation) { + case 'download_document': + LoginWebPage::DoLoginEx('backoffice', false); + $id = utils::ReadParam('id', ''); + $sField = utils::ReadParam('field', ''); + if ($sClass == 'Attachment') + { + $iCacheSec = 31556926; // One year ahead: an attachment cannot change + } + else + { + $iCacheSec = (int)utils::ReadParam('cache', 0); + } + if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField)) + { + ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'attachment'); + if ($iCacheSec > 0) + { + $oPage->set_cache($iCacheSec); + // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page + // so we're resetting its value ! (see N°3416) + $oPage->add_http_headers(''); + } + } + break; + + case 'download_inlineimage': + // No login is required because the "secret" protects us + // Benefit: the inline image can be inserted into any HTML (templating = $this->html(public_log)$) + $id = utils::ReadParam('id', ''); + $sSecret = utils::ReadParam('s', ''); + $iCacheSec = 31556926; // One year ahead: an inline image cannot change + if (!empty($id) && !empty($sSecret)) { + ormDocument::DownloadDocument($oPage, 'InlineImage', $id, 'contents', 'inline', 'secret', $sSecret); + $oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec"); + $oPage->add_header("Pragma: cache"); // Reset the value set .... where ? + $oPage->add_header("Expires: "); // Reset the value set in ajax_page + + // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page + // so we're resetting its value ! (see N°3416) + $oPage->add_http_headers(''); + + $oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok + } + break; + + case 'dict': + $sSignature = Utils::ReadParam('s', ''); // Sanitization prevents / and .. + $oPage->SetContentType('text/javascript'); + $oPage->set_cache(86400); // Cache for 24 hours + + // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page + // so we're resetting its value ! (see N°3416) + $oPage->add_http_headers(''); + + $oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js')); + break; + + default: + $oPage->p("Invalid query."); + } + + $oPage->output(); } catch (Exception $e) { - // note: transform to cope with XSS attacks - echo utils::EscapeHtml($e->GetMessage()); - IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString()); + // note: transform to cope with XSS attacks + echo utils::EscapeHtml($e->GetMessage()); + IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString()); } diff --git a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php index aa09aed747..d69f58ed33 100644 --- a/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php +++ b/tests/php-unit-tests/src/BaseTestCase/ItopDataTestCase.php @@ -1122,10 +1122,10 @@ protected function GivenObject(string $sClass, array $aParams): DBObject * @param string $sClass * @param array $aValues * - * @return string created object key + * @return int * @throws Exception */ - protected function GivenObjectInDB($sClass, $aValues) + protected function GivenObjectInDB($sClass, $aValues):int { // Check and complete the values foreach ($aValues as $sAttCode => $oValue) { @@ -1465,4 +1465,37 @@ static protected function StopStopwatchInTheFuture(DBObject $oObject, string $sS $oObject->Set($sStopwatchAttCode, $oStopwatch); } + + protected function GivenUserLoggedInWithContact(int $iContactOrgId) + { + $iContactId = $this->GivenObjectInDB('Person', [ + 'first_name' => 'TestContact', + 'name' => 'TestContact', + 'org_id' => $iContactOrgId]); + $sLogin = 'demo_test_'.uniqid(__CLASS__, true); + $iUser = $this->GivenObjectInDB('UserLocal', [ + 'login' => $sLogin, + 'password' => 'tagada-Secret,007', + 'language' => 'EN US', + 'contactid' => $iContactId, + 'profile_list' => [ + 'profileid:'.self::$aURP_Profiles['Configuration Manager'] + ] + ]); + \UserRights::Login($sLogin); + } + + protected function GivenUserLoggedInWithoutContact() + { + $sLogin = 'demo_test_'.uniqid(__CLASS__, true); + $iUser = $this->GivenObjectInDB('UserLocal', [ + 'login' => $sLogin, + 'password' => 'tagada-Secret,007', + 'language' => 'EN US', + 'profile_list' => [ + 'profileid:'.self::$aURP_Profiles['Configuration Manager'] + ] + ]); + \UserRights::Login($sLogin); + } } diff --git a/tests/php-unit-tests/unitary-tests/core/InlineImageTest.php b/tests/php-unit-tests/unitary-tests/core/InlineImageTest.php index d71055b137..11710f6b59 100644 --- a/tests/php-unit-tests/unitary-tests/core/InlineImageTest.php +++ b/tests/php-unit-tests/unitary-tests/core/InlineImageTest.php @@ -9,6 +9,7 @@ use Combodo\iTop\Test\UnitTest\ItopDataTestCase; use InlineImage; +use MetaModel; class InlineImageTest extends ItopDataTestCase { @@ -59,4 +60,65 @@ public function OnFormCancelInvalidTempIdProvider() ], ]; } + + public function testSetItemOnObjectWithDefinedOrganization() + { + $iContactOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrgContact']); + $this->GivenUserLoggedInWithContact($iContactOrgId); + + $iOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg']); + $oUserRequest = $this->GivenObject('UserRequest', ['title' => 'TestUserRequest', 'org_id'=>$iOrgId]); + + $oInlineImage = \MetaModel::NewObject('InlineImage',['item_class' => 'UserRequest']); + $oInlineImage->SetItem($oUserRequest); + $this->assertEquals($iOrgId, $oInlineImage->Get('item_org_id'),'The org_id should be the one of the UserRequest'); + } + + public function testSetItemOnObjectWithDefinedOrganizationFollowOrgOfLinkedObject() + { + $iOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg']); + $oUserRequest = $this->createObject('UserRequest', ['title' => 'TestUserRequest', 'org_id'=>$iOrgId, 'description' => 'TestDescription']); + + $oInlineImage = $this->createObject('InlineImage',['item_class' => 'UserRequest','secret'=>'TestSecret']); + $oInlineImage->SetItem($oUserRequest); + $oInlineImage->DBUpdate(); + $this->assertEquals($iOrgId, $oInlineImage->Get('item_org_id'),'The org_id should be the one of the UserRequest - afterCreation'); + + $iNewOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg2']); + $oUserRequest->Set('org_id', $iNewOrgId); + $oUserRequest->DBUpdate(); + $iKey= $oInlineImage->GetKey(); + //Get InlineImage from DB in order to check the org_id modified by DBUpdate + $oInlineImage = MetaModel::GetObject('InlineImage', $iKey); + $this->assertEquals($iNewOrgId, $oInlineImage->Get('item_org_id'),'The org_id should be the one of the UserRequest - afterUpdate'); + } + + public function testSetDefaultOrgIdWhenLoggedInWithContact() + { + $iContactOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrgContact']); + $this->GivenUserLoggedInWithContact($iContactOrgId); + + $oInlineImage = \MetaModel::NewObject('InlineImage',['item_class' => 'UserRequest']); + $oInlineImage->SetDefaultOrgId(); + $this->assertEquals($iContactOrgId, $oInlineImage->Get('item_org_id'),'The org_id should be the one of the contact'); + + $oInlineImage = \MetaModel::NewObject('InlineImage',['item_class' => 'TriggerOnObjectCreate']); + $oInlineImage->SetDefaultOrgId(); + $this->assertEquals(0, $oInlineImage->Get('item_org_id'),'The org_id should be left undefined'); + } + + + public function testSetDefaultOrgIdWhenLoggedInWithoutContact() + { + $this->GivenUserLoggedInWithoutContact(); + + $oInlineImage = \MetaModel::NewObject('InlineImage',['item_class' => 'UserRequest']); + $oInlineImage->SetDefaultOrgId(); + $this->assertEquals(0, $oInlineImage->Get('item_org_id'),'The org_id should be left undefined'); + + $oInlineImage = \MetaModel::NewObject('InlineImage',['item_class' => 'TriggerOnObjectCreate']); + $oInlineImage->SetDefaultOrgId(); + $this->assertEquals(0, $oInlineImage->Get('item_org_id'),'The org_id should be left undefined'); + } + } diff --git a/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php b/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php index 5a743a0e8b..a3a97c878d 100644 --- a/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php +++ b/tests/php-unit-tests/unitary-tests/core/UserRightsTest.php @@ -552,4 +552,19 @@ public function FindUserAndAssertItWasNotFound($sLogin) $oUser = $this->InvokeNonPublicStaticMethod(UserRights::class, "FindUser", [$sLogin]); static::assertNull($oUser, 'FindUser should return null when the login is unknown'); } + + public function testGetOwnerOrganizationAttCode() + { + $this->assertEquals('id', UserRights::GetOwnerOrganizationAttCode('Organization')); + + $this->assertEquals('org_id', UserRights::GetOwnerOrganizationAttCode('User')); + $this->assertEquals('org_id', UserRights::GetOwnerOrganizationAttCode('Server')); + $this->assertEquals('org_id', UserRights::GetOwnerOrganizationAttCode('UserRequest')); + + $this->assertEquals('item_org_id', UserRights::GetOwnerOrganizationAttCode('InlineImage')); + $this->assertEquals('item_org_id', UserRights::GetOwnerOrganizationAttCode('Attachment')); + + $this->assertNull(UserRights::GetOwnerOrganizationAttCode('TriggerOnObjectCreation')); + $this->assertNull(UserRights::GetOwnerOrganizationAttCode('lnkPersonToTeam')); + } } diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-attachments/TestAttachment.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-attachments/TestAttachment.php index 8485c956f0..fdb0f3fcfc 100644 --- a/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-attachments/TestAttachment.php +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/itop-attachments/TestAttachment.php @@ -69,4 +69,64 @@ public function OnRemoveAttachment(EventData $oData) $oDocument = $oAttachment->Get('contents'); $this->sRemoveAttachmentName = $oDocument->GetFileName(); } + + + public function testSetItemOnObjectWithDefinedOrganization() + { + $iOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg']); + $oUserRequest = $this->GivenObject('UserRequest', ['title' => 'TestUserRequest', 'org_id'=>$iOrgId]); + + $oAttachment = new \Attachment(); + $oAttachment->SetItem($oUserRequest); + $this->assertEquals($iOrgId, $oAttachment->Get('item_org_id'),'The org_id should be the one of the UserRequest'); + } + + public function testSetItemOnObjectWithDefinedOrganizationFollowOrgOfLinkedObject() + { + $iOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg']); + $oUserRequest = $this->createObject('UserRequest', ['title' => 'TestUserRequest', 'org_id'=>$iOrgId, 'description' => 'TestDescription']); + + $oAttachment = $this->createObject('Attachment',['item_class' => 'UserRequest']); + $oAttachment->SetItem($oUserRequest); + $oAttachment->DBUpdate(); + $this->assertEquals($iOrgId, $oAttachment->Get('item_org_id'),'The org_id should be the one of the UserRequest - After Insert'); + + $iNewOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg2']); + $oUserRequest->Set('org_id', $iNewOrgId); + $oUserRequest->DBUpdate(); + $iKey= $oAttachment->GetKey(); + //Get InlineImage from DB in order to check the org_id modified by DBUpdate + $oAttachment = MetaModel::GetObject('Attachment', $iKey); + $this->assertEquals($iNewOrgId, $oAttachment->Get('item_org_id'),'The org_id should be the one of the UserRequest - After Update'); + } + + public function testSetItemOnObjectWithoutDefinedOrganization() + { + $oTriggerOnObjectCreate = $this->GivenObject('TriggerOnObjectCreate', ['target_class' => 'UserRequest','description'=>'TestUserRequest']); + + $oAttachment = new \Attachment(); + $oAttachment->SetItem($oTriggerOnObjectCreate); + $this->assertEquals(0, $oAttachment->Get('item_org_id'),'The org_id must be 0 because TriggerOnObjectCreate does not have a link to an organization'); + } + + + public function testSetDefaultOrgIdWhenLoggedInWithContact() + { + $iContactOrgId = $this->GivenObjectInDB('Organization', ['name' => 'TestOrg']); + $this->GivenUserLoggedInWithContact($iContactOrgId); + + $oAttachment = new \Attachment(); + $oAttachment->SetDefaultOrgId(); + $this->assertEquals($iContactOrgId, $oAttachment->Get('item_org_id'),'The org_id should be the one of the contact'); + } + + + public function testSetDefaultOrgIdWhenLoggedInWithoutContact() + { + $this->GivenUserLoggedInWithoutContact(); + + $oAttachment = new \Attachment(); + $oAttachment->SetDefaultOrgId(); + $this->assertEquals(0, $oAttachment->Get('item_org_id'),'The org_id should be left undefined'); + } }