(info) * * @param string Field to order by (id_usuario, nombre_real or fecha_registro) * @param string Which info to get (defaults to nombre_real) * * @return array An array of users */ function users_get_info($order='fullname', $info='fullname') { $users = get_users($order); $ret = []; foreach ($users as $user_id => $user_info) { $ret[$user_id] = $user_info[$info]; } return $ret; } /** * Enable/Disable a user * * @param int user id * @param int new disabled value (0 when enable, 1 when disable) * * @return integer sucess return */ function users_disable($user_id, $new_disabled_value) { return db_process_sql_update( 'tusuario', ['disabled' => $new_disabled_value], ['id_user' => $user_id] ); } /** * Get all the Model groups a user has reading privileges. * * @param string User id * @param string The privilege to evaluate * * @return array A list of the groups the user has certain privileges. */ function users_get_all_model_groups() { $groups = db_get_all_rows_in_table('tmodule_group'); if ($groups === false) { $groups = []; } $returnGroups = []; foreach ($groups as $group) { $returnGroups[$group['id_mg']] = $group['name']; } $returnGroups[0] = 'Not assigned'; // Module group external to DB but it exist return $returnGroups; } /** * Get all the groups a user has reading privileges with the special format to use it on select. * * @param string User id * @param string The privilege to evaluate, and it is false then no check ACL. * @param boolean $returnAllGroup Flag the return group, by default true. * @param boolean $returnAllColumns Flag to return all columns of groups. * @param array $id_groups The id of node that must do not show the children and own. * @param string $keys_field The field of the group used in the array keys. By default ID * * @return array A list of the groups the user has certain privileges. */ function users_get_groups_for_select($id_user, $privilege='AR', $returnAllGroup=true, $returnAllColumns=false, $id_groups=null, $keys_field='id_grupo') { if ($id_groups === false) { $id_groups = null; } $user_groups = users_get_groups($id_user, $privilege, $returnAllGroup, $returnAllColumns, null); if ($id_groups !== null) { $childrens = groups_get_childrens($id_groups); foreach ($childrens as $child) { unset($user_groups[$child['id_grupo']]); } unset($user_groups[$id_groups]); } if (empty($user_groups)) { $user_groups_tree = []; } else { // First group it's needed to retrieve its parent group $first_group = array_slice($user_groups, 0, 1); $first_group = reset($first_group); $parent_group = $first_group['parent']; $user_groups_tree = groups_get_groups_tree_recursive($user_groups, $parent_group); } $fields = []; foreach ($user_groups_tree as $group) { $groupName = ui_print_truncate_text($group['nombre'], GENERIC_SIZE_TEXT, false, true, false); $fields[$group[$keys_field]] = str_repeat('    ', $group['deep']).$groupName; } return $fields; } function get_group_ancestors($group_id, $groups) { if ($group_id == 0) { return 0; } if (!isset($groups[$group_id])) { return null; } $parent = $groups[$group_id]['parent']; if ($groups[$group_id]['propagate'] == 0) { return $group_id; } $r = get_group_ancestors($parent, $groups); if (is_array($r)) { $r = array_merge([$group_id], $r); } else { $r = [ $group_id, $r, ]; } return $r; } function groups_combine_acl($acl_group_a, $acl_group_b) { if (!is_array($acl_group_a)) { if (is_array($acl_group_b)) { return $acl_group_b; } else { return null; } } else { if (!is_array($acl_group_b)) { return $acl_group_a; } } $acl_list = [ 'incident_view' => 1, 'incident_edit' => 1, 'incident_management' => 1, 'agent_view' => 1, 'agent_edit' => 1, 'agent_disable' => 1, 'alert_edit' => 1, 'alert_management' => 1, 'pandora_management' => 1, 'db_management' => 1, 'user_management' => 1, 'report_view' => 1, 'report_edit' => 1, 'report_management' => 1, 'event_view' => 1, 'event_edit' => 1, 'event_management' => 1, 'map_view' => 1, 'map_edit' => 1, 'map_management' => 1, 'vconsole_view' => 1, 'vconsole_edit' => 1, 'vconsole_management' => 1, 'tags' => 1, ]; foreach ($acl_group_a['tags'] as $key => $value) { $acl_group_b['tags'][$key] = array_merge($value, $acl_group_b['tags'][$key]); } foreach ($acl_list as $acl => $aux) { if ($acl == 'tags') { continue; } // propagate ACL $acl_group_b[$acl] = $acl_group_a[$acl] || $acl_group_b[$acl]; } return $acl_group_b; } /** * Get all the groups a user has reading privileges. * * @param string $id_user User id * @param string $privilege The privilege to evaluate, and it is false then no check ACL. * @param boolean $returnAllGroup Flag the return group, by default true. * @param boolean $returnAllColumns Flag to return all columns of groups. * @param array $id_groups The list of group to scan to bottom child. By default null. * @param string $keys_field The field of the group used in the array keys. By default ID * @param boolean $cache Set it to false to not use cache * * @return array A list of the groups the user has certain privileges. */ function users_get_groups( $id_user=false, $privilege='AR', $returnAllGroup=true, $returnAllColumns=false, $id_groups=null, $keys_field='id_grupo', $cache=true ) { static $group_cache = []; // Added users_group_cache to avoid unnecessary proccess on massive calls... static $users_group_cache = []; $users_group_cache_key = $id_user.'|'.$privilege.'|'.$returnAllGroup.'|'.$returnAllColumns; if (empty($id_user)) { global $config; $id_user = null; if (isset($config['id_user'])) { $id_user = $config['id_user']; } } // Check the group cache first. if (array_key_exists($id_user, $group_cache) && $cache) { $forest_acl = $group_cache[$id_user]; } else { // Admin. if (is_user_admin($id_user)) { $forest_acl = db_get_all_rows_sql('SELECT * FROM tgrupo ORDER BY nombre'); } // Per-group permissions. else { $query = 'SELECT * FROM tgrupo ORDER BY parent,id_grupo DESC'; $raw_groups = db_get_all_rows_sql($query); $query = sprintf( "SELECT tgrupo.*, tperfil.*, tusuario_perfil.tags, tusuario_perfil.no_hierarchy FROM tgrupo, tusuario_perfil, tperfil WHERE (tgrupo.id_grupo = tusuario_perfil.id_grupo OR tusuario_perfil.id_grupo = 0) AND tusuario_perfil.id_perfil = tperfil.id_perfil AND tusuario_perfil.id_usuario = '%s' ORDER BY nombre", $id_user ); $raw_forest = db_get_all_rows_sql($query); if ($raw_forest === false) { $raw_forest = []; } foreach ($raw_forest as $g) { // XXX, following code must be remade (TAG) users_get_explode_tags($g); if (!isset($forest_acl[$g['id_grupo']])) { $forest_acl[$g['id_grupo']] = $g; } else { $forest_acl[$g['id_grupo']] = groups_combine_acl($forest_acl[$g['id_grupo']], $g); } } $groups = []; foreach ($raw_groups as $g) { $groups[$g['id_grupo']] = $g; } foreach ($groups as $group) { $parents = get_group_ancestors($group['parent'], $groups); if (is_array($parents)) { foreach ($parents as $parent) { if ((isset($forest_acl[$parent])) && ($groups[$parent]['propagate'] == 1) && ($forest_acl[$parent]['no_hierarchy'] == 0) ) { if (isset($forest_acl[$group['id_grupo']])) { // update ACL propagation $tmp = groups_combine_acl($forest_acl[$parent], $forest_acl[$group['id_grupo']]); } else { // add group to user ACL forest users_get_explode_tags($group); $tmp = groups_combine_acl($forest_acl[$parent], $group); } if ($tmp !== null) { // add only if valid $forest_acl[$group['id_grupo']] = $tmp; } } } } // No parents, direct assignment already done } } // Update the group cache. $group_cache[$id_user] = $forest_acl; } $user_groups = []; if (!$forest_acl) { return $user_groups; } if ($returnAllGroup) { // All group $groupall = [ 'id_grupo' => 0, 'nombre' => __('All'), 'icon' => 'world', 'parent' => 0, 'disabled' => 0, 'custom_id' => null, 'description' => '', 'propagate' => 0, ]; // Add the All group to the beginning to be always the first array_unshift($forest_acl, $groupall); } $acl_column = get_acl_column($privilege); if (array_key_exists($users_group_cache_key, $users_group_cache) && $cache) { return $users_group_cache[$users_group_cache_key]; } foreach ($forest_acl as $group) { // Check the specific permission column. acl_column is undefined for admins. if (isset($group[$acl_column]) && $group[$acl_column] != '1') { continue; } if ($returnAllColumns) { $user_groups[$group[$keys_field]] = $group; } else { $user_groups[$group[$keys_field]] = $group['nombre']; } } $users_group_cache[$users_group_cache_key] = $user_groups; return $user_groups; } /** * Get all the groups a user has reading privileges. Version for tree groups. * * @param string User id * @param string The privilege to evaluate * @param boolean $returnAllGroup Flag the return group, by default true. * @param boolean $returnAllColumns Flag to return all columns of groups. * * @return array A treefield list of the groups the user has certain privileges. */ function users_get_groups_tree($id_user=false, $privilege='AR', $returnAllGroup=true) { $user_groups = users_get_groups($id_user, $privilege, $returnAllGroup, true); $user_groups_tree = groups_get_groups_tree_recursive($user_groups); return $user_groups_tree; } /** * Get the first group of an user. * * Useful function when you need a default group for a user. * * @param string User id * @param string The privilege to evaluate * @param boolean $all_group Flag to return all group, by default true; * * @return array The first group where the user has certain privileges. */ function users_get_first_group($id_user=false, $privilege='AR', $all_group=true) { $groups = array_keys(users_get_groups($id_user, $privilege)); $return = array_shift($groups); if ((!$all_group) && ($return == 0)) { $return = array_shift($groups); } return $return; } /** * Return access to a specific agent by a specific user * * @param int Agent id. * @param string Access mode to be checked. Default AR (Agent reading) * @param string User id. Current user by default * @param bool True to use the metaconsole tables * * @return boolean Access to that agent (false not, true yes) */ function users_access_to_agent( $id_agent, $mode='AR', $id_user=false, $force_meta=false ) { if (empty($id_agent)) { return false; } if ($id_user == false) { global $config; $id_user = $config['id_user']; } return (bool) check_acl_one_of_groups( $id_user, agents_get_all_groups_agent((int) $id_agent, false, $force_meta), $mode ); } /** * Return user by id (user name) * * @param string User id. * * @return mixed User row or false if something goes wrong */ function users_get_user_by_id($id_user) { $result_user = db_get_row('tusuario', 'id_user', $id_user); return $result_user; } define('MAX_TIMES', 10); // // WEBCHAT FUNCTIONS///////////////////////////////// // function users_get_last_messages($last_time=false) { $file_global_counter_chat = $config['attachment_store'].'/pandora_chat.global_counter.txt'; // First lock the file $fp_global_counter = @fopen($file_global_counter_chat, 'a+'); if ($fp_global_counter === false) { echo json_encode($return); return; } // Try to look MAX_TIMES times $tries = 0; while (!flock($fp_global_counter, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { echo json_encode($return); return; } sleep(1); } fscanf($fp_global_counter, '%d', $global_counter_file); if (empty($global_counter_file)) { $global_counter_file = 0; } $timestamp = time(); if ($last_time === false) { $last_time = (24 * 60 * 60); } $from = ($timestamp - $last_time); $log_chat_file = $config['attachment_store'].'/pandora_chat.log.json.txt'; $return = [ 'correct' => false, 'log' => [], ]; if (!file_exists($log_chat_file)) { touch($log_chat_file); } $text_encode = @file_get_contents($log_chat_file); $log = json_decode($text_encode, true); if ($log !== false) { if ($log === null) { $log = []; } $log_last_time = []; foreach ($log as $message) { if ($message['timestamp'] >= $from) { $log_last_time[] = $message; } } $return['correct'] = true; $return['log'] = $log_last_time; $return['global_counter'] = $global_counter_file; } echo json_encode($return); fclose($fp_global_counter); return; } function users_save_login() { global $config; $file_global_user_list = $config['attachment_store'].'/pandora_chat.user_list.json.txt'; $user = db_get_row_filter( 'tusuario', ['id_user' => $config['id_user']] ); $message = sprintf( __('User %s login at %s'), $user['fullname'], date($config['date_format']) ); users_save_text_message($message, 'notification'); // First lock the file $fp_user_list = @fopen($file_global_user_list, 'a+'); if ($fp_user_list === false) { return; } // Try to look MAX_TIMES times $tries = 0; while (!flock($fp_user_list, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { return; } sleep(1); } @fscanf($fp_user_list, "%[^\n]", $user_list_json); $user_list = json_decode($user_list_json, true); if (empty($user_list)) { $user_list = []; } if (isset($user_list[$config['id_user']])) { $user_list[$config['id_user']]['count']++; } else { $user_list[$config['id_user']] = [ 'name' => $user['fullname'], 'count' => 1, ]; } // Clean the file ftruncate($fp_user_list, 0); $status = fwrite($fp_user_list, json_encode($user_list)); if ($status === false) { fclose($fp_user_list); return; } fclose($fp_user_list); } function users_save_logout($user=false, $delete=false) { global $config; $return = [ 'correct' => false, 'users' => [], ]; $file_global_user_list = $config['attachment_store'].'/pandora_chat.user_list.json.txt'; if (empty($user)) { $user = db_get_row_filter( 'tusuario', ['id_user' => $config['id_user']] ); } if ($delete) { $no_json_output = true; $message = sprintf( __('User %s was deleted in the DB at %s'), $user['fullname'], date($config['date_format']) ); } else { $no_json_output = false; $message = sprintf( __('User %s logout at %s'), $user['fullname'], date($config['date_format']) ); } users_save_text_message($message, 'notification', $no_json_output); // First lock the file $fp_user_list = @fopen($file_global_user_list, 'a+'); if ($fp_user_list === false) { return; } // Try to look MAX_TIMES times $tries = 0; while (!flock($fp_user_list, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { return; } sleep(1); } @fscanf($fp_user_list, "%[^\n]", $user_list_json); $user_list = json_decode($user_list_json, true); if (empty($user_list)) { $user_list = []; } if ($delete) { unset($user_list[$user['id_user']]); } else { if (isset($user_list[$config['id_user']])) { $user_list[$config['id_user']]['count']--; } if ($user_list[$config['id_user']]['count'] <= 0) { unset($user_list[$user['id_user']]); } } // Clean the file ftruncate($fp_user_list, 0); $status = fwrite($fp_user_list, json_encode($user_list)); if ($status === false) { fclose($fp_user_list); return; } fclose($fp_user_list); } function users_save_text_message($message=false, $type='message', $no_json_output=false) { global $config; $file_global_counter_chat = $config['attachment_store'].'/pandora_chat.global_counter.txt'; $log_chat_file = $config['attachment_store'].'/pandora_chat.log.json.txt'; $return = ['correct' => false]; $id_user = $config['id_user']; $user = db_get_row_filter( 'tusuario', ['id_user' => $id_user] ); $message_data = []; $message_data['type'] = $type; $message_data['id_user'] = $id_user; $message_data['user_name'] = $user['fullname']; $message_data['text'] = io_safe_input_html($message); // The $message_data['timestamp'] set when adquire the files to save. // First lock the file $fp_global_counter = @fopen($file_global_counter_chat, 'a+'); if ($fp_global_counter === false) { if (!$no_json_output) { echo json_encode($return); } return; } // Try to look MAX_TIMES times $tries = 0; while (!flock($fp_global_counter, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { if (!$no_json_output) { echo json_encode($return); } return; } sleep(1); } @fscanf($fp_global_counter, '%d', $global_counter_file); if (empty($global_counter_file)) { $global_counter_file = 0; } // Clean the file ftruncate($fp_global_counter, 0); $message_data['timestamp'] = time(); $message_data['human_time'] = date($config['date_format'], $message_data['timestamp']); $global_counter = ($global_counter_file + 1); $status = fwrite($fp_global_counter, $global_counter); if ($status === false) { fclose($fp_global_counter); if (!$no_json_output) { echo json_encode($return); } return; } else { $text_encode = @file_get_contents($log_chat_file); $log = json_decode($text_encode, true); $log[$global_counter] = $message_data; $status = file_put_contents($log_chat_file, json_encode($log)); fclose($fp_global_counter); $return['correct'] = true; if (!$no_json_output) { echo json_encode($return); } } return; } function users_long_polling_check_messages($global_counter) { global $config; $file_global_counter_chat = $config['attachment_store'].'/pandora_chat.global_counter.txt'; $log_chat_file = $config['attachment_store'].'/pandora_chat.log.json.txt'; $changes = false; $tries_general = 0; $error = false; while (!$changes) { // First lock the file $fp_global_counter = @fopen($file_global_counter_chat, 'a+'); if ($fp_global_counter) { // Try to look MAX_TIMES times $tries = 0; $lock = true; while (!flock($fp_global_counter, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { $lock = false; $error = true; break; } sleep(1); } if ($lock) { @fscanf($fp_global_counter, '%d', $global_counter_file); if (empty($global_counter_file)) { $global_counter_file = 0; } if ($global_counter_file > $global_counter) { // TODO Optimize slice the array. $text_encode = @file_get_contents($log_chat_file); $log = json_decode($text_encode, true); $return_log = []; foreach ($log as $key => $message) { if ($key <= $global_counter) { continue; } $return_log[] = $message; } $return = [ 'correct' => true, 'global_counter' => $global_counter_file, 'log' => $return_log, ]; echo json_encode($return); fclose($fp_global_counter); return; } } fclose($fp_global_counter); } sleep(3); $tries_general = ($tries_general + 3); if ($tries_general > MAX_TIMES) { break; } } // Because maybe the exit of loop for exaust. echo json_encode(['correct' => false, 'error' => $error]); return; } /** * Get the last global counter for chat. * * @param string $mode There are two modes 'json', 'return' and 'session'. And json is by default. */ function users_get_last_global_counter($mode='json') { global $config; $file_global_counter_chat = $config['attachment_store'].'/pandora_chat.global_counter.txt'; $global_counter_file = 0; $fp_global_counter = @fopen($file_global_counter_chat, 'a+'); if ($fp_global_counter) { $tries = 0; $lock = true; while (!flock($fp_global_counter, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { $lock = false; break; } sleep(1); } if ($lock) { @fscanf($fp_global_counter, '%d', $global_counter_file); if (empty($global_counter_file)) { $global_counter_file = 0; } fclose($fp_global_counter); } } switch ($mode) { case 'json': echo json_encode(['correct' => true, 'global_counter' => $global_counter_file]); break; case 'return': return $global_counter_file; break; case 'session': $_SESSION['global_counter_chat'] = $global_counter_file; break; } } /** * Get the last global counter for chat. * * @param string $mode There are two modes 'json', 'return' and 'session'. And json is by default. */ function users_get_last_type_message() { global $config; $return = 'false'; $file_global_counter_chat = $config['attachment_store'].'/pandora_chat.global_counter.txt'; $log_chat_file = $config['attachment_store'].'/pandora_chat.log.json.txt'; $global_counter_file = 0; $fp_global_counter = @fopen($file_global_counter_chat, 'a+'); if ($fp_global_counter) { $tries = 0; $lock = true; while (!flock($fp_global_counter, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { $lock = false; break; } sleep(1); } if ($lock) { $text_encode = @file_get_contents($log_chat_file); $log = json_decode($text_encode, true); // Prevent from error when chat file log doesn't exists if (empty($log)) { $return = false; } else { $last = end($log); $return = $last['type']; } fclose($fp_global_counter); } } return $return; } function users_is_admin($id_user=false) { global $config; if (!isset($config['is_admin'])) { $config['is_admin'] = []; } if ($id_user === false) { $id_user = $config['id_user']; } if (isset($config['is_admin'][$id_user])) { return $config['is_admin'][$id_user]; } $config['is_admin'][$id_user] = (bool) db_get_value( 'is_admin', 'tusuario', 'id_user', $id_user ); return $config['is_admin'][$id_user]; } function users_is_last_system_message() { $type = users_get_last_type_message(); if ($type != 'message') { return true; } else { return false; } } function users_check_users() { global $config; $return = [ 'correct' => false, 'users' => '', ]; $file_global_user_list = $config['attachment_store'].'/pandora_chat.user_list.json.txt'; // First lock the file $fp_user_list = @fopen($file_global_user_list, 'a+'); if ($fp_user_list === false) { echo json_encode($return); return; } // Try to look MAX_TIMES times $tries = 0; while (!flock($fp_user_list, LOCK_EX)) { $tries++; if ($tries > MAX_TIMES) { echo json_encode($return); return; } sleep(1); } @fscanf($fp_user_list, "%[^\n]", $user_list_json); $user_list = json_decode($user_list_json, true); if (empty($user_list)) { $user_list = []; } fclose($fp_user_list); $user_name_list = []; foreach ($user_list as $user) { $user_name_list[] = $user['name']; } $return['correct'] = true; $return['users'] = implode('
', $user_name_list); echo json_encode($return); return; } // Check if a user can manage a group when group is all // This function dont check acls of the group, only if the // user is admin or pandora manager and the group is all function users_can_manage_group_all($access='PM') { global $config; $access = get_acl_column($access); $sql = sprintf( 'SELECT COUNT(*) FROM tusuario_perfil INNER JOIN tperfil ON tperfil.id_perfil = tusuario_perfil.id_perfil WHERE tusuario_perfil.id_grupo=0 AND tusuario_perfil.id_usuario="%s" AND %s=1 ', $config['id_user'], $access ); if (users_is_admin($config['id_user']) || (int) db_get_value_sql($sql) !== 0) { return true; } return false; } /** * Get the users that belongs to the same groups of the current user * * @param string User id * @param string The privilege to evaluate, and it is false then no check ACL. * @param boolean $returnAllGroup Flag the return group, by default true. * * @return mixed Array with id_user as index and value */ function users_get_user_users( $id_user=false, $privilege='AR', $returnAllGroup=true, $fields=null ) { global $config; $user_groups = users_get_groups($id_user, $privilege, $returnAllGroup); $user_users = []; $array_user_group = []; foreach ($user_groups as $id_user_group => $name_user_group) { $array_user_group[] = $id_user_group; } $group_users = groups_get_users($array_user_group, false, $returnAllGroup); foreach ($group_users as $gu) { if (empty($fields)) { $user_users[$gu['id_user']] = $gu['id_user']; } else { $fields = (array) $fields; foreach ($fields as $field) { $user_users[$gu['id_user']][$field] = $gu[$field]; } } } return $user_users; } function users_get_strict_mode_groups($id_user, $return_group_all) { global $config; $sql = "SELECT * FROM tusuario_perfil WHERE id_usuario = '".$id_user."' AND tags = ''"; $user_groups = db_get_all_rows_sql($sql); if ($user_groups == false) { $user_groups = []; } $return_user_groups = []; if ($return_group_all) { $return_user_groups[0] = __('All'); } foreach ($user_groups as $group) { $return_user_groups[$group['id_grupo']] = groups_get_name($group['id_grupo']); } return $return_user_groups; } function users_get_explode_tags(&$group) { if (empty($group['tags'])) { $group['tags'] = []; $group['tags']['agent_view'] = []; $group['tags']['agent_edit'] = []; $group['tags']['agent_disable'] = []; $group['tags']['event_view'] = []; $group['tags']['event_edit'] = []; $group['tags']['event_management'] = []; } else { $aux = explode(',', $group['tags']); $group['tags'] = []; $group['tags']['agent_view'] = ($group['agent_view']) ? $aux : []; $group['tags']['agent_edit'] = ($group['agent_edit']) ? $aux : []; $group['tags']['agent_disable'] = ($group['agent_disable']) ? $aux : []; $group['tags']['event_view'] = ($group['event_view']) ? $aux : []; $group['tags']['event_edit'] = ($group['event_edit']) ? $aux : []; $group['tags']['event_management'] = ($group['event_management']) ? $aux : []; } }