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:
Romain Quetiez
2009-07-31 13:18:44 +00:00
parent 1fdd659395
commit b5c7cbf509
11 changed files with 884 additions and 150 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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, '')";
}

View File

@@ -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
//
//

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View 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();
?>