diff --git a/core/dbobject.class.php b/core/dbobject.class.php
index 552dfc0d7..978394e59 100644
--- a/core/dbobject.class.php
+++ b/core/dbobject.class.php
@@ -5962,7 +5962,22 @@ abstract class DBObject implements iDisplay
}
/**
+ *
* @api
+ *
+ * @param string $sWarning Warning message displayed when objet is redisplayed
+ *
+ * @return void
+ * @since 3.1.0
+ */
+ final public function AddCheckWarning(string $sWarning)
+ {
+ $this->m_aCheckWarnings[] = $sWarning;
+ }
+
+ /**
+ * @api
+ *
* @param string $sIssue
* @param bool $bIsSecurityIssue
*
diff --git a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml
index de1347f67..f7bcbad83 100644
--- a/datamodels/2.x/itop-structure/datamodel.itop-structure.xml
+++ b/datamodels/2.x/itop-structure/datamodel.itop-structure.xml
@@ -642,6 +642,13 @@
+
+
+ EVENT_DB_CHECK_TO_WRITE
+ CheckUsersOnUpdate
+ 1
+
+
96
@@ -712,6 +719,40 @@
+
+ false
+ public
+ EventListener
+ ListChanges();
+ // Current User may not be allowed to see User class, so we can't use $this->Get('user_list')
+ $oSearch = new DBObjectSearch('User');
+ $oSearch->AddCondition('contactid', $this->GetKey(), '=');
+ $oSearch->AllowAllData();
+ $oUserSet = new DBObjectSet($oSearch);
+
+ // The organization's person was changed and it has associated Users
+ if (array_key_exists('org_id', $aChanges) && ($oUserSet->Count() > 0)) {
+ while($oUser = $oUserSet->Fetch())
+ {
+ $oAddon = UserRights::GetModuleInstance();
+ $aOrgs = $oAddon->GetUserOrgs($oUser,'Organization');
+ $oSet = $oUser->Get('profile_list');
+ $aProfiles = $oSet->GetColumnAsArray('profile');
+
+ // User is not allowed on the new Organization and has 'Portal user' Profile and is enabled
+ if (!in_array($this->Get('org_id'), $aOrgs) && in_array('Portal user',$aProfiles) && ($oUser->Get('status') === 'enabled'))
+ { // Let's block the Person modification,
+ // replace by $this->AddCheckWarning(...) if you don't want to block the modification
+ $this->AddCheckIssue(Dict::Format('Class:Person/Error:ChangingOrgDenied', $this->Get('org_id_friendlyname')));
+ }
+ }
+ }
+ }
+]]>
+
false
public
diff --git a/datamodels/2.x/itop-structure/dictionaries/en.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/en.dict.itop-structure.php
index 7778d3ed3..6b02dc98f 100644
--- a/datamodels/2.x/itop-structure/dictionaries/en.dict.itop-structure.php
+++ b/datamodels/2.x/itop-structure/dictionaries/en.dict.itop-structure.php
@@ -187,6 +187,7 @@ Dict::Add('EN US', 'English', 'English', array(
'Class:Person/UniquenessRule:employee_number' => 'there is already a person in \'$this->org_name$\' organization with the same employee number',
'Class:Person/UniquenessRule:name+' => 'The employee name should be unique inside its organization',
'Class:Person/UniquenessRule:name' => 'There is already a person in \'$this->org_name$\' organization with the same name',
+ 'Class:Person/Error:ChangingOrgDenied' => 'Impossible to move this person under organization \'%1$s\' as it would break his access to the User Portal, his associated user not being allowed on this organization',
));
//
diff --git a/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php b/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php
index a50776735..7b418240d 100644
--- a/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php
+++ b/datamodels/2.x/itop-structure/dictionaries/fr.dict.itop-structure.php
@@ -196,6 +196,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
\'$this->org_name$\'',
'Class:Person/UniquenessRule:name+' => 'Le nom de l\'employé devrait être unique dans l\'organisation',
'Class:Person/UniquenessRule:name' => 'Il y a déjà une personne avec ce nom dans l\'organisation \'$this->org_name$\'',
+ 'Class:Person/Error:ChangingOrgDenied' => 'Impossible de déplacer cette personne sous l\'organisation \'%1$s\', cela casserait son accès au portail utilisateur, car il n\'a pas le droit de voir cette organisation',
));
//