From 43c0df086a71d4216ad3d6fa35e8d2370a03b386 Mon Sep 17 00:00:00 2001 From: Jokob-sk Date: Fri, 21 Jul 2023 08:19:11 +1000 Subject: [PATCH] Plugins filter + #253 --- front/php/templates/language/en_us.php | 4 +++ front/pluginsCore.php | 34 +++++++++++----------- pialert/__main__.py | 2 +- pialert/database.py | 7 ++++- pialert/initialise.py | 1 + pialert/plugins/README.md | 34 ++++++++++++++++++++-- pialert/plugins/dhcp_leases/config.json | 3 +- pialert/plugins/nmap_services/config.json | 3 +- pialert/plugins/snmp_discovery/config.json | 3 +- pialert/plugins/unifi_import/config.json | 3 +- 10 files changed, 68 insertions(+), 26 deletions(-) diff --git a/front/php/templates/language/en_us.php b/front/php/templates/language/en_us.php index 1049f86c..4d9424c8 100755 --- a/front/php/templates/language/en_us.php +++ b/front/php/templates/language/en_us.php @@ -505,6 +505,7 @@ $lang['en_us'] = array( 'Plugins_Unprocessed_Events' => 'Unprocessed Events', 'Plugins_Objects' => 'Plugin Objects', +'Plugins_DeleteAll' => 'Delete all (filters are ignored)', 'Plugins_History' => 'Events History', ////////////////////////////////////////////////////////////////// @@ -534,6 +535,8 @@ The arp-scan time itself depends on the number of IP addresses to check so set t 'TIMEZONE_description' => 'Time zone to display stats correctly. Find your time zone here.', 'ENABLE_PLUGINS_name' => 'Enable Plugins', 'ENABLE_PLUGINS_description' => 'Enables the plugins functionality. Loading plugins requires more hardware resources so you might want to disable them on low-powered system.', +'PLUGINS_KEEP_HIST_name' => 'Plugins History', +'PLUGINS_KEEP_HIST_description' => 'How many days of Plugins History scan entries should be kept (globally, not device specific!).', 'PIALERT_WEB_PROTECTION_name' => 'Enable login', 'PIALERT_WEB_PROTECTION_description' => 'When enabled a login dialog is displayed. Read below carefully if you get locked out of your instance.', 'PIALERT_WEB_PASSWORD_name' => 'Login password', @@ -688,6 +691,7 @@ The arp-scan time itself depends on the number of IP addresses to check so set t 'PHOLUS_DAYS_DATA_name' => 'Data retention', 'PHOLUS_DAYS_DATA_description' => 'How many days of Pholus scan entries should be kept (globally, not device specific!) Enter 0 to disable.', + // Nmap 'Nmap_display_name' => 'Nmap', 'Nmap_icon' => '', diff --git a/front/pluginsCore.php b/front/pluginsCore.php index 7062f396..c026852d 100755 --- a/front/pluginsCore.php +++ b/front/pluginsCore.php @@ -37,6 +37,7 @@ function initFields() { getData(); } + } // ----------------------------------------------------------------------------- @@ -353,7 +354,7 @@ function generateTabs()
- +
@@ -367,7 +368,7 @@ function generateTabs()
- +
@@ -381,7 +382,7 @@ function generateTabs()
- +
@@ -446,38 +447,37 @@ function initTabs() } // -------------------------------------------------------- -// Filter method taht determines if an entry should be shown +// Filter method that determines if an entry should be shown function shouldBeShown(entry, pluginObj) { if (pluginObj.hasOwnProperty('data_filters')) { let dataFilters = pluginObj.data_filters; - // Loop through 'data_filters' array + // Loop through 'data_filters' array and appply filters on individual plugin entries for (let i = 0; i < dataFilters.length; i++) { compare_field_id = dataFilters[i].compare_field_id; compare_column = dataFilters[i].compare_column; compare_operator = dataFilters[i].compare_operator; - compare_js_wrapper = dataFilters[i].compare_js_wrapper; + compare_js_template = dataFilters[i].compare_js_template; + compare_use_quotes = dataFilters[i].compare_use_quotes; compare_field_id_value = $(`#${compare_field_id}`).val(); if(compare_field_id_value != undefined && compare_field_id_value != '--') { - // valid value - console.log(compare_field_id_value) - console.log(compare_column) - console.log(compare_operator) - console.log(entry[compare_column]) - + // valid value // resolve the left and right part of the comparison - let left = compare_js_wrapper.replace('{value}', `"${compare_field_id_value}"`) - let right = compare_js_wrapper.replace('{value}', `"${entry[compare_column]}"`) + let left = compare_js_template.replace('{value}', `${compare_field_id_value}`) + let right = compare_js_template.replace('{value}', `${entry[compare_column]}`) + + // include wrapper quotes if specified + compare_use_quotes ? quotes = '"' : quotes = '' result = eval( - `${eval(left)}` + - ` ${compare_operator} ` + - `${eval(right)}` + quotes + `${eval(left)}` + quotes + + ` ${compare_operator} ` + + quotes + `${eval(right)}` + quotes ); return result; diff --git a/pialert/__main__.py b/pialert/__main__.py index 06b68640..102ca59e 100755 --- a/pialert/__main__.py +++ b/pialert/__main__.py @@ -277,7 +277,7 @@ def main (): last_cleanup = loop_start_time conf.cycle = 'cleanup' mylog('verbose', ['[MAIN] cycle:',conf.cycle]) - db.cleanup_database(startTime, conf.DAYS_TO_KEEP_EVENTS, conf.PHOLUS_DAYS_DATA, conf.HRS_TO_KEEP_NEWDEV) + db.cleanup_database(startTime, conf.DAYS_TO_KEEP_EVENTS, conf.PHOLUS_DAYS_DATA, conf.HRS_TO_KEEP_NEWDEV, conf.PLUGINS_KEEP_HIST) # Commit SQL db.commitDB() diff --git a/pialert/database.py b/pialert/database.py index 4c951085..d1146cf1 100755 --- a/pialert/database.py +++ b/pialert/database.py @@ -76,7 +76,7 @@ class DB(): #=============================================================================== # Cleanup / upkeep database #=============================================================================== - def cleanup_database (self, startTime, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP_NEWDEV): + def cleanup_database (self, startTime, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA, HRS_TO_KEEP_NEWDEV, PLUGINS_KEEP_HIST): """ Cleaning out old records from the tables that don't need to keep all data. """ @@ -130,6 +130,11 @@ class DB(): AND Nmap_Scan.Service = p2.Service );""") + # Delete all Plugins_History entries older than PLUGINS_KEEP_HIST setting + mylog('verbose', [f' Plugins_History: Delete all Plugins_History entries older than {str(PLUGINS_KEEP_HIST)} (PLUGINS_KEEP_HIST setting) days']) + self.sql.execute (f"""DELETE FROM Plugins_History + WHERE DateTimeChanged <= date('now', '-{str(PLUGINS_KEEP_HIST)} day')""") + # Shrink DB mylog('verbose', [' Shrink Database']) self.sql.execute ("VACUUM;") diff --git a/pialert/initialise.py b/pialert/initialise.py index aab1d671..112eb6c8 100755 --- a/pialert/initialise.py +++ b/pialert/initialise.py @@ -72,6 +72,7 @@ def importConfigs (db): conf.LOG_LEVEL = ccd('LOG_LEVEL', 'verbose' , c_d, 'Log verboseness', 'text.select', "['none', 'minimal', 'verbose', 'debug']", 'General') conf.TIMEZONE = ccd('TIMEZONE', 'Europe/Berlin' , c_d, 'Time zone', 'text', '', 'General') conf.ENABLE_PLUGINS = ccd('ENABLE_PLUGINS', True , c_d, 'Enable plugins', 'boolean', '', 'General') + conf.PLUGINS_KEEP_HIST = ccd('PLUGINS_KEEP_HIST', True , c_d, 'Keep history days', 'integer', '7', 'General') conf.PIALERT_WEB_PROTECTION = ccd('PIALERT_WEB_PROTECTION', False , c_d, 'Enable logon', 'boolean', '', 'General') conf.PIALERT_WEB_PASSWORD = ccd('PIALERT_WEB_PASSWORD', '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92' , c_d, 'Logon password', 'readonly', '', 'General') conf.INCLUDED_SECTIONS = ccd('INCLUDED_SECTIONS', ['internet', 'new_devices', 'down_devices', 'events', 'ports'] , c_d, 'Notify on', 'text.multiselect', "['internet', 'new_devices', 'down_devices', 'events', 'ports', 'plugins']", 'General') diff --git a/pialert/plugins/README.md b/pialert/plugins/README.md index 1b87af41..7dcbeecd 100755 --- a/pialert/plugins/README.md +++ b/pialert/plugins/README.md @@ -195,27 +195,55 @@ Used to initialize internal settings. Check the `newdev_template` plugin for det ## Filters -Plugin entries can be filtered based on values entered into filter fields. The `txtMacFilter` textbox/field contains the Mac address of the currently viewed device or simply a mac address that's available in the `mac` query string. +Plugin entries can be filtered based on values entered into filter fields. The `txtMacFilter` textbox/field contains the Mac address of the currently viewed device or simply a Mac address that's available in the `mac` query string. | Property | Required | Description | |----------------------|----------------------|----------------------| | `compare_column` | yes | Plugin column name that's value is used for comparison (**Left** side of the equation) | | `compare_operator` | yes | JavaScript comparison operator | | `compare_field_id` | yes | The `id` of a input text field containing a value is used for comparison (**Right** side of the equation)| - | `compare_js_wrapper` | yes | JavaScript code used to convert left and right side of the equation. `{value}` is replaced with input values. | + | `compare_js_template` | yes | JavaScript code used to convert left and right side of the equation. `{value}` is replaced with input values. | + | `compare_use_quotes` | yes | If `true` then the end result of the `compare_js_template` i swrapped in `"` quotes. Use to compare strings. | +### Example Filter + ```json "data_filters": [ { "compare_column" : "Object_PrimaryID", "compare_operator" : "==", "compare_field_id": "txtMacFilter", - "compare_js_wrapper": "'{value}.toString()'" + "compare_js_template": "'{value}'.toString()", + "compare_use_quotes": true } ], ``` +1. On the `pluginsCore.php` page is an input field with the `txtMacFilter` id: + +```html + +``` + +2. This input field is initialized via the `&mac=` query string. + +3. The app then proceeds to use this Mac value from this field and compares it to the value of the `Object_PrimaryID` database field. The `compare_operator` is `==`. + +4. Both values, from the database field `Object_PrimaryID` and from the `txtMacFilter` are wrapped and evaluated with the `compare_js_template`, that is `'{value}.toString()'`. + +5. `compare_use_quotes` is set to `true` so `'{value}'.toString()` is wrappe dinto `"` quotes. + +6. This results in for example this code: + +```javascript + // left part of teh expression coming from compare_column and right from the input field + // notice the added quotes ()") around the left and right part of teh expression + "eval('ac:82:ac:82:ac:82".toString()')" == "eval('ac:82:ac:82:ac:82".toString()')" +``` + +7. Filters are only applied if a filter is specified and the `txtMacFilter` is not `undefined` or empty (`--`). + ### Mapping the plugin results into a database table PiAlert will take the results of the plugin execution and insert these results into a database table, if a plugin contains the property `"mapped_to_table"` in the `config.json` root. The mapping of the columns is defined in the `database_column_definitions` array. diff --git a/pialert/plugins/dhcp_leases/config.json b/pialert/plugins/dhcp_leases/config.json index 2f8466df..19fba5b2 100755 --- a/pialert/plugins/dhcp_leases/config.json +++ b/pialert/plugins/dhcp_leases/config.json @@ -8,7 +8,8 @@ "compare_column" : "Object_PrimaryID", "compare_operator" : "==", "compare_field_id": "txtMacFilter", - "compare_js_wrapper": "'{value}.toString()'" + "compare_js_template": "'{value}'.toString()", + "compare_use_quotes": true } ], "localized": ["display_name", "description", "icon"], diff --git a/pialert/plugins/nmap_services/config.json b/pialert/plugins/nmap_services/config.json index 7ee84f46..ef2f65a0 100755 --- a/pialert/plugins/nmap_services/config.json +++ b/pialert/plugins/nmap_services/config.json @@ -8,7 +8,8 @@ "compare_column" : "Object_PrimaryID", "compare_operator" : "==", "compare_field_id": "txtMacFilter", - "compare_js_wrapper": "'{value}.toString()'" + "compare_js_template": "'{value}'.toString()", + "compare_use_quotes": true } ], "localized": ["display_name", "description", "icon"], diff --git a/pialert/plugins/snmp_discovery/config.json b/pialert/plugins/snmp_discovery/config.json index 534bb07d..fbb48f73 100755 --- a/pialert/plugins/snmp_discovery/config.json +++ b/pialert/plugins/snmp_discovery/config.json @@ -8,7 +8,8 @@ "compare_column" : "Object_PrimaryID", "compare_operator" : "==", "compare_field_id": "txtMacFilter", - "compare_js_wrapper": "'{value}.toString()'" + "compare_js_template": "'{value}'.toString()", + "compare_use_quotes": true } ], "localized": ["display_name", "description", "icon"], diff --git a/pialert/plugins/unifi_import/config.json b/pialert/plugins/unifi_import/config.json index 96beba17..48db3425 100755 --- a/pialert/plugins/unifi_import/config.json +++ b/pialert/plugins/unifi_import/config.json @@ -8,7 +8,8 @@ "compare_column" : "Object_PrimaryID", "compare_operator" : "==", "compare_field_id": "txtMacFilter", - "compare_js_wrapper": "'{value}.toString()'" + "compare_js_template": "'{value}'.toString()", + "compare_use_quotes": true } ], "localized": ["display_name", "description", "icon"],