audit of client actions/ protection of admin TG v2/ fix of cash accounting status/ update of dependencies

This commit is contained in:
Vladless
2026-03-18 01:17:44 +03:00
parent 77f927660b
commit 6d341a9f57
30 changed files with 2219 additions and 36 deletions
+62 -9
View File
@@ -1,8 +1,14 @@
import asyncio
import os
from time import perf_counter
from fastapi import FastAPI, Request
from starlette.middleware.cors import CORSMiddleware
from starlette.staticfiles import StaticFiles
from config import API_LOGGING, API_VERSION
from audit import ensure_api_context, log_api_access, record_api_access_event_background
from config import API_LOGGING, API_VERSION, API_CORS_ORIGINS
from database import async_session_maker
from logger import logger
if API_VERSION == 1:
@@ -19,22 +25,69 @@ app = FastAPI(
openapi_url="/api/openapi.json",
)
app.add_middleware(
CORSMiddleware,
allow_origins=API_CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.middleware("http")
async def api_access_log_middleware(request: Request, call_next):
context = ensure_api_context(request)
if not API_LOGGING:
return await call_next(request)
response = await call_next(request)
response.headers["X-Request-Id"] = context.request_id
return response
started = perf_counter()
response = await call_next(request)
duration_ms = int((perf_counter() - started) * 1000)
client_ip = request.client.host if request.client else "-"
path_qs = request.url.path
if request.url.query:
path_qs = f"{path_qs}?{request.url.query}"
try:
response = await call_next(request)
except Exception as exc:
duration_ms = int((perf_counter() - started) * 1000)
log_api_access(
request,
status_code=500,
duration_ms=duration_ms,
result="fail",
reason=type(exc).__name__,
)
asyncio.create_task(
record_api_access_event_background(
async_session_maker,
request,
result="fail",
reason=type(exc).__name__,
status_code=500,
)
)
raise
logger.info(f'[API] {client_ip} "{request.method} {path_qs}" {response.status_code} {duration_ms}ms')
duration_ms = int((perf_counter() - started) * 1000)
response.headers["X-Request-Id"] = context.request_id
result = "success" if response.status_code < 400 else "fail"
log_api_access(
request,
status_code=response.status_code,
duration_ms=duration_ms,
result=result,
)
asyncio.create_task(
record_api_access_event_background(
async_session_maker,
request,
result=result,
reason=None if response.status_code < 400 else str(response.status_code),
status_code=response.status_code,
)
)
return response
app.include_router(api_router)
_web_uploads_dir = "static/web_uploads"
os.makedirs(_web_uploads_dir, exist_ok=True)
app.mount("/api/web/uploads", StaticFiles(directory=_web_uploads_dir), name="web_uploads")