Add user role management functionality with CRUD operations and permissions handling

- Created user_role.php for viewing and editing user roles and their permissions.
- Implemented inline editing for role details and permissions.
- Added user_role_manage.php for creating and managing user roles.
- Introduced user_roles.php for listing all user roles with pagination and filtering options.
- Integrated API calls for fetching and updating role data and permissions.
- Enhanced user interface with success messages and navigation controls.
This commit is contained in:
“VeLiTi”
2026-01-19 11:16:54 +01:00
parent 3db13b9ebf
commit 782050c3ca
35 changed files with 4071 additions and 370 deletions

BIN
api/.DS_Store vendored

Binary file not shown.

BIN
api/v1/.DS_Store vendored

Binary file not shown.

BIN
api/v2/.DS_Store vendored

Binary file not shown.

View File

@@ -0,0 +1,158 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// Access Elements
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//------------------------------------------
//NEW ARRAY
//------------------------------------------
$criterias = [];
$clause = '';
//------------------------------------------
//Check for $_GET variables and build up clause
//------------------------------------------
if(isset($get_content) && $get_content!=''){
//GET VARIABLES FROM URL
$requests = explode("&", $get_content);
//Check for keys and values
foreach ($requests as $y){
$v = explode("=", $y);
//INCLUDE VARIABLES IN ARRAY
$criterias[$v[0]] = $v[1];
if ($v[0] == 'page' || $v[0] =='p' || $v[0] =='totals' || $v[0] =='success_msg' || $v[0] =='sort' || $v[0] =='all'){
//do nothing
}
elseif ($v[0] == 'rowid') {
//build up search by ID
$clause .= ' AND a.rowID = :'.$v[0];
}
elseif ($v[0] == 'status') {
//Update status based on status
$clause .= ' AND a.is_active = :'.$v[0];
}
elseif ($v[0] == 'search') {
//build up search
$clause .= ' AND (a.access_name LIKE :'.$v[0].' OR a.access_path LIKE :'.$v[0].' OR a.description LIKE :'.$v[0].')';
}
elseif ($v[0] == 'access_path') {
//build up path search
$clause .= ' AND a.access_path = :'.$v[0];
}
else {
//create clause
$clause .= ' AND a.'.$v[0].' = :'.$v[0];
}
}
}
//Build WHERE clause
$whereclause = '';
if ($clause != ''){
$whereclause = 'WHERE '.substr($clause, 4);
}
// GET SORT INDICATOR
$sort_indicator = $criterias['sort'] ?? '';
switch ($sort_indicator){
case 1:
$sort = ' a.access_name ASC ';
break;
case 2:
$sort = ' a.access_name DESC ';
break;
case 3:
$sort = ' a.access_path ASC ';
break;
case 4:
$sort = ' a.access_path DESC ';
break;
default:
$sort = ' a.access_name ASC ';
break;
}
if (isset($criterias['totals']) && $criterias['totals'] ==''){
//Request for total rows
$sql = 'SELECT count(*) as count FROM access_elements a '.$whereclause;
}
elseif (isset($criterias['all']) && $criterias['all'] ==''){
//Return all records (no paging)
$sql = 'SELECT a.* FROM access_elements a '.$whereclause.' ORDER BY '.$sort;
}
else {
//SQL
$sql = 'SELECT a.* FROM access_elements a '.$whereclause.' ORDER BY '.$sort.' LIMIT :page,:num_rows';
}
$stmt = $pdo->prepare($sql);
//------------------------------------------
//Bind to query
//------------------------------------------
if (!empty($criterias)){
foreach ($criterias as $key => $value){
$key_condition = ':'.$key;
if (str_contains($sql, $key_condition)){
if ($key == 'search'){
$search_value = '%'.$value.'%';
$stmt->bindValue($key, $search_value, PDO::PARAM_STR);
}
elseif ($key == 'p'){
//Do nothing (bug)
}
else {
$stmt->bindValue($key, $value, PDO::PARAM_STR);
}
}
}
}
//------------------------------------------
// Debuglog
//------------------------------------------
if (debug){
$message = $date.';'.$sql.';'.$username;
debuglog($message);
}
//------------------------------------------
//Add paging details
//------------------------------------------
$page_rows = $page_rows_equipment ?? 20;
if(isset($criterias['totals']) && $criterias['totals']==''){
$stmt->execute();
$messages = $stmt->fetch();
$messages = $messages[0];
}
elseif(isset($criterias['all']) && $criterias['all']==''){
//Return all records (no paging)
$stmt->execute();
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
else {
$current_page = isset($criterias['p']) && is_numeric($criterias['p']) ? (int)$criterias['p'] : 1;
$stmt->bindValue('page', ($current_page - 1) * $page_rows, PDO::PARAM_INT);
$stmt->bindValue('num_rows', $page_rows, PDO::PARAM_INT);
//Execute Query
$stmt->execute();
//Get results
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
//------------------------------------------
//JSON_EnCODE
//------------------------------------------
$messages = json_encode($messages, JSON_UNESCAPED_UNICODE);
//------------------------------------------
//Send results
//------------------------------------------
echo $messages;
?>

View File

@@ -12,7 +12,7 @@ $pdo = dbConnect($dbname);
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
//default whereclause
list($whereclause,$condition) = getWhereclauselvl2("software_upgrade_paths",$permission,$partner,'get');
list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,'get');
//NEW ARRAY
$criterias = [];

View File

@@ -12,7 +12,7 @@ $pdo = dbConnect($dbname);
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
//default whereclause
list($whereclause,$condition) = getWhereclauselvl2("software_versions",$permission,$partner,'get');
list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,'get');
//NEW ARRAY
$criterias = [];

