diff --git a/addons/userrights/userrightsprofile.class.inc.php b/addons/userrights/userrightsprofile.class.inc.php index 0e38717d5..2b41ece36 100644 --- a/addons/userrights/userrightsprofile.class.inc.php +++ b/addons/userrights/userrightsprofile.class.inc.php @@ -30,21 +30,18 @@ class UserRightsBaseClass extends cmdbAbstractObject { // Whenever something changes, reload the privileges - public function DBInsertTracked(CMDBChange $oChange) + protected function AfterInsert() { - parent::DBInsertTracked($oChange); UserRights::FlushPrivileges(); } - public function DBUpdateTracked(CMDBChange $oChange) + protected function AfterUpdate() { - parent::DBUpdateTracked($oChange); UserRights::FlushPrivileges(); } - public function DBDeleteTracked(CMDBChange $oChange) + protected function AfterDelete() { - parent::DBDeleteTracked($oChange); UserRights::FlushPrivileges(); } } @@ -405,18 +402,6 @@ class UserRightsProfile extends UserRightsAddOnAPI return true; } - public function IsAdministrator($oUser) - { - if (in_array($oUser->GetKey(), $this->m_aAdmins)) - { - return true; - } - else - { - return false; - } - } - public function Setup() { SetupProfiles::ComputeITILProfiles(); @@ -427,20 +412,36 @@ class UserRightsProfile extends UserRightsAddOnAPI public function Init() { - MetaModel::RegisterPlugin('userrights', 'ACbyProfile', array($this, 'CacheData')); + MetaModel::RegisterPlugin('userrights', 'ACbyProfile', array($this, 'LoadCache')); } - protected $m_aProfiles = array(); // id -> object - protected $m_aUserProfiles = array(); // userid,profileid -> object - protected $m_aUserOrgs = array(); // userid,orgid -> object - protected $m_aAdmins = array(); // id of users being linked to the well-known admin profile + protected $m_aAdmins; // id of users being linked to the well-known admin profile - protected $m_aClassActionGrants = array(); // profile, class, action -> permission - protected $m_aClassStimulusGrants = array(); // profile, class, stimulus -> permission + protected $m_aProfiles; // id -> object + protected $m_aUserProfiles; // userid,profileid -> object + protected $m_aUserOrgs; // userid,orgid -> object - public function CacheData() + protected $m_aClassActionGrants; // profile, class, action -> permission + protected $m_aClassStimulusGrants; // profile, class, stimulus -> permission + + public function ResetCache() { + // Loaded by Load cache + $this->m_aProfiles = null; + $this->m_aUserProfiles = null; + $this->m_aUserOrgs = null; + + $this->m_aAdmins = null; + + // Loaded on demand + $this->m_aClassActionGrants = array(); + $this->m_aClassStimulusGrants = array(); + } + + public function LoadCache() + { + if (!is_null($this->m_aProfiles)) return; // Could be loaded in a shared memory (?) $oProfileSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData("SELECT URP_Profiles")); @@ -480,8 +481,24 @@ exit; return true; } + public function IsAdministrator($oUser) + { + $this->LoadCache(); + + if (in_array($oUser->GetKey(), $this->m_aAdmins)) + { + return true; + } + else + { + return false; + } + } + public function GetSelectFilter($oUser, $sClass) { + $this->LoadCache(); + $aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, UR_ACTION_READ); if ($aObjectPermissions['permission'] == UR_ALLOWED_NO) { @@ -527,6 +544,8 @@ exit; // This verb has been made public to allow the development of an accurate feedback for the current configuration public function GetProfileActionGrant($iProfile, $sClass, $sAction) { + $this->LoadCache(); + if (isset($this->m_aClassActionGrants[$iProfile][$sClass][$sAction])) { return $this->m_aClassActionGrants[$iProfile][$sClass][$sAction]; @@ -559,6 +578,8 @@ exit; protected function GetUserActionGrant($oUser, $sClass, $iActionCode) { + $this->LoadCache(); + // load and cache permissions for the current user on the given class // $iUser = $oUser->GetKey(); @@ -610,6 +631,8 @@ exit; public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null) { + $this->LoadCache(); + if (is_null($oInstanceSet)) { $aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, $iActionCode); @@ -649,6 +672,8 @@ exit; public function IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet = null) { + $this->LoadCache(); + if (is_null($oInstanceSet)) { $aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, $iActionCode); @@ -704,6 +729,8 @@ exit; // This verb has been made public to allow the development of an accurate feedback for the current configuration public function GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode) { + $this->LoadCache(); + if (isset($this->m_aClassStimulusGrants[$iProfile][$sClass][$sStimulusCode])) { return $this->m_aClassStimulusGrants[$iProfile][$sClass][$sStimulusCode]; @@ -727,6 +754,7 @@ exit; public function IsStimulusAllowed($oUser, $sClass, $sStimulusCode, $oInstanceSet = null) { + $this->LoadCache(); // Note: this code is VERY close to the code of IsActionAllowed() $iUser = $oUser->GetKey(); @@ -790,7 +818,7 @@ exit; public function FlushPrivileges() { - $this->CacheData(); + $this->ResetCache(); } } diff --git a/core/dbobject.class.php b/core/dbobject.class.php index add8bed3a..9e587542e 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -836,11 +836,6 @@ abstract class DBObject return $this->m_iKey; } - // To be optionaly overloaded - protected function OnInsert() - { - } - // Insert of record for the new object into the database // Returns the key of the newly created object public function DBInsertNoReload() @@ -899,6 +894,8 @@ abstract class DBObject $this->m_bIsInDB = true; $this->m_bDirty = false; + $this->AfterInsert(); + // Activate any existing trigger $sClass = get_class($this); $oSet = new DBObjectSet(new DBObjectSearch('TriggerOnObjectCreate')); @@ -941,11 +938,6 @@ abstract class DBObject $this->m_iKey = self::GetNextTempId(get_class($this)); } - // To be optionaly overloaded - protected function OnUpdate() - { - } - // Update a record public function DBUpdate() { @@ -992,6 +984,8 @@ abstract class DBObject $this->DBWriteLinks(); $this->m_bDirty = false; + $this->AfterUpdate(); + // Reload to get the external attributes if ($bHasANewExternalKeyValue) { @@ -1013,16 +1007,20 @@ abstract class DBObject return $this->DBInsert(); } } - + // Delete a record public function DBDelete() { $oFilter = new DBObjectSearch(get_class($this)); $oFilter->AddCondition('id', $this->m_iKey, '='); + $this->OnDelete(); + $sSQL = MetaModel::MakeDeleteQuery($oFilter); CMDBSource::Query($sSQL); + $this->AfterDelete(); + $this->m_bIsInDB = false; $this->m_iKey = null; } @@ -1106,6 +1104,35 @@ abstract class DBObject return $aScalarArgs; } + // To be optionaly overloaded + protected function OnInsert() + { + } + + // To be optionaly overloaded + protected function AfterInsert() + { + } + + // To be optionaly overloaded + protected function OnUpdate() + { + } + + // To be optionaly overloaded + protected function AfterUpdate() + { + } + + // To be optionaly overloaded + protected function OnDelete() + { + } + + // To be optionaly overloaded + protected function AfterDelete() + { + } // Return an empty set for the parent of all public static function GetRelationQueries($sRelCode) diff --git a/core/userrights.class.inc.php b/core/userrights.class.inc.php index e4efc8467..6502085a1 100644 --- a/core/userrights.class.inc.php +++ b/core/userrights.class.inc.php @@ -164,7 +164,7 @@ abstract class User extends cmdbAbstractObject 'stimuli' => $sStimuli, ); } - + $aDisplayConfig = array(); $aDisplayConfig['class'] = array('label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+')); $aDisplayConfig['read'] = array('label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+')); @@ -274,14 +274,18 @@ class UserRights // Installation: create the very first user public static function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US') { - return self::$m_oAddOn->CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage); + $bRes = self::$m_oAddOn->CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage); + self::FlushPrivileges(true /* reset admin cache */); + return $bRes; } // Installation (e.g: give default values for users) public static function Setup() { // to be discussed... - return self::$m_oAddOn->Setup(); + $bRes = self::$m_oAddOn->Setup(); + self::FlushPrivileges(true /* reset admin cache */); + return $bRes; } protected static function IsLoggedIn() @@ -575,6 +579,7 @@ class UserRights return self::$m_oAddOn->IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet); } + static $m_aAdmins = array(); public static function IsAdministrator($oUser = null) { if (!self::CheckLogin()) return false; @@ -583,11 +588,20 @@ class UserRights { $oUser = self::$m_oUser; } - return self::$m_oAddOn->IsAdministrator($oUser); + $iUser = $oUser->GetKey(); + if (!isset(self::$m_aAdmins[$iUser])) + { + self::$m_aAdmins[$iUser] = self::$m_oAddOn->IsAdministrator($oUser); + } + return self::$m_aAdmins[$iUser]; } - public static function FlushPrivileges() + public static function FlushPrivileges($bResetAdminCache = false) { + if ($bResetAdminCache) + { + self::$m_aAdmins = array(); + } return self::$m_oAddOn->FlushPrivileges(); }