57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
from fastapi import APIRouter, Depends, Header, HTTPException, Request
|
||
|
|
from fastapi.responses import FileResponse
|
||
|
|
|
||
|
|
from app.core.security import admin_auth, token_digest
|
||
|
|
from app.repositories import crash_report_repository
|
||
|
|
|
||
|
|
|
||
|
|
router = APIRouter(tags=["admin-crash-report"])
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/admin/crash-report/list")
|
||
|
|
def admin_crash_report_list(limit: int = 300, auth=Depends(admin_auth)):
|
||
|
|
limit = max(1, min(limit, 1000))
|
||
|
|
return {"list": crash_report_repository.list_crash_reports(limit)}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/admin/crash-report/file/{report_id}/{file_name}")
|
||
|
|
def admin_crash_report_file(
|
||
|
|
report_id: str,
|
||
|
|
file_name: str,
|
||
|
|
request: Request,
|
||
|
|
X_Admin_Token: str = Header(""),
|
||
|
|
auth=Depends(admin_auth),
|
||
|
|
):
|
||
|
|
allowed = {
|
||
|
|
"metadata": "metadata.json",
|
||
|
|
"metadata.json": "metadata.json",
|
||
|
|
"minidump": "crash.dmp",
|
||
|
|
"crash.dmp": "crash.dmp",
|
||
|
|
"attachments": "attachments.zip",
|
||
|
|
"attachments.zip": "attachments.zip",
|
||
|
|
"server": "server.json",
|
||
|
|
"server.json": "server.json",
|
||
|
|
}
|
||
|
|
stored_name = allowed.get(file_name)
|
||
|
|
if not stored_name:
|
||
|
|
raise HTTPException(status_code=404, detail="崩溃报告文件不存在")
|
||
|
|
|
||
|
|
row = crash_report_repository.get_crash_report(report_id)
|
||
|
|
if not row:
|
||
|
|
raise HTTPException(status_code=404, detail="崩溃报告不存在")
|
||
|
|
|
||
|
|
target = Path(row["storage_path"]) / stored_name
|
||
|
|
if not target.is_file():
|
||
|
|
raise HTTPException(status_code=404, detail="崩溃报告文件不存在")
|
||
|
|
|
||
|
|
crash_report_repository.log_file_access(
|
||
|
|
report_id,
|
||
|
|
stored_name,
|
||
|
|
token_digest(X_Admin_Token)[:16],
|
||
|
|
request.client.host if request.client else "",
|
||
|
|
request.headers.get("user-agent", "")[:300],
|
||
|
|
)
|
||
|
|
return FileResponse(target, media_type="application/octet-stream", filename=stored_name)
|