View File

@@ -0,0 +1,152 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// Report Builder - GET Endpoints
//------------------------------------------
// Set content type to JSON
header('Content-Type: application/json');
// Connect to DB
$pdo = dbConnect($dbname);
// Get the action parameter from URL
$criterias = [];
if (isset($get_content) && $get_content != '') {
$requests = explode("&", $get_content);
foreach ($requests as $y) {
$v = explode("=", $y);
if (isset($v[1])) {
$criterias[$v[0]] = urldecode($v[1]);
} else {
$criterias[$v[0]] = '';
}
}
}
$action = strtolower($criterias['action'] ?? '');
/**
* Validate table name - only allow alphanumeric, underscores, hyphens
*/
function sanitizeTableName($table) {
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $table)) {
return false;
}
return $table;
}
/**
* Get list of tables
*/
if ($action === 'gettables') {
try {
$result = $pdo->query("SHOW TABLES");
$tables = [];
while ($row = $result->fetch(PDO::FETCH_NUM)) {
$tables[] = $row[0];
}
$messages = json_encode([
'success' => true,
'tables' => $tables
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
http_response_code(500);
$messages = json_encode([
'success' => false,
'message' => 'Failed to fetch tables'
], JSON_UNESCAPED_UNICODE);
}
}
/**
* Get columns for a specific table
*/
elseif ($action === 'getcolumns') {
$table = sanitizeTableName($criterias['table'] ?? '');
if (!$table) {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Invalid table name'
], JSON_UNESCAPED_UNICODE);
} else {
try {
$result = $pdo->query("SHOW COLUMNS FROM `$table`");
$columns = [];
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$columns[] = $row['Field'];
}
$messages = json_encode([
'success' => true,
'columns' => $columns
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
http_response_code(500);
$messages = json_encode([
'success' => false,
'message' => 'Failed to fetch columns'
], JSON_UNESCAPED_UNICODE);
}
}
}
/**
* Get table schema information
*/
elseif ($action === 'gettableschema') {
$table = sanitizeTableName($criterias['table'] ?? '');
if (!$table) {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Invalid table name'
], JSON_UNESCAPED_UNICODE);
} else {
try {
$result = $pdo->query("DESCRIBE `$table`");
$schema = [];
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$schema[] = [
'field' => $row['Field'],
'type' => $row['Type'],
'null' => $row['Null'],
'key' => $row['Key'],
'default' => $row['Default'],
'extra' => $row['Extra']
];
}
$messages = json_encode([
'success' => true,
'schema' => $schema
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
http_response_code(500);
$messages = json_encode([
'success' => false,
'message' => 'Failed to fetch table schema'
], JSON_UNESCAPED_UNICODE);
}
}
}
/**
* Invalid or missing action
*/
else {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Invalid or missing action parameter'
], JSON_UNESCAPED_UNICODE);
}
// Send results
echo $messages;
?>

View File

