Index: trunk/core/units/general/helpers/permissions_helper.php
===================================================================
diff -u -N -r8369 -r8402
--- trunk/core/units/general/helpers/permissions_helper.php (.../permissions_helper.php) (revision 8369)
+++ trunk/core/units/general/helpers/permissions_helper.php (.../permissions_helper.php) (revision 8402)
@@ -121,6 +121,31 @@
}
/**
+ * Returns owner + primary category for each item (used for permission checking)
+ *
+ * @param string $prefix
+ * @param string $ids
+ * @return Array
+ * @author Alex
+ */
+ function GetCategoryItemData($prefix, $ids)
+ {
+ if (is_array($ids)) {
+ $ids = implode(',', $ids);
+ }
+ $id_field = $this->Application->getUnitOption($prefix, 'IDField');
+ $table_name = $this->Application->getUnitOption($prefix, 'TableName');
+ $ci_table = $this->Application->getUnitOption('ci', 'TableName');
+
+ $sql = 'SELECT '.$id_field.', CreatedById, ci.CategoryId
+ FROM '.$table_name.' item_table
+ LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = item_table.ResourceId
+ WHERE '.$id_field.' IN ('.$ids.') AND (ci.PrimaryCat = 1)';
+ return $this->Conn->Query($sql, $id_field);
+ }
+
+
+ /**
* Checks non-system permission on event per category basis
*
* @param kEvent $event
@@ -132,6 +157,8 @@
$top_prefix = $event->getEventParam('top_prefix');
$event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler');
+ /* @var $event_handler kCatDBEventHandler */
+
if ($event->Prefix != $top_prefix) {
$top_event = new kEvent($top_prefix.':'.$event->Name);
$id = $event_handler->getPassedID($top_event);
@@ -140,11 +167,6 @@
$id = $event_handler->getPassedID($event);
}
- // 1. get primary category of category item
- $id_field = $this->Application->getUnitOption($top_prefix, 'IDField');
- $table_name = $this->Application->getUnitOption($top_prefix, 'TableName');
- $ci_table = $this->Application->getUnitOption('ci', 'TableName');
-
if (!$id) {
// item being created -> check by current (before editing started, saved in OnPreCreate event) category permissions
$category_id = $this->Application->IsAdmin() ? $this->Application->RecallVar('m_cat_id') : $this->Application->GetVar('m_cat_id');
@@ -154,41 +176,19 @@
}
else {
// item being edited -> check by it's primary category permissions
- $sql = 'SELECT ci.CategoryId, main_table.CreatedById
- FROM '.$table_name.' main_table
- LEFT JOIN '.$ci_table.' ci ON ci.ItemResourceId = main_table.ResourceId
- WHERE (main_table.'.$id_field.' = '.$id.') AND (ci.PrimaryCat = 1)';
- $item_info = $this->Conn->GetRow($sql);
- $category_id = $item_info['CategoryId'];
- $owner_id = $item_info['CreatedById'];
+ $items_info = $this->GetCategoryItemData($top_prefix, $id);
+ $category_id = $items_info[$id]['CategoryId'];
+ $owner_id = $items_info[$id]['CreatedById'];
}
// specific permission check for pending & owner permissions: begin
- if (substr($event->Name, 0, 9) == 'OnPreSave' || $event->Name == 'OnCreate' || $event->Name == 'OnUpdate') {
- if ($event_handler->isNewItemCreate($event)) {
- $check_status = $this->AddCheckPermission($category_id, $top_prefix);
- }
- else {
- $check_status = $this->AddCheckPermission($category_id, $top_prefix) ||
- $this->ModifyCheckPermission($owner_id, $category_id, $top_prefix);
- }
-
- if (!$check_status) {
- $event->status = erPERM_FAIL;
- }
+ $new_item = $this->Application->IsAdmin() && $event_handler->isNewItemCreate($event) ? true : false;
+ $check_status = $this->checkCombinedPermissions($event, $owner_id, $category_id, $new_item);
+ if (isset($check_status)) {
return $check_status;
}
-
- if ($event->Name == 'OnMassDelete') {
- $check_status = $this->DeleteCheckPermission($owner_id, $category_id, $top_prefix);
- if (!$check_status) {
- $event->status = erPERM_FAIL;
- }
- return $check_status;
- }
// specific permission check for pending & owner permissions: end
-
$perm_status = false;
$check_perms = $this->getPermissionByEvent($event, $event_perm_mapping);
@@ -205,7 +205,6 @@
continue;
}
$perm_name = $item_prefix.'.'.$perm_mapping[$perm_name];
- $this->showDebug('Event '.$event->Name.' permission(-s): '.$perm_name.'', Array());
$perm_status = $this->CheckPermission($perm_name, 0, $category_id);
if ($perm_status) {
@@ -227,12 +226,57 @@
return $perm_status;
}
- function showDebug($text, $params)
+ /**
+ * Allows to check combined permissions (*.owner, *.pending) for add/modify/delete operations from admin & front-end
+ *
+ * @param kEvent $event
+ * @param int $owner_id
+ * @param int $category_id
+ * @param bool $new_item
+ * @return mixed
+ */
+ function checkCombinedPermissions(&$event, $owner_id, $category_id, $new_item = false)
{
- return ;
- $is_ajax = $this->Application->GetVar('ajax') == 'yes' || isset($params['ajax']) || isset($params['tab_init']);
- if (!$this->Application->isDebugMode() || $is_ajax) return true;
- echo $text.'
';
+ $ret = null; // true/false when used, null when not used
+ $top_prefix = $event->getEventParam('top_prefix');
+
+ // check admin permission
+ if (substr($event->Name, 0, 9) == 'OnPreSave') {
+ if ($new_item) {
+ $ret = $this->AddCheckPermission($category_id, $top_prefix);
+ }
+ else {
+ // add & modify because $new_item is false, when item is aready created & then saved in temp table (even with 0 id)
+ $ret = $this->AddCheckPermission($category_id, $top_prefix) ||
+ $this->ModifyCheckPermission($owner_id, $category_id, $top_prefix);
+ }
+ }
+
+ // check front-end permissions
+ switch ($event->Name) {
+ case 'OnItemLoad':
+ break;
+
+ case 'OnCreate':
+ $ret = $this->AddCheckPermission($category_id, $top_prefix);
+ break;
+
+ case 'OnUpdate':
+ $ret = $this->ModifyCheckPermission($owner_id, $category_id, $top_prefix);
+ break;
+
+ case 'OnDelete':
+ case 'OnMassDelete':
+ $ret = $this->DeleteCheckPermission($owner_id, $category_id, $top_prefix);
+ break;
+ }
+
+ if ($ret === 0) {
+ // permission check failed (user has no permission)
+ $event->status = erPERM_FAIL;
+ }
+
+ return $ret;
}
function TagPermissionCheck($params, $tag_name)
@@ -243,7 +287,6 @@
if ($permission_groups) {
// check permissions by permission names in current category
- $this->showDebug('Tag '.$tag_name.' permission(-s): '.$permission_groups.'', $params);
$permission_groups = explode('|', $permission_groups);
$group_has_permission = false;
@@ -270,7 +313,6 @@
}
elseif ($perm_event) {
// check permission by event name
- $this->showDebug('Tag '.$tag_name.' permission_event: '.$perm_event.'', $params);
list($prefix, $event) = explode(':', $perm_event);
$event_handler =& $this->Application->recallObject($prefix.'_EventHandler');
return $event_handler->CheckPermission( new kEvent($perm_event) );
@@ -414,14 +456,20 @@
// cached view permission of category: end
}
- if ($cat_id == 0) {
+ if (is_numeric($cat_id) && $cat_id == 0) {
$cat_hierarchy = Array(0);
}
else {
- $sql = 'SELECT ParentPath
+ if (strpos($cat_id, '|') !== false) {
+ $cat_hierarchy = $cat_id;
+ }
+ else {
+ $sql = 'SELECT ParentPath
FROM '.$this->Application->getUnitOption('c', 'TableName').'
WHERE CategoryId = '.$cat_id;
- $cat_hierarchy = $this->Conn->GetOne($sql);
+ $cat_hierarchy = $this->Conn->GetOne($sql);
+ }
+
$cat_hierarchy = explode('|', substr($cat_hierarchy, 1, -1));
$cat_hierarchy = array_reverse($cat_hierarchy);
array_push($cat_hierarchy, 0);
@@ -479,6 +527,38 @@
}
/**
+ * Allows to check VIEW & "OWNER.VIEW.PENDING" permission combinations on item
+ *
+ * @param int $owner_id user_id, that is owner of the item
+ * @param int $category_id primary category of item
+ * @param string $prefix prefix of item
+ * @return int {0 - no VIEW permission, 1 - has VIEW permission}
+ */
+ function ViewCheckPermission($owner_id, $category_id, $prefix)
+ {
+ $perm_prefix = $this->Application->getUnitOption($prefix, 'PermItemPrefix');
+
+ // in progress
+ $use_pending_editing = $this->Application->getUnitOption($prefix, 'UsePendingEditing');
+
+
+ $live_delete = $this->CheckPermission($perm_prefix.'.VIEW', ptCATEGORY, $category_id);
+ if ($live_delete) {
+ return 1;
+ }
+
+ if ($owner_id == $this->Application->RecallVar('user_id')) {
+ // user is item's OWNER -> check this permissions first
+ $live_delete = $this->CheckPermission($perm_prefix.'.OWNER.DELETE', ptCATEGORY, $category_id);
+ if ($live_delete) {
+ return 1;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
* Allows to check DELETE & OWNER.DELETE permission combinations on item
*
* @param int $owner_id user_id, that is owner of the item