From daf87891a783c967d71269586b6667dae4fbcd63 Mon Sep 17 00:00:00 2001 From: Admin MPCZ Date: Sat, 25 Apr 2026 00:05:49 +0000 Subject: [PATCH] feat(qualys/dashboard): is_running base sur DB (multi-worker safe) + bouton Annuler --- app/routers/qualys.py | 32 +++++++++++++++++++++++++---- app/templates/qualys_dashboard.html | 3 +++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/app/routers/qualys.py b/app/routers/qualys.py index f90305a..dacd61f 100644 --- a/app/routers/qualys.py +++ b/app/routers/qualys.py @@ -1186,16 +1186,23 @@ async def qualys_dashboard(request: Request, db=Depends(get_db)): # TODO: ajouter perm specifique 'qualys_dashboard_view' (admin + DSI) if not can_view(perms, "qualys"): return RedirectResponse(url="/dashboard") - from app.services.qualys_service import load_vuln_dashboard, is_dashboard_running + from app.services.qualys_service import load_vuln_dashboard data = load_vuln_dashboard(db) + # Check si un run est en cours via DB (multi-worker safe) + pending = db.execute(text("""SELECT id, run_at FROM qualys_vuln_snapshot_run + WHERE status='pending' AND run_at > now() - interval '15 minutes' + ORDER BY run_at DESC LIMIT 1""")).fetchone() + is_running = pending is not None + env_set = sorted({d["name"] for d in data["env"]}) pos_set = sorted({d["name"] for d in data["pos"]}) matrix = {(c["name"], c["name2"]): c for c in data["env_pos"]} ctx = base_context(request, db, user) ctx.update({"data": data, "env_list": env_set, "pos_list": pos_set, - "matrix": matrix, "is_running": is_dashboard_running()}) + "matrix": matrix, "is_running": is_running, + "running_since": pending.run_at if pending else None}) return templates.TemplateResponse("qualys_dashboard.html", ctx) @@ -1207,8 +1214,10 @@ async def qualys_dashboard_refresh(request: Request, db=Depends(get_db)): perms = get_user_perms(db, user) if not can_edit(perms, "qualys"): return RedirectResponse(url="/qualys/dashboard") - from app.services.qualys_service import compute_vuln_dashboard, is_dashboard_running - if is_dashboard_running(): + from app.services.qualys_service import compute_vuln_dashboard + pending = db.execute(text("""SELECT id FROM qualys_vuln_snapshot_run + WHERE status='pending' AND run_at > now() - interval '15 minutes' LIMIT 1""")).fetchone() + if pending: return RedirectResponse(url="/qualys/dashboard?msg=already_running", status_code=303) import threading def _runner(): @@ -1222,6 +1231,21 @@ async def qualys_dashboard_refresh(request: Request, db=Depends(get_db)): return RedirectResponse(url="/qualys/dashboard?msg=refresh_started", status_code=303) +@router.post("/qualys/dashboard/cancel") +async def qualys_dashboard_cancel(request: Request, db=Depends(get_db)): + user = get_current_user(request) + if not user: + return RedirectResponse(url="/login") + perms = get_user_perms(db, user) + if not can_edit(perms, "qualys"): + return RedirectResponse(url="/qualys/dashboard") + db.execute(text("""UPDATE qualys_vuln_snapshot_run + SET status='cancelled', msg='annule par utilisateur' + WHERE status='pending'""")) + db.commit() + return RedirectResponse(url="/qualys/dashboard?msg=cancelled", status_code=303) + + @router.get("/qualys/dashboard/history", response_class=HTMLResponse) async def qualys_dashboard_history(request: Request, db=Depends(get_db), period: str = "day", days: int = 30, diff --git a/app/templates/qualys_dashboard.html b/app/templates/qualys_dashboard.html index bd38fd5..8e3519e 100644 --- a/app/templates/qualys_dashboard.html +++ b/app/templates/qualys_dashboard.html @@ -15,6 +15,9 @@ +
+ +