Improved the User Rights management API:

- new verbs: HasProfile and ListProfiles
- doing less queries (no need for listing all the profiles, caching the user profiles into the SESSION cookie
- did some code cleanup (unused variables)

SVN:trunk[3852]
This commit is contained in:
Romain Quetiez
2015-12-15 20:30:30 +00:00
parent 65a7a8ee56
commit 3be0bc8ca8
4 changed files with 103 additions and 122 deletions

View File

@@ -405,12 +405,6 @@ class UserRightsProfile extends UserRightsAddOnAPI
{
}
protected $m_aAdmins = array(); // id -> bool, true if the user has the well-known admin profile
protected $m_aPortalUsers = array(); // id -> bool, true if the user has the well-known portal user profile
protected $m_aProfiles; // id -> object
protected $m_aUserProfiles = array(); // userid,profileid -> object
protected $m_aUserOrgs = array(); // userid -> array of orgid
// Built on demand, could be optimized if necessary (doing a query for each attribute that needs to be read)
@@ -458,114 +452,64 @@ class UserRightsProfile extends UserRightsAddOnAPI
return $this->m_aUserOrgs[$iUser];
}
/**
* Read and cache profiles of the given user
*/
protected function GetUserProfiles($iUser)
{
if (!array_key_exists($iUser, $this->m_aUserProfiles))
{
$oSearch = new DBObjectSearch('URP_UserProfile');
$oSearch->AllowAllData();
$oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
$oSearch->AddConditionExpression($oCondition);
$this->m_aUserProfiles[$iUser] = array();
$oUserProfileSet = new DBObjectSet($oSearch, array(), array('userid' => $iUser));
while ($oUserProfile = $oUserProfileSet->Fetch())
{
$this->m_aUserProfiles[$iUser][$oUserProfile->Get('profileid')] = $oUserProfile;
}
}
return $this->m_aUserProfiles[$iUser];
}
public function ResetCache()
{
// Loaded by Load cache
$this->m_aProfiles = null;
$this->m_aUserProfiles = array();
$this->m_aUserOrgs = array();
$this->m_aAdmins = array();
$this->m_aPortalUsers = array();
// Cache
$this->m_aObjectActionGrants = array();
}
public function LoadCache()
{
if (!is_null($this->m_aProfiles)) return;
// Could be loaded in a shared memory (?)
$oKPI = new ExecutionKPI();
if (self::HasSharing())
static $bSharedObjectInitialized = false;
if (!$bSharedObjectInitialized)
{
SharedObject::InitSharedClassProperties();
$bSharedObjectInitialized = true;
if (self::HasSharing())
{
SharedObject::InitSharedClassProperties();
}
}
$oProfileSet = new DBObjectSet(DBObjectSearch::FromOQL_AllData("SELECT URP_Profiles"));
$this->m_aProfiles = array();
while ($oProfile = $oProfileSet->Fetch())
{
$this->m_aProfiles[$oProfile->GetKey()] = $oProfile;
}
$oKPI->ComputeAndReport('Load of user management cache (excepted Action Grants)');
/*
echo "<pre>\n";
print_r($this->m_aProfiles);
print_r($this->m_aUserProfiles);
print_r($this->m_aUserOrgs);
echo "</pre>\n";
exit;
*/
return true;
}
/**
* @param $oUser User
* @return array
*/
public function IsAdministrator($oUser)
{
//$this->LoadCache();
$iUser = $oUser->GetKey();
if (!array_key_exists($iUser, $this->m_aAdmins))
{
$bIsAdmin = false;
foreach($this->GetUserProfiles($iUser) as $oUserProfile)
{
if ($oUserProfile->Get('profile') == ADMIN_PROFILE_NAME)
{
$bIsAdmin = true;
break;
}
}
$this->m_aAdmins[$iUser] = $bIsAdmin;
}
return $this->m_aAdmins[$iUser];
// UserRights caches the list for us
return UserRights::HasProfile(ADMIN_PROFILE_NAME, $oUser);
}
/**
* @param $oUser User
* @return array
*/
public function IsPortalUser($oUser)
{
//$this->LoadCache();
$iUser = $oUser->GetKey();
if (!array_key_exists($iUser, $this->m_aPortalUsers))
{
$bIsPortalUser = false;
foreach($this->GetUserProfiles($iUser) as $oUserProfile)
{
if ($oUserProfile->Get('profile') == PORTAL_PROFILE_NAME)
{
$bIsPortalUser = true;
break;
}
// UserRights caches the list for us
return UserRights::HasProfile(PORTAL_PROFILE_NAME, $oUser);
}
$this->m_aPortalUsers[$iUser] = $bIsPortalUser;
/**
* @param $oUser User
* @return bool
*/
public function ListProfiles($oUser)
{
$aRet = array();
$oSearch = new DBObjectSearch('URP_UserProfile');
$oSearch->AllowAllData();
$oSearch->Addcondition('userid', $oUser->GetKey(), '=');
$oProfiles = new DBObjectSet($oSearch);
while ($oUserProfile = $oProfiles->Fetch())
{
$aRet[$oUserProfile->Get('profileid')] = $oUserProfile->Get('profileid_friendlyname');
}
return $this->m_aPortalUsers[$iUser];
return $aRet;
}
public function GetSelectFilter($oUser, $sClass, $aSettings = array())
@@ -621,8 +565,8 @@ exit;
$sAction = self::$m_aActionCodes[$iActionCode];
$bStatus = null;
$aAttributes = array();
foreach($this->GetUserProfiles($iUser) as $iProfile => $oProfile)
// Call the API of UserRights because it caches the list for us
foreach(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
{
$bGrant = $this->GetProfileActionGrant($iProfile, $sClass, $sAction);
if (!is_null($bGrant))
@@ -645,12 +589,11 @@ exit;
$aRes = array(
'permission' => $iPermission,
// 'attributes' => $aAttributes,
);
$this->m_aObjectActionGrants[$iUser][$sClass][$iActionCode] = $aRes;
return $aRes;
}
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null)
{
$this->LoadCache();
@@ -752,7 +695,8 @@ exit;
// Note: The object set is ignored because it was interesting to optimize for huge data sets
// and acceptable to consider only the root class of the object set
$bStatus = null;
foreach($this->GetUserProfiles($iUser) as $iProfile => $oProfile)
// Call the API of UserRights because it caches the list for us
foreach(UserRights::ListProfiles($oUser) as $iProfile => $oProfile)
{
$bGrant = $this->GetClassStimulusGrant($iProfile, $sClass, $sStimulusCode);
if (!is_null($bGrant))

View File

@@ -418,18 +418,10 @@ EOF
static function ResetSession()
{
if (isset($_SESSION['login_mode']))
{
$sPreviousLoginMode = $_SESSION['login_mode'];
}
else
{
$sPreviousLoginMode = '';
}
// Unset all of the session variables.
unset($_SESSION['auth_user']);
unset($_SESSION['login_mode']);
unset($_SESSION['profile_list']);
UserRights::_ResetSessionCache();
// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
}
@@ -655,6 +647,7 @@ EOF
$_SESSION['auth_user'] = $sAuthUser;
$_SESSION['login_mode'] = $sLoginMode;
UserRights::_InitSessionCache();
}
}
}
@@ -872,7 +865,7 @@ EOF
$aAllowedPortals[] = array(
'id' => $sPortalId,
'label' => $oDispatcher->GetLabel(),
'url' => $oDispatcher->GetUrl(),
'url' => $oDispatcher->GetUrl(),
);
}
}

