Wattle-Guard / app.py
dcata004's picture
Update app.py
b617c93 verified
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()