91 lines
2.0 KiB
Go
91 lines
2.0 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 != "" {
|
|
entries, err = lib.AuditList(&lib.AuditFilter{TargetID: targetHex})
|
|
} else if dossierHex != "" {
|
|
entries, err = lib.AuditList(&lib.AuditFilter{ActorID: dossierHex})
|
|
} 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)
|
|
}
|