Plugins filter + #253
This commit is contained in:
@@ -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 <a target="_blank" href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones" rel="nofollow">here</a>.',
|
||||
'ENABLE_PLUGINS_name' => 'Enable Plugins',
|
||||
'ENABLE_PLUGINS_description' => 'Enables the <a target="_blank" href="https://github.com/jokob-sk/Pi.Alert/tree/main/pialert/plugins">plugins</a> 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 <code>0</code> to disable.',
|
||||
|
||||
|
||||
// Nmap
|
||||
'Nmap_display_name' => 'Nmap',
|
||||
'Nmap_icon' => '<i class="fa fa-ethernet"></i>',
|
||||
|
||||
@@ -37,6 +37,7 @@ function initFields() {
|
||||
|
||||
getData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -353,7 +354,7 @@ function generateTabs()
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="plugin-obj-purge">
|
||||
<button class="btn btn-primary" onclick="purgeAll('${pluginObj.unique_prefix}', 'Plugins_Objects' )"><?= lang('Gen_DeleteAll');?></button>
|
||||
<button class="btn btn-primary" onclick="purgeAll('${pluginObj.unique_prefix}', 'Plugins_Objects' )"><?= lang('Plugins_DeleteAll');?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="eventsTarget_${pluginObj.unique_prefix}" class="tab-pane">
|
||||
@@ -367,7 +368,7 @@ function generateTabs()
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="plugin-obj-purge">
|
||||
<button class="btn btn-primary" onclick="purgeAll('${pluginObj.unique_prefix}', 'Plugins_Events' )"><?= lang('Gen_DeleteAll');?></button>
|
||||
<button class="btn btn-primary" onclick="purgeAll('${pluginObj.unique_prefix}', 'Plugins_Events' )"><?= lang('Plugins_DeleteAll');?></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="historyTarget_${pluginObj.unique_prefix}" class="tab-pane">
|
||||
@@ -381,7 +382,7 @@ function generateTabs()
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="plugin-obj-purge">
|
||||
<button class="btn btn-primary" onclick="purgeAll('${pluginObj.unique_prefix}', 'Plugins_History' )"><?= lang('Gen_DeleteAll');?></button>
|
||||
<button class="btn btn-primary" onclick="purgeAll('${pluginObj.unique_prefix}', 'Plugins_History' )"><?= lang('Plugins_DeleteAll');?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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])
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;")
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
<input class="form-control" id="txtMacFilter" type="text" value="--">
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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"],
|
||||
|
||||
@@ -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"],
|
||||
|
||||
Reference in New Issue
Block a user