audit of client actions/ protection of admin TG v2/ fix of cash accounting status/ update of dependencies
This commit is contained in:
+62
-9
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user