rmm2/backend/api/audit.go

69 lines
1.9 KiB
Go

package api
import (
"log"
"net/http"
"strconv"
)
// auditLog writes an audit log entry, extracting user from JWT context
func (h *Handler) auditLog(r *http.Request, action, targetType, targetID, targetName, details string) {
userName := "api-key"
if claims, ok := r.Context().Value(UserContextKey).(*JWTClaims); ok {
userName = claims.Username
}
sourceIP := r.RemoteAddr
go func() {
if err := h.db.AddAuditLog(userName, action, targetType, targetID, targetName, details, sourceIP); err != nil {
log.Printf("Audit-Log Fehler: %v", err)
}
}()
}
// auditLogDirect writes an audit log entry with explicit userName (for login handler)
func auditLogDirect(h *Handler, r *http.Request, userName, action, targetType, targetID, targetName, details string) {
sourceIP := r.RemoteAddr
go func() {
if err := h.db.AddAuditLog(userName, action, targetType, targetID, targetName, details, sourceIP); err != nil {
log.Printf("Audit-Log Fehler: %v", err)
}
}()
}
// GET /api/v1/audit
func (h *Handler) getAuditLogs(w http.ResponseWriter, r *http.Request) {
// JWT only - check that user context exists
if _, ok := r.Context().Value(UserContextKey).(*JWTClaims); !ok {
writeError(w, http.StatusForbidden, "JWT-Authentifizierung erforderlich")
return
}
limit := 100
offset := 0
action := r.URL.Query().Get("action")
agentID := r.URL.Query().Get("agent_id")
if l := r.URL.Query().Get("limit"); l != "" {
if n, err := strconv.Atoi(l); err == nil && n > 0 {
limit = n
}
}
if o := r.URL.Query().Get("offset"); o != "" {
if n, err := strconv.Atoi(o); err == nil && n >= 0 {
offset = n
}
}
entries, total, err := h.db.GetAuditLogs(limit, offset, action, agentID)
if err != nil {
writeError(w, http.StatusInternalServerError, "Fehler beim Laden")
return
}
writeJSON(w, http.StatusOK, map[string]interface{}{
"data": entries,
"total": total,
})
}