:: Version 3.2.0 ::
Prevent User accidentally disabled
Prerequisite: You must be familiar with the Syntax used in Tutorials and have already created an extension.
If you have a User with Allowed organizations
defined, linked to a Person, it is mandatory that the Person's
Organization is within the list of Allowed
organizations
if some are defined.
-
This check is not done by iTop out the box.
-
In iTop 3.0.0, the control was added to the User object creation/modification, and also on Person deletion
-
Nevertheless, there is still a corner case which is not protected, if you modify the organization of the Person to an Organization which is not in the list of the ''Allowed organizations“ of at least one of the associated User, in that case that User won't be able to connect to iTop anymore.
In this tutorial, you will learn how to add a protection against this unwanted situation. For this we will add/modify a few methods on the Person class:
DoCheckToWrite
You must overwrite this function
- Person
-
public function DoCheckToWrite() { if (array_key_exists('org_id',$this->ListChanges()) && ($this->HasUserAccount(true))) { // Do not let modify Person's organization if linked to active users with allowed organizations $iNewOrg = $this->Get('org_id'); // Get the user org and all its parent organizations $aUserOrgs = [$iNewOrg]; $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization'); if ($sHierarchicalKeyCode !== false) { $sOrgQuery = 'SELECT Org FROM Organization AS Org JOIN Organization AS Root ON Org.' .$sHierarchicalKeyCode.' ABOVE Root.id WHERE Root.id = :id'; $oOrgFilter = new DBObjectSearch::FromOQL_AllData($sOrgQuery); $oOrgFilter->AllowAllData(true); $oOrgSet = new DBObjectSet($oOrgFilter, [], ['id' => $iNewOrg])); while ($aRow = $oOrgSet->FetchAssoc()) { $oOrg = $aRow['Org']; $aUserOrgs[] = $oOrg->GetKey(); } } //CAUTIOUS: Copy the code of GetUsers() function here, if you don't create that function $oUserSet = $this->GetUsers(true); while($oUser = $oUserSet->Fetch()) { if (!UserRights::IsAdministrator($oUser)) { // Allowed orgs must contains the user org (if any) $oSet = $oUser->get('allowed_org_list'); if ($oSet->Count() > 0) { $bFound = false; while ($oOrg = $oSet->Fetch()) { if (in_array($oOrg->Get('allowed_org_id'), $aUserOrgs)) { $bFound = true; break; } } if (!$bFound) { $this->m_aCheckErrors[] = $oUser->Get('login').": " .Dict::S('Class:User/Error:AllowedOrgsMustContainUserOrg'); } } } } } return parent::DoCheckToWrite(); }
Helpers
You can create this Helper function (optional, otherwise insert this code within the above function)
- Person
-
public function GetUsers($bActiveOnly=false) { $sOQL = $bActiveOnly ? 'SELECT User WHERE contactid = :person' : "SELECT User WHERE contactid = :person AND status='active'"; $oFilter = DBSearch::FromOQL($sOQL, array('person' => $this->GetKey())); // As most users are not allowed to see objects of the class User, you need to explicitly allow it: $oFilter->AllowAllData(true); $oUserSet = new DBObjectSet($oFilter); return $oUserSet; }
You can redefine this function (optional, it's just to avoid code duplication)
3_2_0/customization/user-protection.txt · Last modified:
2024/08/13 09:54 (external edit)