feat(dlp): implement case management service and DLP Review integration

This commit is contained in:
igor04091968
2026-05-13 03:08:53 +03:00
parent bc44052391
commit 28a4dae67f
11 changed files with 616 additions and 36 deletions
+61 -36
View File
@@ -1,53 +1,78 @@
#!/usr/bin/env python3
from __future__ import annotations
import sqlite3
import os
from pathlib import Path
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi import FastAPI, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
DB = Path("/opt/activitywatch/dlp-case-management/cases.db")
from case_schema import CaseCommentCreate, CaseCreate, CaseUpdate
from case_storage import CaseStorage
DB = Path(os.environ.get("AW_DLP_CASE_DB_PATH", "/opt/activitywatch/dlp-case-management/cases.db"))
APP = FastAPI(title="AWatch DLP Case Management")
APP.add_middleware(
CORSMiddleware,
allow_origins=["http://127.0.0.1:5600", "http://localhost:5600", "http://10.10.10.13:5600", "*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
STORE = CaseStorage(DB)
class CaseCreate(BaseModel):
incident_id: str
title: str
severity: str = "medium"
assignee: str | None = None
def _conn() -> sqlite3.Connection:
DB.parent.mkdir(parents=True, exist_ok=True)
c = sqlite3.connect(DB)
c.execute(
"CREATE TABLE IF NOT EXISTS cases (id INTEGER PRIMARY KEY, incident_id TEXT, title TEXT, severity TEXT, assignee TEXT, status TEXT DEFAULT 'open')"
)
return c
@APP.get("/health")
def health() -> dict[str, Any]:
return {"ok": True, "db": str(DB)}
@APP.post("/api/0/dlp/cases")
def create_case(payload: CaseCreate) -> dict[str, Any]:
c = _conn()
cur = c.cursor()
cur.execute(
"INSERT INTO cases (incident_id,title,severity,assignee,status) VALUES (?,?,?,?,?)",
(payload.incident_id, payload.title, payload.severity, payload.assignee, "open"),
)
c.commit()
case_id = cur.lastrowid
c.close()
return {"id": case_id}
return STORE.create_case(payload.model_dump(exclude_none=True), actor="api")
@APP.get("/api/0/dlp/cases")
def list_cases() -> list[dict[str, Any]]:
c = _conn()
rows = c.execute("SELECT id,incident_id,title,severity,assignee,status FROM cases ORDER BY id DESC").fetchall()
c.close()
return [
{"id": r[0], "incident_id": r[1], "title": r[2], "severity": r[3], "assignee": r[4], "status": r[5]}
for r in rows
]
def list_cases(
status: str | None = Query(default=None),
host: str | None = Query(default=None),
limit: int = Query(default=200, ge=1, le=2000),
) -> list[dict[str, Any]]:
return STORE.list_cases(status=status, host=host, limit=limit)
@APP.get("/api/0/dlp/cases/{case_id}")
def get_case(case_id: int) -> dict[str, Any]:
try:
case = STORE.get_case(case_id)
except KeyError:
raise HTTPException(status_code=404, detail="case not found")
case["comments"] = STORE.list_comments(case_id, limit=200)
case["audit"] = STORE.list_audit(case_id, limit=200)
return case
@APP.patch("/api/0/dlp/cases/{case_id}")
def update_case(case_id: int, payload: CaseUpdate) -> dict[str, Any]:
patch = payload.model_dump(exclude_none=True)
if not patch:
return STORE.get_case(case_id)
try:
return STORE.update_case(case_id, patch=patch, actor="api")
except KeyError:
raise HTTPException(status_code=404, detail="case not found")
@APP.post("/api/0/dlp/cases/{case_id}/comments")
def add_comment(case_id: int, payload: CaseCommentCreate) -> dict[str, Any]:
try:
STORE.get_case(case_id)
except KeyError:
raise HTTPException(status_code=404, detail="case not found")
return STORE.add_comment(case_id=case_id, comment=payload.comment, author=payload.author)
@APP.get("/api/0/dlp/cases/{case_id}/comments")
def list_comments(case_id: int, limit: int = Query(default=200, ge=1, le=2000)) -> list[dict[str, Any]]:
return STORE.list_comments(case_id=case_id, limit=limit)