Files
keyhunter-parser/tmp/audit_push_pats.py

42 lines
1.6 KiB
Python

"""Audit dead push-PATs in fleet_deploy.json (read-only, no side effects)."""
import json
import os
import sys
import urllib.error
import urllib.request
FLEET = r"C:\Users\User\Desktop\keyhunter\data\fleet_deploy.json"
fleet = json.load(open(FLEET, encoding="utf-8"))
ok_nodes = [r for r in fleet if r.get("ok")]
print(f"Fleet: {len(fleet)} total, {len(ok_nodes)} ok")
dead = []
for i, rec in enumerate(ok_nodes):
tok = rec.get("pat", "")
if not tok:
dead.append((rec["login"], rec.get("repo", "?"), "no-push-pat"))
continue
req = urllib.request.Request(
"https://api.github.com/user",
headers={"Authorization": "Bearer " + tok,
"Accept": "application/vnd.github+json",
"User-Agent": "keyfarm-audit",
"X-GitHub-Api-Version": "2022-11-28"})
try:
with urllib.request.urlopen(req, timeout=15) as r:
pass
except urllib.error.HTTPError as e:
if e.code == 401:
dead.append((rec["login"], rec.get("repo", "?"), "401"))
elif e.code in (403, 429):
dead.append((rec["login"], rec.get("repo", "?"), f"{e.code}-blocked"))
else:
dead.append((rec["login"], rec.get("repo", "?"), f"HTTP-{e.code}"))
except Exception as e:
dead.append((rec["login"], rec.get("repo", "?"), type(e).__name__))
if (i + 1) % 100 == 0:
print(f" {i+1}/{len(ok_nodes)} checked, {len(dead)} dead", flush=True)
print(f"\nDead push-PATs: {len(dead)}")
for login, repo, reason in dead[:50]:
print(f" {login}/{repo}: {reason}")
if len(dead) > 50:
print(f" ... and {len(dead)-50} more")