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, }) }