import gradio as gr import requests import socket import ssl import datetime import json from urllib.parse import urlparse # --- 1. THE LOGIC (Formerly wattle_guard.py) --- # "Red Flag" jurisdictions HIGH_RISK_JURISDICTIONS = ["United States", "China", "Russia", "India"] SAFE_JURISDICTIONS = ["Australia", "Switzerland", "United Kingdom", "Germany", "New Zealand"] def get_server_location(domain): try: ip_address = socket.gethostbyname(domain) # Using a public free API (User-Agent header added to prevent 403 blocks) headers = {'User-Agent': 'WattleGuard/1.0'} response = requests.get(f"http://ip-api.com/json/{ip_address}", headers=headers).json() return { "ip": ip_address, "country": response.get("country", "Unknown"), "region": response.get("regionName", "Unknown"), "isp": response.get("isp", "Unknown") } except Exception as e: return {"error": str(e), "country": "Unknown"} def check_ssl_security(domain): try: context = ssl.create_default_context() with socket.create_connection((domain, 443), timeout=5) as sock: with context.wrap_socket(sock, server_hostname=domain) as ssock: cert = ssock.getpeercert() return {"ssl_valid": True, "cipher": ssock.cipher()} except Exception: return {"ssl_valid": False, "note": "Connection Not Secure"} def generate_risk_score(geo_data): country = geo_data.get("country") if country == "Australia": return "LOW (Sovereign)", "Data resides within Australian jurisdiction." if country in HIGH_RISK_JURISDICTIONS: return "HIGH (Cloud Act Risk)", f"Server in {country}. Requires APP 8.1 assessment." if country in SAFE_JURISDICTIONS: return "MEDIUM (GDPR Aligned)", f"Server in {country}. Likely compatible." return "UNKNOWN", "Manual review required." def run_audit(target_url): # Clean URL logic if not target_url.startswith("http"): target_url = "https://" + target_url try: domain = urlparse(target_url).netloc if not domain: domain = target_url except: return "Error: Invalid URL format." # Run Checks geo = get_server_location(domain) security = check_ssl_security(domain) risk_level, risk_reason = generate_risk_score(geo) # Format Output for the UI return f""" 🇦🇺 WATTLE-GUARD AUDIT REPORT ============================ Target: {domain} Timestamp: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')} 📍 DATA SOVEREIGNTY ------------------- Physical Location: {geo.get('region')}, {geo.get('country')} ISP/Host: {geo.get('isp')} 🚨 RISK ASSESSMENT ------------------ Risk Level: {risk_level} Auditor Note: {risk_reason} 🔒 SECURITY (APP 11) -------------------- SSL Encrypted: {security.get('ssl_valid')} """ # --- 2. THE UI (Gradio) --- iface = gr.Interface( fn=run_audit, inputs=gr.Textbox(label="Vendor URL", placeholder="e.g. openai.com"), outputs=gr.Textbox(label="Audit Report", lines=15), title="🇦🇺 Wattle-Guard: Australian Sovereignty Validator", description="**Compliance Tool for APP 8 & SOCI Act.** Enter a US Vendor URL to check if their data hosting violates Australian Data Sovereignty laws.", examples=["https://openai.com", "https://www.commbank.com.au", "https://tiktok.com"], theme="soft" ) if __name__ == "__main__": iface.launch()