Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,34 +1,101 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
return f"""
|
| 14 |
🇦🇺 WATTLE-GUARD AUDIT REPORT
|
| 15 |
-
|
| 16 |
-
Target: {
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
Risk Level: {risk_level}
|
|
|
|
| 19 |
|
| 20 |
-
|
| 21 |
-
|
|
|
|
| 22 |
"""
|
| 23 |
|
| 24 |
-
#
|
|
|
|
| 25 |
iface = gr.Interface(
|
| 26 |
-
fn=
|
| 27 |
-
inputs="
|
| 28 |
-
outputs="
|
| 29 |
title="🇦🇺 Wattle-Guard: Australian Sovereignty Validator",
|
| 30 |
-
description="Enter a
|
| 31 |
-
examples=["
|
|
|
|
| 32 |
)
|
| 33 |
|
| 34 |
-
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
import requests
|
| 3 |
+
import socket
|
| 4 |
+
import ssl
|
| 5 |
+
import datetime
|
| 6 |
+
import json
|
| 7 |
+
from urllib.parse import urlparse
|
| 8 |
|
| 9 |
+
# --- 1. THE LOGIC (Formerly wattle_guard.py) ---
|
| 10 |
+
|
| 11 |
+
# "Red Flag" jurisdictions
|
| 12 |
+
HIGH_RISK_JURISDICTIONS = ["United States", "China", "Russia", "India"]
|
| 13 |
+
SAFE_JURISDICTIONS = ["Australia", "Switzerland", "United Kingdom", "Germany", "New Zealand"]
|
| 14 |
+
|
| 15 |
+
def get_server_location(domain):
|
| 16 |
+
try:
|
| 17 |
+
ip_address = socket.gethostbyname(domain)
|
| 18 |
+
# Using a public free API (User-Agent header added to prevent 403 blocks)
|
| 19 |
+
headers = {'User-Agent': 'WattleGuard/1.0'}
|
| 20 |
+
response = requests.get(f"http://ip-api.com/json/{ip_address}", headers=headers).json()
|
| 21 |
+
return {
|
| 22 |
+
"ip": ip_address,
|
| 23 |
+
"country": response.get("country", "Unknown"),
|
| 24 |
+
"region": response.get("regionName", "Unknown"),
|
| 25 |
+
"isp": response.get("isp", "Unknown")
|
| 26 |
+
}
|
| 27 |
+
except Exception as e:
|
| 28 |
+
return {"error": str(e), "country": "Unknown"}
|
| 29 |
+
|
| 30 |
+
def check_ssl_security(domain):
|
| 31 |
+
try:
|
| 32 |
+
context = ssl.create_default_context()
|
| 33 |
+
with socket.create_connection((domain, 443), timeout=5) as sock:
|
| 34 |
+
with context.wrap_socket(sock, server_hostname=domain) as ssock:
|
| 35 |
+
cert = ssock.getpeercert()
|
| 36 |
+
return {"ssl_valid": True, "cipher": ssock.cipher()}
|
| 37 |
+
except Exception:
|
| 38 |
+
return {"ssl_valid": False, "note": "Connection Not Secure"}
|
| 39 |
+
|
| 40 |
+
def generate_risk_score(geo_data):
|
| 41 |
+
country = geo_data.get("country")
|
| 42 |
+
if country == "Australia":
|
| 43 |
+
return "LOW (Sovereign)", "Data resides within Australian jurisdiction."
|
| 44 |
+
if country in HIGH_RISK_JURISDICTIONS:
|
| 45 |
+
return "HIGH (Cloud Act Risk)", f"Server in {country}. Requires APP 8.1 assessment."
|
| 46 |
+
if country in SAFE_JURISDICTIONS:
|
| 47 |
+
return "MEDIUM (GDPR Aligned)", f"Server in {country}. Likely compatible."
|
| 48 |
+
return "UNKNOWN", "Manual review required."
|
| 49 |
+
|
| 50 |
+
def run_audit(target_url):
|
| 51 |
+
# Clean URL logic
|
| 52 |
+
if not target_url.startswith("http"):
|
| 53 |
+
target_url = "https://" + target_url
|
| 54 |
|
| 55 |
+
try:
|
| 56 |
+
domain = urlparse(target_url).netloc
|
| 57 |
+
if not domain: domain = target_url
|
| 58 |
+
except:
|
| 59 |
+
return "Error: Invalid URL format."
|
| 60 |
+
|
| 61 |
+
# Run Checks
|
| 62 |
+
geo = get_server_location(domain)
|
| 63 |
+
security = check_ssl_security(domain)
|
| 64 |
+
risk_level, risk_reason = generate_risk_score(geo)
|
| 65 |
+
|
| 66 |
+
# Format Output for the UI
|
| 67 |
return f"""
|
| 68 |
🇦🇺 WATTLE-GUARD AUDIT REPORT
|
| 69 |
+
============================
|
| 70 |
+
Target: {domain}
|
| 71 |
+
Timestamp: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
| 72 |
+
|
| 73 |
+
📍 DATA SOVEREIGNTY
|
| 74 |
+
-------------------
|
| 75 |
+
Physical Location: {geo.get('region')}, {geo.get('country')}
|
| 76 |
+
ISP/Host: {geo.get('isp')}
|
| 77 |
+
|
| 78 |
+
🚨 RISK ASSESSMENT
|
| 79 |
+
------------------
|
| 80 |
Risk Level: {risk_level}
|
| 81 |
+
Auditor Note: {risk_reason}
|
| 82 |
|
| 83 |
+
🔒 SECURITY (APP 11)
|
| 84 |
+
--------------------
|
| 85 |
+
SSL Encrypted: {security.get('ssl_valid')}
|
| 86 |
"""
|
| 87 |
|
| 88 |
+
# --- 2. THE UI (Gradio) ---
|
| 89 |
+
|
| 90 |
iface = gr.Interface(
|
| 91 |
+
fn=run_audit,
|
| 92 |
+
inputs=gr.Textbox(label="Vendor URL", placeholder="e.g. openai.com"),
|
| 93 |
+
outputs=gr.Textbox(label="Audit Report", lines=15),
|
| 94 |
title="🇦🇺 Wattle-Guard: Australian Sovereignty Validator",
|
| 95 |
+
description="**Compliance Tool for APP 8 & SOCI Act.** Enter a US Vendor URL to check if their data hosting violates Australian Data Sovereignty laws.",
|
| 96 |
+
examples=["https://openai.com", "https://www.commbank.com.au", "https://tiktok.com"],
|
| 97 |
+
theme="soft"
|
| 98 |
)
|
| 99 |
|
| 100 |
+
if __name__ == "__main__":
|
| 101 |
+
iface.launch()
|