Spaces:
Sleeping
Sleeping
Update app/main.py
Browse files- app/main.py +18 -3
app/main.py
CHANGED
|
@@ -5,15 +5,23 @@ import httpx
|
|
| 5 |
from fastapi import FastAPI, HTTPException
|
| 6 |
from fastapi.middleware.cors import CORSMiddleware
|
| 7 |
from starlette.responses import PlainTextResponse
|
| 8 |
-
from .storage import get_suffixes_from_hf, validate_prefix
|
| 9 |
|
| 10 |
USER_AGENT = os.getenv("USER_AGENT", "OPLC/1.0 (+https://github.com/your-org/oplc)")
|
| 11 |
BACKEND_MODE = os.getenv("BACKEND_MODE", "proxy").lower()
|
| 12 |
ENABLE_PADDING = os.getenv("PADDING", "true").lower() == "true"
|
| 13 |
HIBP_RANGE_URL = "https://api.pwnedpasswords.com/range/{}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
app = FastAPI(title="Open Password Leak Check (OPLC)")
|
| 16 |
-
app.add_middleware(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
@app.get("/healthz", response_class=PlainTextResponse)
|
| 19 |
async def healthz() -> str:
|
|
@@ -28,17 +36,24 @@ async def range_lookup(prefix: str):
|
|
| 28 |
raise HTTPException(status_code=400, detail=str(e))
|
| 29 |
|
| 30 |
if BACKEND_MODE == "proxy":
|
| 31 |
-
async with httpx.AsyncClient(
|
|
|
|
|
|
|
|
|
|
| 32 |
r = await client.get(HIBP_RANGE_URL.format(prefix))
|
| 33 |
if r.status_code != 200:
|
| 34 |
raise HTTPException(status_code=502, detail=f"Upstream error: {r.status_code}")
|
| 35 |
return PlainTextResponse(r.text, headers={"Cache-Control": "max-age=86400, public"})
|
|
|
|
| 36 |
elif BACKEND_MODE == "hf":
|
|
|
|
|
|
|
| 37 |
suffixes = await get_suffixes_from_hf(prefix)
|
| 38 |
if ENABLE_PADDING:
|
| 39 |
suffixes = add_padding(suffixes)
|
| 40 |
suffixes.sort()
|
| 41 |
return PlainTextResponse("\n".join(suffixes), headers={"Cache-Control": "max-age=86400, public"})
|
|
|
|
| 42 |
raise HTTPException(status_code=500, detail="Unsupported BACKEND_MODE")
|
| 43 |
|
| 44 |
def add_padding(suffixes: list[str]) -> list[str]:
|
|
|
|
| 5 |
from fastapi import FastAPI, HTTPException
|
| 6 |
from fastapi.middleware.cors import CORSMiddleware
|
| 7 |
from starlette.responses import PlainTextResponse
|
|
|
|
| 8 |
|
| 9 |
USER_AGENT = os.getenv("USER_AGENT", "OPLC/1.0 (+https://github.com/your-org/oplc)")
|
| 10 |
BACKEND_MODE = os.getenv("BACKEND_MODE", "proxy").lower()
|
| 11 |
ENABLE_PADDING = os.getenv("PADDING", "true").lower() == "true"
|
| 12 |
HIBP_RANGE_URL = "https://api.pwnedpasswords.com/range/{}"
|
| 13 |
+
HEX = "0123456789ABCDEF"
|
| 14 |
+
|
| 15 |
+
def validate_prefix(prefix: str) -> None:
|
| 16 |
+
if len(prefix) != 5 or any(c not in HEX for c in prefix):
|
| 17 |
+
raise ValueError("prefix must be 5 hex chars (SHA-1 uppercased)")
|
| 18 |
|
| 19 |
app = FastAPI(title="Open Password Leak Check (OPLC)")
|
| 20 |
+
app.add_middleware(
|
| 21 |
+
CORSMiddleware,
|
| 22 |
+
allow_origins=["*"], allow_credentials=False,
|
| 23 |
+
allow_methods=["GET"], allow_headers=["*"],
|
| 24 |
+
)
|
| 25 |
|
| 26 |
@app.get("/healthz", response_class=PlainTextResponse)
|
| 27 |
async def healthz() -> str:
|
|
|
|
| 36 |
raise HTTPException(status_code=400, detail=str(e))
|
| 37 |
|
| 38 |
if BACKEND_MODE == "proxy":
|
| 39 |
+
async with httpx.AsyncClient(
|
| 40 |
+
timeout=30.0,
|
| 41 |
+
headers={"User-Agent": USER_AGENT, "Add-Padding": "true" if ENABLE_PADDING else "false"},
|
| 42 |
+
) as client:
|
| 43 |
r = await client.get(HIBP_RANGE_URL.format(prefix))
|
| 44 |
if r.status_code != 200:
|
| 45 |
raise HTTPException(status_code=502, detail=f"Upstream error: {r.status_code}")
|
| 46 |
return PlainTextResponse(r.text, headers={"Cache-Control": "max-age=86400, public"})
|
| 47 |
+
|
| 48 |
elif BACKEND_MODE == "hf":
|
| 49 |
+
# Import here so proxy mode never imports storage (avoids cache dir on startup)
|
| 50 |
+
from .storage import get_suffixes_from_hf
|
| 51 |
suffixes = await get_suffixes_from_hf(prefix)
|
| 52 |
if ENABLE_PADDING:
|
| 53 |
suffixes = add_padding(suffixes)
|
| 54 |
suffixes.sort()
|
| 55 |
return PlainTextResponse("\n".join(suffixes), headers={"Cache-Control": "max-age=86400, public"})
|
| 56 |
+
|
| 57 |
raise HTTPException(status_code=500, detail="Unsupported BACKEND_MODE")
|
| 58 |
|
| 59 |
def add_padding(suffixes: list[str]) -> list[str]:
|