diff --git a/pandora_console/extras/mr/37.sql b/pandora_console/extras/mr/37.sql index cc35df6ab0..a3aef948b8 100644 --- a/pandora_console/extras/mr/37.sql +++ b/pandora_console/extras/mr/37.sql @@ -36,11 +36,11 @@ CREATE TABLE `tdiscovery_tmp_connections` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `tpen` ( - `id_np` int(10) unsigned NOT NULL, `pen` int(10) unsigned NOT NULL, - `manufacturer` TEXT NOT NULL, - `description` TEXT NULL, - PRIMARY KEY (`id_np`,`pen`), + `manufacturer` TEXT, + `description` TEXT, + `id_np` int(10) unsigned, + PRIMARY KEY (`pen`), CONSTRAINT `fk_np_id` FOREIGN KEY (`id_np`) REFERENCES `tnetwork_profile` (`id_np`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql index 86eecd0ae7..4de9b6a1f3 100644 --- a/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql +++ b/pandora_console/extras/pandoradb_migrate_6.0_to_7.0.mysql.sql @@ -1480,11 +1480,11 @@ ALTER TABLE `tnetwork_component` MODIFY COLUMN `ff_type` tinyint(1) unsigned NUL -- Table `tpen` -- ---------------------------------------------------------------------- CREATE TABLE IF NOT EXISTS `tpen` ( - `id_np` int(10) unsigned NOT NULL, `pen` int(10) unsigned NOT NULL, - `manufacturer` TEXT NOT NULL, - `description` TEXT NULL, - PRIMARY KEY (`id_np`,`pen`), + `manufacturer` TEXT, + `description` TEXT, + `id_np` int(10) unsigned, + PRIMARY KEY (`pen`), CONSTRAINT `fk_np_id` FOREIGN KEY (`id_np`) REFERENCES `tnetwork_profile` (`id_np`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/pandora_console/godmode/modules/private_enterprise_numbers.php b/pandora_console/godmode/modules/private_enterprise_numbers.php index 286142628a..ca6add6640 100644 --- a/pandora_console/godmode/modules/private_enterprise_numbers.php +++ b/pandora_console/godmode/modules/private_enterprise_numbers.php @@ -1,127 +1,68 @@ run(); -} catch (Exception $ex) { - ui_print_error_message(__('Something went wrong. Please, take a look in the Pandora FMS log')); - echo '[PEN Configuration]'.$ex->getMessage(); + // User access and validation is being processed on class constructor. + $obj = new ConfigPEN($ajaxPage); +} catch (Exception $e) { + if (is_ajax()) { + echo json_encode(['error' => '[ConfigPEN]'.$e->getMessage() ]); + exit; + } else { + echo '[ConfigPEN]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; } -?> - + // Stop any execution. + exit; +} else { + // Run. + $obj->run(); +} diff --git a/pandora_console/include/class/ConfigPEN.class.php b/pandora_console/include/class/ConfigPEN.class.php index c254a0fe60..4a051d170c 100644 --- a/pandora_console/include/class/ConfigPEN.class.php +++ b/pandora_console/include/class/ConfigPEN.class.php @@ -35,6 +35,13 @@ require_once $config['homedir'].'/include/class/HTML.class.php'; class ConfigPEN extends HTML { + /** + * Url of controller. + * + * @var string + */ + public $ajaxController; + /** * URL Base * @@ -44,9 +51,11 @@ class ConfigPEN extends HTML /** - * Constructor + * Contructor. + * + * @param string $ajax_page Target ajax page. */ - public function __construct() + public function __construct($ajax_page) { global $config; @@ -63,8 +72,228 @@ class ConfigPEN extends HTML exit; } + $this->ajaxController = $ajax_page; $this->offset = ''; - $this->baseUrl = 'index.php?sec=configuration_wizard_setup&sec2=godmode/modules/private_enterprise_numbers'; + $this->baseUrl = ui_get_full_url( + 'index.php?sec=configuration_wizard_setup&sec2=godmode/modules/private_enterprise_numbers' + ); + + } + + + /** + * Returns an array with all the credentials matching filter and ACL. + * + * @param array $fields Fields array or 'count' keyword to retrieve count. + * @param array $filter Filters to be applied. + * @param integer $offset Offset (pagination). + * @param integer $limit Limit (pagination). + * @param string $order Sort order. + * @param string $sort_field Sort field. + * + * @return array With all results or false if error. + * @throws Exception On error. + */ + public static function getAll( + $fields, + $filter=null, + $offset=null, + $limit=null, + $order=null, + $sort_field=null + ) { + $sql_filters = []; + $order_by = ''; + $pagination = ''; + + $count = false; + if (!is_array($fields) && $fields == 'count') { + $fields = ['*']; + $count = true; + } else if (!is_array($fields)) { + error_log('[configPEN.getAll] Fields must be an array or "count".'); + throw new Exception('[configPEN.getAll] Fields must be an array or "count".'); + } + + if (is_array($filter)) { + if (!empty($filter['free_search'])) { + $sql_filters[] = vsprintf( + ' AND (lower(`manufacturer`) like lower("%%%s%%") + OR pen = "%s") ', + array_fill(0, 2, $filter['free_search']) + ); + } + + if (!empty($filter['pen'])) { + $sql_filters[] = sprintf( + ' AND `pen` = %d', + $filter['pen'] + ); + } + } + + if (isset($order)) { + $dir = 'asc'; + if ($order == 'desc') { + $dir = 'desc'; + }; + + if (in_array( + $sort_field, + [ + 'pen', + 'manufacturer', + 'description', + ] + ) + ) { + $order_by = sprintf( + 'ORDER BY `%s` %s', + $sort_field, + $dir + ); + } + } + + if (isset($limit) && $limit > 0 + && isset($offset) && $offset >= 0 + ) { + $pagination = sprintf( + ' LIMIT %d OFFSET %d ', + $limit, + $offset + ); + } + + $sql = sprintf( + 'SELECT %s + FROM `tpen` + WHERE 1=1 + %s + %s + %s', + join(',', $fields), + join(' ', $sql_filters), + $order_by, + $pagination + ); + + if ($count) { + $sql = sprintf('SELECT count(*) as n FROM ( %s ) tt', $sql); + + return db_get_value_sql($sql); + } + + return db_get_all_rows_sql($sql); + } + + + /** + * AJAX: Return JSON content for datatable. + * + * @return void + */ + function draw() + { + global $config; + + // Datatables offset, limit and order. + $filter = get_parameter('filter', []); + $start = get_parameter('start', 0); + $length = get_parameter('length', $config['block_size']); + $order = get_datatable_order(true); + try { + ob_start(); + + $fields = ['*']; + + // Retrieve data. + $data = $this->getAll( + // Fields. + $fields, + // Filter. + $filter, + // Offset. + $start, + // Limit. + $length, + // Order. + $order['direction'], + // Sort field. + $order['field'] + ); + + // Retrieve counter. + $count = $this->getAll( + 'count', + $filter + ); + + if ($data) { + $data = array_reduce( + $data, + function ($carry, $item) { + // Transforms array of arrays $data into an array + // of objects, making a post-process of certain fields. + $tmp = (object) $item; + + $tmp->description = io_safe_output($tmp->description); + $tmp->manufacturer = io_safe_output($tmp->manufacturer); + + $tmp->options = ''; + + $tmp->options = ''; + $tmp->options .= html_print_image( + 'images/eye.png', + true, + ['title' => __('Show')] + ); + $tmp->options .= ''; + $tmp->options .= ''; + $tmp->options .= html_print_image( + 'images/cross.png', + true, + ['title' => __('Delete')] + ); + $tmp->options .= ''; + + $carry[] = $tmp; + return $carry; + } + ); + } + + // Datatables format: RecordsTotal && recordsfiltered. + echo json_encode( + [ + 'data' => $data, + 'recordsTotal' => $count, + 'recordsFiltered' => $count, + ] + ); + // Capture output. + $response = ob_get_clean(); + } catch (Exception $e) { + echo json_encode(['error' => $e->getMessage()]); + exit; + } + + // If not valid, show error with issue. + json_decode($response); + if (json_last_error() == JSON_ERROR_NONE) { + // If valid dump. + echo $response; + } else { + echo json_encode( + ['error' => $response] + ); + } + + exit; } @@ -79,6 +308,7 @@ class ConfigPEN extends HTML // Require specific CSS and JS. ui_require_css_file('wizard'); ui_require_css_file('discovery'); + ui_require_css_file('pen'); // Header section. // Breadcrums. @@ -120,6 +350,12 @@ class ConfigPEN extends HTML ui_get_full_url('ajax.php', false, false, false) ); + // Ajax page (hidden). + html_print_input_hidden( + 'ajax_page', + $this->ajaxController + ); + // Allow message area. html_print_div(['id' => 'message_show_area']); // Prints the main table. @@ -132,6 +368,175 @@ class ConfigPEN extends HTML } + /** + * Load modal information for PEN management. + * + * Ajax. Direct HTML. + * + * @return void + */ + public function loadModal() + { + $values = []; + $id = (int) get_parameter('pen', 0); + if ($id > 0) { + $values = $this->getAll( + // Fields. + ['*'], + // Filter. + ['pen' => $id] + ); + if (is_array($values)) { + $values = $values[0]; + } + } + + $form = [ + 'action' => '#', + 'id' => 'modal_form', + 'onsubmit' => 'return false;', + 'class' => '', + ]; + + $inputs = []; + + $inputs[] = [ + 'label' => __('PEN'), + 'class' => 'flex-row', + 'id' => 'div-pen', + 'arguments' => [ + 'name' => 'pen', + 'type' => 'number', + 'value' => $values['pen'], + 'required' => true, + 'return' => true, + 'size' => 50, + ], + ]; + + $inputs[] = [ + 'label' => __('Manufacturer'), + 'class' => 'flex-row', + 'arguments' => [ + 'name' => 'manufacturer', + 'id' => 'manufacturer', + 'type' => 'text', + 'required' => true, + 'value' => io_safe_output($values['manufacturer']), + 'return' => true, + ], + ]; + + $inputs[] = [ + 'label' => __('Description'), + 'class' => 'flex-row', + 'arguments' => [ + 'name' => 'description', + 'id' => 'description', + 'type' => 'textarea', + 'value' => io_safe_output($values['description']), + 'return' => true, + 'rows' => 50, + 'columns' => 30, + ], + ]; + + echo '