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