diff --git a/front/plugins/__template/rename_me.py b/front/plugins/__template/rename_me.py
index 6fe0bd61..1dae2e3f 100755
--- a/front/plugins/__template/rename_me.py
+++ b/front/plugins/__template/rename_me.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/__test/test.py b/front/plugins/__test/test.py
index 555a6bd6..2a62cbfb 100755
--- a/front/plugins/__test/test.py
+++ b/front/plugins/__test/test.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# Just a testing library plugin for development purposes
import os
import sys
diff --git a/front/plugins/_publisher_apprise/apprise.py b/front/plugins/_publisher_apprise/apprise.py
index f84c069d..15cb333f 100755
--- a/front/plugins/_publisher_apprise/apprise.py
+++ b/front/plugins/_publisher_apprise/apprise.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import json
import subprocess
diff --git a/front/plugins/_publisher_email/email_smtp.py b/front/plugins/_publisher_email/email_smtp.py
index df18cb6a..a29ea137 100755
--- a/front/plugins/_publisher_email/email_smtp.py
+++ b/front/plugins/_publisher_email/email_smtp.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
import re
diff --git a/front/plugins/_publisher_mqtt/mqtt.py b/front/plugins/_publisher_mqtt/mqtt.py
index 9d7a6ee8..76e6afea 100755
--- a/front/plugins/_publisher_mqtt/mqtt.py
+++ b/front/plugins/_publisher_mqtt/mqtt.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import json
import os
diff --git a/front/plugins/_publisher_ntfy/ntfy.py b/front/plugins/_publisher_ntfy/ntfy.py
index 71f91811..9d86be91 100755
--- a/front/plugins/_publisher_ntfy/ntfy.py
+++ b/front/plugins/_publisher_ntfy/ntfy.py
@@ -1,5 +1,5 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import json
import os
diff --git a/front/plugins/_publisher_pushover/pushover.py b/front/plugins/_publisher_pushover/pushover.py
index 28e87a5a..d51dc1ed 100755
--- a/front/plugins/_publisher_pushover/pushover.py
+++ b/front/plugins/_publisher_pushover/pushover.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
import conf
from const import confFileName, logPath
from pytz import timezone
diff --git a/front/plugins/_publisher_pushsafer/pushsafer.py b/front/plugins/_publisher_pushsafer/pushsafer.py
index dda0b601..a46681e5 100755
--- a/front/plugins/_publisher_pushsafer/pushsafer.py
+++ b/front/plugins/_publisher_pushsafer/pushsafer.py
@@ -1,5 +1,5 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import json
import os
diff --git a/front/plugins/_publisher_telegram/tg.py b/front/plugins/_publisher_telegram/tg.py
index 45bda08e..237096cc 100755
--- a/front/plugins/_publisher_telegram/tg.py
+++ b/front/plugins/_publisher_telegram/tg.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import subprocess
import os
diff --git a/front/plugins/_publisher_webhook/webhook.py b/front/plugins/_publisher_webhook/webhook.py
index deace014..597e2a8b 100755
--- a/front/plugins/_publisher_webhook/webhook.py
+++ b/front/plugins/_publisher_webhook/webhook.py
@@ -1,5 +1,5 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import json
import subprocess
diff --git a/front/plugins/arp_scan/script.py b/front/plugins/arp_scan/script.py
index eda50387..f6c36363 100755
--- a/front/plugins/arp_scan/script.py
+++ b/front/plugins/arp_scan/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import time
import argparse
diff --git a/front/plugins/asuswrt_import/script.py b/front/plugins/asuswrt_import/script.py
index bb4c1a4b..b7be6277 100755
--- a/front/plugins/asuswrt_import/script.py
+++ b/front/plugins/asuswrt_import/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/avahi_scan/avahi_scan.py b/front/plugins/avahi_scan/avahi_scan.py
index 119dff22..5c552181 100755
--- a/front/plugins/avahi_scan/avahi_scan.py
+++ b/front/plugins/avahi_scan/avahi_scan.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
import os
import sys
import socket
diff --git a/front/plugins/csv_backup/script.py b/front/plugins/csv_backup/script.py
index 124843ee..2a7f0433 100755
--- a/front/plugins/csv_backup/script.py
+++ b/front/plugins/csv_backup/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import argparse
diff --git a/front/plugins/db_cleanup/script.py b/front/plugins/db_cleanup/script.py
index e657b75a..bf0743de 100755
--- a/front/plugins/db_cleanup/script.py
+++ b/front/plugins/db_cleanup/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/ddns_update/script.py b/front/plugins/ddns_update/script.py
index f38d231d..39bdade4 100755
--- a/front/plugins/ddns_update/script.py
+++ b/front/plugins/ddns_update/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import argparse
diff --git a/front/plugins/dhcp_leases/script.py b/front/plugins/dhcp_leases/script.py
index 2366bc93..88e15dd1 100755
--- a/front/plugins/dhcp_leases/script.py
+++ b/front/plugins/dhcp_leases/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
from __future__ import unicode_literals
import argparse
diff --git a/front/plugins/dhcp_servers/script.py b/front/plugins/dhcp_servers/script.py
index 665ae155..51074c99 100755
--- a/front/plugins/dhcp_servers/script.py
+++ b/front/plugins/dhcp_servers/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# Based on the work of https://github.com/leiweibau/Pi.Alert
import subprocess
diff --git a/front/plugins/dig_scan/digscan.py b/front/plugins/dig_scan/digscan.py
index 90fa17ad..15280af2 100755
--- a/front/plugins/dig_scan/digscan.py
+++ b/front/plugins/dig_scan/digscan.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
import subprocess
diff --git a/front/plugins/freebox/freebox.py b/front/plugins/freebox/freebox.py
index f3088cb6..9c3b8ea9 100755
--- a/front/plugins/freebox/freebox.py
+++ b/front/plugins/freebox/freebox.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/icmp_scan/icmp.py b/front/plugins/icmp_scan/icmp.py
index 461a7e32..82544800 100755
--- a/front/plugins/icmp_scan/icmp.py
+++ b/front/plugins/icmp_scan/icmp.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# test script by running:
# tbc
diff --git a/front/plugins/internet_ip/script.py b/front/plugins/internet_ip/script.py
index 5cb98e11..ff5d3cea 100755
--- a/front/plugins/internet_ip/script.py
+++ b/front/plugins/internet_ip/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import time
diff --git a/front/plugins/internet_speedtest/script.py b/front/plugins/internet_speedtest/script.py
index c0f1a083..feca2887 100755
--- a/front/plugins/internet_speedtest/script.py
+++ b/front/plugins/internet_speedtest/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/ipneigh/ipneigh.py b/front/plugins/ipneigh/ipneigh.py
index 4ca9ee9f..3d999f7a 100755
--- a/front/plugins/ipneigh/ipneigh.py
+++ b/front/plugins/ipneigh/ipneigh.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/luci_import/script.py b/front/plugins/luci_import/script.py
index 692fa55b..307dd9cb 100755
--- a/front/plugins/luci_import/script.py
+++ b/front/plugins/luci_import/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/maintenance/maintenance.py b/front/plugins/maintenance/maintenance.py
index 379f88a1..c12d0607 100755
--- a/front/plugins/maintenance/maintenance.py
+++ b/front/plugins/maintenance/maintenance.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/mikrotik_scan/mikrotik.py b/front/plugins/mikrotik_scan/mikrotik.py
index e25631aa..5cbcc4c7 100755
--- a/front/plugins/mikrotik_scan/mikrotik.py
+++ b/front/plugins/mikrotik_scan/mikrotik.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/nbtscan_scan/nbtscan.py b/front/plugins/nbtscan_scan/nbtscan.py
index 729b4842..689c093b 100755
--- a/front/plugins/nbtscan_scan/nbtscan.py
+++ b/front/plugins/nbtscan_scan/nbtscan.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/nmap_dev_scan/nmap_dev.py b/front/plugins/nmap_dev_scan/nmap_dev.py
index 70641d5a..d1d7e7ca 100755
--- a/front/plugins/nmap_dev_scan/nmap_dev.py
+++ b/front/plugins/nmap_dev_scan/nmap_dev.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# test script by running:
# tbc
diff --git a/front/plugins/nmap_scan/script.py b/front/plugins/nmap_scan/script.py
index 2d149d05..39d412af 100755
--- a/front/plugins/nmap_scan/script.py
+++ b/front/plugins/nmap_scan/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import argparse
diff --git a/front/plugins/nslookup_scan/nslookup.py b/front/plugins/nslookup_scan/nslookup.py
index 5fd3360c..8d9997ad 100755
--- a/front/plugins/nslookup_scan/nslookup.py
+++ b/front/plugins/nslookup_scan/nslookup.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# test script by running:
# tbc
diff --git a/front/plugins/omada_sdn_imp/omada_sdn.py b/front/plugins/omada_sdn_imp/omada_sdn.py
index 0957f163..ae429b01 100755
--- a/front/plugins/omada_sdn_imp/omada_sdn.py
+++ b/front/plugins/omada_sdn_imp/omada_sdn.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
__author__ = "ffsb"
__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...
@@ -134,7 +134,7 @@ def callomada(myargs):
omada_output = ""
retries = 2
- while omada_output == "" and retries > 1:
+ while omada_output == "" and retries > 0:
retries = retries - 1
try:
mf = io.StringIO()
@@ -183,51 +183,71 @@ def add_uplink(
sadevices_linksbymac,
port_byswitchmac_byclientmac,
):
- # Ensure switch_mac exists in device_data_bymac
+ # Ensure switch exists
if switch_mac not in device_data_bymac:
mylog("none", [f"[{pluginName}] switch_mac '{switch_mac}' not found in device_data_bymac"])
return
- # Ensure SWITCH_AP key exists in the dictionary
- if SWITCH_AP not in device_data_bymac[switch_mac]:
- mylog("none", [f"[{pluginName}] Missing key '{SWITCH_AP}' in device_data_bymac[{switch_mac}]"])
+ dev_switch = 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
- # Check if uplink should be added
- if device_data_bymac[switch_mac][SWITCH_AP] in [None, "null"]:
- device_data_bymac[switch_mac][SWITCH_AP] = uplink_mac
+ # Add uplink only if empty
+ if dev_switch[SWITCH_AP] in (None, "null"):
+ 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:
mylog("none", [f"[{pluginName}] uplink_mac '{uplink_mac}' not found in device_data_bymac"])
return
- # Determine port to uplink
- if (
- device_data_bymac[switch_mac].get(TYPE) == "Switch" and device_data_bymac[uplink_mac].get(TYPE) == "Switch"
- ):
+ dev_uplink = device_data_bymac[uplink_mac]
+
+ # 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)
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
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
- device_data_bymac[switch_mac][PORT_SSID] = port_to_uplink
+ # Assign port to switch
+ 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, []):
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(
- switch_mac,
- link,
- device_data_bymac,
- sadevices_linksbymac,
- port_byswitchmac_byclientmac,
- )
+ if dev_switch[TYPE] == "Switch":
+ add_uplink(
+ switch_mac,
+ link,
+ device_data_bymac,
+ sadevices_linksbymac,
+ port_byswitchmac_byclientmac,
+ )
# ----------------------------------------------
diff --git a/front/plugins/omada_sdn_openapi/script.py b/front/plugins/omada_sdn_openapi/script.py
index a15af4f5..7d341126 100755
--- a/front/plugins/omada_sdn_openapi/script.py
+++ b/front/plugins/omada_sdn_openapi/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
"""
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)}")
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."""
OmadaHelper.verbose("Starting authentication process")
diff --git a/front/plugins/pihole_api_scan/pihole_api_scan.py b/front/plugins/pihole_api_scan/pihole_api_scan.py
index 37a01d49..d9f9822a 100644
--- a/front/plugins/pihole_api_scan/pihole_api_scan.py
+++ b/front/plugins/pihole_api_scan/pihole_api_scan.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
"""
NetAlertX plugin: PIHOLEAPI
Imports devices from Pi-hole v6 API (Network endpoints) into NetAlertX plugin results.
diff --git a/front/plugins/snmp_discovery/script.py b/front/plugins/snmp_discovery/script.py
index a0583e8f..0dd92b06 100755
--- a/front/plugins/snmp_discovery/script.py
+++ b/front/plugins/snmp_discovery/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
from __future__ import unicode_literals
import subprocess
diff --git a/front/plugins/sync/sync.py b/front/plugins/sync/sync.py
index f17d169b..99af3cdf 100755
--- a/front/plugins/sync/sync.py
+++ b/front/plugins/sync/sync.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/unifi_api_import/unifi_api_import.py b/front/plugins/unifi_api_import/unifi_api_import.py
index 2d2e3e30..4c51f7b4 100755
--- a/front/plugins/unifi_api_import/unifi_api_import.py
+++ b/front/plugins/unifi_api_import/unifi_api_import.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/unifi_import/script.py b/front/plugins/unifi_import/script.py
index 57775c68..d62154b7 100755
--- a/front/plugins/unifi_import/script.py
+++ b/front/plugins/unifi_import/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# Inspired by https://github.com/stevehoek/Pi.Alert
from __future__ import unicode_literals
diff --git a/front/plugins/vendor_update/script.py b/front/plugins/vendor_update/script.py
index 7b0c3661..8359130d 100755
--- a/front/plugins/vendor_update/script.py
+++ b/front/plugins/vendor_update/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/wake_on_lan/wake_on_lan.py b/front/plugins/wake_on_lan/wake_on_lan.py
index 02008184..4ef01e84 100755
--- a/front/plugins/wake_on_lan/wake_on_lan.py
+++ b/front/plugins/wake_on_lan/wake_on_lan.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/front/plugins/website_monitor/script.py b/front/plugins/website_monitor/script.py
index 79e108ec..140c0945 100755
--- a/front/plugins/website_monitor/script.py
+++ b/front/plugins/website_monitor/script.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# Based on the work of https://github.com/leiweibau/Pi.Alert
import requests
diff --git a/install/production-filesystem/entrypoint.d/10-mounts.py b/install/production-filesystem/entrypoint.d/10-mounts.py
index b021bb84..e10033c9 100755
--- a/install/production-filesystem/entrypoint.d/10-mounts.py
+++ b/install/production-filesystem/entrypoint.d/10-mounts.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
import os
import sys
diff --git a/ruff.toml b/ruff.toml
new file mode 100644
index 00000000..0eeecf5d
--- /dev/null
+++ b/ruff.toml
@@ -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"]
diff --git a/scripts/checkmk/script.py b/scripts/checkmk/script.py
index d1f5b6f2..ea4cdaf8 100755
--- a/scripts/checkmk/script.py
+++ b/scripts/checkmk/script.py
@@ -1,5 +1,5 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
NetAlertX-New-Devices-Checkmk-Script
diff --git a/scripts/db_cleanup/db_cleanup.py b/scripts/db_cleanup/db_cleanup.py
index e1e7dc75..9fabf0e5 100755
--- a/scripts/db_cleanup/db_cleanup.py
+++ b/scripts/db_cleanup/db_cleanup.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
import subprocess
import os
diff --git a/scripts/opnsense_leases/opnsense_leases.py b/scripts/opnsense_leases/opnsense_leases.py
index 1715d0bb..69897211 100755
--- a/scripts/opnsense_leases/opnsense_leases.py
+++ b/scripts/opnsense_leases/opnsense_leases.py
@@ -30,7 +30,8 @@ def parse_timestamp(date_str):
dt = datetime.strptime(clean_date, '%Y/%m/%d %H:%M:%S')
return int(dt.timestamp())
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
@@ -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
lines = output.split('\n')
+
# 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()
cleaned_lines = []
diff --git a/server/__main__.py b/server/__main__.py
index 86ccd6bb..b8eab41d 100755
--- a/server/__main__.py
+++ b/server/__main__.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
#
# -------------------------------------------------------------------------------
# NetAlertX v2.70 / 2021-02-01
diff --git a/server/api.py b/server/api.py
index 0876bbae..bfb801d7 100755
--- a/server/api.py
+++ b/server/api.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import json
import time
import threading
diff --git a/server/api_server/dbquery_endpoint.py b/server/api_server/dbquery_endpoint.py
index 98db3991..40c2d691 100755
--- a/server/api_server/dbquery_endpoint.py
+++ b/server/api_server/dbquery_endpoint.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import base64
diff --git a/server/api_server/device_endpoint.py b/server/api_server/device_endpoint.py
index bec8ff73..401aba2f 100755
--- a/server/api_server/device_endpoint.py
+++ b/server/api_server/device_endpoint.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/server/api_server/devices_endpoint.py b/server/api_server/devices_endpoint.py
index 92d5baeb..003fa66c 100755
--- a/server/api_server/devices_endpoint.py
+++ b/server/api_server/devices_endpoint.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import base64
diff --git a/server/api_server/events_endpoint.py b/server/api_server/events_endpoint.py
index 799b2263..2ceddd37 100755
--- a/server/api_server/events_endpoint.py
+++ b/server/api_server/events_endpoint.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/server/api_server/history_endpoint.py b/server/api_server/history_endpoint.py
index 8a28ca4a..7220b048 100755
--- a/server/api_server/history_endpoint.py
+++ b/server/api_server/history_endpoint.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sys
diff --git a/server/api_server/sessions_endpoint.py b/server/api_server/sessions_endpoint.py
index 703ad307..225dbe39 100755
--- a/server/api_server/sessions_endpoint.py
+++ b/server/api_server/sessions_endpoint.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
import os
import sqlite3
diff --git a/server/db/db_upgrade.py b/server/db/db_upgrade.py
index d3b5f4d8..97da3dd0 100755
--- a/server/db/db_upgrade.py
+++ b/server/db/db_upgrade.py
@@ -136,23 +136,6 @@ def ensure_views(sql) -> bool:
"""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
sql.execute("""DROP VIEW IF EXISTS Convert_Events_to_Sessions;""")
sql.execute("""CREATE VIEW Convert_Events_to_Sessions AS SELECT EVE1.eve_MAC,
diff --git a/server/helper.py b/server/helper.py
index dbb9588e..df355708 100755
--- a/server/helper.py
+++ b/server/helper.py
@@ -624,6 +624,11 @@ def extract_ip_addresses(text):
# Helper function to determine if a MAC address is random
def is_random_mac(mac):
"""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)
is_random = mac[1].upper() in ["2", "6", "A", "E"]
@@ -631,7 +636,7 @@ def is_random_mac(mac):
if is_random:
not_random_prefixes = get_setting_value("UI_NOT_RANDOM_MAC")
for prefix in not_random_prefixes:
- if mac.startswith(prefix):
+ if mac.upper().startswith(prefix.upper()):
is_random = False
break
return is_random
diff --git a/server/initialise.py b/server/initialise.py
index 1552d976..82febc20 100755
--- a/server/initialise.py
+++ b/server/initialise.py
@@ -10,7 +10,7 @@ import re
# Register NetAlertX libraries
import conf
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 app_state import updateState
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)
write_notification(f'[Upgrade]: App upgraded from {prev_version} to \
- {new_version} code> 🚀 Please clear the cache: \
- - Click OK below
- Clear the browser cache (shift + \
- browser refresh button)
- Clear app cache with the \
- (reload) button in the header
- Go to Settings and click Save
\
+ {new_version} 🚀 Please clear the cache: \
+ - Click OK below
\
+ - Clear the browser cache (shift + browser refresh button)
\
+ - Clear app cache with the (reload) button in the header
\
+ - Go to Settings and click Save
\
Check out new features and what has changed in the \
📓 release notes.',
'interrupt',
@@ -804,8 +805,6 @@ def renameSettings(config_file):
str(config_file) + "_temp", str(config_file)
) # Convert config_file to a string
- # ensure correct ownership
- fixPermissions()
else:
mylog(
"debug", "[Config] No old setting names found in the file. No changes made."
diff --git a/server/utils/datetime_utils.py b/server/utils/datetime_utils.py
index cb51a16d..9c30d3bb 100644
--- a/server/utils/datetime_utils.py
+++ b/server/utils/datetime_utils.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python
+#!/usr/bin/env python
# from datetime import datetime
from dateutil import parser
diff --git a/test/api_endpoints/test_devices_endpoints.py b/test/api_endpoints/test_devices_endpoints.py
index 7d8fbb8c..3a867687 100644
--- a/test/api_endpoints/test_devices_endpoints.py
+++ b/test/api_endpoints/test_devices_endpoints.py
@@ -199,7 +199,7 @@ def test_devices_by_status(client, api_token, test_mac):
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
resp = client.delete("/devices", json={"macs": ["AA:BB:CC:*"]}, headers=auth_headers(api_token))
diff --git a/test/backend/test_sql_injection_prevention.py b/test/backend/test_sql_injection_prevention.py
index 33550064..496003d3 100644
--- a/test/backend/test_sql_injection_prevention.py
+++ b/test/backend/test_sql_injection_prevention.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
"""
Comprehensive SQL Injection Prevention Tests for NetAlertX
diff --git a/test/backend/test_sql_security.py b/test/backend/test_sql_security.py
index 3434344e..bc9f0b9b 100644
--- a/test/backend/test_sql_security.py
+++ b/test/backend/test_sql_security.py
@@ -210,7 +210,6 @@ class TestDatabaseParameterSupport(unittest.TestCase):
# This should not cause SQL injection
malicious_input = "'; DROP TABLE test_table; --"
cursor.execute("SELECT * FROM test_table WHERE name = :name", {'name': malicious_input})
- # results = cursor.fetchall()
# The table should still exist and be queryable
cursor.execute("SELECT COUNT(*) FROM test_table")
diff --git a/test/docker_tests/test_mount_diagnostics_pytest.py b/test/docker_tests/test_mount_diagnostics_pytest.py
index 2a1bf40b..c186d1a3 100644
--- a/test/docker_tests/test_mount_diagnostics_pytest.py
+++ b/test/docker_tests/test_mount_diagnostics_pytest.py
@@ -1,4 +1,4 @@
-# !/usr/bin/env python3
+#!/usr/bin/env python3
"""
Pytest-based Mount Diagnostic Tests for NetAlertX
diff --git a/test/integration/integration_test.py b/test/integration/integration_test.py
index 65acfc9f..18b14cd4 100755
--- a/test/integration/integration_test.py
+++ b/test/integration/integration_test.py
@@ -19,7 +19,8 @@ from messaging.reporting import get_notifications # noqa: E402 [flake8 lint sup
@pytest.fixture
def test_db_path():
- path = tempfile.mktemp(suffix=".db")
+ with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as tmp:
+ path = tmp.name
yield path
if os.path.exists(path):
os.remove(path)