From a50f50d99ea2badfbcbcd4efd3720976c702a309 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Tue, 24 Jan 2023 09:33:47 +0100 Subject: [PATCH 1/3] 9987 Commit provisional --- .../include/functions_inventory.php | 136 +++++++++ pandora_console/include/functions_ui.php | 264 ++++++++++-------- .../javascript/i18n/dataTables.ca.json | 244 ++++++++++++++++ .../javascript/i18n/dataTables.en.json | 239 ++++++++++++++++ .../javascript/i18n/dataTables.es.json | 242 ++++++++++++++++ .../javascript/i18n/dataTables.fr.json | 245 ++++++++++++++++ .../javascript/i18n/dataTables.ja.json | 78 ++++++ .../javascript/i18n/dataTables.ru.json | 247 ++++++++++++++++ .../javascript/i18n/dataTables.zh.json | 244 ++++++++++++++++ pandora_console/include/styles/pandora.css | 8 + .../operation/inventory/inventory.php | 220 ++++++++++++++- 11 files changed, 2048 insertions(+), 119 deletions(-) create mode 100644 pandora_console/include/javascript/i18n/dataTables.ca.json create mode 100644 pandora_console/include/javascript/i18n/dataTables.en.json create mode 100644 pandora_console/include/javascript/i18n/dataTables.es.json create mode 100644 pandora_console/include/javascript/i18n/dataTables.fr.json create mode 100644 pandora_console/include/javascript/i18n/dataTables.ja.json create mode 100644 pandora_console/include/javascript/i18n/dataTables.ru.json create mode 100644 pandora_console/include/javascript/i18n/dataTables.zh.json diff --git a/pandora_console/include/functions_inventory.php b/pandora_console/include/functions_inventory.php index 2ac322a4fe..0f47ba6e12 100644 --- a/pandora_console/include/functions_inventory.php +++ b/pandora_console/include/functions_inventory.php @@ -687,6 +687,142 @@ function inventory_get_data( } +function inventory_get_datatable( + $agents_ids, + $inventory_module_name, + $utimestamp, + $inventory_search_string='', + $export_csv=false, + $return_mode=false, + $order_by_agent=false +) { + global $config; + + $offset = (int) get_parameter('offset'); + + $where = []; + + array_push( + $where, + 'tmodule_inventory.id_module_inventory = tagent_module_inventory.id_module_inventory' + ); + + // Discart empty first position. + if (isset($agents_ids[0]) === true && empty($agents_ids[0]) === true) { + unset($agents_ids[0]); + } + + // If there are no agents selected. + if (empty($agents_ids) === true) { + return ERR_NODATA; + } + + if (array_search(-1, $agents_ids) === false) { + array_push($where, 'id_agente IN ('.implode(',', $agents_ids).')'); + } + + if ($inventory_module_name[0] !== '0' + && $inventory_module_name !== '' + && $inventory_module_name !== 'all' + ) { + array_push($where, "tmodule_inventory.name IN ('".implode("','", (array) $inventory_module_name)."')"); + } + + if ($inventory_search_string != '') { + array_push($where, "tagent_module_inventory.data LIKE '%".$inventory_search_string."%'"); + } + + $sql = 'SELECT * + FROM tmodule_inventory, tagent_module_inventory + WHERE + '.implode(' AND ', $where).' + ORDER BY tmodule_inventory.id_module_inventory LIMIT '.$offset.', '.$config['block_size']; + + $sql_count = 'SELECT COUNT(*) + FROM tmodule_inventory, tagent_module_inventory + WHERE '.implode(' AND ', $where); + + $rows = db_get_all_rows_sql($sql); + $count = db_get_sql($sql_count); + + if ($order_by_agent === false) { + $modules = []; + $module_rows = []; + + foreach ($rows as $row) { + array_push($modules, $row['name']); + } + + foreach ($modules as $module) { + $rows_tmp = []; + foreach ($rows as $row) { + if ($row['name'] === $module) { + $agent_name = db_get_value_sql( + 'SELECT alias + FROM tagente + WHERE id_agente = '.$row['id_agente'] + ); + + $row['name_agent'] = $agent_name; + array_push($rows_tmp, $row); + $module_rows[$module] = $rows_tmp; + } + } + } + + // hd($module_rows); + // echo ''; + return $module_rows; + } else { + $agents_rows = []; + $agent_data = []; + $rows_tmp = []; + foreach ($rows as $row) { + $agent_name = db_get_value_sql( + 'SELECT alias + FROM tagente + WHERE id_agente = '.$row['id_agente'] + ); + $row['name_agent'] = $agent_name; + $agent_data[$row['id_agente']][] = $row; + } + + foreach ($agent_data as $id_agent => $rows) { + $agent_name = db_get_value_sql( + 'SELECT alias + FROM tagente + WHERE id_agente = '.$id_agent + ); + + $rows_tmp['agent'] = $agent_name; + + foreach ($rows as $row) { + if ($utimestamp > 0) { + $data_row = db_get_row_sql( + "SELECT data, timestamp + FROM tagente_datos_inventory + WHERE utimestamp <= '".$utimestamp."' + AND id_agent_module_inventory = ".$row['id_agent_module_inventory'].' ORDER BY utimestamp DESC' + ); + + if ($data_row !== false) { + $row['data'] = $data_row['data']; + $row['timestamp'] = $data_row['timestamp']; + } else { + continue; + } + } + } + + $rows_tmp['row'] = $rows; + array_push($agents_rows, $rows_tmp); + } + + return $agents_rows; + } +} + + function inventory_get_dates($module_inventory_name, $inventory_agent, $inventory_id_group) { $sql = 'SELECT tagente_datos_inventory.utimestamp, diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index df491679c8..eb408d2be4 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3256,8 +3256,8 @@ function ui_print_datatable(array $parameters) throw new Exception('[ui_print_datatable]: Columns and columns names must have same length'); } - if (!isset($parameters['ajax_url'])) { - throw new Exception('[ui_print_datatable]: Parameter ajax_url is required'); + if (!isset($parameters['ajax_url']) && !isset($parameters['data_element'])) { + throw new Exception('[ui_print_datatable]: Parameter ajax_url or data_element is required'); } if (!isset($parameters['default_pagination'])) { @@ -3490,18 +3490,6 @@ function ui_print_datatable(array $parameters) $pagination_class = $parameters['pagination_class']; } - // Javascript controller. - $js = ' $value) { + $row_tmp[$columns[$key]] = $value; + } + + $row_tmp['Timestamp'] = $row['timestamp']; + array_push($data, (object) $row_tmp); + } + } + + $id_table = 'id_'.$row['id_module_inventory']; + + $table = ui_print_datatable( + [ + 'id' => $id_table, + 'class' => 'info_table w100p', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $columns, + 'no_sortable_columns' => [], + 'data_element' => $data, + 'searching' => true, + 'dom_elements' => 'lftipB', + 'order' => [ + 'field' => $columns[0], + 'direction' => 'asc', + ], + 'zeroRecords' => __('No inventory found'), + 'emptyTable' => __('No inventory found'), + 'return' => true, + 'default_pagination' => 10, + 'no_sortable_columns' => [-1], + ] + ); + + $modules .= ui_toggle( + $table, + ''.$row['name'].'', + '', + '', + true, + true, + '', + 'white-box-content w100p', + 'box-shadow white_table_graph w100p', + 'images/arrow_down_green.png', + 'images/arrow_right_green.png', + false, + false, + false, + '', + '', + null, + null, + $id_table + ); + } + + ui_toggle( + $modules, + $agent_rows['agent'], + '', + '', + false, + false + ); + } + } else { + foreach ($rows as $module_rows) { + $agent = ''; + foreach ($module_rows as $row) { + $columns = explode(';', io_safe_output($row['data_format'])); + array_push($columns, 'Timestamp'); + $data = []; + + $data_explode = explode(PHP_EOL, $row['data']); + foreach ($data_explode as $values) { + // Exclude results don't match filter. + if ($inventory_search_string && preg_match('/'.io_safe_output($inventory_search_string).'/', ($values)) == 0) { + continue; + } + + $data_tmp = []; + if ($values !== '') { + $values_explode = explode(';', io_safe_output($values)); + + foreach ($values_explode as $key => $value) { + $data_tmp[$columns[$key]] = $value; + } + + $data_tmp['Timestamp'] = $row['timestamp']; + array_push($data, $data_tmp); + } + } + + + $id_table = 'id_'.$row['id_module_inventory']; + + $table = ui_print_datatable( + [ + 'id' => $id_table, + 'class' => 'info_table w100p', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $columns, + 'no_sortable_columns' => [], + 'data_element' => $data, + 'searching' => true, + 'dom_elements' => 'lftipB', + 'order' => [ + 'field' => $columns[0], + 'direction' => 'asc', + ], + 'zeroRecords' => __('No inventory found'), + 'emptyTable' => __('No inventory found'), + 'return' => true, + 'default_pagination' => 10, + 'no_sortable_columns' => [-1], + ] + ); + + $agent .= ui_toggle( + $table, + ''.$row['name_agent'].'', + '', + '', + true, + true, + '', + 'white-box-content w100p', + 'box-shadow white_table_graph w100p', + 'images/arrow_down_green.png', + 'images/arrow_right_green.png', + false, + false, + false, + '', + '', + null, + null, + $id_table + ); + } + + ui_toggle( + $agent, + $module_rows[0]['name'], + '', + '', + false, + false + ); + } + } + } else { + $result = []; + + $sql = 'SELECT alias, direccion, nombre + FROM tagente + WHERE id_agente = '.$inventory_id_agent; + $results = db_get_all_rows_sql($sql); + + foreach ($results as $result) { + hd($result); + } + + ui_print_datatable( + [ + 'id' => 'basic_info', + 'class' => 'info_table w100p', + 'style' => 'width: 100%', + 'columns' => $columns, + 'column_names' => $columns, + 'no_sortable_columns' => [], + 'data_element' => $data, + 'searching' => true, + 'dom_elements' => 'lftipB', + 'order' => [ + 'field' => $columns[0], + 'direction' => 'asc', + ], + 'zeroRecords' => __('No inventory found'), + 'emptyTable' => __('No inventory found'), + 'default_pagination' => 10, + 'no_sortable_columns' => [-1], + ] + ); + } } else { if (empty($inventory_data) === true) { ui_print_info_message(['no_close' => true, 'message' => __('No data found.') ]); @@ -546,6 +750,10 @@ ui_require_jquery_file('bgiframe'); $("#id_group").blur (function () { $(this).css ("width", "180px"); }); + + // Reduce margins between table and pagination. + $('.dataTables_paginate.paging_simple_numbers').css('margin-top', 10); + $('.dataTables_paginate.paging_simple_numbers').css('margin-bottom', 10); }); /* ]]> */ From 3ebd958298160e7d536ac9fdb4de1ff7c2f19c53 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Wed, 25 Jan 2023 14:29:18 +0100 Subject: [PATCH 2/3] 9987 New inventory view --- pandora_console/include/functions_ui.php | 8 +- .../include/styles/pandora_black.css | 8 + .../operation/inventory/inventory.php | 179 +++++++++++++++--- 3 files changed, 168 insertions(+), 27 deletions(-) diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index eb408d2be4..448a7a5144 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -3631,10 +3631,15 @@ function ui_print_datatable(array $parameters) } $searching = 'false'; - if (isset($parameters['searching'])) { + if (isset($parameters['searching']) && $parameters['searching'] === true) { $searching = 'true'; } + $ordering = 'true'; + if (isset($parameters['ordering']) && $parameters['ordering'] === false) { + $ordering = 'false'; + } + $js .= '},'; $languaje = substr(get_user_language(), 0, 2); @@ -3680,6 +3685,7 @@ function ui_print_datatable(array $parameters) { className: "no-class", targets: "_all" }, { bSortable: false, targets: '.$no_sortable_columns.' } ], + ordering: '.$ordering.', columns: ['; foreach ($parameters['datacolumns'] as $data) { diff --git a/pandora_console/include/styles/pandora_black.css b/pandora_console/include/styles/pandora_black.css index 2affa15eb4..169668c8b3 100644 --- a/pandora_console/include/styles/pandora_black.css +++ b/pandora_console/include/styles/pandora_black.css @@ -1210,3 +1210,11 @@ input[type="image"] { .mono { font-family: source-code, mono, monospace; } + +.title-blue { + text-transform: none !important; + font-size: 1em !important; + margin: 0px !important; + padding: 0px !important; + color: #95a3bf; +} diff --git a/pandora_console/operation/inventory/inventory.php b/pandora_console/operation/inventory/inventory.php index 69f402e2df..76c22a3a57 100755 --- a/pandora_console/operation/inventory/inventory.php +++ b/pandora_console/operation/inventory/inventory.php @@ -360,7 +360,7 @@ $table->data[0][1] .= ''; $table->data[0][2] = ''.__('Module').''; if ($is_metaconsole === true) { - $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, $filteringFunction, __('All'), 0, true, false, true, '', false, 'min-width: 194px; max-width: 200px;'); + $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, $filteringFunction, __('Basic info'), 0, true, false, true, '', false, 'min-width: 194px; max-width: 200px;'); } else { $sql = 'SELECT name as indexname, name FROM tmodule_inventory, tagent_module_inventory @@ -369,7 +369,20 @@ if ($is_metaconsole === true) { $sql .= ' AND id_agente = '.$inventory_id_agent; } - $table->data[0][3] = html_print_select_from_sql($sql, 'module_inventory_general_view', $inventory_module, '', __('All'), 'all', true, false, false); + $fields = []; + $result = db_get_all_rows_sql($sql); + if ($result === false) { + $result = []; + } + + foreach ($result as $row) { + $id = array_shift($row); + $value = array_shift($row); + $fields[$id] = $value; + } + + array_unshift($fields, 'All'); + $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, '', __('Basic info'), 'basic', true, false, false); } @@ -687,38 +700,152 @@ if ($is_metaconsole === false) { } } } else { - $result = []; - - $sql = 'SELECT alias, direccion, nombre - FROM tagente - WHERE id_agente = '.$inventory_id_agent; - $results = db_get_all_rows_sql($sql); - - foreach ($results as $result) { - hd($result); + $id_agente = $inventory_id_agent; + $agentes = []; + $data = []; + $class = 'info_table w100p'; + $style = 'width: 100%'; + $ordering = false; + $searching = false; + $dom = 't'; + $columns = [ + __('Alias'), + __('IP'), + __("IP's Secondary"), + __('Group'), + __('Secondary groups'), + __('Description'), + __('OS'), + __('Interval'), + __('Last contact'), + __('Last status change'), + __('Custom fields'), + __('Values Custom Fields'), + ]; + if ((int) $id_agente === 0) { + $class = 'databox info_table w100p'; + $style = 'width: 99%'; + $ordering = true; + $searching = true; + $dom = 'lftipB'; + $agentes = db_get_all_rows_sql('SELECT id_agente FROM tagente'); + } else { + array_push($agentes, $id_agente); } - ui_print_datatable( + foreach ($agentes as $id) { + if ((int) $id_agente === 0) { + $id = $id['id_agente']; + } + + $agent = db_get_row('tagente', 'id_agente', $id); + + $ip = ''.__('N/A').''; + if (empty($agent['direccion']) === false) { + $ip = $agent['direccion']; + } + + + $secondary_ips = ''; + foreach (agents_get_addresses($id) as $ip) { + if ($ip !== $agent['direccion']) { + $secondary_ips .= ''.$ip.''; + } + } + + $group = groups_get_name($agent['id_grupo']); + $secondary_groups = enterprise_hook('agents_get_secondary_groups', [$id]); + + if (empty($secondary_groups['for_select']) === true) { + $sec_group_data = ''.__('N/A').''; + } else { + $sec_group = []; + foreach ($secondary_groups['for_select'] as $name) { + $sec_group[] = $name; + } + + $sec_group_data = implode(', ', $sec_group); + } + + $os = ui_print_os_icon($agent['id_os'], false, true).' '; + $os .= io_safe_output(get_os_name($agent['id_os'])).' '.io_safe_output($agent['os_version']); + $interval = human_time_description_raw($agent['intervalo'], false, 'large'); + $last_contact = ui_print_timestamp($agent['ultimo_contacto'], true); + // $last_contact .= ' / '.date_w_fixed_tz($agent['ultimo_contacto_remoto']); + $last_status_change_agent = agents_get_last_status_change($agent['id_agente']); + $time_elapsed = !empty($last_status_change_agent) ? human_time_comparation($last_status_change_agent) : ''.__('N/A').''; + + $sql_fields = 'SELECT tcf.name, tcd.description, tcf.is_password_type + FROM tagent_custom_fields tcf + INNER JOIN tagent_custom_data tcd ON tcd.id_field=tcf.id_field + WHERE tcd.id_agent='.$id.' AND tcd.description!=""'; + $field_result = db_get_all_rows_sql($sql_fields); + + $custom_fields_names = ''; + $custom_fields_values = ''; + foreach ($field_result as $field) { + $field_name = str_replace(' ', ' ', io_safe_output($field['name'])); + $custom_fields_names .= ''.$field_name.''; + + $description = $field['description']; + $password_length = strlen(io_safe_output($field['description'])); + $asterisks = ''; + + if ((int) $field['is_password_type'] === 1) { + for ($i = 0; $i < $password_length; $i++) { + $asterisks .= '●'; + } + + $description = $asterisks; + } + + $custom_fields_values .= ''.$description.''; + } + + $data_tmp = [ + __('Alias') => $agent['alias'], + __('IP') => $ip, + __("IP's Secondary") => $secondary_ips, + __('Group') => $group, + __('Secondary groups') => $sec_group_data, + __('Description') => $agent['comentarios'], + __('OS') => $os, + __('Interval') => $interval, + __('Last contact') => $last_contact, + __('Last status change') => $time_elapsed, + __('Custom fields') => $custom_fields_names, + __('Values Custom Fields') => $custom_fields_values, + ]; + + array_push($data, $data_tmp); + } + + $table = ui_print_datatable( [ - 'id' => 'basic_info', - 'class' => 'info_table w100p', - 'style' => 'width: 100%', - 'columns' => $columns, - 'column_names' => $columns, - 'no_sortable_columns' => [], - 'data_element' => $data, - 'searching' => true, - 'dom_elements' => 'lftipB', - 'order' => [ + 'id' => 'basic_info', + 'class' => $class, + 'style' => $style, + 'columns' => $columns, + 'column_names' => $columns, + 'ordering' => $ordering, + 'data_element' => $data, + 'searching' => $searching, + 'dom_elements' => $dom, + 'order' => [ 'field' => $columns[0], 'direction' => 'asc', ], - 'zeroRecords' => __('No inventory found'), - 'emptyTable' => __('No inventory found'), - 'default_pagination' => 10, - 'no_sortable_columns' => [-1], + 'zeroRecords' => __('Agent info not found'), + 'emptyTable' => __('Agent info not found'), + 'default_pagination' => 10, + 'return' => true, ] ); + if ((int) $id_agente === 0) { + echo $table; + } else { + echo '
'.$table.'
'; + } } } else { if (empty($inventory_data) === true) { From 64fabf28c59fe565134dbb67d56cbabe3f594143 Mon Sep 17 00:00:00 2001 From: Pablo Aragon Date: Thu, 26 Jan 2023 10:06:27 +0100 Subject: [PATCH 3/3] 9987 New inventory view - Pending Meta design --- pandora_console/include/functions_inventory.php | 2 -- pandora_console/operation/inventory/inventory.php | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/functions_inventory.php b/pandora_console/include/functions_inventory.php index 0f47ba6e12..4146e9f2ac 100644 --- a/pandora_console/include/functions_inventory.php +++ b/pandora_console/include/functions_inventory.php @@ -770,8 +770,6 @@ function inventory_get_datatable( } } - // hd($module_rows); - // echo ''; return $module_rows; } else { $agents_rows = []; diff --git a/pandora_console/operation/inventory/inventory.php b/pandora_console/operation/inventory/inventory.php index 76c22a3a57..13d5a6c10a 100755 --- a/pandora_console/operation/inventory/inventory.php +++ b/pandora_console/operation/inventory/inventory.php @@ -360,7 +360,8 @@ $table->data[0][1] .= ''; $table->data[0][2] = ''.__('Module').''; if ($is_metaconsole === true) { - $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, $filteringFunction, __('Basic info'), 0, true, false, true, '', false, 'min-width: 194px; max-width: 200px;'); + // array_unshift($fields, __('All')); + $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, $filteringFunction, __('All'), 0, true, false, true, '', false, 'min-width: 194px; max-width: 200px;'); } else { $sql = 'SELECT name as indexname, name FROM tmodule_inventory, tagent_module_inventory @@ -381,7 +382,7 @@ if ($is_metaconsole === true) { $fields[$id] = $value; } - array_unshift($fields, 'All'); + array_unshift($fields, __('All')); $table->data[0][3] = html_print_select($fields, 'module_inventory_general_view', $inventory_module, '', __('Basic info'), 'basic', true, false, false); }