feat: add persistence and audit trails

This commit is contained in:
truetype committed 2026-02-05 11:07:20 +01:00
1 parent d381c02946
commit 2f2e9ab3e3
9 files changed
+633 -151

No files matched your search

+20 -3
View File
@@ -1,7 +1,6 @@
from __future__ import annotations
import dataclasses
import subprocess
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import HTMLResponse
@@ -9,12 +8,16 @@ from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
from app.policy import TunnelPolicy
from app.services import PortScanner
from app.storage import Storage
from app.tunnel_manager import TunnelManager
app = FastAPI(title="Gradio Tunnel Dashboard")
manager = TunnelManager()
scanner = PortScanner()
policy = TunnelPolicy.load()
storage = Storage.from_env()
scanner = PortScanner(policy=policy, storage=storage)
manager = TunnelManager(storage=storage)
app.mount("/static", StaticFiles(directory="app/static"), name="static")
templates = Jinja2Templates(directory="app/templates")
@@ -52,6 +55,16 @@ async def list_tunnels() -> list[dict[str, str | int | None]]:
]
@app.get("/api/history/events")
async def history_events() -> list[dict[str, object | None]]:
return storage.recent_events()
@app.get("/api/history/services")
async def history_services() -> list[dict[str, object | None]]:
return storage.recent_services()
@app.get("/api/tunnels/{port}/logs")
async def tunnel_logs(port: int) -> dict[str, list[str]]:
logs = manager.get_logs(port)
@@ -64,6 +77,9 @@ async def tunnel_logs(port: int) -> dict[str, list[str]]:
async def start_tunnel(payload: TunnelRequest) -> dict[str, str | int | None]:
if payload.port <= 0 or payload.port > 65535:
raise HTTPException(status_code=400, detail="Invalid port.")
allowed, reason = policy.is_port_allowed(payload.port)
if not allowed:
raise HTTPException(status_code=403, detail=reason or "Porta non autorizzata.")
info = manager.start_tunnel(payload.port)
return {
"port": info.port,
@@ -87,3 +103,4 @@ async def stop_tunnel(port: int) -> dict[str, bool]:
@app.on_event("shutdown")
def shutdown_event() -> None:
manager.shutdown()
storage.close()