File size: 3,475 Bytes
f7b9253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import os, socket, threading, webbrowser, time
import gradio as gr
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse, PlainTextResponse
import uvicorn
from dotenv import load_dotenv
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from showcase_ui import build_showcase_app
from admin_ui import build_admin_app

load_dotenv()

HOST = "0.0.0.0"
PORT = int(os.getenv("PORT", 7860))
ADMIN_USER     = os.getenv("ADMIN_USER",     "admin")
ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD", "admin")

# ── RATE LIMITER ──────────────────────────────────────────────────────
limiter = Limiter(key_func=get_remote_address, default_limits=["60/minute"])

# ── ДОДАТКИ ───────────────────────────────────────────────────────────
app_showcase = build_showcase_app()
app_admin    = build_admin_app()

# ── FASTAPI ───────────────────────────────────────────────────────────
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

BLOCKED_PATHS = (
    "/config.json", "/.env", "/utils.py", "/main.py",
    "/admin_ui.py", "/showcase_ui.py", "/queue/", "/upload",
    "/.git", "/static/../",
)

@app.middleware("http")
async def security_middleware(request: Request, call_next):
    path = request.url.path.lower()
    for blocked in BLOCKED_PATHS:
        if path.startswith(blocked):
            return PlainTextResponse("404 Not Found", status_code=404)
    if ".." in path or "%2e" in path or "%2f" in path:
        return PlainTextResponse("400 Bad Request", status_code=400)
    ua = request.headers.get("user-agent", "").lower()
    bad_agents = ("sqlmap", "nikto", "nmap", "masscan", "zgrab")
    if any(b in ua for b in bad_agents):
        return PlainTextResponse("403 Forbidden", status_code=403)
    response = await call_next(request)
    response.headers["X-Content-Type-Options"] = "nosniff"
    response.headers["X-Frame-Options"] = "SAMEORIGIN"
    response.headers["X-XSS-Protection"] = "1; mode=block"
    response.headers["Referrer-Policy"] = "no-referrer"
    return response

@app.get("/figvam")
def redirect_admin():
    return RedirectResponse(url="/figvam/")

app = gr.mount_gradio_app(app, app_admin,    path="/figvam",
                          auth=(ADMIN_USER, ADMIN_PASSWORD),
                          auth_message="Unstop Admin")
app = gr.mount_gradio_app(app, app_showcase, path="/")

# ── ЛОКАЛЬНИЙ ЗАПУСК ──────────────────────────────────────────────────
def wait_and_open():
    for _ in range(40):
        try:
            with socket.create_connection(("localhost", PORT), timeout=1):
                webbrowser.open(f"http://localhost:{PORT}")
                return
        except OSError:
            time.sleep(0.5)

if __name__ == "__main__":
    threading.Thread(target=wait_and_open, daemon=True).start()
    uvicorn.run(app, host=HOST, port=PORT, log_level="warning")