inou/api/api_audit.go

93 lines
2.1 KiB
Go

package main
import (
"encoding/json"
"inou/lib"
"net/http"
)
type AuditRequest struct {
Dossier string `json:"dossier"`
Action string `json:"action"`
Target string `json:"target"`
Details string `json:"details"`
}
type AuditResponse struct {
ID string `json:"id"`
Dossier string `json:"dossier"`
Action string `json:"action"`
Target string `json:"target"`
Details string `json:"details"`
Timestamp int64 `json:"timestamp"`
}
func handleAudit(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method == "POST" {
// Localhost only for writes
if !isLocalhost(r) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
var req AuditRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
dossierID := req.Dossier
targetID := req.Target
if dossierID == "" || req.Action == "" {
http.Error(w, "dossier and action required", http.StatusBadRequest)
return
}
lib.AuditLog(dossierID, req.Action, targetID, req.Details)
json.NewEncoder(w).Encode(map[string]bool{"ok": true})
return
}
// GET - query audit log
targetHex := r.URL.Query().Get("target")
dossierHex := r.URL.Query().Get("dossier")
var entries []*lib.AuditEntry
var err error
if targetHex != "" {
targetID := targetHex
entries, err = lib.AuditQueryByTarget(targetID, 0, 0)
} else if dossierHex != "" {
dossierID := dossierHex
entries, err = lib.AuditQueryByActor(dossierID, 0, 0)
} else {
http.Error(w, "target or dossier parameter required", http.StatusBadRequest)
return
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var resp []AuditResponse
for _, e := range entries {
resp = append(resp, AuditResponse{
ID: e.AuditID,
Dossier: e.Actor1ID,
Action: e.Action,
Target: e.TargetID,
Details: e.Details,
Timestamp: e.Timestamp,
})
}
if resp == nil {
resp = []AuditResponse{}
}
json.NewEncoder(w).Encode(resp)
}