From b2c528f0b50f17d3a0c9e0fb3b3ffb7447d8f076 Mon Sep 17 00:00:00 2001 From: prasad <prasad@vtiger.com> Date: Mon, 5 Feb 2018 18:43:16 +0530 Subject: [PATCH] Fixes #753: Seperated ACL (Tasks default Sharing, Events as configured in Calendar Settings) --- .../QueryGenerator/EnhancedQueryGenerator.php | 14 ++++ include/QueryGenerator/QueryGenerator.php | 14 ++++ modules/Accounts/models/Module.php | 16 +++++ modules/Calendar/Activity.php | 65 ++++++++++++++----- modules/Contacts/models/Module.php | 16 +++++ modules/HelpDesk/models/Module.php | 8 +++ modules/Home/models/Module.php | 8 +++ modules/Inventory/models/Module.php | 8 +++ modules/Leads/models/Module.php | 8 +++ modules/Potentials/models/Module.php | 8 +++ modules/PriceBooks/models/Relation.php | 14 ++++ modules/Products/models/RelationListView.php | 15 +++++ modules/Reports/ReportRun.php | 19 ++++++ modules/Vtiger/models/Module.php | 16 +++++ 14 files changed, 214 insertions(+), 15 deletions(-) diff --git a/include/QueryGenerator/EnhancedQueryGenerator.php b/include/QueryGenerator/EnhancedQueryGenerator.php index d3d067ee5..a9f8c3f9b 100644 --- a/include/QueryGenerator/EnhancedQueryGenerator.php +++ b/include/QueryGenerator/EnhancedQueryGenerator.php @@ -829,6 +829,20 @@ class EnhancedQueryGenerator extends QueryGenerator { $fieldSqlList[$index] = $fieldSql; } + $currentUserModel = Users_Record_Model::getCurrentUserModel(); + if(($baseModule == 'Calendar' || $baseModule == 'Events') && !$currentUserModel->isAdminUser()) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + + if($condition) { + if($this->conditionInstanceCount > 0) { + $sql .= $condition.' AND '; + }else { + $sql .= ' AND '.$condition; + } + } + } + // This is needed as there can be condition in different order and there is an assumption in makeGroupSqlReplacements API // that it expects the array in an order and then replaces the sql with its the corresponding place ksort($fieldSqlList); diff --git a/include/QueryGenerator/QueryGenerator.php b/include/QueryGenerator/QueryGenerator.php index 737cafabe..c548e9396 100644 --- a/include/QueryGenerator/QueryGenerator.php +++ b/include/QueryGenerator/QueryGenerator.php @@ -919,6 +919,20 @@ class QueryGenerator { $fieldSqlList[$index] = $fieldSql; } } + + $currentUserModel = Users_Record_Model::getCurrentUserModel(); + if(($baseModule == 'Calendar' || $baseModule == 'Events') && !$currentUserModel->isAdminUser()) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if ($condition) { + if ($this->conditionInstanceCount > 0) { + $sql .= $condition . ' AND '; + } else { + $sql .= ' AND ' . $condition; + } + } + } + // This is needed as there can be condition in different order and there is an assumption in makeGroupSqlReplacements API // that it expects the array in an order and then replaces the sql with its the corresponding place ksort($fieldSqlList); diff --git a/modules/Accounts/models/Module.php b/modules/Accounts/models/Module.php index bced04aa4..853d5e5fc 100644 --- a/modules/Accounts/models/Module.php +++ b/modules/Accounts/models/Module.php @@ -110,6 +110,14 @@ class Accounts_Module_Model extends Vtiger_Module_Model { $nonAdminQuery = $this->getNonAdminAccessControlQueryForRelation($relatedModuleName); if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if(trim($nonAdminQuery)) { + $relModuleFocus = CRMEntity::getInstance($relatedModuleName); + $condition = $relModuleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } // There could be more than one contact for an activity. @@ -162,6 +170,14 @@ class Accounts_Module_Model extends Vtiger_Module_Model { AND (vtiger_activity.status is NULL OR vtiger_activity.status NOT IN ('Completed', 'Deferred', 'Cancelled')) AND (vtiger_activity.eventstatus is NULL OR vtiger_activity.eventstatus NOT IN ('Held', 'Cancelled'))"; + if(!$currentUser->isAdminUser()) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } + if ($mode === 'upcoming') { $query .= " AND CASE WHEN vtiger_activity.activitytype='Task' THEN due_date >= '$currentDate' ELSE CONCAT(due_date,' ',time_end) >= '$nowInDBFormat' END"; } elseif ($mode === 'overdue') { diff --git a/modules/Calendar/Activity.php b/modules/Calendar/Activity.php index b384cfcd9..545cda938 100644 --- a/modules/Calendar/Activity.php +++ b/modules/Calendar/Activity.php @@ -1052,21 +1052,22 @@ function insertIntoRecurringTable(& $recurObj) $query = ' '; $tabId = getTabid($module); if($is_admin==false && $profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] - == 1 && $defaultOrgSharingPermission[$tabId] == 3) { - $tableName = 'vt_tmp_u'.$user->id.'_t'.$tabId; - $sharingRuleInfoVariable = $module.'_share_read_permission'; - $sharingRuleInfo = $$sharingRuleInfoVariable; + == 1) { $sharedTabId = null; - $this->setupTemporaryTable($tableName, $sharedTabId, $user, - $current_user_parent_role_seq, $current_user_groups); - - $sharedUsers = $this->getListViewAccessibleUsers($user->id); - // we need to include group id's in $sharedUsers list to get the current user's group records - if($current_user_groups){ - $sharedUsers = $sharedUsers.','. implode(',',$current_user_groups); - } - $query = " INNER JOIN $tableName $tableName$scope ON ($tableName$scope.id = ". - "vtiger_crmentity$scope.smownerid and $tableName$scope.shared=0 and $tableName$scope.id IN ($sharedUsers)) "; + //For Events + $tableName = 'vt_tmp_u'.$user->id.'_t'.$tabId.'_events'; + $this->setupTemporaryTableForEvents($tableName, $sharedTabId, $user, + $current_user_parent_role_seq, $current_user_groups); + $query = " LEFT JOIN $tableName $tableName$scope ON ($tableName$scope.id = ". + "vtiger_crmentity$scope.smownerid AND vtiger_activity.activitytype NOT IN ('Emails', 'Task')) "; + + //For Task + $task_tableName = 'vt_tmp_u'.$user->id.'_t'.$tabId.'_task'; + $this->setupTemporaryTableForTask($task_tableName, $tabId, $user, + $current_user_parent_role_seq, $current_user_groups, $defaultOrgSharingPermission[$tabId]); + + $query .= " LEFT JOIN $task_tableName $task_tableName$scope ON ($task_tableName$scope.id = ". + "vtiger_crmentity$scope.smownerid AND vtiger_activity.activitytype = 'Task') "; } return $query; } @@ -1087,7 +1088,7 @@ function insertIntoRecurringTable(& $recurObj) return $query; } - protected function setupTemporaryTable($tableName, $tabId, $user, $parentRole, $userGroups) { + protected function setupTemporaryTableForEvents($tableName, $tabId, $user, $parentRole, $userGroups) { $module = null; if (!empty($tabId)) { $module = getTabname($tabId); @@ -1113,6 +1114,26 @@ function insertIntoRecurringTable(& $recurObj) return false; } + protected function setupTemporaryTableForTask($tableName, $tabId, $user, $parentRole, $userGroups, $sharingPermission) { + $module = null; + if (!empty($tabId)) { + $module = getTabname($tabId); + } + + if($sharingPermission == 3) { + $query = $this->getNonAdminAccessQuery($module, $user, $parentRole, $userGroups); + } else { + $query = " (SELECT $user->id as id) UNION (SELECT id FROM vtiger_users " + . "WHERE vtiger_users.deleted=0 AND vtiger_users.status='Active') " + . "UNION (SELECT groupid FROM vtiger_groups)"; + } + + $query = "CREATE TEMPORARY TABLE IF NOT EXISTS $tableName(id INT(11) PRIMARY KEY, shared ". + "int(1) DEFAULT 0) IGNORE ".$query; + $db = PearDatabase::getInstance(); + $db->pquery($query, array()); + } + protected function getListViewAccessibleUsers($sharedid) { $db = PearDatabase::getInstance();; $query = "SELECT vtiger_users.id as userid FROM vtiger_sharedcalendar @@ -1131,5 +1152,19 @@ function insertIntoRecurringTable(& $recurObj) $shared_ids = implode(",",$userid); return $shared_ids; } + + public function buildWhereClauseConditionForCalendar($scope = '') { + $userModel = Users_Record_Model::getCurrentUserModel(); + require('user_privileges/user_privileges_'.$userModel->id.'.php'); + + $query = ""; + if($profileGlobalPermission[1] == 1 && $profileGlobalPermission[2] == 1) { + $tabId = getTabid("Calendar"); + $eventTempTable = 'vt_tmp_u'.$userModel->id.'_t'.$tabId.'_events'.$scope; + $taskTempTable = 'vt_tmp_u'.$userModel->id.'_t'.$tabId.'_task'.$scope; + $query = " ($eventTempTable.shared IS NOT NULL OR $taskTempTable.shared IS NOT NULL) "; + } + return $query; + } } ?> diff --git a/modules/Contacts/models/Module.php b/modules/Contacts/models/Module.php index 7d492ec7a..5817ded31 100644 --- a/modules/Contacts/models/Module.php +++ b/modules/Contacts/models/Module.php @@ -65,6 +65,14 @@ class Contacts_Module_Model extends Vtiger_Module_Model { AND (vtiger_activity.status is NULL OR vtiger_activity.status NOT IN ('Completed', 'Deferred')) AND (vtiger_activity.eventstatus is NULL OR vtiger_activity.eventstatus NOT IN ('Held'))"; + if(!$currentUser->isAdminUser()) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } + if ($recordId) { $query .= " AND vtiger_cntactivityrel.contactid = ?"; } elseif ($mode === 'upcoming') { @@ -251,6 +259,14 @@ class Contacts_Module_Model extends Vtiger_Module_Model { $nonAdminQuery = $this->getNonAdminAccessControlQueryForRelation($relatedModuleName); if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if(trim($nonAdminQuery)) { + $relModuleFocus = CRMEntity::getInstance($relatedModuleName); + $condition = $relModuleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } } else { $query = parent::getRelationQuery($recordId, $functionName, $relatedModule, $relationId); diff --git a/modules/HelpDesk/models/Module.php b/modules/HelpDesk/models/Module.php index 5426fb6e1..7f8237801 100644 --- a/modules/HelpDesk/models/Module.php +++ b/modules/HelpDesk/models/Module.php @@ -164,6 +164,14 @@ class HelpDesk_Module_Model extends Vtiger_Module_Model { $nonAdminQuery = $this->getNonAdminAccessControlQueryForRelation($relatedModuleName); if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if(trim($nonAdminQuery)) { + $relModuleFocus = CRMEntity::getInstance($relatedModuleName); + $condition = $relModuleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } } else { $query = parent::getRelationQuery($recordId, $functionName, $relatedModule, $relationId); diff --git a/modules/Home/models/Module.php b/modules/Home/models/Module.php index 2bea4aa11..f2fa1265a 100644 --- a/modules/Home/models/Module.php +++ b/modules/Home/models/Module.php @@ -198,6 +198,14 @@ class Home_Module_Model extends Vtiger_Module_Model { AND (vtiger_activity.status is NULL OR vtiger_activity.status NOT IN ('Completed', 'Deferred', 'Cancelled')) AND (vtiger_activity.eventstatus is NULL OR vtiger_activity.eventstatus NOT IN ('Held', 'Cancelled'))"; + if(!$currentUser->isAdminUser()) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } + if ($mode === 'upcoming') { $query .= " AND CASE WHEN vtiger_activity.activitytype='Task' THEN due_date >= '$currentDate' ELSE CONCAT(due_date,' ',time_end) >= '$nowInDBFormat' END"; } elseif ($mode === 'overdue') { diff --git a/modules/Inventory/models/Module.php b/modules/Inventory/models/Module.php index 991e5d59f..5e917570b 100644 --- a/modules/Inventory/models/Module.php +++ b/modules/Inventory/models/Module.php @@ -84,6 +84,14 @@ class Inventory_Module_Model extends Vtiger_Module_Model { $nonAdminQuery = $this->getNonAdminAccessControlQueryForRelation($relatedModuleName); if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if(trim($nonAdminQuery)) { + $relModuleFocus = CRMEntity::getInstance($relatedModuleName); + $condition = $relModuleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } } else { $query = parent::getRelationQuery($recordId, $functionName, $relatedModule, $relationId); diff --git a/modules/Leads/models/Module.php b/modules/Leads/models/Module.php index 94289dad9..2f3126412 100644 --- a/modules/Leads/models/Module.php +++ b/modules/Leads/models/Module.php @@ -297,6 +297,14 @@ class Leads_Module_Model extends Vtiger_Module_Model { $nonAdminQuery = $this->getNonAdminAccessControlQueryForRelation($relatedModuleName); if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if(trim($nonAdminQuery)) { + $relModuleFocus = CRMEntity::getInstance($relatedModuleName); + $condition = $relModuleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } } else { $query = parent::getRelationQuery($recordId, $functionName, $relatedModule, $relationId); diff --git a/modules/Potentials/models/Module.php b/modules/Potentials/models/Module.php index 1e7782f48..9ea4f242b 100644 --- a/modules/Potentials/models/Module.php +++ b/modules/Potentials/models/Module.php @@ -278,6 +278,14 @@ class Potentials_Module_Model extends Vtiger_Module_Model { $nonAdminQuery = $this->getNonAdminAccessControlQueryForRelation($relatedModuleName); if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if(trim($nonAdminQuery)) { + $relModuleFocus = CRMEntity::getInstance($relatedModuleName); + $condition = $relModuleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } } else { $query = parent::getRelationQuery($recordId, $functionName, $relatedModule, $relationId); diff --git a/modules/PriceBooks/models/Relation.php b/modules/PriceBooks/models/Relation.php index a265a1c5c..793b76b0f 100644 --- a/modules/PriceBooks/models/Relation.php +++ b/modules/PriceBooks/models/Relation.php @@ -48,6 +48,20 @@ class PriceBooks_Relation_Model extends Vtiger_Relation_Model{ if(!empty($selectColumnSql)) { $query = $selectColumnSql.' FROM '.$newQuery[1]; } + + if($relatedModuleName == 'Calendar') { + $nonAdminQuery = Users_Privileges_Model::getNonAdminAccessControlQuery($relatedModuleName); + + if (trim($nonAdminQuery)) { + $query = appendFromClauseToQuery($query, $nonAdminQuery); + + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } + } return $query; } diff --git a/modules/Products/models/RelationListView.php b/modules/Products/models/RelationListView.php index 19e7d665f..b9c320d1e 100644 --- a/modules/Products/models/RelationListView.php +++ b/modules/Products/models/RelationListView.php @@ -70,6 +70,21 @@ class Products_RelationListView_Model extends Vtiger_RelationListView_Model { } } + $nonAdminQuery = Users_Privileges_Model::getNonAdminAccessControlQuery($relatedModuleName); + if (trim($nonAdminQuery)) { + if($relatedModuleName == 'Calendar') { + $query = appendFromClauseToQuery($query, $nonAdminQuery); + + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } else { + $query = appendFromClauseToQuery($query, $nonAdminQuery); + } + } + return $query; } diff --git a/modules/Reports/ReportRun.php b/modules/Reports/ReportRun.php index 5f9c6564c..44af415b7 100644 --- a/modules/Reports/ReportRun.php +++ b/modules/Reports/ReportRun.php @@ -2828,6 +2828,25 @@ class ReportRun extends CRMEntity { } $log->info("ReportRun :: Successfully returned getReportsQuery" . $module); + + $secondarymodule = explode(":", $this->secondarymodule); + if(in_array('Calendar', $secondarymodule) || $module == 'Calendar') { + $currentUserModel = Users_Record_Model::getCurrentUserModel(); + $tabId = getTabid('Calendar'); + $task_tableName = 'vt_tmp_u'.$currentUserModel->id.'_t'.$tabId.'_task'; + $event_tableName = 'vt_tmp_u'.$currentUserModel->id.'_t'.$tabId.'_events'; + if(!$currentUserModel->isAdminUser() + && stripos($query, $event_tableName) && stripos($query, $task_tableName)) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $scope = ''; + if(in_array('Calendar', $secondarymodule)) $scope = 'Calendar'; + $condition = $moduleFocus->buildWhereClauseConditionForCalendar($scope); + if($condition) { + $query .= ' AND '.$condition; + } + } + } + return $query; } diff --git a/modules/Vtiger/models/Module.php b/modules/Vtiger/models/Module.php index f1ffd66ce..ad7ddf65b 100644 --- a/modules/Vtiger/models/Module.php +++ b/modules/Vtiger/models/Module.php @@ -1089,6 +1089,14 @@ class Vtiger_Module_Model extends Vtiger_Module { AND (vtiger_activity.status is NULL OR vtiger_activity.status NOT IN ('Completed', 'Deferred', 'Cancelled')) AND (vtiger_activity.eventstatus is NULL OR vtiger_activity.eventstatus NOT IN ('Held','Cancelled'))"; + if(!$currentUser->isAdminUser()) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } + $params = array($this->getName()); if ($recordId) { @@ -1521,6 +1529,14 @@ class Vtiger_Module_Model extends Vtiger_Module { if ($nonAdminQuery) { $query = appendFromClauseToQuery($query, $nonAdminQuery); + + if($functionName == 'get_activities' && trim($nonAdminQuery)) { + $moduleFocus = CRMEntity::getInstance('Calendar'); + $condition = $moduleFocus->buildWhereClauseConditionForCalendar(); + if($condition) { + $query .= ' AND '.$condition; + } + } } return $query; -- GitLab