""" Bardach Contacts - Clear junk businessHomePage values from Microsoft 365. Targets: - All junk contacts with ms-outlook:// URLs - Suspicious contact "Facebook" with value "Penfield@1964" - Suspicious contact "Megan Billings" with value "John" Does NOT touch: - 10 legitimate websites - 1 Facebook page link (DiBella's Restaurant) """ import json import subprocess import sys import time # --- Configuration --- TENANT_ID = "dd4a82e8-85a3-44ac-8800-07945ab4d95f" CLIENT_ID = "fabb3421-8b34-484b-bc17-e46de9703418" CLIENT_SECRET = "~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO" SCOPE = "https://graph.microsoft.com/.default" USER = "barbara@bardach.net" TOKEN_URL = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token" GRAPH_BASE = f"https://graph.microsoft.com/v1.0/users/{USER}/contacts" ANALYSIS_FILE = "D:/ClaudeTools/temp/bardach_url_analysis.json" TOKEN_REFRESH_INTERVAL = 200 def get_token(): """Acquire OAuth2 token via client credentials.""" result = subprocess.run( [ "curl", "-s", "-X", "POST", TOKEN_URL, "-H", "Content-Type: application/x-www-form-urlencoded", "-d", f"client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&scope={SCOPE}&grant_type=client_credentials", ], capture_output=True, text=True ) data = json.loads(result.stdout) if "access_token" not in data: print(f"[ERROR] Failed to acquire token: {data}") sys.exit(1) print("[OK] Token acquired") return data["access_token"] def patch_contact(token, contact_id, display_name, index, total): """PATCH a single contact to clear businessHomePage.""" url = f"{GRAPH_BASE}/{contact_id}" result = subprocess.run( [ "curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "-X", "PATCH", url, "-H", f"Authorization: Bearer {token}", "-H", "Content-Type: application/json", "-d", '{"businessHomePage": ""}', ], capture_output=True, text=True ) http_code = result.stdout.strip() success = http_code in ("200", "204") if not success: print(f" [FAIL] {index}/{total} - {display_name} - HTTP {http_code}") return success def main(): # Load analysis data with open(ANALYSIS_FILE, "r", encoding="utf-8") as f: data = json.load(f) # Build target list targets = [] # 1) Junk contacts with ms-outlook:// pattern for c in data.get("junk_contacts", []): if c.get("url", "").startswith("ms-outlook://"): targets.append((c["id"], c["displayName"])) # 2) Suspicious contacts: "Facebook" and "Megan Billings" for c in data.get("suspicious_contacts", []): name = c.get("displayName", "") if name == "Facebook" or name == "Megan Billings": targets.append((c["id"], c["displayName"])) total = len(targets) print(f"[INFO] Contacts to patch: {total}") if total == 0: print("[WARNING] No targets found. Exiting.") return # Acquire initial token token = get_token() successes = 0 failures = 0 for i, (cid, name) in enumerate(targets, 1): # Re-acquire token every TOKEN_REFRESH_INTERVAL operations if i > 1 and (i - 1) % TOKEN_REFRESH_INTERVAL == 0: print(f"[INFO] Re-acquiring token at operation {i}...") token = get_token() ok = patch_contact(token, cid, name, i, total) if ok: successes += 1 else: failures += 1 # Progress every 50 if i % 50 == 0 or i == total: print(f"[PROGRESS] {i}/{total} done (success={successes}, fail={failures})") print() print("=" * 50) print(f"[SUMMARY] Total: {total} Success: {successes} Failures: {failures}") print("=" * 50) if __name__ == "__main__": main()