diff --git a/application/portalwebpage.class.inc.php b/application/portalwebpage.class.inc.php
index 57fa8bfdc..930239c25 100644
--- a/application/portalwebpage.class.inc.php
+++ b/application/portalwebpage.class.inc.php
@@ -793,24 +793,7 @@ EOF
}
}
- $sOQL = "SELECT $sClass WHERE org_id = :org_id";
- $oSearch = DBObjectSearch::FromOQL($sOQL);
- $iUser = UserRights::GetContactId();
- if ($iUser > 0 && !IsPowerUser())
- {
- $oSearch->AddCondition('caller_id', $iUser);
- }
- $oSearch->AddCondition('id', $iId);
-
- $oContact = MetaModel::GetObject('Contact', $iUser, false); // false => Can fail
- if (!is_object($oContact))
- {
- throw new Exception(Dict::S('Portal:ErrorNoContactForThisUser'));
- }
-
- $oSet = new DBObjectSet($oSearch, array(), array('org_id' => $oContact->Get('org_id')));
-
- $oObj = $oSet->Fetch();
+ $oObj = MetaModel::GetObject($sClass, $iId, false);
if (!is_object($oObj))
{
throw new Exception("Could not find the object $sClass/$iId");
diff --git a/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml b/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml
index 949a61541..7b782ec6b 100755
--- a/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml
+++ b/datamodels/2.x/itop-request-mgmt-itil/datamodel.itop-request-mgmt-itil.xml
@@ -17,6 +17,8 @@
+ org_id AND caller_id = :contact->id]]>
+ org_id]]>
@@ -24,6 +26,8 @@
+ org_id AND caller_id = :contact->id]]>
+ org_id]]>
diff --git a/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml b/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml
index df59ef647..b9f87b6a5 100755
--- a/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml
+++ b/datamodels/2.x/itop-request-mgmt/datamodel.itop-request-mgmt.xml
@@ -17,6 +17,8 @@
+ org_id AND caller_id = :contact->id]]>
+ org_id]]>
diff --git a/portal/index.php b/portal/index.php
index c4dfecff9..8bcf85898 100644
--- a/portal/index.php
+++ b/portal/index.php
@@ -50,6 +50,46 @@ function GetTicketClasses()
return $aClasses;
}
+
+/**
+ * Helper to protect the portal against malicious usages
+ * Throws an exception if the current user is not allowed to view the object details
+ */
+function ValidateObject($oObject)
+{
+ if (IsPowerUser())
+ {
+ $sValidationDefine = 'PORTAL_'.strtoupper(get_class($oObject)).'_DISPLAY_POWERUSER_QUERY';
+ }
+ else
+ {
+ $sValidationDefine = 'PORTAL_'.strtoupper(get_class($oObject)).'_DISPLAY_QUERY';
+ }
+ if (defined($sValidationDefine))
+ {
+ $sValidationOql = constant($sValidationDefine);
+ $oSearch = DBObjectSearch::FromOQL($sValidationOql);
+ $oSearch->AddCondition('id', $oObject->GetKey());
+
+ if ($iUser = UserRights::GetContactId())
+ {
+ $oContact = MetaModel::GetObject('Contact', $iUser);
+ $aArgs = $oContact->ToArgs('contact');
+ }
+ else
+ {
+ $aArgs = array();
+ }
+
+ $oSet = new DBObjectSet($oSearch, array(), $aArgs);
+ if ($oSet->Count() == 0)
+ {
+ throw new SecurityException('You are not allowed to access the object '.get_class($oObject).'::'.$oObject->GetKey());
+ }
+ }
+}
+
+
/**
* Helper to get the relevant constant
*/
@@ -1249,6 +1289,7 @@ try
$oP->set_title(Dict::S('Portal:TitleDetailsFor_Request'));
DisplayMainMenu($oP);
$oObj = $oP->FindObjectFromArgs(GetTicketClasses());
+ ValidateObject($oObj);
DisplayObject($oP, $oObj, $oUserOrg);
break;
@@ -1258,6 +1299,7 @@ try
if (!MetaModel::DBIsReadOnly())
{
$oObj = $oP->FindObjectFromArgs(GetTicketClasses());
+ ValidateObject($oObj);
$aAttList = array(
GetConstant(get_class($oObj), 'PUBLIC_LOG'),
'user_satisfaction',
diff --git a/portal/readme.txt b/portal/readme.txt
index ac3190873..45972d92c 100644
--- a/portal/readme.txt
+++ b/portal/readme.txt
@@ -41,6 +41,8 @@ PORTAL__TYPE: optional attribute to be set with the value of "requ
PORTAL__LIST_ZLIST: list of attribute displayed in the lists (opened and resolved)
PORTAL__CLOSED_ZLIST: list of attribute displayed in the list of closed tickets
PORTAL__DETAILS_ZLIST: selection and presentation of attributes in the page that shows their details
+PORTAL__DISPLAY_QUERY: selection of displayable objects (use parameters contact->attcode to check things against the user/contact)
+PORTAL__DISPLAY_POWERUSER_QUERY: selection of displayable objects for power users (use parameters contact->attcode to check things against the user/contact)
How to add a type of ticket (example: Incident)