mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2026-10-03 03:05:04 -04:00
125 lines
6.5 KiB
Python
125 lines
6.5 KiB
Python
import re
|
|
|
|
_SQL_IDENTIFIER_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?$")
|
|
|
|
|
|
def current_scan_presence_condition(mac_column: str) -> str:
|
|
"""SQL fragment: TRUE if any CurrentScan row for mac_column asserts presence.
|
|
The one and only definition of 'is this MAC present this cycle' - every
|
|
caller uses this, nobody writes their own CurrentScan presence predicate.
|
|
|
|
mac_column MUST be a trusted, hardcoded SQL column/table.column reference
|
|
written by NetAlertX code (e.g. "devMac", "CurrentScan.scanMac") - this
|
|
function does raw string interpolation, not parameterized SQL. Never pass
|
|
plugin data, user input, or any runtime string value here.
|
|
|
|
The inner CurrentScan is aliased as presence_scan so a qualified
|
|
mac_column like "CurrentScan.scanMac" resolves to the outer reference,
|
|
not this subquery's own row - without the alias the bare table name
|
|
shadows it, turning the comparison into a same-row tautology that's
|
|
true for any row with a non-NULL scanMac. mac_column may not reference
|
|
presence_scan itself for the same reason.
|
|
|
|
Not usable everywhere a presence check appears: the "New Connections"
|
|
query in session_events.py and the raw Sessions insert in
|
|
create_new_devices() (device_handling.py) both need the actual
|
|
scanLastIP/scanVendor *values* off the presence-asserting row via a
|
|
MIN()/GROUP BY aggregate, not just a boolean - see
|
|
scan-pipeline-hardening.md Design §1's correction for why those two
|
|
(plus "IP Changed", an eighth non-canonical site) keep their own
|
|
hand-written aggregation instead of calling this helper.
|
|
"""
|
|
if not _SQL_IDENTIFIER_RE.match(mac_column):
|
|
raise ValueError(f"mac_column must be a plain identifier, got: {mac_column!r}")
|
|
if mac_column == "presence_scan" or mac_column.startswith("presence_scan."):
|
|
raise ValueError(
|
|
f"mac_column must not reference presence_scan - that's this helper's own "
|
|
f"internal subquery alias, got: {mac_column!r}"
|
|
)
|
|
return f"""EXISTS (
|
|
SELECT 1 FROM CurrentScan AS presence_scan
|
|
WHERE presence_scan.scanMac = {mac_column} AND presence_scan.scanPresence = 1
|
|
)"""
|
|
|
|
|
|
def nic_derived_presence_condition(mac_column: str) -> str:
|
|
"""SQL fragment answering exactly: 'would NIC reconciliation
|
|
(update_devPresentLastScan_based_on_nics(), step 7 of process_scan())
|
|
consider mac_column present, based on this cycle's CurrentScan rows for
|
|
its NIC children (devParentRelType = 'nic') and its own devReqNicsOnline
|
|
(ANY vs ALL)?' It intentionally does not read or write
|
|
Devices.devPresentLastScan - see nic-parent-orphan-disconnect-events.md's
|
|
Invariant for why that's still equivalent to step 7's own answer within
|
|
the same cycle (step 6 sets every device's devPresentLastScan, NIC
|
|
children included, to exactly current_scan_presence_condition()'s value
|
|
for this cycle, before step 7 ever reads it). Not a general-purpose
|
|
presence predicate - it answers this one question, nothing broader.
|
|
|
|
Deliberately NOT a replacement for current_scan_presence_condition() -
|
|
composed with it via OR at each call site (insert_events()'s Device
|
|
Down/Disconnected queries, update_devLastConnection_from_CurrentScan()).
|
|
Deliberately does NOT replicate update_devPresentLastScan_based_on_nics()'s
|
|
"parent was directly detected this scan" carve-out: that carve-out is
|
|
redundant here, because a directly-detected parent already satisfies
|
|
current_scan_presence_condition() on its own, and the two are OR'd.
|
|
|
|
mac_column must be a trusted, hardcoded SQL column/table.column reference
|
|
written by NetAlertX code - same constraint as
|
|
current_scan_presence_condition(), enforced the same way.
|
|
|
|
The inner Devices scan is aliased as nic_presence_parent, not the more
|
|
obvious nic_parent, for the same shadowing reason
|
|
current_scan_presence_condition() aliases its own inner CurrentScan as
|
|
presence_scan rather than bare CurrentScan: a caller correlating this
|
|
condition from a query that itself aliases its row as nic_parent (a
|
|
natural name to pick, given this helper's own docstring uses it) would
|
|
otherwise have mac_column="nic_parent.devMac" resolve to this
|
|
subquery's own inner alias instead of the caller's outer row, collapsing
|
|
the comparison into an always-true same-row tautology - confirmed live
|
|
in this exact shape in nic-parent-reconnect-events.md's implementation
|
|
notes. mac_column may not reference nic_presence_parent for the same
|
|
reason presence_scan is guarded below.
|
|
"""
|
|
if not _SQL_IDENTIFIER_RE.match(mac_column):
|
|
raise ValueError(f"mac_column must be a plain identifier, got: {mac_column!r}")
|
|
if mac_column == "presence_scan" or mac_column.startswith("presence_scan."):
|
|
raise ValueError(
|
|
f"mac_column must not reference presence_scan - that's "
|
|
f"current_scan_presence_condition()'s own internal subquery "
|
|
f"alias, got: {mac_column!r}"
|
|
)
|
|
if mac_column == "nic_presence_parent" or mac_column.startswith("nic_presence_parent."):
|
|
raise ValueError(
|
|
f"mac_column must not reference nic_presence_parent - that's "
|
|
f"this function's own internal subquery alias, got: {mac_column!r}"
|
|
)
|
|
|
|
return f"""EXISTS (
|
|
SELECT 1 FROM Devices AS nic_presence_parent
|
|
WHERE nic_presence_parent.devMac = {mac_column}
|
|
AND (
|
|
(
|
|
IFNULL(CAST(nic_presence_parent.devReqNicsOnline AS TEXT), '') = '1'
|
|
AND EXISTS (SELECT 1 FROM Devices AS any_nic
|
|
WHERE any_nic.devParentMAC = nic_presence_parent.devMac
|
|
AND any_nic.devParentRelType = 'nic')
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM Devices AS nic
|
|
WHERE nic.devParentMAC = nic_presence_parent.devMac
|
|
AND nic.devParentRelType = 'nic'
|
|
AND NOT {current_scan_presence_condition("nic.devMac")}
|
|
)
|
|
)
|
|
OR
|
|
(
|
|
IFNULL(CAST(nic_presence_parent.devReqNicsOnline AS TEXT), '') != '1'
|
|
AND EXISTS (
|
|
SELECT 1 FROM Devices AS nic
|
|
WHERE nic.devParentMAC = nic_presence_parent.devMac
|
|
AND nic.devParentRelType = 'nic'
|
|
AND {current_scan_presence_condition("nic.devMac")}
|
|
)
|
|
)
|
|
)
|
|
)"""
|