/data and /tmp standarization

This commit is contained in:
Adam Outler
2025-11-04 22:26:35 +00:00
parent 90a07c61eb
commit 5b871865db
250 changed files with 7462 additions and 4940 deletions

View File

@@ -1,50 +1,50 @@
#---------------------------------------------------------------------------------#
# ---------------------------------------------------------------------------------#
# NetAlertX #
# Open Source Network Guard / WIFI & LAN intrusion detector #
# Open Source Network Guard / WIFI & LAN intrusion detector #
# #
# reporting.py - NetAlertX Back module. Template to email reporting in HTML format #
#---------------------------------------------------------------------------------#
# ---------------------------------------------------------------------------------#
# Puche 2021 pi.alert.application@gmail.com GNU GPLv3 #
# jokob-sk 2022 jokob.sk@gmail.com GNU GPLv3 #
# leiweibau 2022 https://github.com/leiweibau GNU GPLv3 #
# cvc90 2023 https://github.com/cvc90 GNU GPLv3 #
#---------------------------------------------------------------------------------#
# ---------------------------------------------------------------------------------#
import datetime
import json
import os
import sys
# Register NetAlertX directories
INSTALL_PATH="/app"
INSTALL_PATH = os.getenv("NETALERTX_APP", "/app")
sys.path.extend([f"{INSTALL_PATH}/server"])
import conf
from const import applicationPath, logPath, apiPath, confFileName
from helper import timeNowTZ, get_file_content, write_file, get_timezone_offset, get_setting_value
from logger import logResult, mylog
from helper import (
get_timezone_offset,
get_setting_value,
)
from logger import mylog
from db.sql_safe_builder import create_safe_condition_builder
#===============================================================================
# ===============================================================================
# REPORTING
#===============================================================================
# ===============================================================================
#-------------------------------------------------------------------------------
def get_notifications (db):
# -------------------------------------------------------------------------------
def get_notifications(db):
sql = db.sql # TO-DO
sql = db.sql #TO-DO
# Reporting section
mylog('verbose', ['[Notification] Check if something to report'])
mylog("verbose", ["[Notification] Check if something to report"])
# prepare variables for JSON construction
# prepare variables for JSON construction
json_new_devices = []
json_new_devices_meta = {}
json_down_devices = []
json_down_devices_meta = {}
json_down_reconnected = []
json_down_reconnected_meta = {}
json_events = []
json_events = []
json_events_meta = {}
json_plugins = []
json_plugins_meta = {}
@@ -52,37 +52,42 @@ def get_notifications (db):
# Disable reporting on events for devices where reporting is disabled based on the MAC address
# Disable notifications (except down/down reconnected) on devices where devAlertEvents is disabled
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
sql.execute("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType not in ('Device Down', 'Down Reconnected', 'New Device' ) AND eve_MAC IN
(
SELECT devMac FROM Devices WHERE devAlertEvents = 0
)""")
# Disable down/down reconnected notifications on devices where devAlertDown is disabled
sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
sql.execute("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_EventType in ('Device Down', 'Down Reconnected') AND eve_MAC IN
(
SELECT devMac FROM Devices WHERE devAlertDown = 0
)""")
sections = get_setting_value('NTFPRCS_INCLUDED_SECTIONS')
mylog('verbose', ['[Notification] Included sections: ', sections ])
sections = get_setting_value("NTFPRCS_INCLUDED_SECTIONS")
if 'new_devices' in sections:
mylog("verbose", ["[Notification] Included sections: ", sections])
if "new_devices" in sections:
# Compose New Devices Section (no empty lines in SQL queries!)
# Use SafeConditionBuilder to prevent SQL injection vulnerabilities
condition_builder = create_safe_condition_builder()
new_dev_condition_setting = get_setting_value('NTFPRCS_new_dev_condition')
new_dev_condition_setting = get_setting_value("NTFPRCS_new_dev_condition")
try:
safe_condition, parameters = condition_builder.get_safe_condition_legacy(new_dev_condition_setting)
safe_condition, parameters = condition_builder.get_safe_condition_legacy(
new_dev_condition_setting
)
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
AND eve_EventType = 'New Device' {}
ORDER BY eve_DateTime""".format(safe_condition)
except Exception as e:
mylog('verbose', ['[Notification] Error building safe condition for new devices: ', e])
mylog(
"verbose",
["[Notification] Error building safe condition for new devices: ", e],
)
# Fall back to safe default (no additional conditions)
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
@@ -90,23 +95,23 @@ def get_notifications (db):
ORDER BY eve_DateTime"""
parameters = {}
mylog('debug', ['[Notification] new_devices SQL query: ', sqlQuery ])
mylog('debug', ['[Notification] new_devices parameters: ', parameters ])
mylog("debug", ["[Notification] new_devices SQL query: ", sqlQuery])
mylog("debug", ["[Notification] new_devices parameters: ", parameters])
# Get the events as JSON using parameterized query
json_obj = db.get_table_as_json(sqlQuery, parameters)
json_new_devices_meta = {
"title": "🆕 New devices",
"columnNames": json_obj.columnNames
"columnNames": json_obj.columnNames,
}
json_new_devices = json_obj.json["data"]
json_new_devices = json_obj.json["data"]
if 'down_devices' in sections:
# Compose Devices Down Section
if "down_devices" in sections:
# Compose Devices Down Section
# - select only Down Alerts with pending email of devices that didn't reconnect within the specified time window
minutes = int(get_setting_value('NTFPRCS_alert_down_time') or 0)
minutes = int(get_setting_value("NTFPRCS_alert_down_time") or 0)
tz_offset = get_timezone_offset()
sqlQuery = f"""
SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
@@ -123,54 +128,68 @@ def get_notifications (db):
)
ORDER BY down_events.eve_DateTime;
"""
# Get the events as JSON
# Get the events as JSON
json_obj = db.get_table_as_json(sqlQuery)
json_down_devices_meta = {
json_down_devices_meta = {
"title": "🔴 Down devices",
"columnNames": json_obj.columnNames
"columnNames": json_obj.columnNames,
}
json_down_devices = json_obj.json["data"]
json_down_devices = json_obj.json["data"]
mylog('debug', ['[Notification] json_down_devices: ', json.dumps(json_down_devices) ])
if 'down_reconnected' in sections:
# Compose Reconnected Down Section
# - select only Devices, that were previously down and now are Connected
sqlQuery = f"""
mylog(
"debug",
["[Notification] json_down_devices: ", json.dumps(json_down_devices)],
)
if "down_reconnected" in sections:
# Compose Reconnected Down Section
# - select only Devices, that were previously down and now are Connected
sqlQuery = """
SELECT devName, eve_MAC, devVendor, eve_IP, eve_DateTime, eve_EventType
FROM Events_Devices AS reconnected_devices
WHERE reconnected_devices.eve_EventType = 'Down Reconnected'
AND reconnected_devices.eve_PendingAlertEmail = 1
ORDER BY reconnected_devices.eve_DateTime;
"""
# Get the events as JSON
# Get the events as JSON
json_obj = db.get_table_as_json(sqlQuery)
json_down_reconnected_meta = {
"title": "🔁 Reconnected down devices",
"columnNames": json_obj.columnNames
"columnNames": json_obj.columnNames,
}
json_down_reconnected = json_obj.json["data"]
json_down_reconnected = json_obj.json["data"]
mylog('debug', ['[Notification] json_down_reconnected: ', json.dumps(json_down_reconnected) ])
mylog(
"debug",
[
"[Notification] json_down_reconnected: ",
json.dumps(json_down_reconnected),
],
)
if 'events' in sections:
if "events" in sections:
# Compose Events Section (no empty lines in SQL queries!)
# Use SafeConditionBuilder to prevent SQL injection vulnerabilities
condition_builder = create_safe_condition_builder()
event_condition_setting = get_setting_value('NTFPRCS_event_condition')
event_condition_setting = get_setting_value("NTFPRCS_event_condition")
try:
safe_condition, parameters = condition_builder.get_safe_condition_legacy(event_condition_setting)
safe_condition, parameters = condition_builder.get_safe_condition_legacy(
event_condition_setting
)
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
AND eve_EventType IN ('Connected', 'Down Reconnected', 'Disconnected','IP Changed') {}
ORDER BY eve_DateTime""".format(safe_condition)
except Exception as e:
mylog('verbose', ['[Notification] Error building safe condition for events: ', e])
mylog(
"verbose",
["[Notification] Error building safe condition for events: ", e],
)
# Fall back to safe default (no additional conditions)
sqlQuery = """SELECT eve_MAC as MAC, eve_DateTime as Datetime, devLastIP as IP, eve_EventType as "Event Type", devName as "Device name", devComments as Comments FROM Events_Devices
WHERE eve_PendingAlertEmail = 1
@@ -178,51 +197,43 @@ def get_notifications (db):
ORDER BY eve_DateTime"""
parameters = {}
mylog('debug', ['[Notification] events SQL query: ', sqlQuery ])
mylog('debug', ['[Notification] events parameters: ', parameters ])
mylog("debug", ["[Notification] events SQL query: ", sqlQuery])
mylog("debug", ["[Notification] events parameters: ", parameters])
# Get the events as JSON using parameterized query
json_obj = db.get_table_as_json(sqlQuery, parameters)
json_events_meta = {
"title": "⚡ Events",
"columnNames": json_obj.columnNames
}
json_events = json_obj.json["data"]
json_events_meta = {"title": "⚡ Events", "columnNames": json_obj.columnNames}
json_events = json_obj.json["data"]
if 'plugins' in sections:
if "plugins" in sections:
# Compose Plugins Section
sqlQuery = """SELECT Plugin, Object_PrimaryId, Object_SecondaryId, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status from Plugins_Events"""
# Get the events as JSON
sqlQuery = """SELECT Plugin, Object_PrimaryId, Object_SecondaryId, DateTimeChanged, Watched_Value1, Watched_Value2, Watched_Value3, Watched_Value4, Status from Plugins_Events"""
# Get the events as JSON
json_obj = db.get_table_as_json(sqlQuery)
json_plugins_meta = {
"title": "🔌 Plugins",
"columnNames": json_obj.columnNames
}
json_plugins = json_obj.json["data"]
json_plugins_meta = {"title": "🔌 Plugins", "columnNames": json_obj.columnNames}
json_plugins = json_obj.json["data"]
final_json = {
"new_devices": json_new_devices,
"new_devices_meta": json_new_devices_meta,
"down_devices": json_down_devices,
"down_devices_meta": json_down_devices_meta,
"down_reconnected": json_down_reconnected,
"down_reconnected_meta": json_down_reconnected_meta,
"events": json_events,
"events_meta": json_events_meta,
"plugins": json_plugins,
"plugins_meta": json_plugins_meta,
}
final_json = {
"new_devices": json_new_devices,
"new_devices_meta": json_new_devices_meta,
"down_devices": json_down_devices,
"down_devices_meta": json_down_devices_meta,
"down_reconnected": json_down_reconnected,
"down_reconnected_meta": json_down_reconnected_meta,
"events": json_events,
"events_meta": json_events_meta,
"plugins": json_plugins,
"plugins_meta": json_plugins_meta,
}
return final_json
#-------------------------------------------------------------------------------
def skip_repeated_notifications (db):
# -------------------------------------------------------------------------------
def skip_repeated_notifications(db):
"""
Skips sending alerts for devices recently notified.
@@ -235,9 +246,9 @@ def skip_repeated_notifications (db):
# Skip repeated notifications
# due strfime : Overflow --> use "strftime / 60"
mylog('verbose','[Skip Repeated Notifications] Skip Repeated')
db.sql.execute ("""UPDATE Events SET eve_PendingAlertEmail = 0
mylog("verbose", "[Skip Repeated Notifications] Skip Repeated")
db.sql.execute("""UPDATE Events SET eve_PendingAlertEmail = 0
WHERE eve_PendingAlertEmail = 1 AND eve_MAC IN
(
SELECT devMac FROM Devices
@@ -247,12 +258,6 @@ def skip_repeated_notifications (db):
devSkipRepeated * 60) >
(strftime('%s','now','localtime')/60 )
)
""" )
""")
db.commitDB()