Synced files: - Quote wizard frontend (all components, hooks, types, config) - API updates (config, models, routers, schemas, services) - Client work (bg-builders, gurushow) - Scripts (BGB Lesley termination, CIPP, Datto, migration) - Temp files (Bardach contacts, VWP investigation, misc) - Credentials and session logs - Email service, PHP API, session logs Machine: ACG-M-L5090 Timestamp: 2026-03-10 19:11:00 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
import json
|
|
|
|
d = json.load(open('D:/ClaudeTools/temp/vwp_signins_raw.json'))
|
|
signins = d.get('value', [])
|
|
print(f'Total sign-ins returned: {len(signins)}')
|
|
print()
|
|
|
|
ips = {}
|
|
locations = {}
|
|
failed = 0
|
|
risky = 0
|
|
legacy = []
|
|
|
|
for s in signins:
|
|
ts = s.get('createdDateTime', 'N/A')
|
|
ip = s.get('ipAddress', 'N/A')
|
|
loc = s.get('location', {})
|
|
city = loc.get('city', '?')
|
|
state = loc.get('state', '?')
|
|
country = loc.get('countryOrRegion', '?')
|
|
loc_str = f'{city}, {state}, {country}'
|
|
status_code = s.get('status', {}).get('errorCode', 0)
|
|
status_reason = s.get('status', {}).get('failureReason', '')
|
|
risk = s.get('riskLevelDuringSignIn', 'none')
|
|
risk_state = s.get('riskState', 'none')
|
|
app = s.get('clientAppUsed', 'N/A')
|
|
app_name = s.get('appDisplayName', 'N/A')
|
|
resource = s.get('resourceDisplayName', '')
|
|
|
|
ips[ip] = ips.get(ip, 0) + 1
|
|
locations[loc_str] = locations.get(loc_str, 0) + 1
|
|
|
|
flags = []
|
|
if status_code != 0:
|
|
failed += 1
|
|
flags.append(f'FAILED({status_code})')
|
|
if risk not in ('none', 'low', None, ''):
|
|
risky += 1
|
|
flags.append(f'RISK:{risk}')
|
|
if country not in ('US', 'Unknown', '', None):
|
|
flags.append(f'FOREIGN:{country}')
|
|
if app in ('IMAP4', 'POP3', 'SMTP', 'Authenticated SMTP', 'Other clients', 'Exchange ActiveSync'):
|
|
legacy.append({'ts': ts, 'protocol': app, 'ip': ip})
|
|
flags.append('LEGACY_AUTH')
|
|
|
|
marker = '[SUSPICIOUS]' if flags else ' '
|
|
flag_str = ' [' + '|'.join(flags) + ']' if flags else ''
|
|
|
|
print(f'{marker} {ts} | IP: {ip} | {loc_str} | App: {app_name} | Client: {app} | Resource: {resource}{flag_str}')
|
|
if status_code != 0:
|
|
print(f' Failure: {status_reason}')
|
|
|
|
print(f'\n--- Sign-in Summary ---')
|
|
print(f'Total: {len(signins)}')
|
|
print(f'Failed: {failed}')
|
|
print(f'Risky: {risky}')
|
|
print(f'Legacy auth: {len(legacy)}')
|
|
print(f'Unique IPs: {len(ips)}')
|
|
print(f'\n--- IP Breakdown ---')
|
|
for ip, cnt in sorted(ips.items(), key=lambda x: x[1], reverse=True):
|
|
print(f' {ip}: {cnt}')
|
|
print(f'\n--- Location Breakdown ---')
|
|
for loc_s, cnt in sorted(locations.items(), key=lambda x: x[1], reverse=True):
|
|
print(f' {loc_s}: {cnt}')
|
|
if legacy:
|
|
print(f'\n--- Legacy Auth Details ---')
|
|
for l in legacy:
|
|
print(f' {l["ts"]} | {l["protocol"]} | {l["ip"]}')
|