@@ -0,0 +1,123 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// Role Access Permissions
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//------------------------------------------
//NEW ARRAY
//------------------------------------------
$criterias = [];
$clause = '';
//------------------------------------------
//Check for $_GET variables and build up clause
//------------------------------------------
if(isset($get_content) && $get_content!=''){
//GET VARIABLES FROM URL
$requests = explode("&", $get_content);
//Check for keys and values
foreach ($requests as $y){
$v = explode("=", $y);
//INCLUDE VARIABLES IN ARRAY
$criterias[$v[0]] = $v[1];
if ($v[0] == 'page' || $v[0] =='p' || $v[0] =='totals' || $v[0] =='success_msg'){
//do nothing
}
elseif ($v[0] == 'rowid') {
//build up search by ID
$clause .= ' AND rap.rowID = :'.$v[0];
}
elseif ($v[0] == 'role_id') {
//build up search by role_id
$clause .= ' AND rap.role_id = :'.$v[0];
}
elseif ($v[0] == 'access_id') {
//build up search by access_id
$clause .= ' AND rap.access_id = :'.$v[0];
}
else {
//create clause
$clause .= ' AND rap.'.$v[0].' = :'.$v[0];
}
}
}
//Build WHERE clause
$whereclause = '';
if ($clause != ''){
$whereclause = 'WHERE '.substr($clause, 4);
}
if (isset($criterias['totals']) && $criterias['totals'] ==''){
//Request for total rows
$sql = 'SELECT count(*) as count FROM role_access_permissions rap '.$whereclause;
}
else {
//SQL with joined tables for names
$sql = 'SELECT rap.*,
r.name as role_name,
ae.access_name,
ae.access_path
FROM role_access_permissions rap
LEFT JOIN user_roles r ON rap.role_id = r.rowID
LEFT JOIN access_elements ae ON rap.access_id = ae.rowID
'.$whereclause.'
ORDER BY ae.access_name ASC';
}
$stmt = $pdo->prepare($sql);
//------------------------------------------
//Bind to query
//------------------------------------------
if (!empty($criterias)){
foreach ($criterias as $key => $value){
$key_condition = ':'.$key;
if (str_contains($sql, $key_condition)){
if ($key == 'p'){
//Do nothing (bug)
}
else {
$stmt->bindValue($key, $value, PDO::PARAM_STR);
}
}
}
}
//------------------------------------------
// Debuglog
//------------------------------------------
if (debug){
$message = $date.';'.$sql.';'.$username;
debuglog($message);
}
//------------------------------------------
//Execute Query
//------------------------------------------
if(isset($criterias['totals']) && $criterias['totals']==''){
$stmt->execute();
$messages = $stmt->fetch();
$messages = $messages[0];
}
else {
//Execute Query
$stmt->execute();
//Get results
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
//------------------------------------------
//JSON_EnCODE
//------------------------------------------
$messages = json_encode($messages, JSON_UNESCAPED_UNICODE);
//------------------------------------------
//Send results
//------------------------------------------
echo $messages;
?>

View File

@@ -55,17 +55,20 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){
}
//GET EQUIPMENT AND PRODUCT DATA BASED ON SERIAL NUMBER
$sql = 'SELECT
$sql = "SELECT
p.rowID as product_rowid,
p.productcode,
e.sw_version as current_sw_version,
e.hw_version,
e.sw_version_license,
e.sw_version_upgrade,
e.rowID as equipment_rowid
e.rowID as equipment_rowid,
partner.*
FROM equipment e
JOIN products p ON e.productrowid = p.rowID
WHERE e.serialnumber = ?';
LEFT JOIN partner ON partner.partnerID = SUBSTRING_INDEX(JSON_UNQUOTE(JSON_EXTRACT(e.accounthierarchy, '$.soldto')), '-', 1)
AND partner.is_dealer = 1 AND partner.status = 1
WHERE e.serialnumber = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$criterias['sn']]);
$equipment_data = $stmt->fetch(PDO::FETCH_ASSOC);
@@ -81,6 +84,17 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){
$sw_version_upgrade = $equipment_data['sw_version_upgrade'];
$equipment_rowid = $equipment_data['equipment_rowid'];
$dealer_info = [
'is_dealer' => $equipment_data['is_dealer'] ?? 0,
'name' => $equipment_data['name'] ?? '',
'address' => $equipment_data['address'] ?? '',
'city' => $equipment_data['city'] ?? '',
'postalcode' => $equipment_data['postalcode'] ?? '',
'country' => $equipment_data['country'] ?? '',
'email' => $equipment_data['email'] ?? '',
'phone' => $equipment_data['phone'] ?? ''
];
if (debug) {
$debug['equipment_data'] = [
'product_rowid' => $product_rowid,
@@ -402,7 +416,7 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){
}
}
$output[] = [
$entry = [
"productcode" => $productcode,
"name" => $version['name'] ?? '',
"version" => $version['version'],
@@ -416,8 +430,11 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){
"source_type" => '',
"price" => $final_price,
"currency" => $final_currency,
"is_current" => $is_current
"is_current" => $is_current,
"dealer_info" => $dealer_info
];
$output[] = $entry;
}
if (debug) {

View File

@@ -0,0 +1,128 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// User Role Assignments
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//------------------------------------------
//NEW ARRAY
//------------------------------------------
$criterias = [];
$clause = '';
//------------------------------------------
//Check for $_GET variables and build up clause
//------------------------------------------
if(isset($get_content) && $get_content!=''){
//GET VARIABLES FROM URL
$requests = explode("&", $get_content);
//Check for keys and values
foreach ($requests as $y){
$v = explode("=", $y);
//INCLUDE VARIABLES IN ARRAY
$criterias[$v[0]] = $v[1];
if ($v[0] == 'page' || $v[0] =='p' || $v[0] =='totals' || $v[0] =='success_msg'){
//do nothing
}
elseif ($v[0] == 'rowid') {
//build up search by ID
$clause .= ' AND ura.rowID = :'.$v[0];
}
elseif ($v[0] == 'role_id') {
//build up search by role_id
$clause .= ' AND ura.role_id = :'.$v[0];
}
elseif ($v[0] == 'user_id') {
//build up search by user_id
$clause .= ' AND ura.user_id = :'.$v[0];
}
elseif ($v[0] == 'status') {
//Update status based on status
$clause .= ' AND ura.is_active = :'.$v[0];
}
else {
//create clause
$clause .= ' AND ura.'.$v[0].' = :'.$v[0];
}
}
}
//Build WHERE clause
$whereclause = '';
if ($clause != ''){
$whereclause = 'WHERE '.substr($clause, 4);
}
if (isset($criterias['totals']) && $criterias['totals'] ==''){
//Request for total rows
$sql = 'SELECT count(*) as count FROM user_role_assignments ura '.$whereclause;
}
else {
//SQL with joined tables for names
$sql = 'SELECT ura.*,
u.username,
u.email,
r.name as role_name,
r.description as role_description
FROM user_role_assignments ura
LEFT JOIN users u ON ura.user_id = u.id
LEFT JOIN user_roles r ON ura.role_id = r.rowID
'.$whereclause.'
ORDER BY u.username ASC';
}
$stmt = $pdo->prepare($sql);
//------------------------------------------
//Bind to query
//------------------------------------------
if (!empty($criterias)){
foreach ($criterias as $key => $value){
$key_condition = ':'.$key;
if (str_contains($sql, $key_condition)){
if ($key == 'p'){
//Do nothing (bug)
}
else {
$stmt->bindValue($key, $value, PDO::PARAM_STR);
}
}
}
}
//------------------------------------------
// Debuglog
//------------------------------------------
if (debug){
$message = $date.';'.$sql.';'.$username;
debuglog($message);
}
//------------------------------------------
//Execute Query
//------------------------------------------
if(isset($criterias['totals']) && $criterias['totals']==''){
$stmt->execute();
$messages = $stmt->fetch();
$messages = $messages[0];
}
else {
//Execute Query
$stmt->execute();
//Get results
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
//------------------------------------------
//JSON_EnCODE
//------------------------------------------
$messages = json_encode($messages, JSON_UNESCAPED_UNICODE);
//------------------------------------------
//Send results
//------------------------------------------
echo $messages;
?>

151
api/v2/get/user_roles.php Normal file
View File

@@ -0,0 +1,151 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// User Roles
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//------------------------------------------
//NEW ARRAY
//------------------------------------------
$criterias = [];
$clause = '';
//------------------------------------------
//Check for $_GET variables and build up clause
//------------------------------------------
if(isset($get_content) && $get_content!=''){
//GET VARIABLES FROM URL
$requests = explode("&", $get_content);
//Check for keys and values
foreach ($requests as $y){
$v = explode("=", $y);
//INCLUDE VARIABLES IN ARRAY
$criterias[$v[0]] = $v[1];
if ($v[0] == 'page' || $v[0] =='p' || $v[0] =='totals' || $v[0] =='success_msg' || $v[0] =='sort'){
//do nothing
}
elseif ($v[0] == 'rowid') {
//build up search by ID
$clause .= ' AND r.rowID = :'.$v[0];
}
elseif ($v[0] == 'status') {
//Update status based on status
$clause .= ' AND r.is_active = :'.$v[0];
}
elseif ($v[0] == 'search') {
//build up search
$clause .= ' AND (r.name LIKE :'.$v[0].' OR r.description LIKE :'.$v[0].')';
}
elseif ($v[0] == 'name') {
//build up name search
$clause .= ' AND r.name = :'.$v[0];
}
else {
//create clause
$clause .= ' AND r.'.$v[0].' = :'.$v[0];
}
}
}
//Build WHERE clause
$whereclause = '';
if ($clause != ''){
$whereclause = 'WHERE '.substr($clause, 4);
}
// GET SORT INDICATOR
$sort_indicator = $criterias['sort'] ?? '';
switch ($sort_indicator){
case 1:
$sort = ' r.name ASC ';
break;
case 2:
$sort = ' r.name DESC ';
break;
case 3:
$sort = ' r.created ASC ';
break;
case 4:
$sort = ' r.created DESC ';
break;
default:
$sort = ' r.rowID ';
break;
}
if (isset($criterias['totals']) && $criterias['totals'] ==''){
//Request for total rows
$sql = 'SELECT count(*) as count FROM user_roles r '.$whereclause;
}
else {
//SQL with permission count
$sql = 'SELECT r.*,
(SELECT COUNT(*) FROM role_access_permissions WHERE role_id = r.rowID) as permission_count
FROM user_roles r '.$whereclause.' ORDER BY '.$sort.' LIMIT :page,:num_rows';
}
$stmt = $pdo->prepare($sql);
//------------------------------------------
//Bind to query
//------------------------------------------
if (!empty($criterias)){
foreach ($criterias as $key => $value){
$key_condition = ':'.$key;
if (str_contains($sql, $key_condition)){
if ($key == 'search'){
$search_value = '%'.$value.'%';
$stmt->bindValue($key, $search_value, PDO::PARAM_STR);
}
elseif ($key == 'p'){
//Do nothing (bug)
}
else {
$stmt->bindValue($key, $value, PDO::PARAM_STR);
}
}
}
}
//------------------------------------------
// Debuglog
//------------------------------------------
if (debug){
$message = $date.';'.$sql.';'.$username;
debuglog($message);
}
//------------------------------------------
//Add paging details
//------------------------------------------
$page_rows = $page_rows_equipment ?? 20;
if(isset($criterias['totals']) && $criterias['totals']==''){
$stmt->execute();
$messages = $stmt->fetch();
$messages = $messages[0];
}
else {
$current_page = isset($criterias['p']) && is_numeric($criterias['p']) ? (int)$criterias['p'] : 1;
$stmt->bindValue('page', ($current_page - 1) * $page_rows, PDO::PARAM_INT);
$stmt->bindValue('num_rows', $page_rows, PDO::PARAM_INT);
//Execute Query
$stmt->execute();
//Get results
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
//------------------------------------------
//JSON_EnCODE
//------------------------------------------
$messages = json_encode($messages, JSON_UNESCAPED_UNICODE);
//------------------------------------------
//Send results
//------------------------------------------
echo $messages;
?>

View File

@@ -0,0 +1,79 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// Access Elements
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//CONTENT FROM API (POST)
$post_content = json_decode($input,true);
//SET PARAMETERS FOR QUERY
$id = $post_content['rowID'] ?? '';
$command = ($id == '')? 'insert' : 'update';
if (isset($post_content['delete'])){$command = 'delete';}
$date = date('Y-m-d H:i:s');
//CREATE EMPTY STRINGS
$clause = '';
$clause_insert ='';
$input_insert = '';
$execute_input = [];
$criterias = [];
//ADD STANDARD PARAMETERS TO ARRAY BASED ON INSERT OR UPDATE
if ($command == 'update'){
$post_content['updatedby'] = $username;;
$post_content['updated'] = $date;
}
elseif ($command == 'insert'){
$post_content['created'] = $date;
$post_content['createdby'] = $username;;
}
//CREAT NEW ARRAY AND MAP TO CLAUSE
if(isset($post_content) && $post_content!=''){
foreach ($post_content as $key => $var){
if ($key == 'submit' || $key == 'rowID' || str_contains($key, 'old_')){
//do nothing
}
else {
$criterias[$key] = $var;
$clause .= ' , '.$key.' = ?';
$clause_insert .= ' , '.$key.'';
$input_insert .= ', ?';
$execute_input[]= $var;
}
}
}
//CLEAN UP INPUT
$clause = substr($clause, 2);
$clause_insert = substr($clause_insert, 2);
$input_insert = substr($input_insert, 1);
//QUERY AND VERIFY ALLOWED
if ($command == 'update' && isAllowed('access_element_manage',$profile,$permission,'U') === 1){
$sql = 'UPDATE access_elements SET '.$clause.' WHERE rowID = ?';
$execute_input[] = $id;
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
}
elseif ($command == 'insert' && isAllowed('access_element_manage',$profile,$permission,'C') === 1){
$sql = 'INSERT INTO access_elements ('.$clause_insert.') VALUES ('.$input_insert.')';
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
}
elseif ($command == 'delete' && isAllowed('access_element_manage',$profile,$permission,'D') === 1){
//Delete role permissions using this access element first (foreign key constraint)
$stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE access_id = ?');
$stmt->execute([$id]);
//Delete access element
$stmt = $pdo->prepare('DELETE FROM access_elements WHERE rowID = ?');
$stmt->execute([$id]);
}
?>

View File

@@ -0,0 +1,124 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// Report Builder - POST Endpoints
//------------------------------------------
// Set content type to JSON
header('Content-Type: application/json');
// Connect to DB
$pdo = dbConnect($dbname);
// Parse input data
$data = json_decode($input, true);
$action = strtolower($data['action'] ?? '');
/**
* Security check: Only allow SELECT queries
*/
function isSelectQuery($query) {
$query = trim($query);
$query = preg_replace('/\s+/', ' ', $query); // Normalize whitespace
// Only allow SELECT queries
if (!preg_match('/^SELECT\s/i', $query)) {
return false;
}
// Block dangerous keywords that could be used for injection
$dangerousPatterns = [
'/;\s*DROP\s/i',
'/;\s*DELETE\s/i',
'/;\s*UPDATE\s/i',
'/;\s*INSERT\s/i',
'/;\s*CREATE\s/i',
'/;\s*ALTER\s/i',
'/;\s*TRUNCATE\s/i',
'/INTO\s+OUTFILE\s/i',
'/LOAD_FILE\s*\(/i',
'/SLEEP\s*\(/i',
'/BENCHMARK\s*\(/i',
];
foreach ($dangerousPatterns as $pattern) {
if (preg_match($pattern, $query)) {
return false;
}
}
return true;
}
/**
* Execute a SELECT query
*/
if ($action === 'executequery') {
$query = $data['query'] ?? '';
if (empty($query)) {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Query parameter is required'
], JSON_UNESCAPED_UNICODE);
}
// Security check: only allow SELECT queries
elseif (!isSelectQuery($query)) {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Only SELECT queries are allowed'
], JSON_UNESCAPED_UNICODE);
} else {
try {
// Execute the query
$stmt = $pdo->query($query);
// Fetch all results
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Get row count
$rowCount = count($results);
// Limit results to prevent memory issues
$maxResults = 5000;
if ($rowCount > $maxResults) {
$results = array_slice($results, 0, $maxResults);
$message = "Query executed successfully. Showing first $maxResults of $rowCount rows.";
} else {
$message = "Query executed successfully. $rowCount rows returned.";
}
$messages = json_encode([
'success' => true,
'results' => $results,
'rowCount' => $rowCount,
'message' => $message
], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Query execution failed: ' . $e->getMessage()
], JSON_UNESCAPED_UNICODE);
}
}
}
/**
* Invalid or missing action
*/
else {
http_response_code(400);
$messages = json_encode([
'success' => false,
'message' => 'Invalid or missing action parameter'
], JSON_UNESCAPED_UNICODE);
}
// Send results
echo $messages;
?>

