Comments across the codebase credited one individual by role and, in places, described that person's own machines: which SQL Server versions a host ran, which devices were enrolled, what a particular dashboard showed, how many findings sat open on which server. In a public repository that reads as a profile of someone's unpatched estate. The observations are why the code looks the way it does, so they stay. Every CVE id, version, build number, count and date is preserved, as are the verbatim quotes that motivated specific sort and filter rules — only the attribution changes, to "field report", "observed", "a host". A local variable in tests/test_autodesk_year.py was renamed for the same reason; its value and every assertion around it are byte-identical. PROJECT_OVERVIEW.md additionally loses a subtitle naming the kind of organisation this was built for, and a support section pointing at an internal team, both replaced with neutral wording. Comments, docstrings and markdown prose only: 74 files, 200 lines, one-for-one swaps. detect_changes reports 104 touched symbols and zero affected execution flows, and all 55 test scripts pass. Nothing here needs re-testing.
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"""Re-enrolled device: the LIVE enrolment wins — run: python tests/test_intune_reenrollment.py
|
|
|
|
Field report 2026-08-18: an Android asset was wiped and enrolled again, so
|
|
Intune listed it twice under the same deviceName — dead entry (old device id)
|
|
next to the live one. TrueVuln matched both to the same asset (correct, one
|
|
asset) but processed both, each pinning its own device id:
|
|
|
|
... re-enrolled — device id 1111… -> 2222…
|
|
... re-enrolled — device id 2222… -> 1111…
|
|
|
|
The last one in Graph's arbitrary order won, which was the DEAD enrolment, so
|
|
every detectedApps read went to the old device's frozen app list and CVEs that
|
|
had been closed kept reopening.
|
|
|
|
Pinned here: duplicates collapse to the newest check-in before any asset is
|
|
touched.
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from app.services.intune_service import _dedupe_reenrolled
|
|
|
|
|
|
def demo():
|
|
stale = {"id": "11111111", "deviceName": "AndroidEnterprise-TESTDEVICE01",
|
|
"lastSyncDateTime": "2026-06-08T13:33:00Z"}
|
|
live = {"id": "22222222", "deviceName": "AndroidEnterprise-TESTDEVICE01",
|
|
"lastSyncDateTime": "2026-08-12T05:35:00Z"}
|
|
other = {"id": "c111", "deviceName": "LAPTOP-1",
|
|
"lastSyncDateTime": "2026-08-12T05:35:00Z"}
|
|
|
|
# Both orders must land on the live enrolment — Graph's order is arbitrary.
|
|
for devices in ([stale, live], [live, stale]):
|
|
kept, dropped = _dedupe_reenrolled(devices)
|
|
assert [d["id"] for d in kept] == ["22222222"], kept
|
|
assert dropped == 1, dropped
|
|
|
|
# Distinct devices are untouched.
|
|
kept, dropped = _dedupe_reenrolled([live, other])
|
|
assert sorted(d["id"] for d in kept) == ["22222222", "c111"], kept
|
|
assert dropped == 0
|
|
|
|
# No check-in on the newer record → enrolledDateTime decides.
|
|
no_sync = {"id": "d222", "deviceName": "TABLET-9",
|
|
"enrolledDateTime": "2026-08-01T00:00:00Z"}
|
|
older = {"id": "e333", "deviceName": "TABLET-9",
|
|
"enrolledDateTime": "2025-01-01T00:00:00Z"}
|
|
kept, dropped = _dedupe_reenrolled([older, no_sync])
|
|
assert [d["id"] for d in kept] == ["d222"], kept
|
|
|
|
# A nameless record can't be keyed, so it is never merged away.
|
|
kept, _ = _dedupe_reenrolled([{"id": "f444"}, {"id": "f555"}])
|
|
assert len(kept) == 2, kept
|
|
|
|
print("OK — re-enrolled duplicates collapse to the live device")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
demo()
|