refactor: A-series dead code cleanup and ETHOS compliance sweep
- Remove dead queries.RetryCommand function (DEV-019, 31 lines) - Remove security_settings.go.broken leftover from A-3 - Remove 5 compiled test binaries from aggregator-agent/ (~61MB) - Remove config_builder.go.restored from repo root - Remove test_disk_detection.go and test_disk.go (throwaway test files) - Fix 6 banned word violations (production-ready, enhanced, robust, seamlessly) - Add .gitignore rules for compiled agent binaries - Document machine ID duplication for D-1 fix prompt - Document 30+ pre-existing emoji violations for D-2 pass No behavior changes. All 41 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,205 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/Fimeg/RedFlag/aggregator-server/internal/services"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// SecuritySettingsHandler handles security settings API endpoints
|
||||
type SecuritySettingsHandler struct {
|
||||
securitySettingsService *services.SecuritySettingsService
|
||||
}
|
||||
|
||||
// NewSecuritySettingsHandler creates a new security settings handler
|
||||
func NewSecuritySettingsHandler(securitySettingsService *services.SecuritySettingsService) *SecuritySettingsHandler {
|
||||
return &SecuritySettingsHandler{
|
||||
securitySettingsService: securitySettingsService,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllSecuritySettings returns all security settings for the authenticated user
|
||||
func (h *SecuritySettingsHandler) GetAllSecuritySettings(c *gin.Context) {
|
||||
// Get user from context
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
settings, err := h.securitySettingsService.GetAllSettings(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"settings": settings,
|
||||
"user_has_permission": true, // Check actual permissions
|
||||
})
|
||||
}
|
||||
|
||||
// GetSecuritySettingsByCategory returns settings for a specific category
|
||||
func (h *SecuritySettingsHandler) GetSecuritySettingsByCategory(c *gin.Context) {
|
||||
category := c.Param("category") // e.g., "command_signing", "nonce_validation"
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
settings, err := h.securitySettingsService.GetSettingsByCategory(userID, category)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, settings)
|
||||
}
|
||||
|
||||
// UpdateSecuritySetting updates a specific security setting
|
||||
func (h *SecuritySettingsHandler) UpdateSecuritySetting(c *gin.Context) {
|
||||
var req struct {
|
||||
Value interface{} `json:"value" binding:"required"`
|
||||
Reason string `json:"reason"` // Optional audit trail
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
category := c.Param("category")
|
||||
key := c.Param("key")
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
// Validate before applying
|
||||
if err := h.securitySettingsService.ValidateSetting(category, key, req.Value); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Apply the setting
|
||||
err := h.securitySettingsService.SetSetting(category, key, req.Value, userID, req.Reason)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Return updated setting
|
||||
setting, err := h.securitySettingsService.GetSetting(category, key)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "Setting updated successfully",
|
||||
"setting": map[string]interface{}{
|
||||
"category": category,
|
||||
"key": key,
|
||||
"value": setting,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// ValidateSecuritySettings validates settings without applying them
|
||||
func (h *SecuritySettingsHandler) ValidateSecuritySettings(c *gin.Context) {
|
||||
var req struct {
|
||||
Category string `json:"category" binding:"required"`
|
||||
Key string `json:"key" binding:"required"`
|
||||
Value interface{} `json:"value" binding:"required"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err := h.securitySettingsService.ValidateSetting(req.Category, req.Key, req.Value)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"valid": false,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"valid": true,
|
||||
"message": "Setting is valid",
|
||||
})
|
||||
}
|
||||
|
||||
// GetSecurityAuditTrail returns audit trail of security setting changes
|
||||
func (h *SecuritySettingsHandler) GetSecurityAuditTrail(c *gin.Context) {
|
||||
// Pagination parameters
|
||||
page := c.DefaultQuery("page", "1")
|
||||
pageSize := c.DefaultQuery("page_size", "50")
|
||||
|
||||
pageInt, _ := strconv.Atoi(page)
|
||||
pageSizeInt, _ := strconv.Atoi(pageSize)
|
||||
|
||||
auditEntries, totalCount, err := h.securitySettingsService.GetAuditTrail(pageInt, pageSizeInt)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"audit_entries": auditEntries,
|
||||
"pagination": gin.H{
|
||||
"page": pageInt,
|
||||
"page_size": pageSizeInt,
|
||||
"total": totalCount,
|
||||
"total_pages": (totalCount + pageSizeInt - 1) / pageSizeInt,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// GetSecurityOverview returns current security status overview
|
||||
func (h *SecuritySettingsHandler) GetSecurityOverview(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
overview, err := h.securitySettingsService.GetSecurityOverview(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, overview)
|
||||
}
|
||||
|
||||
// ApplySecuritySettings applies batch of setting changes atomically
|
||||
func (h *SecuritySettingsHandler) ApplySecuritySettings(c *gin.Context) {
|
||||
var req struct {
|
||||
Settings map[string]map[string]interface{} `json:"settings" binding:"required"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
// Validate all settings first
|
||||
for category, settings := range req.Settings {
|
||||
for key, value := range settings {
|
||||
if err := h.securitySettingsService.ValidateSetting(category, key, value); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"error": fmt.Sprintf("Validation failed for %s.%s: %v", category, key, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply all settings atomically
|
||||
err := h.securitySettingsService.ApplySettingsBatch(req.Settings, userID, req.Reason)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "All settings applied successfully",
|
||||
"applied_count": len(req.Settings),
|
||||
})
|
||||
}
|
||||
@@ -196,38 +196,6 @@ func (q *CommandQueries) CancelCommand(id uuid.UUID) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// RetryCommand creates a new command based on a failed/timed_out/cancelled command
|
||||
func (q *CommandQueries) RetryCommand(originalID uuid.UUID) (*models.AgentCommand, error) {
|
||||
// Get the original command
|
||||
original, err := q.GetCommandByID(originalID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Only allow retry of failed, timed_out, or cancelled commands
|
||||
if original.Status != "failed" && original.Status != "timed_out" && original.Status != "cancelled" {
|
||||
return nil, fmt.Errorf("command must be failed, timed_out, or cancelled to retry")
|
||||
}
|
||||
|
||||
// Create new command with same parameters, linking it to the original
|
||||
newCommand := &models.AgentCommand{
|
||||
ID: uuid.New(),
|
||||
AgentID: original.AgentID,
|
||||
CommandType: original.CommandType,
|
||||
Params: original.Params,
|
||||
Status: models.CommandStatusPending,
|
||||
CreatedAt: time.Now(),
|
||||
RetriedFromID: &originalID,
|
||||
}
|
||||
|
||||
// Store the new command
|
||||
if err := q.CreateCommand(newCommand); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newCommand, nil
|
||||
}
|
||||
|
||||
// GetActiveCommands retrieves commands that are not in a final/terminal state
|
||||
// Shows anything that's in progress or can be retried (excludes completed and cancelled)
|
||||
func (q *CommandQueries) GetActiveCommands() ([]models.ActiveCommandInfo, error) {
|
||||
|
||||
@@ -35,7 +35,7 @@ type Config struct {
|
||||
RateLimitPerSecond int
|
||||
}
|
||||
|
||||
// DefaultConfig returns production-ready default configuration
|
||||
// DefaultConfig returns default configuration values
|
||||
func DefaultConfig() Config {
|
||||
return Config{
|
||||
CheckInterval: 10 * time.Second,
|
||||
|
||||
Reference in New Issue
Block a user