feat: implement Phase 4 enhancements
Some checks failed
CI / lint-and-test (push) Has been cancelled
Some checks failed
CI / lint-and-test (push) Has been cancelled
- Migrate frontend to Alpine.js for reactive state management
- Add source health dashboard in UI and /api/source-health endpoint
- Add event tagging (PATCH /api/events/{id}/tags) and commenting (POST /api/events/{id}/comments)
- Add CSV/JSON export from the UI
- Add rule-based alerting engine (rules.py) with CRUD endpoints (/api/rules)
- Add SIEM export via webhook (siem.py)
- Add AOC audit trail middleware logging all mutations to aoc_audit collection
- Update config with SIEM_ENABLED, SIEM_WEBHOOK_URL, ALERTS_ENABLED
- Add tests for rules engine, tags, comments, and source health
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import time
|
||||
|
||||
from audit_trail import log_action
|
||||
from auth import require_auth
|
||||
from config import ALERTS_ENABLED
|
||||
from database import events_collection
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from graph.audit_logs import fetch_audit_logs
|
||||
@@ -8,6 +10,7 @@ from metrics import track_fetch, track_fetch_duration, track_fetch_error
|
||||
from models.api import FetchAuditLogsResponse
|
||||
from models.event_model import normalize_event
|
||||
from pymongo import UpdateOne
|
||||
from siem import forward_event
|
||||
from sources.intune_audit import fetch_intune_audit
|
||||
from sources.unified_audit import fetch_unified_audit
|
||||
from watermark import get_watermark, set_watermark
|
||||
@@ -52,12 +55,26 @@ def run_fetch(hours: int = 168):
|
||||
else:
|
||||
ops.append(UpdateOne({"id": doc.get("id"), "timestamp": doc.get("timestamp")}, {"$set": doc}, upsert=True))
|
||||
events_collection.bulk_write(ops, ordered=False)
|
||||
|
||||
if ALERTS_ENABLED:
|
||||
from rules import evaluate_event
|
||||
for doc in normalized:
|
||||
evaluate_event(doc)
|
||||
|
||||
for doc in normalized:
|
||||
forward_event(doc)
|
||||
|
||||
return {"stored_events": len(normalized), "errors": errors}
|
||||
|
||||
|
||||
@router.get("/fetch-audit-logs", response_model=FetchAuditLogsResponse)
|
||||
def fetch_logs(hours: int = Query(default=168, ge=1, le=720)):
|
||||
def fetch_logs(
|
||||
hours: int = Query(default=168, ge=1, le=720),
|
||||
user: dict = Depends(require_auth),
|
||||
):
|
||||
try:
|
||||
return run_fetch(hours=hours)
|
||||
result = run_fetch(hours=hours)
|
||||
log_action("fetch_audit_logs", "/api/fetch-audit-logs", {"hours": hours, "stored": result["stored_events"]}, user.get("sub", "anonymous"))
|
||||
return result
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=502, detail=str(exc)) from exc
|
||||
|
||||
Reference in New Issue
Block a user