View File

@@ -13,20 +13,7 @@ class PortalDispatcher
public function IsUserAllowed()
{
$bRet = true;
if (array_key_exists('profile_list', $_SESSION))
{
$aProfiles = $_SESSION['profile_list'];
}
else
{
$oUser = UserRights::GetUserObject();
$oSet = $oUser->Get('profile_list');
while(($oLnkUserProfile = $oSet->Fetch()) !== null)
{
$aProfiles[] = $oLnkUserProfile->Get('profileid_friendlyname');
}
$_SESSION['profile_list'] = $aProfiles;
}
$aProfiles = UserRights::ListProfiles();
foreach($this->aData['deny'] as $sDeniedProfile)
{

View File

@@ -67,6 +67,18 @@ abstract class UserRightsAddOnAPI
abstract public function IsPortalUser($oUser);
abstract public function FlushPrivileges();
/**
* Default behavior for addons that do not support profiles
*
* @param $oUser User
* @return array
*/
public function ListProfiles($oUser)
{
return array();
}
/**
* ...
*/
@@ -821,7 +833,6 @@ class UserRights
}
}
public static function IsActionAllowed($sClass, $iActionCode, /*dbObjectSet*/ $oInstanceSet = null, $oUser = null)
{
// When initializing, we need to let everything pass trough
@@ -929,7 +940,7 @@ class UserRights
return self::$m_oAddOn->IsActionAllowedOnAttribute($oUser, $sClass, $sAttCode, $iActionCode, $oInstanceSet);
}
static $m_aAdmins = array();
protected static $m_aAdmins = array();
public static function IsAdministrator($oUser = null)
{
if (!self::CheckLogin()) return false;
@@ -946,7 +957,7 @@ class UserRights
return self::$m_aAdmins[$iUser];
}
static $m_aPortalUsers = array();
protected static $m_aPortalUsers = array();
public static function IsPortalUser($oUser = null)
{
if (!self::CheckLogin()) return false;
@@ -963,6 +974,39 @@ class UserRights
return self::$m_aPortalUsers[$iUser];
}
public static function ListProfiles($oUser = null)
{
if (is_null($oUser))
{
$oUser = self::$m_oUser;
}
if ($oUser->GetKey() == self::$m_oUser->GetKey())
{
// Data about the current user can be found into the session data
if (array_key_exists('profile_list', $_SESSION))
{
$aProfiles = $_SESSION['profile_list'];
}
}
if (!isset($aProfiles))
{
$aProfiles = self::$m_oAddOn->ListProfiles($oUser);
}
return $aProfiles;
}
/**
* @param $sProfileName Profile name to search for
* @param $oUser User|null
* @return bool
*/
public static function HasProfile($sProfileName, $oUser = null)
{
$bRet = in_array($sProfileName, self::ListProfiles($oUser));
return $bRet;
}
/**
* Reset cached data
* @param Bool Reset admin cache as well
@@ -975,7 +1019,9 @@ class UserRights
if ($bResetAdminCache)
{
self::$m_aAdmins = array();
self::$m_aPortalUsers = array();
}
self::_ResetSessionCache();
return self::$m_oAddOn->FlushPrivileges();
}
@@ -1033,6 +1079,17 @@ class UserRights
{
return self::$m_oAddOn->MakeSelectFilter($sClass, $aAllowedOrgs, $aSettings, $sAttCode);
}
public static function _InitSessionCache()
{
// Cache data about the current user into the session
$_SESSION['profile_list'] = self::ListProfiles();
}
public static function _ResetSessionCache()
{
unset($_SESSION['profile_list']);
}
}
/**