Fase 0 complete: extract all business logic, auth, database, and 176 endpoints from monolithic app.py into dedicated modules. Structure: - app.py: FastAPI hub (CORS, routers, startup/shutdown) - models.py: 13 Pydantic request models - utils.py: shared utilities (embed status, upload validation, process registries) - config.py: constants, env vars, model catalogs - auth/: crypto, jwt_auth, oidc, rate_limit - database/: db(), init_db(), schema DDL - services/: genai, compliance, chat, terraform, embeddings, cis_reports, mcp - routes/: 13 APIRouter modules (auth, users, oci_config, oci_explorer, genai, mcp, adb, embeddings, reports, chat, terraform, settings, cis_engine) Also: README updated with OCIR auth instructions for manual docker run. 86 tests passing.
21 lines
662 B
Python
21 lines
662 B
Python
"""Rate limiting for login brute-force protection."""
|
|
import time
|
|
import threading
|
|
from fastapi import HTTPException
|
|
|
|
_login_attempts: dict = {}
|
|
_login_attempts_lock = threading.Lock()
|
|
_LOGIN_WINDOW = 300 # 5 minutes
|
|
_LOGIN_MAX = 10 # max attempts per window
|
|
|
|
|
|
def _check_rate_limit(ip: str):
|
|
now = time.time()
|
|
with _login_attempts_lock:
|
|
attempts = _login_attempts.get(ip, [])
|
|
attempts = [t for t in attempts if now - t < _LOGIN_WINDOW]
|
|
if len(attempts) >= _LOGIN_MAX:
|
|
raise HTTPException(429, "Muitas tentativas de login. Aguarde 5 minutos.")
|
|
attempts.append(now)
|
|
_login_attempts[ip] = attempts
|