Spaces:
Running
Running
| 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() |