Show account names and roles on cards from scheduled scans

Cards from scheduled scans of editor-saved profiles showed the account's
GUID as its name and no Elev/Ansat badge: the profile editor stored bare
id strings, the scheduler passes them straight to run_scan, and run_scan
normalised them to displayName=<id>, userRole="other". Before 1.7.10 the
scan-start profile overwrite kept repairing profiles to named objects,
which is why this surfaced now.

- run_scan: _enrich_bare_users() looks bare accounts up in the directory
  (list_users, falling back to lookup_user) for name and role.
- M365Connector.build_role_sku_map(): the SKU map /api/users built inline,
  now shared so cards and the account list classify roles identically.
  lookup_user() also returns assignedLicenses.
- Profile editor saves {id, displayName, userRole} (manual accounts keep
  email/manual), like the 💾 save.
- _accountPill: an account_name equal to account_id counts as missing;
  name and role are filled from the loaded user list, so existing cards
  display correctly without a rescan.
- Excel export: the scan's account-name map no longer breaks on bare id
  strings (.get() on a str raised and dropped the whole map).

Tests: tests/test_account_names.py (10); the run_scan test fails on the
old engine with "Collecting emails — guid-henrik…".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
StyxX65andClaude Opus 5.5 committed 2026-09-28 14:40:14 +02:00
1 parent c55db48894
commit 20156ffc93
8 files changed
+283 -37

No files matched your search

+3 -19
View File
@@ -24,25 +24,9 @@ def get_users():
out = []
seen = set()
# Build SKU map for role classification.
# get_subscribed_skus() tries /subscribedSkus → /me/licenseDetails.
# Then always merge per-user licenseDetails on top — this ensures we
# have skuPartNumbers for every distinct SKU in the tenant, not just
# the admin's own license (which is all /me/licenseDetails returns).
try:
sku_map = state.connector.get_subscribed_skus()
except Exception:
sku_map = {}
try:
per_user = state.connector.build_sku_map_from_users(users)
if per_user:
added = len(set(per_user) - set(sku_map))
sku_map.update(per_user)
if added:
logger.info("[skus] merged %d additional SKU(s) from per-user licenseDetails", added)
except Exception:
pass
# SKU map for role classification — shared with the scan engine so the
# account list and scanned cards classify Elev/Ansat identically.
sku_map = state.connector.build_role_sku_map(users)
# Load any manual role overrides set by the admin
_role_overrides = _load_role_overrides()