View File

@@ -0,0 +1,75 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// Role Access Permissions
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//CONTENT FROM API (POST)
$post_content = json_decode($input,true);
//SET PARAMETERS FOR QUERY
$id = $post_content['rowID'] ?? '';
$command = ($id == '')? 'insert' : 'update';
if (isset($post_content['delete'])){$command = 'delete';}
$date = date('Y-m-d H:i:s');
//CREATE EMPTY STRINGS
$clause = '';
$clause_insert ='';
$input_insert = '';
$execute_input = [];
$criterias = [];
//ADD STANDARD PARAMETERS TO ARRAY BASED ON INSERT OR UPDATE
if ($command == 'update'){
$post_content['updatedby'] = $username;;
$post_content['updated'] = $date;
}
elseif ($command == 'insert'){
$post_content['created'] = $date;
$post_content['createdby'] = $username;;
}
//CREAT NEW ARRAY AND MAP TO CLAUSE
if(isset($post_content) && $post_content!=''){
foreach ($post_content as $key => $var){
if ($key == 'submit' || $key == 'rowID' || str_contains($key, 'old_')){
//do nothing
}
else {
$criterias[$key] = $var;
$clause .= ' , '.$key.' = ?';
$clause_insert .= ' , '.$key.'';
$input_insert .= ', ?';
$execute_input[]= $var;
}
}
}
//CLEAN UP INPUT
$clause = substr($clause, 2);
$clause_insert = substr($clause_insert, 2);
$input_insert = substr($input_insert, 1);
//QUERY AND VERIFY ALLOWED
if ($command == 'update' && isAllowed('user_role_manage',$profile,$permission,'U') === 1){
$sql = 'UPDATE role_access_permissions SET '.$clause.' WHERE rowID = ?';
$execute_input[] = $id;
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
}
elseif ($command == 'insert' && isAllowed('user_role_manage',$profile,$permission,'C') === 1){
$sql = 'INSERT INTO role_access_permissions ('.$clause_insert.') VALUES ('.$input_insert.')';
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
}
elseif ($command == 'delete' && isAllowed('user_role_manage',$profile,$permission,'D') === 1){
//Delete permission
$stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE rowID = ?');
$stmt->execute([$id]);
}
?>

