patchcenter/app/main.py
Khalid MOUTAOUAKIL 5cc10c5b6c Module QuickWin complet + filtres serveurs OS/owner
- QuickWin: campagnes patching rapide avec exclusions générales (OS/reboot) et spécifiques (applicatifs)
- Config serveurs: pagination, filtres (search, env, domain, zone, per_page), dry run, bulk edit
- Détail campagne: pagination hprod/prod séparée, filtres (search, status, domain), section prod masquée si hprod non terminé
- Auth: redirection qw_only vers /quickwin, profil lecture seule quickwin
- Serveurs: filtres OS (Linux/Windows) et Owner (secops/ipop/na), exclusion EOL
- Sidebar: lien QuickWin conditionné sur permission campaigns ou quickwin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 16:27:45 +02:00

91 lines
3.1 KiB
Python

"""PatchCenter v2 — Entry point FastAPI"""
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from starlette.middleware.base import BaseHTTPMiddleware
from .config import APP_NAME, APP_VERSION
from .dependencies import get_current_user, get_user_perms
from .database import SessionLocal
from .routers import auth, dashboard, servers, settings, users, campaigns, planning, specifics, audit, contacts, qualys, safe_patching, audit_full, quickwin
class PermissionsMiddleware(BaseHTTPMiddleware):
"""Injecte user + perms dans request.state pour tous les templates"""
async def dispatch(self, request: Request, call_next):
user = get_current_user(request)
perms = {}
if user:
db = SessionLocal()
try:
perms = get_user_perms(db, user)
finally:
db.close()
request.state.user = user
request.state.perms = perms
response = await call_next(request)
return response
app = FastAPI(title=APP_NAME, version=APP_VERSION)
app.add_middleware(PermissionsMiddleware)
app.mount("/static", StaticFiles(directory="app/static"), name="static")
app.include_router(auth.router)
app.include_router(dashboard.router)
app.include_router(servers.router)
app.include_router(settings.router)
app.include_router(users.router)
app.include_router(campaigns.router)
app.include_router(planning.router)
app.include_router(specifics.router)
app.include_router(audit.router)
app.include_router(contacts.router)
app.include_router(qualys.router)
app.include_router(safe_patching.router)
app.include_router(audit_full.router)
app.include_router(quickwin.router)
@app.get("/")
async def root(request: Request):
user = get_current_user(request)
if user:
return RedirectResponse(url="/dashboard")
return RedirectResponse(url="/login")
@app.get("/health")
async def health():
return {"status": "ok", "app": APP_NAME, "version": APP_VERSION}
# --- Error handlers ---
from fastapi.templating import Jinja2Templates
_error_templates = Jinja2Templates(directory="app/templates")
@app.exception_handler(500)
async def internal_error(request: Request, exc):
return _error_templates.TemplateResponse("error.html", {
"request": request, "code": 500,
"title": "Application en maintenance",
"message": "Une erreur interne est survenue. L'équipe technique a été notifiée.",
}, status_code=500)
@app.exception_handler(404)
async def not_found(request: Request, exc):
return _error_templates.TemplateResponse("error.html", {
"request": request, "code": 404,
"title": "Page introuvable",
"message": "La page demandée n'existe pas.",
}, status_code=404)
@app.exception_handler(Exception)
async def generic_error(request: Request, exc):
import traceback
traceback.print_exc()
return _error_templates.TemplateResponse("error.html", {
"request": request, "code": 500,
"title": "Application en maintenance",
"message": "Une erreur interne est survenue. L'équipe technique a été notifiée.",
}, status_code=500)