refactor: decompose monolith — app.py 10,600→143 lines, 30+ modules
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.
This commit is contained in:
20
backend/auth/rate_limit.py
Normal file
20
backend/auth/rate_limit.py
Normal file
@@ -0,0 +1,20 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user