View File

@@ -0,0 +1,141 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// User Role Assignments
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//CONTENT FROM API (POST)
$post_content = json_decode($input,true);
//SET PARAMETERS FOR QUERY
$id = $post_content['rowID'] ?? '';
$date = date('Y-m-d H:i:s');
//------------------------------------------
// BATCH UPDATE - Update all roles for a user
//------------------------------------------
if (isset($post_content['batch_update']) && isset($post_content['user_id']) && isAllowed('user_manage',$profile,$permission,'U') === 1){
$user_id = $post_content['user_id'];
$selected_roles = $post_content['roles'] ?? [];
//Get currently assigned active roles
$stmt = $pdo->prepare('SELECT role_id, rowID FROM user_role_assignments WHERE user_id = ? AND is_active = 1');
$stmt->execute([$user_id]);
$current_roles = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$current_roles[$row['role_id']] = $row['rowID'];
}
//Remove roles that are no longer selected (soft delete)
foreach ($current_roles as $role_id => $assignment_id){
if (!in_array($role_id, $selected_roles)){
$stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 0, updatedby = ?, updated = ? WHERE rowID = ?');
$stmt->execute([$username, $date, $assignment_id]);
}
}
//Add new roles that are selected but not currently assigned
foreach ($selected_roles as $role_id){
if (!array_key_exists($role_id, $current_roles)){
//Check if this user-role combination existed before (inactive)
$stmt = $pdo->prepare('SELECT rowID FROM user_role_assignments WHERE user_id = ? AND role_id = ? AND is_active = 0 LIMIT 1');
$stmt->execute([$user_id, $role_id]);
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
if ($existing){
//Reactivate existing assignment
$stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 1, assigned_by = ?, assigned_at = ?, updatedby = ?, updated = ? WHERE rowID = ?');
$stmt->execute([$username, $date, $username, $date, $existing['rowID']]);
} else {
//Create new assignment
$stmt = $pdo->prepare('INSERT INTO user_role_assignments (user_id, role_id, is_active, assigned_by, assigned_at, created, createdby) VALUES (?, ?, 1, ?, ?, ?, ?)');
$stmt->execute([$user_id, $role_id, $username, $date, $date, $userkey]);
}
}
}
}
//------------------------------------------
// SINGLE OPERATIONS (for backward compatibility or direct API calls)
//------------------------------------------
else {
$command = ($id == '')? 'insert' : 'update';
if (isset($post_content['delete'])){$command = 'delete';}
//CREATE EMPTY STRINGS
$clause = '';
$clause_insert ='';
$input_insert = '';
$execute_input = [];
$criterias = [];
//ADD STANDARD PARAMETERS TO ARRAY BASED ON INSERT OR UPDATE
if ($command == 'update'){
$post_content['updatedby'] = $username;
$post_content['updated'] = $date;
}
elseif ($command == 'insert'){
$post_content['created'] = $date;
$post_content['createdby'] = $username;
$post_content['assigned_by'] = $username;
$post_content['assigned_at'] = $date;
}
//CREAT NEW ARRAY AND MAP TO CLAUSE
if(isset($post_content) && $post_content!=''){
foreach ($post_content as $key => $var){
if ($key == 'submit' || $key == 'rowID' || $key == 'delete' || $key == 'batch_update' || str_contains($key, 'old_')){
//do nothing
}
else {
$criterias[$key] = $var;
$clause .= ' , '.$key.' = ?';
$clause_insert .= ' , '.$key.'';
$input_insert .= ', ?';
$execute_input[]= $var;
}
}
}
//CLEAN UP INPUT
$clause = substr($clause, 2);
$clause_insert = substr($clause_insert, 2);
$input_insert = substr($input_insert, 1);
//QUERY AND VERIFY ALLOWED
if ($command == 'update' && isAllowed('user_manage',$profile,$permission,'U') === 1){
$sql = 'UPDATE user_role_assignments SET '.$clause.' WHERE rowID = ?';
$execute_input[] = $id;
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
}
elseif ($command == 'insert' && isAllowed('user_manage',$profile,$permission,'C') === 1){
//Check if this user-role combination already exists (including inactive ones)
$stmt = $pdo->prepare('SELECT rowID, is_active FROM user_role_assignments WHERE user_id = ? AND role_id = ? LIMIT 1');
$stmt->execute([$post_content['user_id'], $post_content['role_id']]);
$existing = $stmt->fetch(PDO::FETCH_ASSOC);
if ($existing){
//If exists but inactive, reactivate it
if ($existing['is_active'] == 0){
$stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 1, assigned_by = ?, assigned_at = ?, updatedby = ?, updated = ? WHERE rowID = ?');
$stmt->execute([$username, $date, $username, $date, $existing['rowID']]);
}
//If already active, do nothing (or could throw an error)
} else {
//Insert new assignment
$sql = 'INSERT INTO user_role_assignments ('.$clause_insert.') VALUES ('.$input_insert.')';
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
}
}
elseif ($command == 'delete' && isAllowed('user_manage',$profile,$permission,'D') === 1){
//Soft delete by setting is_active to 0
$stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 0, updatedby = ?, updated = ? WHERE rowID = ?');
$stmt->execute([$username, $date, $id]);
}
}
?>

