""" alerts.py Contiene endpoint para administrar el CRUD y la lógica de las alertas. """ from fastapi import APIRouter, Depends, HTTPException, Request, status from sqlalchemy.orm import Session from database import get_db import models import schemas from typing import List, Optional from datetime import datetime from auth import get_current_user from audit import log_action router = APIRouter() @router.post("/alerts/", response_model=schemas.AlertResponse, tags=['Alerts']) def create_alert( alert: schemas.AlertCreate, request: Request, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_message = db.query(models.Message).filter( models.Message.id_mess_g == alert.message_id, models.Message.group_id == alert.group_id ).first() if not db_message: raise HTTPException(status_code=404, detail="Message not found") db_rule = db.query(models.Rule).filter(models.Rule.id == alert.rule_id).first() if not db_rule: raise HTTPException(status_code=404, detail="Rule not found") db_alert = models.Alert( message_id=alert.message_id, group_id=alert.group_id, rule_id=alert.rule_id, status=alert.status, notes=alert.notes, created_at=datetime.utcnow() ) db.add(db_alert) db.flush() log_action( db=db, entity_type='alert', entity_id=db_alert.id, action='create', user_id=current_user, after=db_alert, ip_address=request.client.host ) db.commit() db.refresh(db_alert) return db_alert @router.get("/alerts/", response_model=List[schemas.AlertResponse], tags=['Alerts']) def read_alerts( skip: int = 0, limit: int = 100, status: Optional[str] = None, severity: Optional[str] = None, date_from: Optional[datetime] = None, date_to: Optional[datetime] = None, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): query = db.query(models.Alert) if status: query = query.filter(models.Alert.status == status) if severity: query = query.filter(models.Alert.rule.has(models.Rule.severity == severity)) if date_from: query = query.filter(models.Alert.created_at >= date_from) if date_to: query = query.filter(models.Alert.created_at <= date_to) return query.offset(skip).limit(limit).all() @router.get("/alerts/{alert_id}", response_model=schemas.AlertResponse, tags=['Alerts']) def read_alert( alert_id: int, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_alert = db.query(models.Alert).filter(models.Alert.id == alert_id).first() if not db_alert: raise HTTPException(status_code=404, detail="Alert not found") return db_alert @router.put("/alerts/{alert_id}", response_model=schemas.AlertResponse, tags=['Alerts']) def update_alert( alert_id: int, alert: schemas.AlertCreate, request: Request, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_alert = db.query(models.Alert).filter(models.Alert.id == alert_id).first() if not db_alert: raise HTTPException(status_code=404, detail="Alert not found") before_snapshot = { 'id': db_alert.id, 'message_id': db_alert.message_id, 'group_id': db_alert.group_id, 'rule_id': db_alert.rule_id, 'status': db_alert.status, 'notes': db_alert.notes, } for field, value in alert.model_dump().items(): setattr(db_alert, field, value) log_action( db=db, entity_type='alert', entity_id=alert_id, action='update', user_id=current_user, before=before_snapshot, after=db_alert, ip_address=request.client.host ) db.commit() db.refresh(db_alert) return db_alert @router.delete("/alerts/{alert_id}", tags=['Alerts']) def delete_alert( alert_id: int, request: Request, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_alert = db.query(models.Alert).filter(models.Alert.id == alert_id).first() if not db_alert: raise HTTPException(status_code=404, detail="Alert not found") log_action( db=db, entity_type='alert', entity_id=alert_id, action='delete', user_id=current_user, before=db_alert, ip_address=request.client.host ) db.delete(db_alert) db.commit() return {"message": "Alert deleted successfully"} @router.post("/alerts/{alert_id}/resolve", tags=['Alerts']) def resolve_alert( alert_id: int, request: Request, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_alert = db.query(models.Alert).filter(models.Alert.id == alert_id).first() if not db_alert: raise HTTPException(status_code=404, detail="Alert not found") log_action( db=db, entity_type='alert', entity_id=alert_id, action='status_change', user_id=current_user, before={'status': db_alert.status}, after={'status': 'close'}, ip_address=request.client.host ) db_alert.status = "close" db.commit() db.refresh(db_alert) return db_alert @router.post("/alerts/{alert_id}/reopen", tags=['Alerts']) def open_alert( alert_id: int, request: Request, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_alert = db.query(models.Alert).filter(models.Alert.id == alert_id).first() if not db_alert: raise HTTPException(status_code=404, detail="Alert not found") log_action( db=db, entity_type='alert', entity_id=alert_id, action='status_change', user_id=current_user, before={'status': db_alert.status}, after={'status': 'open'}, ip_address=request.client.host ) db_alert.status = "open" db.commit() db.refresh(db_alert) return db_alert @router.post("/alerts/{alert_id}/in-progress", tags=['Alerts']) def set_alert_in_progress( alert_id: int, request: Request, db: Session = Depends(get_db), current_user: int = Depends(get_current_user) ): db_alert = db.query(models.Alert).filter(models.Alert.id == alert_id).first() if not db_alert: raise HTTPException(status_code=404, detail="Alert not found") # Solo cambiar si está abierta, no sobreescribir estados más avanzados if db_alert.status != "open": return db_alert log_action( db=db, entity_type='alert', entity_id=alert_id, action='status_change', user_id=current_user, before={'status': db_alert.status}, after={'status': 'in_progress'}, ip_address=request.client.host ) db_alert.status = "in_progress" db.commit() db.refresh(db_alert) return db_alert