mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Just a testing library plugin for development purposes
|
# Just a testing library plugin for development purposes
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import conf
|
import conf
|
||||||
from const import confFileName, logPath
|
from const import confFileName, logPath
|
||||||
from pytz import timezone
|
from pytz import timezone
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import socket
|
import socket
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# test script by running:
|
# test script by running:
|
||||||
# tbc
|
# tbc
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# test script by running:
|
# test script by running:
|
||||||
# tbc
|
# tbc
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# test script by running:
|
# test script by running:
|
||||||
# tbc
|
# tbc
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
__author__ = "ffsb"
|
__author__ = "ffsb"
|
||||||
__version__ = "0.1" # initial
|
__version__ = "0.1" # initial
|
||||||
__version__ = "0.2" # added logic to retry omada api call once as it seems to sometimes fail for some reasons, and error handling logic...
|
__version__ = "0.2" # added logic to retry omada api call once as it seems to sometimes fail for some reasons, and error handling logic...
|
||||||
@@ -134,7 +134,7 @@ def callomada(myargs):
|
|||||||
|
|
||||||
omada_output = ""
|
omada_output = ""
|
||||||
retries = 2
|
retries = 2
|
||||||
while omada_output == "" and retries > 1:
|
while omada_output == "" and retries > 0:
|
||||||
retries = retries - 1
|
retries = retries - 1
|
||||||
try:
|
try:
|
||||||
mf = io.StringIO()
|
mf = io.StringIO()
|
||||||
@@ -183,51 +183,71 @@ def add_uplink(
|
|||||||
sadevices_linksbymac,
|
sadevices_linksbymac,
|
||||||
port_byswitchmac_byclientmac,
|
port_byswitchmac_byclientmac,
|
||||||
):
|
):
|
||||||
# Ensure switch_mac exists in device_data_bymac
|
# Ensure switch exists
|
||||||
if switch_mac not in device_data_bymac:
|
if switch_mac not in device_data_bymac:
|
||||||
mylog("none", [f"[{pluginName}] switch_mac '{switch_mac}' not found in device_data_bymac"])
|
mylog("none", [f"[{pluginName}] switch_mac '{switch_mac}' not found in device_data_bymac"])
|
||||||
return
|
return
|
||||||
|
|
||||||
# Ensure SWITCH_AP key exists in the dictionary
|
dev_switch = device_data_bymac[switch_mac]
|
||||||
if SWITCH_AP not in device_data_bymac[switch_mac]:
|
|
||||||
mylog("none", [f"[{pluginName}] Missing key '{SWITCH_AP}' in device_data_bymac[{switch_mac}]"])
|
# Ensure list is long enough to contain SWITCH_AP index
|
||||||
|
if len(dev_switch) <= SWITCH_AP:
|
||||||
|
mylog("none", [f"[{pluginName}] SWITCH_AP index {SWITCH_AP} missing in record for {switch_mac}"])
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check if uplink should be added
|
# Add uplink only if empty
|
||||||
if device_data_bymac[switch_mac][SWITCH_AP] in [None, "null"]:
|
if dev_switch[SWITCH_AP] in (None, "null"):
|
||||||
device_data_bymac[switch_mac][SWITCH_AP] = uplink_mac
|
dev_switch[SWITCH_AP] = uplink_mac
|
||||||
|
|
||||||
# Ensure uplink_mac exists in device_data_bymac
|
# Validate uplink_mac exists
|
||||||
if uplink_mac not in device_data_bymac:
|
if uplink_mac not in device_data_bymac:
|
||||||
mylog("none", [f"[{pluginName}] uplink_mac '{uplink_mac}' not found in device_data_bymac"])
|
mylog("none", [f"[{pluginName}] uplink_mac '{uplink_mac}' not found in device_data_bymac"])
|
||||||
return
|
return
|
||||||
|
|
||||||
# Determine port to uplink
|
dev_uplink = device_data_bymac[uplink_mac]
|
||||||
if (
|
|
||||||
device_data_bymac[switch_mac].get(TYPE) == "Switch" and device_data_bymac[uplink_mac].get(TYPE) == "Switch"
|
# Get TYPE safely
|
||||||
):
|
switch_type = dev_switch[TYPE] if len(dev_switch) > TYPE else None
|
||||||
|
uplink_type = dev_uplink[TYPE] if len(dev_uplink) > TYPE else None
|
||||||
|
|
||||||
|
# Switch-to-switch link → use port mapping
|
||||||
|
if switch_type == "Switch" and uplink_type == "Switch":
|
||||||
port_to_uplink = port_byswitchmac_byclientmac.get(switch_mac, {}).get(uplink_mac)
|
port_to_uplink = port_byswitchmac_byclientmac.get(switch_mac, {}).get(uplink_mac)
|
||||||
if port_to_uplink is None:
|
if port_to_uplink is None:
|
||||||
mylog("none", [f"[{pluginName}] Missing port info for switch_mac '{switch_mac}' and uplink_mac '{uplink_mac}'"])
|
mylog("none", [
|
||||||
|
f"[{pluginName}] Missing port info for {switch_mac} → {uplink_mac}"
|
||||||
|
])
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
port_to_uplink = device_data_bymac[uplink_mac].get(PORT_SSID)
|
# Other device types → read PORT_SSID index
|
||||||
|
if len(dev_uplink) <= PORT_SSID:
|
||||||
|
mylog("none", [
|
||||||
|
f"[{pluginName}] PORT_SSID index missing for uplink {uplink_mac}"
|
||||||
|
])
|
||||||
|
return
|
||||||
|
port_to_uplink = dev_uplink[PORT_SSID]
|
||||||
|
|
||||||
# Assign port to switch_mac
|
# Assign port to switch
|
||||||
device_data_bymac[switch_mac][PORT_SSID] = port_to_uplink
|
if len(dev_switch) > PORT_SSID:
|
||||||
|
dev_switch[PORT_SSID] = port_to_uplink
|
||||||
|
else:
|
||||||
|
mylog("none", [
|
||||||
|
f"[{pluginName}] PORT_SSID index missing in switch {switch_mac}"
|
||||||
|
])
|
||||||
|
|
||||||
# Recursively add uplinks for linked devices
|
# Process children recursively
|
||||||
for link in sadevices_linksbymac.get(switch_mac, []):
|
for link in sadevices_linksbymac.get(switch_mac, []):
|
||||||
if (
|
if (
|
||||||
link in device_data_bymac and device_data_bymac[link].get(SWITCH_AP) in [None, "null"] and device_data_bymac[switch_mac].get(TYPE) == "Switch"
|
link in device_data_bymac and len(device_data_bymac[link]) > SWITCH_AP and device_data_bymac[link][SWITCH_AP] in (None, "null") and len(dev_switch) > TYPE
|
||||||
):
|
):
|
||||||
add_uplink(
|
if dev_switch[TYPE] == "Switch":
|
||||||
switch_mac,
|
add_uplink(
|
||||||
link,
|
switch_mac,
|
||||||
device_data_bymac,
|
link,
|
||||||
sadevices_linksbymac,
|
device_data_bymac,
|
||||||
port_byswitchmac_byclientmac,
|
sadevices_linksbymac,
|
||||||
)
|
port_byswitchmac_byclientmac,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------
|
# ----------------------------------------------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This plugin imports devices and clients from Omada Controller using their OpenAPI.
|
This plugin imports devices and clients from Omada Controller using their OpenAPI.
|
||||||
@@ -296,7 +296,7 @@ class OmadaAPI:
|
|||||||
OmadaHelper.verbose(f"{method} request error: {str(ex)}")
|
OmadaHelper.verbose(f"{method} request error: {str(ex)}")
|
||||||
return OmadaHelper.response("error", f"{method} request failed to endpoint '{endpoint}' with error: {str(ex)}")
|
return OmadaHelper.response("error", f"{method} request failed to endpoint '{endpoint}' with error: {str(ex)}")
|
||||||
|
|
||||||
def authenticate(self) -> Dict[str, any]:
|
def authenticate(self) -> Dict[str, Any]:
|
||||||
"""Make an endpoint request to get access token."""
|
"""Make an endpoint request to get access token."""
|
||||||
OmadaHelper.verbose("Starting authentication process")
|
OmadaHelper.verbose("Starting authentication process")
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""
|
"""
|
||||||
NetAlertX plugin: PIHOLEAPI
|
NetAlertX plugin: PIHOLEAPI
|
||||||
Imports devices from Pi-hole v6 API (Network endpoints) into NetAlertX plugin results.
|
Imports devices from Pi-hole v6 API (Network endpoints) into NetAlertX plugin results.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Inspired by https://github.com/stevehoek/Pi.Alert
|
# Inspired by https://github.com/stevehoek/Pi.Alert
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
# Based on the work of https://github.com/leiweibau/Pi.Alert
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
4
ruff.toml
Normal file
4
ruff.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[lint]
|
||||||
|
select = ["E", "F"] # or whatever you are using
|
||||||
|
# Add E402 so Ruff knows the noqa is legitimate
|
||||||
|
extend-select = ["E402"]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
NetAlertX-New-Devices-Checkmk-Script
|
NetAlertX-New-Devices-Checkmk-Script
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ def parse_timestamp(date_str):
|
|||||||
dt = datetime.strptime(clean_date, '%Y/%m/%d %H:%M:%S')
|
dt = datetime.strptime(clean_date, '%Y/%m/%d %H:%M:%S')
|
||||||
return int(dt.timestamp())
|
return int(dt.timestamp())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Failed to parse timestamp: {date_str} ({e})")
|
if logger:
|
||||||
|
logger.error(f"Failed to parse timestamp: {date_str} ({e})")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -83,9 +84,8 @@ def get_lease_file(hostname, username, password=None, key_filename=None, port=22
|
|||||||
|
|
||||||
# Clean up the output by removing the command echo and shell prompts
|
# Clean up the output by removing the command echo and shell prompts
|
||||||
lines = output.split('\n')
|
lines = output.split('\n')
|
||||||
|
|
||||||
# Remove first line (command echo) and any lines containing shell prompts
|
# Remove first line (command echo) and any lines containing shell prompts
|
||||||
# cleaned_lines = [line for line in lines
|
|
||||||
# if not line.strip().startswith(command.strip()) and not line.strip().endswith('> ') and not line.strip().endswith('# ')]
|
|
||||||
cmd = command.strip()
|
cmd = command.strip()
|
||||||
|
|
||||||
cleaned_lines = []
|
cleaned_lines = []
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# NetAlertX v2.70 / 2021-02-01
|
# NetAlertX v2.70 / 2021-02-01
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|||||||
@@ -136,23 +136,6 @@ def ensure_views(sql) -> bool:
|
|||||||
"""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;"""
|
"""CREATE VIEW Sessions_Devices AS SELECT * FROM Sessions LEFT JOIN "Devices" ON ses_MAC = devMac;"""
|
||||||
)
|
)
|
||||||
|
|
||||||
sql.execute(""" CREATE VIEW IF NOT EXISTS LatestEventsPerMAC AS
|
|
||||||
WITH RankedEvents AS (
|
|
||||||
SELECT
|
|
||||||
e.*,
|
|
||||||
ROW_NUMBER() OVER (PARTITION BY e.eve_MAC ORDER BY e.eve_DateTime DESC) AS row_num
|
|
||||||
FROM Events AS e
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
e.*,
|
|
||||||
d.*,
|
|
||||||
c.*
|
|
||||||
FROM RankedEvents AS e
|
|
||||||
LEFT JOIN Devices AS d ON e.eve_MAC = d.devMac
|
|
||||||
INNER JOIN CurrentScan AS c ON e.eve_MAC = c.cur_MAC
|
|
||||||
WHERE e.row_num = 1;
|
|
||||||
""")
|
|
||||||
|
|
||||||
# handling the Convert_Events_to_Sessions / Sessions screens
|
# handling the Convert_Events_to_Sessions / Sessions screens
|
||||||
sql.execute("""DROP VIEW IF EXISTS Convert_Events_to_Sessions;""")
|
sql.execute("""DROP VIEW IF EXISTS Convert_Events_to_Sessions;""")
|
||||||
sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
|
sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
|
||||||
|
|||||||
@@ -624,6 +624,11 @@ def extract_ip_addresses(text):
|
|||||||
# Helper function to determine if a MAC address is random
|
# Helper function to determine if a MAC address is random
|
||||||
def is_random_mac(mac):
|
def is_random_mac(mac):
|
||||||
"""Determine if a MAC address is random, respecting user-defined prefixes not to mark as random."""
|
"""Determine if a MAC address is random, respecting user-defined prefixes not to mark as random."""
|
||||||
|
|
||||||
|
# Validate input
|
||||||
|
if not mac or len(mac) < 2:
|
||||||
|
return False
|
||||||
|
|
||||||
# Check if second character matches "2", "6", "A", "E" (case insensitive)
|
# Check if second character matches "2", "6", "A", "E" (case insensitive)
|
||||||
is_random = mac[1].upper() in ["2", "6", "A", "E"]
|
is_random = mac[1].upper() in ["2", "6", "A", "E"]
|
||||||
|
|
||||||
@@ -631,7 +636,7 @@ def is_random_mac(mac):
|
|||||||
if is_random:
|
if is_random:
|
||||||
not_random_prefixes = get_setting_value("UI_NOT_RANDOM_MAC")
|
not_random_prefixes = get_setting_value("UI_NOT_RANDOM_MAC")
|
||||||
for prefix in not_random_prefixes:
|
for prefix in not_random_prefixes:
|
||||||
if mac.startswith(prefix):
|
if mac.upper().startswith(prefix.upper()):
|
||||||
is_random = False
|
is_random = False
|
||||||
break
|
break
|
||||||
return is_random
|
return is_random
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import re
|
|||||||
# Register NetAlertX libraries
|
# Register NetAlertX libraries
|
||||||
import conf
|
import conf
|
||||||
from const import fullConfPath, fullConfFolder, default_tz
|
from const import fullConfPath, fullConfFolder, default_tz
|
||||||
from helper import getBuildTimeStampAndVersion, fixPermissions, collect_lang_strings, updateSubnets, generate_random_string
|
from helper import getBuildTimeStampAndVersion, collect_lang_strings, updateSubnets, generate_random_string
|
||||||
from utils.datetime_utils import timeNowDB
|
from utils.datetime_utils import timeNowDB
|
||||||
from app_state import updateState
|
from app_state import updateState
|
||||||
from logger import mylog
|
from logger import mylog
|
||||||
@@ -680,10 +680,11 @@ def importConfigs(pm, db, all_plugins):
|
|||||||
ccd('VERSION', new_version , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True)
|
ccd('VERSION', new_version , c_d, '_KEEP_', '_KEEP_', '_KEEP_', '_KEEP_', None, "_KEEP_", None, None, True)
|
||||||
|
|
||||||
write_notification(f'[Upgrade]: App upgraded from <code>{prev_version}</code> to \
|
write_notification(f'[Upgrade]: App upgraded from <code>{prev_version}</code> to \
|
||||||
<code>{new_version}</ code> 🚀 Please clear the cache: \
|
<code>{new_version}</code> 🚀 Please clear the cache: \
|
||||||
<ol> <li>Click OK below</li> <li>Clear the browser cache (shift + \
|
<ol> <li>Click OK below</li> \
|
||||||
browser refresh button)</li> <li> Clear app cache with the <i class="fa-solid fa-rotate"></i> \
|
<li>Clear the browser cache (shift + browser refresh button)</li> \
|
||||||
(reload) button in the header</li><li>Go to Settings and click Save</li> </ol>\
|
<li> Clear app cache with the <i class="fa-solid fa-rotate"></i> (reload) button in the header</li>\
|
||||||
|
<li>Go to Settings and click Save</li> </ol>\
|
||||||
Check out new features and what has changed in the \
|
Check out new features and what has changed in the \
|
||||||
<a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.',
|
<a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.',
|
||||||
'interrupt',
|
'interrupt',
|
||||||
@@ -804,8 +805,6 @@ def renameSettings(config_file):
|
|||||||
str(config_file) + "_temp", str(config_file)
|
str(config_file) + "_temp", str(config_file)
|
||||||
) # Convert config_file to a string
|
) # Convert config_file to a string
|
||||||
|
|
||||||
# ensure correct ownership
|
|
||||||
fixPermissions()
|
|
||||||
else:
|
else:
|
||||||
mylog(
|
mylog(
|
||||||
"debug", "[Config] No old setting names found in the file. No changes made."
|
"debug", "[Config] No old setting names found in the file. No changes made."
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# from datetime import datetime
|
# from datetime import datetime
|
||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ def test_devices_by_status(client, api_token, test_mac):
|
|||||||
assert "★" in fav_data["title"]
|
assert "★" in fav_data["title"]
|
||||||
|
|
||||||
|
|
||||||
def test_delete_test_devices(client, api_token, test_mac):
|
def test_delete_test_devices(client, api_token):
|
||||||
|
|
||||||
# Delete by MAC
|
# Delete by MAC
|
||||||
resp = client.delete("/devices", json={"macs": ["AA:BB:CC:*"]}, headers=auth_headers(api_token))
|
resp = client.delete("/devices", json={"macs": ["AA:BB:CC:*"]}, headers=auth_headers(api_token))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Comprehensive SQL Injection Prevention Tests for NetAlertX
|
Comprehensive SQL Injection Prevention Tests for NetAlertX
|
||||||
|
|
||||||
|
|||||||
@@ -210,7 +210,6 @@ class TestDatabaseParameterSupport(unittest.TestCase):
|
|||||||
# This should not cause SQL injection
|
# This should not cause SQL injection
|
||||||
malicious_input = "'; DROP TABLE test_table; --"
|
malicious_input = "'; DROP TABLE test_table; --"
|
||||||
cursor.execute("SELECT * FROM test_table WHERE name = :name", {'name': malicious_input})
|
cursor.execute("SELECT * FROM test_table WHERE name = :name", {'name': malicious_input})
|
||||||
# results = cursor.fetchall()
|
|
||||||
|
|
||||||
# The table should still exist and be queryable
|
# The table should still exist and be queryable
|
||||||
cursor.execute("SELECT COUNT(*) FROM test_table")
|
cursor.execute("SELECT COUNT(*) FROM test_table")
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# !/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Pytest-based Mount Diagnostic Tests for NetAlertX
|
Pytest-based Mount Diagnostic Tests for NetAlertX
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ from messaging.reporting import get_notifications # noqa: E402 [flake8 lint sup
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def test_db_path():
|
def test_db_path():
|
||||||
path = tempfile.mktemp(suffix=".db")
|
with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as tmp:
|
||||||
|
path = tmp.name
|
||||||
yield path
|
yield path
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
|
|||||||
Reference in New Issue
Block a user