123
api/v2/post/user_roles.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
defined($security_key) or exit;
//------------------------------------------
// User Roles
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//CONTENT FROM API (POST)
$post_content = json_decode($input,true);
//SET PARAMETERS FOR QUERY
$id = $post_content['rowID'] ?? '';
$command = ($id == '')? 'insert' : 'update';
if (isset($post_content['delete'])){$command = 'delete';}
$date = date('Y-m-d H:i:s');
//CREATE EMPTY STRINGS
$clause = '';
$clause_insert ='';
$input_insert = '';
$execute_input = [];
$criterias = [];
//ADD STANDARD PARAMETERS TO ARRAY BASED ON INSERT OR UPDATE
if ($command == 'update'){
$post_content['updatedby'] = $username;
$post_content['updated'] = $date;
}
elseif ($command == 'insert'){
$post_content['created'] = $date;
$post_content['createdby'] = $username;
}
//CREAT NEW ARRAY AND MAP TO CLAUSE
if(isset($post_content) && $post_content!=''){
foreach ($post_content as $key => $var){
if ($key == 'submit' || $key == 'rowID' || $key == 'permissions' || str_contains($key, 'old_')){
//do nothing
}
else {
$criterias[$key] = $var;
$clause .= ' , '.$key.' = ?';
$clause_insert .= ' , '.$key.'';
$input_insert .= ', ?';
$execute_input[]= $var;
}
}
}
//CLEAN UP INPUT
$clause = substr($clause, 2);
$clause_insert = substr($clause_insert, 2);
$input_insert = substr($input_insert, 1);
//QUERY AND VERIFY ALLOWED
if ($command == 'update' && isAllowed('user_role_manage',$profile,$permission,'U') === 1){
$sql = 'UPDATE user_roles SET '.$clause.' WHERE rowID = ?';
$execute_input[] = $id;
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
//Handle permissions update
if (isset($post_content['permissions'])){
//First delete all existing permissions for this role
$stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE role_id = ?');
$stmt->execute([$id]);
//Insert new permissions
foreach ($post_content['permissions'] as $access_id => $perms){
$can_create = isset($perms['can_create']) ? 1 : 0;
$can_read = isset($perms['can_read']) ? 1 : 0;
$can_update = isset($perms['can_update']) ? 1 : 0;
$can_delete = isset($perms['can_delete']) ? 1 : 0;
//Only insert if at least one permission is set
if ($can_create || $can_read || $can_update || $can_delete){
$stmt = $pdo->prepare('INSERT INTO role_access_permissions (role_id, access_id, can_create, can_read, can_update, can_delete, created, createdby) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
$stmt->execute([$id, $access_id, $can_create, $can_read, $can_update, $can_delete, $date, $userkey]);
}
}
}
}
elseif ($command == 'insert' && isAllowed('user_role_manage',$profile,$permission,'C') === 1){
$sql = 'INSERT INTO user_roles ('.$clause_insert.') VALUES ('.$input_insert.')';
$stmt = $pdo->prepare($sql);
$stmt->execute($execute_input);
//Get the new role ID
$new_role_id = $pdo->lastInsertId();
//Handle permissions for new role
if (isset($post_content['permissions'])){
foreach ($post_content['permissions'] as $access_id => $perms){
$can_create = isset($perms['can_create']) ? 1 : 0;
$can_read = isset($perms['can_read']) ? 1 : 0;
$can_update = isset($perms['can_update']) ? 1 : 0;
$can_delete = isset($perms['can_delete']) ? 1 : 0;
//Only insert if at least one permission is set
if ($can_create || $can_read || $can_update || $can_delete){
$stmt = $pdo->prepare('INSERT INTO role_access_permissions (role_id, access_id, can_create, can_read, can_update, can_delete, created, createdby) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
$stmt->execute([$new_role_id, $access_id, $can_create, $can_read, $can_update, $can_delete, $date, $userkey]);
}
}
}
}
elseif ($command == 'delete' && isAllowed('user_role_manage',$profile,$permission,'D') === 1){
//Delete role permissions first (foreign key constraint)
$stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE role_id = ?');
$stmt->execute([$id]);
//Delete user role assignments
$stmt = $pdo->prepare('DELETE FROM user_role_assignments WHERE role_id = ?');
$stmt->execute([$id]);
//Delete role
$stmt = $pdo->prepare('DELETE FROM user_roles WHERE rowID = ?');
$stmt->execute([$id]);
}
?>

View File

@@ -44,10 +44,11 @@ $user_name_old = $user_data['username'];
$view_old = $user_data['view'];
$partnerhierarchy_old = json_decode($user_data['partnerhierarchy']);
$salesid_new = ((isset($post_content['salesid']) && $post_content['salesid'] != '' && $post_content['salesid'] != $partnerhierarchy_old->salesid)? $post_content['salesid'] : $partnerhierarchy_old->salesid);
$soldto_new = ((isset($post_content['soldto']) && $post_content['soldto'] != '' && $post_content['soldto'] != $partnerhierarchy_old->soldto)? $post_content['soldto'] : $partnerhierarchy_old->soldto);
$shipto_new = ((isset($post_content['shipto']) && $post_content['shipto'] != '' && $post_content['shipto'] != $partnerhierarchy_old->shipto)? $post_content['shipto'] : $partnerhierarchy_old->shipto);
$location_new = ((isset($post_content['location']) && $post_content['location'] != '' && $post_content['location'] != $partnerhierarchy_old->location)? $post_content['location'] : $partnerhierarchy_old->location);
// Allow clearing values by checking if key exists (even if empty)
$salesid_new = (array_key_exists('salesid', $post_content)) ? $post_content['salesid'] : ($partnerhierarchy_old->salesid ?? '');
$soldto_new = (array_key_exists('soldto', $post_content)) ? $post_content['soldto'] : ($partnerhierarchy_old->soldto ?? '');
$shipto_new = (array_key_exists('shipto', $post_content)) ? $post_content['shipto'] : ($partnerhierarchy_old->shipto ?? '');
$location_new = (array_key_exists('location', $post_content)) ? $post_content['location'] : ($partnerhierarchy_old->location ?? '');
if ($permission == 4){
//ADMIN+ ONLY ARE ALLOWED TO CHANGE SALES AND SOLD