Add companion identity handling and statistics tracking for ACL endpoints.

This commit is contained in:
agessaman
2026-03-12 20:57:13 -07:00
parent 9326868f6e
commit 985e0c829f
24 changed files with 83 additions and 24 deletions
+60 -1
View File
@@ -3071,12 +3071,49 @@ class APIEndpoints:
}
)
# Add companion identities (no login/ACL fields; use registered + active for status)
companion_bridges = getattr(self.daemon_instance, "companion_bridges", {})
# Build hash -> active TCP connection and client IP (frame server has at most one client)
active_by_hash = {}
client_ip_by_hash = {}
for fs in getattr(self.daemon_instance, "companion_frame_servers", []):
try:
ch = getattr(fs, "companion_hash", None)
h = (
int(ch, 16)
if isinstance(ch, str) and ch.startswith("0x")
else (int(ch) if ch is not None else None)
)
if h is not None:
writer = getattr(fs, "_client_writer", None)
active_by_hash[h] = writer is not None
if writer is not None:
peername = writer.get_extra_info("peername") if hasattr(writer, "get_extra_info") else None
client_ip_by_hash[h] = str(peername[0]) if peername else None
except (ValueError, TypeError):
pass
for name, identity, config in identity_manager.get_identities_by_type("companion"):
hash_byte = identity.get_public_key()[0]
active = active_by_hash.get(hash_byte, False)
entry = {
"name": name,
"type": "companion",
"hash": f"0x{hash_byte:02X}",
"registered": hash_byte in companion_bridges,
"active": active,
}
if active:
entry["client_ip"] = client_ip_by_hash.get(hash_byte)
else:
entry["client_ip"] = None
acl_info_list.append(entry)
return self._success(
{
"acls": acl_info_list,
"total_identities": len(acl_info_list),
"total_authenticated_clients": sum(
a["authenticated_clients"] for a in acl_info_list
a.get("authenticated_clients", 0) for a in acl_info_list
),
}
)
@@ -3138,6 +3175,15 @@ class APIEndpoints:
"hash": f"0x{hash_byte:02X}",
}
# Add companions
for name, identity, config in identity_manager.get_identities_by_type("companion"):
hash_byte = identity.get_public_key()[0]
identity_map[hash_byte] = {
"name": name,
"type": "companion",
"hash": f"0x{hash_byte:02X}",
}
# Filter by identity if requested
target_hash = None
if identity_hash:
@@ -3334,6 +3380,7 @@ class APIEndpoints:
identity_stats = {
"repeater": {"count": 0, "clients": 0},
"room_server": {"count": 0, "clients": 0},
"companion": {"count": 0, "clients": 0},
}
# Count repeater
@@ -3370,6 +3417,18 @@ class APIEndpoints:
else:
guest_count += 1
# Count companions (no admin/guest; they use frame server, not OTA login)
companions = identity_manager.get_identities_by_type("companion")
identity_stats["companion"]["count"] = len(companions)
for name, identity, config in companions:
hash_byte = identity.get_public_key()[0]
acl = acl_dict.get(hash_byte)
if acl:
clients = acl.get_all_clients()
identity_stats["companion"]["clients"] += len(clients)
total_clients += len(clients)
return self._success(
{
"total_identities": len(acl_dict),