Refactor permission checks across multiple files to utilize isAllowed function for better access control management. Updated hierarchy level checks in account, contracts, equipments, partners, users, and API endpoints to streamline permission validation. Enhanced download options visibility based on user permissions in various reports and management pages. Improved modal behavior and auto-installation process in software tool after payment success. Added new helper functions for building dynamic where clauses based on user hierarchy levels.

This commit is contained in:
“VeLiTi”
2026-01-28 14:32:49 +01:00
parent f7733b4113
commit 9e5f5581be
20 changed files with 360 additions and 133 deletions

BIN
assets/.DS_Store vendored

Binary file not shown.

View File

@@ -1507,101 +1507,179 @@ function ioAPIv2_FileUpload($api_call, $fileData, $additionalData = [], $token =
}
//------------------------------------------
// DEFINE WHERECLAUSE BASED ON ACCOUNTHIERARCHY ALL
// DEFINE WHERECLAUSE BASED ON ACCOUNTHIERARCHY
//------------------------------------------
function getWhereclause($table_name, $permission, $partner, $method) {
// API name converter to table
$table = [
"equipment" => "e.accounthierarchy",
"products" => "p.accounthierarchy",
"profile" => "partnerhierarchy",
"text_variables" => "tv.accounthierarchy",
"products_attributes_items" => "pat.accounthierarchy",
"products_attributes_groups" => "pag.accounthierarchy",
"pricelists" => "pls.accounthierarchy",
"pricelists_items" => "pli.accounthierarchy"
];
function getWhereclause($table_name,$permission,$partner,$method){
$table = ($table_name != '') ? $table[$table_name] : 'accounthierarchy';
$type = ($method == 'get') ? 'WHERE ' : ' AND ';
//api_name converter to table
$table =[
"equipment" => "e.accounthierarchy",
"products" => "p.accounthierarchy",
"profile" => "partnerhierarchy",
"text_variables" => "tv.accounthierarchy",
"products_attributes_items" => "pat.accounthierarchy",
"products_attributes_groups" => "pag.accounthierarchy",
"pricelists" => "pls.accounthierarchy",
"pricelists_items" => "pli.accounthierarchy"
];
// If permission is 4, grant full access (admin+)
if ($permission == '4' || $permission === 4) {
return array('', '');
}
$table = ($table_name != '') ? $table[$table_name] : 'accounthierarchy';
$type = ($method == 'get') ? 'WHERE ' : ' AND ';
//SoldTo is empty
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
// Determine hierarchy level based on which fields are filled
$hierarchy_level = getHierarchyLevel($partner);
// Build condition based on hierarchy level
$condition = buildHierarchyCondition($partner, $hierarchy_level);
// Build whereclause
$whereclause = ($condition != '') ? $type . $table . ' LIKE "' . $condition . '"' : '';
//default whereclause
$whereclause = '';
switch ($permission) {
case '4':
$whereclause = '';
$condition = '';
break;
case '3':
$condition = '__salesid___'.$partner->salesid.'___soldto___%';
$whereclause = $type.$table.' like "'.$condition.'"';
break;
case '2':
$condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search;
$whereclause = $type.$table.' like "'.$condition.'"';
break;
default:
$condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search.'___shipto___'.substr($partner->shipto, 0, strpos($partner->shipto, "-")).'%___location___'.substr($partner->location, 0, strpos($partner->location, "-")).'%';
$whereclause = $type.$table.' like "'.$condition.'"';
break;
}
return array($whereclause,$condition);
return array($whereclause, $condition);
}
//------------------------------------------
// DEFINE WHERECLAUSE BASED ON ACCOUNTHIERARCHY SALES AND SOLD
//------------------------------------------
function getWhereclauselvl2($table_name,$permission,$partner,$method){
function getWhereclauselvl2($table_name, $permission, $partner, $method) {
// API name converter to table
$table = [
"pricelist" => "pls.accounthierarchy",
"communications" => "salesID",
"partners" => "salesID",
"discounts" => "d.accounthierarchy",
"invoice" => "inv.accounthierarchy",
"attributes" => "pat.accounthierarchy",
"config" => "pc.accounthierarchy",
"software" => "p.accounthierarchy",
"transactions" => "tx.accounthierarchy",
"dealers" => "d.accounthierarchy",
"categories" => "c.accounthierarchy",
"products_software_licenses" => "l.accounthierarchy"
];
//api_name converter to table
$table =[
"pricelist" => "pls.accounthierarchy",
"communications" => "salesID",
"partners" => "salesID",
"discounts" => "d.accounthierarchy",
"invoice" => "inv.accounthierarchy",
"attributes" => "pat.accounthierarchy",
"config" => "pc.accounthierarchy",
"software" => "p.accounthierarchy",
"transactions" => "tx.accounthierarchy",
"dealers" => "d.accounthierarchy",
"categories" => "c.accounthierarchy",
"products_software_licenses" => "l.accounthierarchy"
];
$table = ($table_name != '') ? $table[$table_name] : 'accounthierarchy';
$type = ($method == 'get') ? 'WHERE ' : ' AND ';
$table = ($table_name != '') ? $table[$table_name] : 'accounthierarchy';
$type = ($method == 'get') ? 'WHERE ' : ' AND ';
//SoldTo is empty
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
// If permission is 4, grant full access (admin+)
if ($permission == '4' || $permission === 4) {
return array('', '');
}
//default whereclause
$whereclause = '';
// Determine hierarchy level (lvl2 only uses salesid and soldto)
$hierarchy_level = getHierarchyLevelLvl2($partner);
// Build condition based on hierarchy level
$condition = buildHierarchyConditionLvl2($partner, $hierarchy_level);
// Build whereclause
$whereclause = ($condition != '') ? $type . $table . ' LIKE "' . $condition . '"' : '';
switch ($permission) {
case '4':
$whereclause = '';
$condition = '';
break;
case '3':
$condition = '__salesid___'.$partner->salesid.'___soldto___%';
$whereclause = $type.$table.' like "'.$condition.'" ';
break;
default:
$condition = '__salesid___'.$partner->salesid.'___soldto___'.substr($partner->soldto, 0, strpos($partner->soldto, "-")).$soldto_search;
$whereclause = $type.$table.' like "'.$condition.'"';
break;
}
return array($whereclause,$condition);
return array($whereclause, $condition);
}
// Helper function to determine hierarchy level for full hierarchy (4 levels)
function getHierarchyLevel($partner) {
// Level 4: All fields filled (salesid, soldto, shipto, location)
if (!empty($partner->salesid) && !empty($partner->soldto) &&
!empty($partner->shipto) && !empty($partner->location)) {
return 4;
}
// Level 3: salesid, soldto, shipto filled (location empty)
if (!empty($partner->salesid) && !empty($partner->soldto) &&
!empty($partner->shipto) && empty($partner->location)) {
return 3;
}
// Level 2: salesid, soldto filled (shipto and location empty)
if (!empty($partner->salesid) && !empty($partner->soldto) &&
empty($partner->shipto) && empty($partner->location)) {
return 2;
}
// Level 1: Only salesid filled
if (!empty($partner->salesid) && empty($partner->soldto)) {
return 1;
}
// Level 0: No restrictions (all access)
return 0;
}
// Helper function to determine hierarchy level for lvl2 (2 levels only)
function getHierarchyLevelLvl2($partner) {
// Level 2: salesid and soldto filled
if (!empty($partner->salesid) && !empty($partner->soldto)) {
return 2;
}
// Level 1: Only salesid filled
if (!empty($partner->salesid) && empty($partner->soldto)) {
return 1;
}
// Level 0: No restrictions (all access)
return 0;
}
// Helper function to build condition string for full hierarchy
function buildHierarchyCondition($partner, $level) {
$condition = '';
switch ($level) {
case 4: // Exact match on all 4 levels
$condition = '__salesid___' . $partner->salesid .
'___soldto___' . substr($partner->soldto, 0, strpos($partner->soldto, "-")) . '-' .
substr($partner->soldto, strpos($partner->soldto, "-") + 1) .
'___shipto___' . substr($partner->shipto, 0, strpos($partner->shipto, "-")) . '-' .
substr($partner->shipto, strpos($partner->shipto, "-") + 1) .
'___location___' . substr($partner->location, 0, strpos($partner->location, "-")) . '-' .
substr($partner->location, strpos($partner->location, "-") + 1) . '%';
break;
case 3: // Match salesid, soldto, shipto - all locations under this shipto
$condition = '__salesid___' . $partner->salesid .
'___soldto___' . substr($partner->soldto, 0, strpos($partner->soldto, "-")) . '-' .
substr($partner->soldto, strpos($partner->soldto, "-") + 1) .
'___shipto___' . substr($partner->shipto, 0, strpos($partner->shipto, "-")) . '-%';
break;
case 2: // Match salesid, soldto - all shiptos and locations under this soldto
$condition = '__salesid___' . $partner->salesid .
'___soldto___' . substr($partner->soldto, 0, strpos($partner->soldto, "-")) . '-%';
break;
case 1: // Match salesid only - all soldtos, shiptos, and locations under this salesid
$condition = '__salesid___' . $partner->salesid . '___soldto___%';
break;
case 0: // No restrictions
$condition = '';
break;
}
return $condition;
}
// Helper function to build condition string for lvl2
function buildHierarchyConditionLvl2($partner, $level) {
$condition = '';
switch ($level) {
case 2: // Match salesid and soldto
$condition = '__salesid___' . $partner->salesid .
'___soldto___' . substr($partner->soldto, 0, strpos($partner->soldto, "-")) . '-%';
break;
case 1: // Match salesid only
$condition = '__salesid___' . $partner->salesid . '___soldto___%';
break;
case 0: // No restrictions
$condition = '';
break;
}
return $condition;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//get user profile||$profile=settings, $permision = userright()
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -1648,6 +1726,7 @@ function getProfile($profile, $permission){
$always_allowed = [
'com_log' => 'CRU',
'application' => 'CRU',
'user_role_assignments' => 'R',
'user_permissions' => 'R',
'software_update' => 'R',
'software_download' => 'R',
@@ -1662,10 +1741,19 @@ function getProfile($profile, $permission){
return 1;
}
// 2. Check always_allowed list
if (isset($always_allowed[$access_element]) && str_contains($always_allowed[$access_element], $action)) {
return 1;
// 2. Check always_allowed list (supports multi-action like 'RU')
if (isset($always_allowed[$access_element])) {
$actions = str_split($action);
$all_in_allowed = true;
foreach ($actions as $single_action) {
if (!str_contains($always_allowed[$access_element], $single_action)) {
$all_in_allowed = false;
break;
}
}
if ($all_in_allowed) {
return 1;
}
}
// 3. Check RBAC permissions array (from getUserPermissions())
@@ -1680,10 +1768,20 @@ function getProfile($profile, $permission){
'D' => 'can_delete'
];
$permission_key = $action_map[$action] ?? null;
// Check each action in the string (supports 'R', 'RU', 'CRUD', etc.)
$actions = str_split($action);
$all_allowed = true;
if ($permission_key && isset($element_permissions[$permission_key]) && $element_permissions[$permission_key] == 1) {
foreach ($actions as $single_action) {
$permission_key = $action_map[$single_action] ?? null;
if (!$permission_key || !isset($element_permissions[$permission_key]) || $element_permissions[$permission_key] != 1) {
$all_allowed = false;
break;
}
}
if ($all_allowed) {
return 1;
}