Replace all hardcoded 'mabase_prod.' table prefixes in dashboard route
SQL queries with configurable database names from settings:
- http_logs, http_logs_raw → settings.CLICKHOUSE_DB_LOGS
- All other tables → settings.CLICKHOUSE_DB_PROCESSING
Also qualify previously unqualified table references (bare FROM/JOIN
table_name) with the appropriate database prefix for consistency.
Each route file now imports 'from ..config import settings' and uses
f-strings with {settings.CLICKHOUSE_DB_PROCESSING} or
{settings.CLICKHOUSE_DB_LOGS} for database-qualified table names.
Files updated: analysis, attributes, audit, botnets, bruteforce,
clustering, detections, entities, fingerprints, header_fingerprint,
heatmap, incidents, investigation_summary, metrics, ml_features,
rotation, search, tcp_spoofing, variability (19 files).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
"""
|
|
Endpoints pour la liste des attributs uniques
|
|
"""
|
|
from fastapi import APIRouter, HTTPException, Query
|
|
from ..database import db
|
|
from ..models import AttributeListResponse, AttributeListItem
|
|
from ..config import settings
|
|
|
|
router = APIRouter(prefix="/api/attributes", tags=["attributes"])
|
|
|
|
|
|
@router.get("/{attr_type}", response_model=AttributeListResponse)
|
|
async def get_attributes(
|
|
attr_type: str,
|
|
limit: int = Query(100, ge=1, le=1000, description="Nombre maximum de résultats")
|
|
):
|
|
"""
|
|
Récupère la liste des valeurs uniques pour un type d'attribut
|
|
"""
|
|
try:
|
|
# Mapping des types vers les colonnes
|
|
type_column_map = {
|
|
"ip": "src_ip",
|
|
"ja4": "ja4",
|
|
"country": "country_code",
|
|
"asn": "asn_number",
|
|
"host": "host",
|
|
"threat_level": "threat_level",
|
|
"model_name": "model_name",
|
|
"asn_org": "asn_org"
|
|
}
|
|
|
|
if attr_type not in type_column_map:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Type invalide. Types supportés: {', '.join(type_column_map.keys())}"
|
|
)
|
|
|
|
column = type_column_map[attr_type]
|
|
|
|
# Requête de base
|
|
base_query = f"""
|
|
SELECT
|
|
{column} AS value,
|
|
count() AS count
|
|
FROM {settings.CLICKHOUSE_DB_PROCESSING}.ml_detected_anomalies
|
|
WHERE detected_at >= now() - INTERVAL 24 HOUR
|
|
"""
|
|
|
|
# Ajout du filtre pour exclure les valeurs vides/nulles
|
|
# Gestion spéciale pour les types IPv6/IPv4 qui ne peuvent pas être comparés à ''
|
|
if attr_type == "ip":
|
|
# Pour les adresses IP, on convertit en string et on filtre
|
|
query = f"""
|
|
SELECT value, count FROM (
|
|
SELECT toString({column}) AS value, count() AS count
|
|
FROM {settings.CLICKHOUSE_DB_PROCESSING}.ml_detected_anomalies
|
|
WHERE detected_at >= now() - INTERVAL 24 HOUR
|
|
GROUP BY {column}
|
|
)
|
|
WHERE value != '' AND value IS NOT NULL
|
|
ORDER BY count DESC
|
|
LIMIT %(limit)s
|
|
"""
|
|
else:
|
|
query = f"""
|
|
{base_query}
|
|
AND {column} != '' AND {column} IS NOT NULL
|
|
GROUP BY value
|
|
ORDER BY count DESC
|
|
LIMIT %(limit)s
|
|
"""
|
|
|
|
result = db.query(query, {"limit": limit})
|
|
|
|
items = [
|
|
AttributeListItem(
|
|
value=str(row[0]),
|
|
count=row[1]
|
|
)
|
|
for row in result.result_rows
|
|
]
|
|
|
|
return AttributeListResponse(
|
|
type=attr_type,
|
|
items=items,
|
|
total=len(items)
|
|
)
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Erreur: {str(e)}")
|