refactor: UI improvements and code cleanup
Frontend: - DetectionsList: Simplify columns, improve truncation and display for IPs, hosts, bot info - IncidentsView: Replace metric cards with compact stat cards (unique IPs, known bots, ML anomalies, threat levels) - InvestigationView: Add section navigation anchors, reorganize layout with proper IDs - ThreatIntelView: Add navigation links to investigation pages, add comment column, improve table layout Backend: - Various route and model adjustments - Configuration updates Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -1,11 +1,11 @@
|
||||
"""
|
||||
Routes pour la gestion des incidents clusterisés
|
||||
"""
|
||||
import hashlib
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from typing import List, Optional
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
from ..database import db
|
||||
from ..models import BaseModel
|
||||
|
||||
router = APIRouter(prefix="/api/incidents", tags=["incidents"])
|
||||
|
||||
@ -83,7 +83,6 @@ async def get_incident_clusters(
|
||||
|
||||
# Collect sample IPs to fetch real UA and trend data in bulk
|
||||
sample_ips = [row[10] for row in result.result_rows if row[10]]
|
||||
subnets_list = [row[0] for row in result.result_rows]
|
||||
|
||||
# Fetch real primary UA per sample IP from view_dashboard_entities
|
||||
ua_by_ip: dict = {}
|
||||
@ -182,7 +181,7 @@ async def get_incident_clusters(
|
||||
primary_ua = ua_by_ip.get(sample_ip, "")
|
||||
|
||||
clusters.append({
|
||||
"id": f"INC-{datetime.now().strftime('%Y%m%d')}-{len(clusters)+1:03d}",
|
||||
"id": f"INC-{hashlib.md5(subnet.encode()).hexdigest()[:8].upper()}",
|
||||
"score": risk_score,
|
||||
"severity": severity,
|
||||
"total_detections": row[1],
|
||||
@ -213,22 +212,13 @@ async def get_incident_clusters(
|
||||
@router.get("/{cluster_id}")
|
||||
async def get_incident_details(cluster_id: str):
|
||||
"""
|
||||
Récupère les détails d'un incident spécifique
|
||||
Récupère les détails d'un incident spécifique.
|
||||
Non encore implémenté — les détails par cluster seront disponibles dans une prochaine version.
|
||||
"""
|
||||
try:
|
||||
# Extraire le subnet du cluster_id (simplifié)
|
||||
# Dans une implémentation réelle, on aurait une table de mapping
|
||||
|
||||
return {
|
||||
"id": cluster_id,
|
||||
"details": "Implementation en cours",
|
||||
"timeline": [],
|
||||
"entities": [],
|
||||
"classifications": []
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=501,
|
||||
detail="Détails par incident non encore implémentés. Utilisez /api/incidents/clusters pour la liste."
|
||||
)
|
||||
|
||||
|
||||
@router.post("/{cluster_id}/classify")
|
||||
@ -239,34 +229,38 @@ async def classify_incident(
|
||||
comment: str = ""
|
||||
):
|
||||
"""
|
||||
Classe un incident rapidement
|
||||
Classe un incident rapidement.
|
||||
Non encore implémenté — utilisez /api/analysis/{ip}/classify pour classifier une IP.
|
||||
"""
|
||||
try:
|
||||
# Implementation future - sauvegarde dans la table classifications
|
||||
return {
|
||||
"status": "success",
|
||||
"cluster_id": cluster_id,
|
||||
"label": label,
|
||||
"tags": tags or [],
|
||||
"comment": comment
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
|
||||
raise HTTPException(
|
||||
status_code=501,
|
||||
detail="Classification par incident non encore implémentée. Utilisez /api/analysis/{ip}/classify."
|
||||
)
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def list_incidents(
|
||||
status: str = Query("active", description="Statut des incidents"),
|
||||
severity: str = Query(None, description="Filtrer par sévérité"),
|
||||
severity: Optional[str] = Query(None, description="Filtrer par sévérité (LOW/MEDIUM/HIGH/CRITICAL)"),
|
||||
hours: int = Query(24, ge=1, le=168)
|
||||
):
|
||||
"""
|
||||
Liste tous les incidents avec filtres
|
||||
Liste tous les incidents avec filtres.
|
||||
Délègue à get_incident_clusters ; le filtre severity est appliqué post-requête.
|
||||
"""
|
||||
try:
|
||||
# Redirige vers clusters pour l'instant
|
||||
return await get_incident_clusters(hours=hours, limit=50)
|
||||
|
||||
result = await get_incident_clusters(hours=hours, limit=100)
|
||||
items = result["items"]
|
||||
|
||||
if severity:
|
||||
sev_upper = severity.upper()
|
||||
items = [c for c in items if c.get("severity") == sev_upper]
|
||||
|
||||
return {
|
||||
"items": items,
|
||||
"total": len(items),
|
||||
"period_hours": hours,
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
|
||||
|
||||
Reference in New Issue
Block a user