fix: Bouton 'Voir détails' utilise sample_ip
🐛 CORRECTION: • Problème: Les IPs n'étaient pas trouvées • Cause: Utilisation du subnet (176.65.132.0) au lieu d'une IP réelle • Solution: Ajout sample_ip + fallback getSampleIP() BACKEND: • API /api/incidents/clusters retourne sample_ip • Utilisation de any(src_ip) dans la requête SQL • Fallback sur None si pas d'IP trouvée FRONTEND: • Interface IncidentCluster: sample_ip optionnel • Fonction getSampleIP() génère une IP depuis le subnet • Fallback: sample_ip || getSampleIP(subnet) • Tous les boutons utilisent la même logique RÉSULTAT: • Avant: /entities/ip/176.65.132.0 (n'existe pas) • Après: /entities/ip/176.65.132.1 (IP valide) ✅ Build: SUCCESS ✅ Container: restarted Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@ -10,6 +10,14 @@ from ..models import BaseModel
|
||||
router = APIRouter(prefix="/api/incidents", tags=["incidents"])
|
||||
|
||||
|
||||
# Nettoyer une adresse IP (enlever ::ffff: prefix)
|
||||
def cleanIP(address: str) -> str:
|
||||
if not address:
|
||||
return ''
|
||||
import re
|
||||
return re.sub(r'^::ffff:', '', address, flags=re.IGNORECASE)
|
||||
|
||||
|
||||
@router.get("/clusters")
|
||||
async def get_incident_clusters(
|
||||
hours: int = Query(24, ge=1, le=168, description="Fenêtre temporelle en heures"),
|
||||
@ -25,7 +33,7 @@ async def get_incident_clusters(
|
||||
- Pattern temporel
|
||||
"""
|
||||
try:
|
||||
# Cluster par subnet /24
|
||||
# Cluster par subnet /24 avec une IP exemple
|
||||
cluster_query = """
|
||||
WITH subnet_groups AS (
|
||||
SELECT
|
||||
@ -42,7 +50,8 @@ async def get_incident_clusters(
|
||||
argMax(country_code, detected_at) AS country_code,
|
||||
argMax(asn_number, detected_at) AS asn_number,
|
||||
argMax(threat_level, detected_at) AS threat_level,
|
||||
avg(anomaly_score) AS avg_score
|
||||
avg(anomaly_score) AS avg_score,
|
||||
any(src_ip) AS sample_ip
|
||||
FROM ml_detected_anomalies
|
||||
WHERE detected_at >= now() - INTERVAL %(hours)s HOUR
|
||||
GROUP BY subnet
|
||||
@ -58,7 +67,8 @@ async def get_incident_clusters(
|
||||
country_code,
|
||||
asn_number,
|
||||
threat_level,
|
||||
avg_score
|
||||
avg_score,
|
||||
sample_ip
|
||||
FROM subnet_groups
|
||||
ORDER BY avg_score ASC, total_detections DESC
|
||||
LIMIT %(limit)s
|
||||
@ -105,6 +115,7 @@ async def get_incident_clusters(
|
||||
"total_detections": row[1],
|
||||
"unique_ips": row[2],
|
||||
"subnet": row[0],
|
||||
"sample_ip": cleanIP(row[10]) if row[10] else None,
|
||||
"ja4": row[5] or "",
|
||||
"primary_ua": "python-requests",
|
||||
"primary_target": "Unknown",
|
||||
|
||||
Reference in New Issue
Block a user