mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
User management by profile ready for integration with the UI
and some caching has been implemented for the building of queries (both from an OQL or from a programmatic query) SVN:trunk[90]
This commit is contained in:
@@ -318,6 +318,19 @@ class UserRightsMatrix extends UserRightsAddOnAPI
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT UserRightsMatrixUsers WHERE login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oLogin = $oSet->Fetch();
|
||||
return $oLogin->Get('userid');
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
|
||||
@@ -34,7 +34,12 @@ class UserRightsNull extends UserRightsAddOnAPI
|
||||
|
||||
public function CheckCredentials($sUserName, $sPassword)
|
||||
{
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
@@ -43,17 +48,17 @@ class UserRightsNull extends UserRightsAddOnAPI
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($sUserName, $sClass, $iActionCode, dbObjectSet $aInstances)
|
||||
public function IsActionAllowed($iUserId, $sClass, $iActionCode, dbObjectSet $aInstances)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($sUserName, $sClass, $sStimulusCode, dbObjectSet $aInstances)
|
||||
public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, dbObjectSet $aInstances)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($sUserName, $sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances)
|
||||
public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances)
|
||||
{
|
||||
return UR_ALLOWED_YES;
|
||||
}
|
||||
|
||||
@@ -245,23 +245,23 @@ class URP_ProfileProjection extends DBObject
|
||||
public function ProjectUser(URP_Users $oUser)
|
||||
{
|
||||
$sExpr = $this->Get('value');
|
||||
if (preg_match('/^\s*([a-zA-Z0-9;]+)\s*$/', $sExpr, $aMatches))
|
||||
{
|
||||
// Constant value(s)
|
||||
$aRes = explode(';', $aMatches[1]);
|
||||
}
|
||||
elseif ($sExpr == '<any>')
|
||||
{
|
||||
$aRes = array('<any>');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strtolower(substr($sExpr, 0, 6)) == 'select')
|
||||
{
|
||||
$sColumn = $this->Get('attribute');
|
||||
// SELECT...
|
||||
$oValueSetDef = new ValueSetObjects($sExpr, $sColumn);
|
||||
$aValues = $oValueSetDef->GetValues(array('user' => $oUser), '');
|
||||
$aRes = array_values($aValues);
|
||||
}
|
||||
elseif ($sExpr == '<any>')
|
||||
{
|
||||
$aRes = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Constant value(s)
|
||||
$aRes = explode(';', trim($sExpr));
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
@@ -302,23 +302,23 @@ class URP_ClassProjection extends DBObject
|
||||
public function ProjectObject($oObject)
|
||||
{
|
||||
$sExpr = $this->Get('value');
|
||||
if (preg_match('/^\s*([a-zA-Z0-9;]+)\s*$/', $sExpr, $aMatches))
|
||||
{
|
||||
// Constant value(s)
|
||||
$aRes = explode(';', $aMatches[1]);
|
||||
}
|
||||
elseif ($sExpr == '<any>')
|
||||
{
|
||||
$aRes = array('<any>');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strtolower(substr($sExpr, 0, 6)) == 'select')
|
||||
{
|
||||
$sColumn = $this->Get('attribute');
|
||||
// SELECT...
|
||||
$oValueSetDef = new ValueSetObjects($sExpr, $sColumn);
|
||||
$aValues = $oValueSetDef->GetValues(array('this' => $oObject), '');
|
||||
$aValues = $oValueSetDef->GetValues(array('user' => $oObject), '');
|
||||
$aRes = array_values($aValues);
|
||||
}
|
||||
elseif ($sExpr == '<any>')
|
||||
{
|
||||
$aRes = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Constant value(s)
|
||||
$aRes = explode(';', trim($sExpr));
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
@@ -389,7 +389,7 @@ class URP_StimulusGrant extends DBObject
|
||||
MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
MetaModel::Init_AddAttribute(new AttributeString("stimulus", array("label"=>"stimulus", "description"=>"stimulus code", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array())));
|
||||
|
||||
//MetaModel::Init_InheritFilters();
|
||||
// Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked)
|
||||
@@ -498,7 +498,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassProjection WHERE class = '$sClass' AND dimensionid = $iDimensionId"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassProjection WHERE class = :class AND dimensionid = :dimension"), array(), array('class'=>$sClass, 'dimension'=>$iDimensionId));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
@@ -524,7 +524,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ProfileProjection WHERE dimensionid = $iDimensionId AND profileid = $iProfileId"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ProfileProjection WHERE dimensionid = :dimension AND profileid = :profile"), array(), array('dimension'=>$iDimensionId, 'profile'=>$iProfileId));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
@@ -557,7 +557,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = '$sClass' AND action = '$sAction' AND profileid = $iProfileId"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = :class AND action = :action AND profileid = :profile"), array(), array('class'=>$sClass, 'action'=>$sAction, 'profile'=>$iProfileId));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
@@ -579,7 +579,7 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_StimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND profileid = $iProfileId"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_StimulusGrant WHERE class = :class AND stimulus = :stimulus AND profileid = :profile"), array(), array('class'=>$sClass, 'stimulus'=>$sStimulusCode, 'profile'=>$iProfileId));
|
||||
$bAddCell = ($oSet->Count() < 1);
|
||||
}
|
||||
if ($bAddCell)
|
||||
@@ -621,119 +621,368 @@ class UserRightsProfile extends UserRightsAddOnAPI
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function Init()
|
||||
{
|
||||
MetaModel::RegisterPlugin('userrights', 'ACbyProfile', array($this, 'CacheData'));
|
||||
}
|
||||
|
||||
protected $m_aUsers = array(); // id -> object
|
||||
protected $m_aDimensions = array(); // id -> object
|
||||
protected $m_aClassProj = array(); // class,dimensionid -> object
|
||||
protected $m_aProfiles = array(); // id -> object
|
||||
protected $m_aUserProfiles = array(); // userid,profileid -> object
|
||||
protected $m_aProPro = array(); // profileid,dimensionid -> object
|
||||
|
||||
protected $m_aClassActionGrants = array(); // profile, class, action -> permission
|
||||
protected $m_aObjectActionGrants = array(); // userid, class, id, action -> permission, list of attributes
|
||||
|
||||
public function CacheData()
|
||||
{
|
||||
// Could be loaded in a shared memory (?)
|
||||
|
||||
$oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users"));
|
||||
while ($oUser = $oUserSet->Fetch())
|
||||
{
|
||||
$this->m_aUsers[$oUser->GetKey()] = $oUser;
|
||||
}
|
||||
|
||||
$oDimensionSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Dimensions"));
|
||||
while ($oDimension = $oDimensionSet->Fetch())
|
||||
{
|
||||
$this->m_aDimensions[$oDimension->GetKey()] = $oDimension;
|
||||
}
|
||||
|
||||
$oClassProjSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassProjection"));
|
||||
while ($oClassProj = $oClassProjSet->Fetch())
|
||||
{
|
||||
$this->m_aClassProjs[$oClassProj->Get('class')][$oClassProj->Get('dimensionid')] = $oClassProj;
|
||||
}
|
||||
|
||||
$oProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Profiles"));
|
||||
while ($oProfile = $oProfileSet->Fetch())
|
||||
{
|
||||
$this->m_aProfiles[$oProfile->GetKey()] = $oProfile;
|
||||
}
|
||||
|
||||
$oUserProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_UserProfile"));
|
||||
while ($oUserProfile = $oUserProfileSet->Fetch())
|
||||
{
|
||||
$this->m_aUserProfiles[$oUserProfile->Get('userid')][$oUserProfile->Get('profileid')] = $oUserProfile;
|
||||
}
|
||||
|
||||
$oProProSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ProfileProjection"));
|
||||
while ($oProPro = $oProProSet->Fetch())
|
||||
{
|
||||
$this->m_aProPros[$oProPro->Get('profileid')][$oProPro->Get('dimensionid')] = $oProPro;
|
||||
}
|
||||
|
||||
/*
|
||||
echo "<pre>\n";
|
||||
print_r($this->m_aUsers);
|
||||
print_r($this->m_aDimensions);
|
||||
print_r($this->m_aClassProjs);
|
||||
print_r($this->m_aProfiles);
|
||||
print_r($this->m_aUserProfiles);
|
||||
print_r($this->m_aProPros);
|
||||
echo "</pre>\n";
|
||||
exit;
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function CheckCredentials($sUserName, $sPassword)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users WHERE login = '$sUserName'"));
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users WHERE login = :login"), array(), array('login' => $sUserName));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oLogin = $oSet->Fetch();
|
||||
if ($oLogin->Get('password') == $sPassword)
|
||||
$oUser = $oSet->Fetch();
|
||||
if ($oUser->Get('password') == $sPassword)
|
||||
{
|
||||
return true;
|
||||
return $oUser->GetKey();
|
||||
}
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
public function GetUserId($sUserName)
|
||||
{
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users WHERE login = :login"), array(), array('login' => $sUserName));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
// todo: throw an exception?
|
||||
return false;
|
||||
}
|
||||
|
||||
$oUser = $oSet->Fetch();
|
||||
return $oUser->GetKey();
|
||||
}
|
||||
|
||||
public function GetFilter($sUserName, $sClass)
|
||||
{
|
||||
$oNullFilter = new DBObjectSearch($sClass);
|
||||
return $oNullFilter;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($sUserName, $sClass, $iActionCode, dbObjectSet $aInstances)
|
||||
protected function GetClassActionGrant($iProfile, $sClass, $sAction)
|
||||
{
|
||||
// #@# temporary
|
||||
return true;
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
$aTest = @$this->m_aClassActionGrants[$iProfile][$sClass][$sAction];
|
||||
if (isset($aTest)) return $aTest;
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = '$sClass' AND action = '$sAction' AND login = '$sUserName'"));
|
||||
// Get the permission for this profile/class/action
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = :class AND action = :action AND profileid = :profile");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('class'=>$sClass, 'action'=>$sAction, 'profile'=>$iProfile));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
return null;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
|
||||
$this->m_aClassActionGrants[$iProfile][$sClass][$sAction] = $oGrantRecord;
|
||||
return $oGrantRecord;
|
||||
}
|
||||
|
||||
public function IsActionAllowedOnAttribute($sUserName, $sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances)
|
||||
protected function GetObjectActionGrant($oUser, $sClass, $iActionCode, $oObject)
|
||||
{
|
||||
// #@# temporary
|
||||
return true;
|
||||
if (!array_key_exists($iActionCode, self::$m_aActionCodes))
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
// load and cache permissions for the current user on the given object
|
||||
//
|
||||
$aTest = @$this->m_aObjectActionGrants[$oUser->GetKey()][$sClass][$oObject->GetKey][$iActionCode];
|
||||
if (is_array($aTest)) return $aTest;
|
||||
|
||||
$sAction = self::$m_aActionCodes[$iActionCode];
|
||||
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_AttributeGrant WHERE URP_AttributeGrant.class = '$sClass' AND URP_AttributeGrant.attcode = '$sAttCode' AND URP_AttributeGrant.action = '$sAction' AND URP_AttributeGrant.login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
$iInstancePermission = UR_ALLOWED_NO;
|
||||
$aAttributes = array();
|
||||
foreach($this->GetMatchingProfiles($oUser, $oObject) as $iProfile)
|
||||
{
|
||||
$oGrantRecord = $this->GetClassActionGrant($iProfile, $sClass, $sAction);
|
||||
if (is_null($oGrantRecord))
|
||||
{
|
||||
continue; // loop to the next profile
|
||||
}
|
||||
elseif ($oGrantRecord->Get('permission') == 'yes')
|
||||
{
|
||||
$iInstancePermission = UR_ALLOWED_YES;
|
||||
|
||||
// merge the list of attributes allowed for this profile
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT URP_AttributeGrant WHERE actiongrantid = :actiongrantid");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('actiongrantid' => $oGrantRecord->GetKey()));
|
||||
$aAttributes = array_merge($aAttributes, $oSet->GetColumnAsArray('attcode', false));
|
||||
}
|
||||
}
|
||||
|
||||
$aRes = array(
|
||||
'permission' => $iInstancePermission,
|
||||
'attributes' => $aAttributes,
|
||||
);
|
||||
$this->m_aObjectActionGrants[$oUser->GetKey()][$sClass][$oObject->GetKey()][$iActionCode] = $aRes;
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
public function IsActionAllowed($iUserId, $sClass, $iActionCode, dbObjectSet $oInstances)
|
||||
{
|
||||
$oUser = $this->m_aUsers[$iUserId];
|
||||
|
||||
$oInstances->Rewind();
|
||||
while($oObject = $oInstances->Fetch())
|
||||
{
|
||||
$aObjectPermissions = $this->GetObjectActionGrant($oUser, $sClass, $iActionCode, $oObject);
|
||||
|
||||
$iInstancePermission = $aObjectPermissions['permission'];
|
||||
if (isset($iGlobalPermission))
|
||||
{
|
||||
if ($iInstancePermission != $iGlobalPermission)
|
||||
{
|
||||
$iGlobalPermission = UR_ALLOWED_DEPENDS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iGlobalPermission = $iInstancePermission;
|
||||
}
|
||||
}
|
||||
if (isset($iGlobalPermission))
|
||||
{
|
||||
return $iGlobalPermission;
|
||||
}
|
||||
else
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
}
|
||||
return $iRetCode;
|
||||
}
|
||||
|
||||
public function IsStimulusAllowed($sUserName, $sClass, $sStimulusCode, dbObjectSet $aInstances)
|
||||
public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, dbObjectSet $oInstances)
|
||||
{
|
||||
// #@# temporary
|
||||
return true;
|
||||
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_StimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND login = '$sUserName'"));
|
||||
if ($oSet->Count() < 1)
|
||||
$oUser = $this->m_aUsers[$iUserId];
|
||||
|
||||
$oInstances->Rewind();
|
||||
while($oObject = $oInstances->Fetch())
|
||||
{
|
||||
$aObjectPermissions = $this->GetObjectActionGrant($oUser, $sClass, $iActionCode, $oObject);
|
||||
|
||||
$aAttributes = $aObjectPermissions['attributes'];
|
||||
if (in_array($sAttCode, $aAttributes))
|
||||
{
|
||||
$iInstancePermission = $aObjectPermissions['permission'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$iInstancePermission = UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
if (isset($iGlobalPermission))
|
||||
{
|
||||
if ($iInstancePermission != $iGlobalPermission)
|
||||
{
|
||||
$iGlobalPermission = UR_ALLOWED_DEPENDS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iGlobalPermission = $iInstancePermission;
|
||||
}
|
||||
}
|
||||
if (isset($iGlobalPermission))
|
||||
{
|
||||
return $iGlobalPermission;
|
||||
}
|
||||
else
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
switch ($oGrantRecord->Get('permission'))
|
||||
public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, dbObjectSet $oInstances)
|
||||
{
|
||||
$oUser = $this->m_aUsers[$iUserId];
|
||||
|
||||
// Note: this code is VERY close to the code of IsActionAllowed()
|
||||
|
||||
$oInstances->Rewind();
|
||||
while($oObject = $oInstances->Fetch())
|
||||
{
|
||||
case 'yes':
|
||||
$iRetCode = UR_ALLOWED_YES;
|
||||
break;
|
||||
case 'no':
|
||||
default:
|
||||
$iRetCode = UR_ALLOWED_NO;
|
||||
break;
|
||||
$iInstancePermission = UR_ALLOWED_NO;
|
||||
foreach($this->GetMatchingProfiles($oUser, $oObject) as $iProfile)
|
||||
{
|
||||
// Get the permission for this profile/class/stimulus
|
||||
$oSearch = DBObjectSearch::FromOQL("SELECT URP_StimulusGrant WHERE class = :class AND stimulus = :stimulus AND profileid = :profile");
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('class'=>$sClass, 'stimulus'=>$sStimulusCode, 'profile'=>$iProfile));
|
||||
if ($oSet->Count() < 1)
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
|
||||
$oGrantRecord = $oSet->Fetch();
|
||||
$sPermission = $oGrantRecord->Get('permission');
|
||||
if ($sPermission == 'yes')
|
||||
{
|
||||
$iInstancePermission = UR_ALLOWED_YES;
|
||||
}
|
||||
}
|
||||
if (isset($iGlobalPermission))
|
||||
{
|
||||
if ($iInstancePermission != $iGlobalPermission)
|
||||
{
|
||||
$iGlobalPermission = UR_ALLOWED_DEPENDS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iGlobalPermission = $iInstancePermission;
|
||||
}
|
||||
}
|
||||
return $iRetCode;
|
||||
if (isset($iGlobalPermission))
|
||||
{
|
||||
return $iGlobalPermission;
|
||||
}
|
||||
else
|
||||
{
|
||||
return UR_ALLOWED_NO;
|
||||
}
|
||||
}
|
||||
|
||||
protected function GetMatchingProfilesByDim($oUser, $oObject, $oDimension)
|
||||
{
|
||||
//
|
||||
// List profiles for which the user projection overlaps the object projection in the given dimension
|
||||
//
|
||||
$iUser = $oUser->GetKey();
|
||||
$sClass = get_class($oObject);
|
||||
$iPKey = $oObject->GetKey();
|
||||
$iDimension = $oDimension->GetKey();
|
||||
|
||||
$aObjectProjection = $this->m_aClassProjs[$sClass][$iDimension]->ProjectObject($oObject);
|
||||
|
||||
$aRes = array();
|
||||
foreach ($this->m_aUserProfiles[$iUser] as $iProfile => $oProfile)
|
||||
{
|
||||
if (is_null($aObjectProjection))
|
||||
{
|
||||
$aRes[] = $iProfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// user projection to be cached on a given page !
|
||||
$aUserProjection = $this->m_aProPros[$iProfile][$iDimension]->ProjectUser($oUser);
|
||||
|
||||
if (is_null($aUserProjection))
|
||||
{
|
||||
$aRes[] = $iProfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aMatchingValues = array_intersect($aObjectProjection, $aUserProjection);
|
||||
if (count($aMatchingValues) > 0)
|
||||
{
|
||||
$aRes[] = $iProfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
protected $m_aMatchingProfiles = array(); // cache of the matching profiles for a given user/object
|
||||
|
||||
protected function GetMatchingProfiles($oUser, $oObject)
|
||||
{
|
||||
$iUser = $oUser->GetKey();
|
||||
$sClass = get_class($oObject);
|
||||
$iObject = $oObject->GetKey();
|
||||
//
|
||||
// List profiles for which the user projection overlaps the object projection in each and every dimension
|
||||
// Caches the result
|
||||
//
|
||||
$aTest = @$this->m_aMatchingProfiles[$iUser][$sClass][$iObject];
|
||||
if (is_array($aTest))
|
||||
{
|
||||
return $aTest;
|
||||
}
|
||||
|
||||
$aProfileRes = array();
|
||||
foreach ($this->m_aDimensions as $iDimension => $oDimension)
|
||||
{
|
||||
foreach ($this->GetMatchingProfilesByDim($oUser, $oObject, $oDimension) as $iProfile)
|
||||
{
|
||||
@$aProfileRes[$iProfile] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
$aRes = array();
|
||||
$iDimCount = count($this->m_aDimensions);
|
||||
foreach ($aProfileRes as $iProfile => $iMatches)
|
||||
{
|
||||
if ($iMatches == $iDimCount)
|
||||
{
|
||||
$aRes[] = $iProfile;
|
||||
}
|
||||
}
|
||||
$this->m_aMatchingProfiles[$iUser][$sClass][$iObject] = $aRes;
|
||||
return $aRes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ class DBObjectSearch
|
||||
private $m_sClassAlias;
|
||||
private $m_aClasses; // queried classes (alias => class name)
|
||||
private $m_oSearchCondition;
|
||||
private $m_aParams;
|
||||
private $m_aFullText;
|
||||
private $m_aPointingTo;
|
||||
private $m_aReferencedBy;
|
||||
@@ -64,6 +65,7 @@ class DBObjectSearch
|
||||
$this->m_sClassAlias = $sClassAlias;
|
||||
$this->m_aClasses = array($sClassAlias => $sClass);
|
||||
$this->m_oSearchCondition = new TrueExpression;
|
||||
$this->m_aParams = array();
|
||||
$this->m_aFullText = array();
|
||||
$this->m_aPointingTo = array();
|
||||
$this->m_aReferencedBy = array();
|
||||
@@ -174,6 +176,8 @@ class DBObjectSearch
|
||||
{
|
||||
$oTranslated = $oFilter->GetCriteria()->Translate($aTranslation, false);
|
||||
$this->AddConditionExpression($oTranslated);
|
||||
// #@# what about collisions in parameter names ???
|
||||
$this->m_aParams = array_merge($this->m_aParams, $oFilter->m_aParams);
|
||||
}
|
||||
|
||||
public function ResetCondition()
|
||||
@@ -232,22 +236,22 @@ class DBObjectSearch
|
||||
break;
|
||||
|
||||
case 'Contains':
|
||||
$oRightExpr = new ScalarExpression("%$value%");
|
||||
$this->m_aParams[$sFilterCode] = "%$value%";
|
||||
$sOperator = 'LIKE';
|
||||
break;
|
||||
|
||||
case 'Begins with':
|
||||
$oRightExpr = new ScalarExpression("$value%");
|
||||
$this->m_aParams[$sFilterCode] = "$value%";
|
||||
$sOperator = 'LIKE';
|
||||
break;
|
||||
|
||||
case 'Finishes with':
|
||||
$oRightExpr = new ScalarExpression("%$value");
|
||||
$this->m_aParams[$sFilterCode] = "%$value";
|
||||
$sOperator = 'LIKE';
|
||||
break;
|
||||
|
||||
default:
|
||||
$oRightExpr = new ScalarExpression($value);
|
||||
$this->m_aParams[$sFilterCode] = $value;
|
||||
$sOperator = $sOpCode;
|
||||
}
|
||||
|
||||
@@ -262,6 +266,7 @@ class DBObjectSearch
|
||||
case 'Begins with':
|
||||
case 'Finishes with':
|
||||
default:
|
||||
$oRightExpr = new VariableExpression($sFilterCode);
|
||||
$oNewCondition = new BinaryExpression($oField, $sOperator, $oRightExpr);
|
||||
}
|
||||
|
||||
@@ -453,10 +458,14 @@ class DBObjectSearch
|
||||
{
|
||||
return $this->m_aRelatedTo;
|
||||
}
|
||||
public function GetInternalParams()
|
||||
{
|
||||
return $this->m_aParams;
|
||||
}
|
||||
|
||||
public function RenderCondition()
|
||||
{
|
||||
return $this->m_oSearchCondition->Render();
|
||||
return $this->m_oSearchCondition->Render($this->m_aParams);
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
@@ -588,11 +597,13 @@ class DBObjectSearch
|
||||
return $retValue;
|
||||
}
|
||||
|
||||
public function ToOQL()
|
||||
public function ToOQL(&$aParams = null)
|
||||
{
|
||||
$bRetrofitParams = (!is_null($aParams));
|
||||
|
||||
$sRes = "SELECT ".$this->GetClass().' AS '.$this->GetClassAlias();
|
||||
$sRes .= $this->ToOQL_Joins();
|
||||
$sRes .= " WHERE ".$this->m_oSearchCondition->Render();
|
||||
$sRes .= " WHERE ".$this->m_oSearchCondition->Render($aParams, $bRetrofitParams);
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
@@ -762,10 +773,20 @@ class DBObjectSearch
|
||||
}
|
||||
}
|
||||
|
||||
static public function FromOQL($sQuery, array $aParams = array(), $oObject = null)
|
||||
static protected $m_aOQLQueries = array();
|
||||
|
||||
static public function FromOQL($sQuery)
|
||||
{
|
||||
if (empty($sQuery)) return null;
|
||||
|
||||
// Query caching
|
||||
$bOQLCacheEnabled = true;
|
||||
if ($bOQLCacheEnabled && array_key_exists($sQuery, self::$m_aOQLQueries))
|
||||
{
|
||||
// hit!
|
||||
return clone self::$m_aOQLQueries[$sQuery];
|
||||
}
|
||||
|
||||
$oOql = new OqlInterpreter($sQuery);
|
||||
$oOqlQuery = $oOql->ParseObjectQuery();
|
||||
|
||||
@@ -856,6 +877,11 @@ class DBObjectSearch
|
||||
$oResultFilter->m_oSearchCondition = $oResultFilter->OQLExpressionToCondition($sQuery, $oConditionTree, $aAliases);
|
||||
}
|
||||
|
||||
if ($bOQLCacheEnabled)
|
||||
{
|
||||
self::$m_aOQLQueries[$sQuery] = clone $oResultFilter;
|
||||
}
|
||||
|
||||
return $oResultFilter;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,24 @@ class DBObjectSet
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function GetColumnAsArray($sAttCode, $bWithId = true)
|
||||
{
|
||||
$aRet = array();
|
||||
$this->Rewind();
|
||||
while ($oObject = $this->Fetch())
|
||||
{
|
||||
if ($bWithId)
|
||||
{
|
||||
$aRet[$oObject->GetKey()] = $oObject->Get($sAttCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRet[] = $oObject->Get($sAttCode);
|
||||
}
|
||||
}
|
||||
return $aRet;
|
||||
}
|
||||
|
||||
public function GetFilter()
|
||||
{
|
||||
return $this->m_oFilter;
|
||||
|
||||
@@ -16,8 +16,8 @@ abstract class Expression
|
||||
// recursive translation of identifiers
|
||||
abstract public function Translate($aTranslationData, $bMatchAll = true);
|
||||
|
||||
// recursive rendering
|
||||
abstract public function Render($aArgs = array());
|
||||
// recursive rendering (aArgs used as input by default, or used as output if bRetrofitParams set to True
|
||||
abstract public function Render(&$aArgs = null, $bRetrofitParams = false);
|
||||
|
||||
// recursively builds an array of class => fieldname
|
||||
abstract public function ListRequiredFields();
|
||||
@@ -119,11 +119,11 @@ class BinaryExpression extends Expression
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$sOperator = $this->GetOperator();
|
||||
$sLeft = $this->GetLeftExpr()->Render($aArgs);
|
||||
$sRight = $this->GetRightExpr()->Render($aArgs);
|
||||
$sLeft = $this->GetLeftExpr()->Render($aArgs, $bRetrofitParams);
|
||||
$sRight = $this->GetRightExpr()->Render($aArgs, $bRetrofitParams);
|
||||
return "($sLeft $sOperator $sRight)";
|
||||
}
|
||||
|
||||
@@ -164,9 +164,18 @@ class UnaryExpression extends Expression
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
return CMDBSource::Quote($this->m_value);
|
||||
if ($bRetrofitParams)
|
||||
{
|
||||
$iParamIndex = count($aArgs) + 1; // 1-based indexation
|
||||
$aArgs['param'.$iParamIndex] = $this->m_value;
|
||||
return ':param'.$iParamIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CMDBSource::Quote($this->m_value);
|
||||
}
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
@@ -228,7 +237,7 @@ class FieldExpression extends UnaryExpression
|
||||
public function GetName() {return $this->m_sName;}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
if (empty($this->m_sParent))
|
||||
{
|
||||
@@ -290,16 +299,16 @@ class VariableExpression extends UnaryExpression
|
||||
public function GetName() {return $this->m_sName;}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
if (array_key_exists($this->m_sName, $aArgs))
|
||||
{
|
||||
return $aArgs[$this->m_sName];
|
||||
}
|
||||
elseif (is_null($aArgs))
|
||||
if (is_null($aArgs) || $bRetrofitParams)
|
||||
{
|
||||
return ':'.$this->m_sName;
|
||||
}
|
||||
elseif (array_key_exists($this->m_sName, $aArgs))
|
||||
{
|
||||
return CMDBSource::Quote($aArgs[$this->m_sName]);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CoreException('Missing query argument', array('expecting'=>$this->m_sName, 'available'=>$aArgs));
|
||||
@@ -330,12 +339,12 @@ class ListExpression extends Expression
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Render($aArgs);
|
||||
$aRes[] = $oExpr->Render($aArgs, $bRetrofitParams);
|
||||
}
|
||||
return '('.implode(', ', $aRes).')';
|
||||
}
|
||||
@@ -390,12 +399,12 @@ class FunctionExpression extends Expression
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aArgs as $oExpr)
|
||||
{
|
||||
$aRes[] = $oExpr->Render($aArgs);
|
||||
$aRes[] = $oExpr->Render($aArgs, $bRetrofitParams);
|
||||
}
|
||||
return $this->m_sVerb.'('.implode(', ', $aRes).')';
|
||||
}
|
||||
@@ -449,9 +458,9 @@ class IntervalExpression extends Expression
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
return 'INTERVAL '.$this->m_oValue->Render($aArgs).' '.$this->m_sUnit;
|
||||
return 'INTERVAL '.$this->m_oValue->Render($aArgs, $bRetrofitParams).' '.$this->m_sUnit;
|
||||
}
|
||||
|
||||
public function Translate($aTranslationData, $bMatchAll = true)
|
||||
@@ -486,12 +495,12 @@ class CharConcatExpression extends Expression
|
||||
}
|
||||
|
||||
// recursive rendering
|
||||
public function Render($aArgs = array())
|
||||
public function Render(&$aArgs = null, $bRetrofitParams = false)
|
||||
{
|
||||
$aRes = array();
|
||||
foreach ($this->m_aExpressions as $oExpr)
|
||||
{
|
||||
$sCol = $oExpr->Render($aArgs);
|
||||
$sCol = $oExpr->Render($aArgs, $bRetrofitParams);
|
||||
// Concat will be globally NULL if one single argument is null !
|
||||
$aRes[] = "COALESCE($sCol, '')";
|
||||
}
|
||||
|
||||
@@ -164,6 +164,10 @@ abstract class MetaModel
|
||||
}
|
||||
}
|
||||
|
||||
private static $m_bTraceQueries = true;
|
||||
private static $m_aQueriesLog = array();
|
||||
|
||||
|
||||
private static $m_sDBName = "";
|
||||
private static $m_sTablePrefix = ""; // table prefix for the current application instance (allow several applications on the same DB)
|
||||
private static $m_Category2Class = array();
|
||||
@@ -1167,15 +1171,36 @@ abstract class MetaModel
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static $m_aQueryStructCache = array();
|
||||
|
||||
public static function MakeSelectQuery(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array())
|
||||
{
|
||||
$aTranslation = array();
|
||||
$aClassAliases = array();
|
||||
$aTableAliases = array();
|
||||
$oConditionTree = $oFilter->GetCriteria();
|
||||
$oSelect = self::MakeQuery($oFilter->GetClassAlias(), $oConditionTree, $aClassAliases, $aTableAliases, $aTranslation, $oFilter);
|
||||
// Query caching
|
||||
//
|
||||
$bQueryCacheEnabled = true;
|
||||
$sOqlQuery = $oFilter->ToOql();
|
||||
if ($bQueryCacheEnabled)
|
||||
{
|
||||
if (array_key_exists($sOqlQuery, self::$m_aQueryStructCache))
|
||||
{
|
||||
// hit!
|
||||
$oSelect = clone self::$m_aQueryStructCache[$sOqlQuery];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($oSelect))
|
||||
{
|
||||
$aTranslation = array();
|
||||
$aClassAliases = array();
|
||||
$aTableAliases = array();
|
||||
$oConditionTree = $oFilter->GetCriteria();
|
||||
$oSelect = self::MakeQuery($oFilter->GetClassAlias(), $oConditionTree, $aClassAliases, $aTableAliases, $aTranslation, $oFilter);
|
||||
|
||||
self::$m_aQueryStructCache[$sOqlQuery] = clone $oSelect;
|
||||
}
|
||||
|
||||
// Check the order by specification
|
||||
//
|
||||
foreach ($aOrderBy as $sFieldAlias => $bAscending)
|
||||
{
|
||||
MyHelpers::CheckValueInArray('field name in ORDER BY spec', $sFieldAlias, self::GetAttributesList($oFilter->GetClass()));
|
||||
@@ -1196,7 +1221,7 @@ abstract class MetaModel
|
||||
|
||||
// Prepare arguments (translate any object into scalars)
|
||||
//
|
||||
$aScalarArgs = array();
|
||||
$aScalarArgs = $oFilter->GetInternalParams();
|
||||
foreach($aArgs as $sArgName => $value)
|
||||
{
|
||||
if (self::IsValidObject($value))
|
||||
@@ -1215,9 +1240,41 @@ abstract class MetaModel
|
||||
$aScalarArgs[$sArgName] = (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
//MyHelpers::var_dump_html($oSelect->RenderSelect($aOrderBy));
|
||||
return $oSelect->RenderSelect($aOrderBy, $aScalarArgs);
|
||||
|
||||
// Go
|
||||
//
|
||||
$sRes = $oSelect->RenderSelect($aOrderBy, $aScalarArgs);
|
||||
|
||||
if (self::$m_bTraceQueries)
|
||||
{
|
||||
$aParams = array();
|
||||
if (!array_key_exists($sOqlQuery, self::$m_aQueriesLog))
|
||||
{
|
||||
self::$m_aQueriesLog[$sOqlQuery] = array(
|
||||
'sql' => array(),
|
||||
'count' => 0,
|
||||
);
|
||||
}
|
||||
self::$m_aQueriesLog[$sOqlQuery]['count']++;
|
||||
self::$m_aQueriesLog[$sOqlQuery]['sql'][] = $sRes;
|
||||
}
|
||||
|
||||
return $sRes;
|
||||
}
|
||||
|
||||
public static function ShowQueryTrace()
|
||||
{
|
||||
$iTotal = 0;
|
||||
foreach (self::$m_aQueriesLog as $sOql => $aQueryData)
|
||||
{
|
||||
echo "<h2>$sOql</h2>\n";
|
||||
$iTotal += $aQueryData['count'];
|
||||
echo '<p>'.$aQueryData['count'].'</p>';
|
||||
echo '<p>Example: '.$aQueryData['sql'][0].'</p>';
|
||||
}
|
||||
echo "<h2>Total</h2>\n";
|
||||
echo "<p>Count of executed queries: $iTotal</p>";
|
||||
echo "<p>Count of built queries: ".count(self::$m_aQueriesLog)."</p>";
|
||||
}
|
||||
|
||||
public static function MakeDeleteQuery(DBObjectSearch $oFilter)
|
||||
@@ -2390,6 +2447,8 @@ abstract class MetaModel
|
||||
throw new CoreException('Database not found, check your configuration file', array('config_file'=>$sConfigFile, 'db_name'=>self::$m_sDBName));
|
||||
}
|
||||
}
|
||||
// Some of the init could not be done earlier (requiring classes to be declared and DB to be accessible)
|
||||
self::InitPlugins();
|
||||
}
|
||||
|
||||
public static function LoadConfig($sConfigFile)
|
||||
@@ -2425,6 +2484,15 @@ abstract class MetaModel
|
||||
CMDBSource::Init($sServer, $sUser, $sPwd); // do not select the DB (could not exist)
|
||||
}
|
||||
|
||||
protected static $m_aPlugins = array();
|
||||
public static function RegisterPlugin($sType, $sName, $aInitCallSpec = array())
|
||||
{
|
||||
self::$m_aPlugins[$sName] = array(
|
||||
'type' => $sType,
|
||||
'init' => $aInitCallSpec,
|
||||
);
|
||||
}
|
||||
|
||||
protected static function Plugin($sConfigFile, $sModuleType, $sToInclude)
|
||||
{
|
||||
if (!file_exists($sToInclude))
|
||||
@@ -2434,6 +2502,22 @@ abstract class MetaModel
|
||||
require_once($sToInclude);
|
||||
}
|
||||
|
||||
protected static function InitPlugins()
|
||||
{
|
||||
foreach(self::$m_aPlugins as $sName => $aData)
|
||||
{
|
||||
$aCallSpec = @$aData['init'];
|
||||
if (count($aCallSpec) == 2)
|
||||
{
|
||||
if (!is_callable($aCallSpec))
|
||||
{
|
||||
throw new CoreException('Wrong declaration in plugin', array('plugin' => $aData['name'], 'type' => $aData['type'], 'class' => $aData['class'], 'init' => $aData['init']));
|
||||
}
|
||||
call_user_func($aCallSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Building an object
|
||||
//
|
||||
//
|
||||
|
||||
@@ -46,11 +46,12 @@ abstract class UserRightsAddOnAPI
|
||||
{
|
||||
abstract public function Setup(); // initial installation
|
||||
abstract public function Init(); // loads data (possible optimizations)
|
||||
abstract public function CheckCredentials($iUserId, $sPassword); // returns the id of the user or false
|
||||
abstract public function GetFilter($iUserId, $sClass); // returns a filter object
|
||||
abstract public function IsActionAllowed($iUserId, $sClass, $iActionCode, dbObjectSet $aInstances);
|
||||
abstract public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, dbObjectSet $aInstances);
|
||||
abstract public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances);
|
||||
abstract public function CheckCredentials($sLogin, $sPassword); // returns the id of the user or false
|
||||
abstract public function GetUserId($sLogin); // returns the id of the user or false
|
||||
abstract public function GetFilter($sLogin, $sClass); // returns a filter object
|
||||
abstract public function IsActionAllowed($iUserId, $sClass, $iActionCode, dbObjectSet $oInstances);
|
||||
abstract public function IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, dbObjectSet $oInstances);
|
||||
abstract public function IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, dbObjectSet $oInstances);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,9 +149,18 @@ class UserRights
|
||||
return self::$m_sUser;
|
||||
}
|
||||
|
||||
public static function GetUserId()
|
||||
public static function GetUserId($sName = '')
|
||||
{
|
||||
return self::$m_iUserId;
|
||||
if (empty($sName))
|
||||
{
|
||||
// return current user id
|
||||
return self::$m_iUserId;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find the id out of the login string
|
||||
return self::$m_oAddOn->GetUserId($sName);
|
||||
}
|
||||
}
|
||||
|
||||
public static function GetRealUser()
|
||||
@@ -182,28 +192,49 @@ class UserRights
|
||||
return self::$m_oAddOn->GetFilter(self::$m_iUserId, $sClass);
|
||||
}
|
||||
|
||||
public static function IsActionAllowed($sClass, $iActionCode, dbObjectSet $aInstances)
|
||||
public static function IsActionAllowed($sClass, $iActionCode, dbObjectSet $oInstances, $iUserId = null)
|
||||
{
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return true;
|
||||
if (!self::CheckLogin()) return false;
|
||||
|
||||
return self::$m_oAddOn->IsActionAllowed(self::$m_iUserId, $sClass, $iActionCode, $aInstances);
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowed(self::$m_iUserId, $sClass, $iActionCode, $oInstances);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowed($iUserId, $sClass, $iActionCode, $oInstances);
|
||||
}
|
||||
}
|
||||
|
||||
public static function IsStimulusAllowed($sClass, $sStimulusCode, dbObjectSet $aInstances)
|
||||
public static function IsStimulusAllowed($sClass, $sStimulusCode, dbObjectSet $oInstances, $iUserId = null)
|
||||
{
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return true;
|
||||
if (!self::CheckLogin()) return false;
|
||||
|
||||
return self::$m_oAddOn->IsStimulusAllowed(self::$m_iUserId, $sClass, $sStimulusCode, $aInstances);
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsStimulusAllowed(self::$m_iUserId, $sClass, $sStimulusCode, $oInstances);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsStimulusAllowed($iUserId, $sClass, $sStimulusCode, $oInstances);
|
||||
}
|
||||
}
|
||||
|
||||
public static function IsActionAllowedOnAttribute($sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances)
|
||||
public static function IsActionAllowedOnAttribute($sClass, $sAttCode, $iActionCode, dbObjectSet $oInstances, $iUserId = null)
|
||||
{
|
||||
if (!MetaModel::HasCategory($sClass, 'bizmodel')) return true;
|
||||
if (!self::CheckLogin()) return false;
|
||||
|
||||
return self::$m_oAddOn->IsActionAllowedOnAttribute(self::$m_iUserId, $sClass, $sAttCode, $iActionCode, $aInstances);
|
||||
if (is_null($iUserId))
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowedOnAttribute(self::$m_iUserId, $sClass, $sAttCode, $iActionCode, $oInstances);
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::$m_oAddOn->IsActionAllowedOnAttribute($iUserId, $sClass, $sAttCode, $iActionCode, $oInstances);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,14 @@ function ComputeProjections($oPage, $sScope)
|
||||
$oDimension->CheckProjectionSpec($aClassProjs[$sClass][$iDimension]);
|
||||
|
||||
$aValues = $aClassProjs[$sClass][$iDimension]->ProjectObject($oObject);
|
||||
$sValues = implode(', ', $aValues);
|
||||
if (is_null($aValues))
|
||||
{
|
||||
$sValues = '<any>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValues = implode(', ', $aValues);
|
||||
}
|
||||
$oObjectProj['dim'.$oDimension->GetKey()] = htmlentities($sValues);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,14 @@ function ComputeProjections($oPage)
|
||||
$oDimension->CheckProjectionSpec($aProPros[$iProfile][$iDimension]);
|
||||
|
||||
$aValues = $aProPros[$iProfile][$iDimension]->ProjectUser($oUser);
|
||||
$sValues = implode(', ', $aValues);
|
||||
if (is_null($aValues))
|
||||
{
|
||||
$sValues = '<any>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValues = implode(', ', $aValues);
|
||||
}
|
||||
$aUserProfileProj['dim'.$oDimension->GetKey()] = htmlentities($sValues);
|
||||
}
|
||||
|
||||
|
||||
285
pages/usermanagement_userstatus.php
Normal file
285
pages/usermanagement_userstatus.php
Normal file
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
require_once('../application/application.inc.php');
|
||||
require_once('../application/itopwebpage.class.inc.php');
|
||||
|
||||
require_once('../application/startup.inc.php');
|
||||
|
||||
|
||||
function ComputeObjectProjections($oPage, $oObject)
|
||||
{
|
||||
// Load the classes for a further usage
|
||||
//
|
||||
$aClasses = MetaModel::GetClasses();
|
||||
|
||||
// Load the dimensions for a further usage
|
||||
//
|
||||
$aDimensions = array();
|
||||
$oDimensionSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Dimensions"));
|
||||
while ($oDimension = $oDimensionSet->Fetch())
|
||||
{
|
||||
$aDimensions[$oDimension->GetKey()] = $oDimension;
|
||||
}
|
||||
|
||||
// Load the class projections for a further usage
|
||||
//
|
||||
$aClassProj = array();
|
||||
$oClassProjSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassProjection"));
|
||||
while ($oClassProj = $oClassProjSet->Fetch())
|
||||
{
|
||||
$aClassProjs[$oClassProj->Get('class')][$oClassProj->Get('dimensionid')] = $oClassProj;
|
||||
}
|
||||
|
||||
// Setup display structure
|
||||
//
|
||||
$aDisplayConfig = array();
|
||||
foreach ($aDimensions as $iDimension => $oDimension)
|
||||
{
|
||||
$aDisplayConfig['dim'.$oDimension->GetKey()] = array('label' => $oDimension->GetName(), 'description' => $oDimension->Get('description'));
|
||||
}
|
||||
|
||||
// Load objects
|
||||
//
|
||||
$aDisplayData = array();
|
||||
$sClass = get_class($oObject);
|
||||
$aObjectProj = array();
|
||||
foreach ($aDimensions as $iDimension => $oDimension)
|
||||
{
|
||||
// #@# to be moved, may be time consuming
|
||||
$oDimension->CheckProjectionSpec($aClassProjs[$sClass][$iDimension]);
|
||||
|
||||
$aValues = $aClassProjs[$sClass][$iDimension]->ProjectObject($oObject);
|
||||
if (is_null($aValues))
|
||||
{
|
||||
$sValues = '<any>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValues = implode(', ', $aValues);
|
||||
}
|
||||
$oObjectProj['dim'.$oDimension->GetKey()] = htmlentities($sValues);
|
||||
}
|
||||
|
||||
$aDisplayData[] = $oObjectProj;
|
||||
|
||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||
}
|
||||
|
||||
|
||||
function ComputeUserProjections($oPage, $oUser)
|
||||
{
|
||||
// Load the profiles for a further usage
|
||||
//
|
||||
$aProfiles = array();
|
||||
$oProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Profiles"));
|
||||
while ($oProfile = $oProfileSet->Fetch())
|
||||
{
|
||||
$aProfiles[$oProfile->GetKey()] = $oProfile;
|
||||
}
|
||||
|
||||
// Load the dimensions for a further usage
|
||||
//
|
||||
$aDimensions = array();
|
||||
$oDimensionSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Dimensions"));
|
||||
while ($oDimension = $oDimensionSet->Fetch())
|
||||
{
|
||||
$aDimensions[$oDimension->GetKey()] = $oDimension;
|
||||
}
|
||||
|
||||
// Load the profile projections for a further usage
|
||||
//
|
||||
$aProPro = array();
|
||||
$oProProSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ProfileProjection"));
|
||||
while ($oProPro = $oProProSet->Fetch())
|
||||
{
|
||||
$aProPros[$oProPro->Get('profileid')][$oProPro->Get('dimensionid')] = $oProPro;
|
||||
}
|
||||
|
||||
// Setup display structure
|
||||
//
|
||||
$aDisplayConfig = array();
|
||||
$aDisplayConfig['profile'] = array('label' => 'Profile', 'description' => 'Profile in which the projection is specified');
|
||||
foreach ($aDimensions as $iDimension => $oDimension)
|
||||
{
|
||||
$aDisplayConfig['dim'.$oDimension->GetKey()] = array('label' => $oDimension->GetName(), 'description' => $oDimension->Get('description'));
|
||||
}
|
||||
|
||||
// Create a record per profile
|
||||
//
|
||||
$aDisplayData = array();
|
||||
$oUserProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_UserProfile WHERE userid = :user->id"), array(), array('user' => $oUser));
|
||||
while ($oUserProfile = $oUserProfileSet->Fetch())
|
||||
{
|
||||
$iProfile = $oUserProfile->Get('profileid');
|
||||
$oProfile = $aProfiles[$iProfile];
|
||||
|
||||
$aUserProfileProj = array();
|
||||
$aUserProfileProj['profile'] = $oProfile->GetName();
|
||||
foreach ($aDimensions as $iDimension => $oDimension)
|
||||
{
|
||||
// #@# to be moved, may be time consuming
|
||||
$oDimension->CheckProjectionSpec($aProPros[$iProfile][$iDimension]);
|
||||
|
||||
$aValues = $aProPros[$iProfile][$iDimension]->ProjectUser($oUser);
|
||||
if (is_null($aValues))
|
||||
{
|
||||
$sValues = '<any>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$sValues = implode(', ', $aValues);
|
||||
}
|
||||
$aUserProfileProj['dim'.$oDimension->GetKey()] = htmlentities($sValues);
|
||||
}
|
||||
|
||||
$aDisplayData[] = $aUserProfileProj;
|
||||
}
|
||||
|
||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||
}
|
||||
|
||||
|
||||
function ComputeUserRights($oPage, $oUser, $oObject)
|
||||
{
|
||||
// Set the stage
|
||||
//
|
||||
$iUser = $oUser->GetKey();
|
||||
$sClass = get_class($oObject);
|
||||
$iPKey = $oObject->GetKey();
|
||||
$oInstances = DBObjectSet::FromArray($sClass, array($oObject));
|
||||
$aPermissions = array(
|
||||
UR_ALLOWED_NO => '<span style="background-color: #ffdddd;">UR_ALLOWED_NO</span>',
|
||||
UR_ALLOWED_YES => '<span style="background-color: #ddffdd;">UR_ALLOWED_YES</span>',
|
||||
UR_ALLOWED_DEPENDS => '<span style="">UR_ALLOWED_DEPENDS</span>',
|
||||
);
|
||||
$aActions = array(
|
||||
UR_ACTION_READ => 'Read',
|
||||
UR_ACTION_MODIFY => 'Modify',
|
||||
UR_ACTION_DELETE => 'Delete',
|
||||
UR_ACTION_BULK_READ => 'Bulk Read',
|
||||
UR_ACTION_BULK_MODIFY => 'Bulk Modify',
|
||||
UR_ACTION_BULK_DELETE => 'Bulk Delete',
|
||||
);
|
||||
$aAttributeActions = array(
|
||||
UR_ACTION_READ => 'Read',
|
||||
UR_ACTION_MODIFY => 'Modify',
|
||||
UR_ACTION_BULK_READ => 'Bulk Read',
|
||||
UR_ACTION_BULK_MODIFY => 'Bulk Modify',
|
||||
);
|
||||
|
||||
// Determine allowed actions for the object
|
||||
//
|
||||
$aDisplayData = array();
|
||||
foreach($aActions as $iActionCode => $sActionDesc)
|
||||
{
|
||||
$iPermission = UserRights::IsActionAllowed($sClass, $iActionCode, $oInstances, $iUser);
|
||||
$aDisplayData[] = array(
|
||||
'action' => $sActionDesc,
|
||||
'permission' => $aPermissions[$iPermission],
|
||||
);
|
||||
}
|
||||
$aDisplayConfig = array();
|
||||
$aDisplayConfig['action'] = array('label' => 'Action', 'description' => '');
|
||||
$aDisplayConfig['permission'] = array('label' => 'Permission', 'description' => '');
|
||||
$oPage->p('<h3>Actions</h3>');
|
||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||
|
||||
|
||||
// Determine allowed actions for the object
|
||||
//
|
||||
$aDisplayData = array();
|
||||
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
|
||||
{
|
||||
if (!$oAttDef->IsDirectField()) continue;
|
||||
|
||||
foreach($aAttributeActions as $iActionCode => $sActionDesc)
|
||||
{
|
||||
$iPermission = UserRights::IsActionAllowedOnAttribute($sClass, $sAttCode, $iActionCode, $oInstances, $iUser);
|
||||
$aDisplayData[] = array(
|
||||
'attribute' => $sAttCode,
|
||||
'action' => $sActionDesc,
|
||||
'permission' => $aPermissions[$iPermission],
|
||||
);
|
||||
}
|
||||
}
|
||||
$oPage->p('<h3>Attributes</h3>');
|
||||
if (count($aDisplayData) > 0)
|
||||
{
|
||||
$aDisplayConfig = array();
|
||||
$aDisplayConfig['attribute'] = array('label' => 'Attribute', 'description' => '');
|
||||
$aDisplayConfig['action'] = array('label' => 'Action', 'description' => '');
|
||||
$aDisplayConfig['permission'] = array('label' => 'Permission', 'description' => '');
|
||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->p('<em>none</em>');
|
||||
}
|
||||
|
||||
// Determine allowed stimuli
|
||||
//
|
||||
$aDisplayData = array();
|
||||
foreach(MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus)
|
||||
{
|
||||
$iPermission = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oInstances, $iUser);
|
||||
$aDisplayData[] = array(
|
||||
'stimulus' => $sStimulusCode,
|
||||
'permission' => $aPermissions[$iPermission],
|
||||
);
|
||||
}
|
||||
$oPage->p('<h3>Stimuli</h3>');
|
||||
if (count($aDisplayData) > 0)
|
||||
{
|
||||
$aDisplayConfig = array();
|
||||
$aDisplayConfig['stimulus'] = array('label' => 'Stimulus', 'description' => '');
|
||||
$aDisplayConfig['permission'] = array('label' => 'Permission', 'description' => '');
|
||||
$oPage->table($aDisplayConfig, $aDisplayData);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oPage->p('<em>none</em>');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
require_once('../application/loginwebpage.class.inc.php');
|
||||
login_web_page::DoLogin(); // Check user rights and prompt if needed
|
||||
|
||||
// Display the menu on the left
|
||||
$oContext = new UserContext();
|
||||
$oAppContext = new ApplicationContext();
|
||||
$iActiveNodeId = utils::ReadParam('menu', -1);
|
||||
$currentOrganization = utils::ReadParam('org_id', 1);
|
||||
$iUser = utils::ReadParam('user_id', -1);
|
||||
$sObjectClass = utils::ReadParam('object_class', '');
|
||||
$iObjectId = utils::ReadParam('object_id', 0);
|
||||
|
||||
$oPage = new iTopWebPage("iTop user management - user status", $currentOrganization);
|
||||
$oPage->no_cache();
|
||||
|
||||
|
||||
if ($iUser == -1)
|
||||
{
|
||||
$oPage->p('Missing parameter "user_id" - current user is '.UserRights::GetUserId());
|
||||
}
|
||||
else
|
||||
{
|
||||
$oUser = MetaModel::GetObject('URP_Users', $iUser);
|
||||
|
||||
$oPage->p('<h2>Projections for user '.$oUser->GetName().'</h2>');
|
||||
ComputeUserProjections($oPage, $oUser);
|
||||
|
||||
if (strlen($sObjectClass) != 0)
|
||||
{
|
||||
$oObject = MetaModel::GetObject($sObjectClass, $iObjectId);
|
||||
|
||||
$oPage->p('<h2>Projections for object '.$oObject->GetName().'</h2>');
|
||||
ComputeObjectProjections($oPage, $oObject);
|
||||
|
||||
$oPage->p('<h2>Resulting rights</h2>');
|
||||
ComputeUserRights($oPage, $oUser, $oObject);
|
||||
}
|
||||
}
|
||||
|
||||
$oPage->output();
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user