package controller import ( "fmt" "net/http" "time" "ezops/model" "ezops/pkg/auditcleaner" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // AuditSettingsHandler 审计策略配置 // Logan.Li type AuditSettingsHandler struct { db *gorm.DB } func NewAuditSettingsHandler(db *gorm.DB) *AuditSettingsHandler { return &AuditSettingsHandler{db: db} } func (h *AuditSettingsHandler) getOrCreate() (model.AuditSettings, error) { var s model.AuditSettings err := h.db.First(&s).Error if err == nil { return s, nil } if err != gorm.ErrRecordNotFound { return s, err } s = model.AuditSettings{ RetentionDays: 180, RecordAll: true, SessionWatermarkEnabled: true, SessionRecordEnabled: true, ClipboardEnabled: true, FileUploadEnabled: true, FileDownloadEnabled: true, } return s, h.db.Create(&s).Error } func auditSettingsPayload(s model.AuditSettings) gin.H { return gin.H{ "retention_days": s.RetentionDays, "record_all": s.RecordAll, "session_watermark_enabled": s.SessionWatermarkEnabled, "session_record_enabled": s.SessionRecordEnabled, "clipboard_enabled": s.ClipboardEnabled, "file_upload_enabled": s.FileUploadEnabled, "file_download_enabled": s.FileDownloadEnabled, "command_policy_enabled": s.CommandPolicyEnabled, "approval_required": s.ApprovalRequired, "last_cleanup_at": s.LastCleanupAt, "last_cleanup_summary": s.LastCleanupSummary, "allowed_retention_days": model.AllowedAuditRetentionDays, } } // GetAuditSettings 获取审计策略 // Logan.Li // GET /api/v1/admin/audit-settings func (h *AuditSettingsHandler) GetAuditSettings(c *gin.Context) { s, err := h.getOrCreate() if err != nil { c.JSON(http.StatusInternalServerError, model.Response{Code: 500, Message: "读取配置失败"}) return } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: "success", Data: auditSettingsPayload(s), }) } // ApplyAuditSettings 应用审计策略并立即清理超期日志 // Logan.Li // PUT /api/v1/admin/audit-settings func (h *AuditSettingsHandler) ApplyAuditSettings(c *gin.Context) { var req struct { RetentionDays int `json:"retention_days" binding:"required"` RecordAll bool `json:"record_all"` SessionWatermarkEnabled bool `json:"session_watermark_enabled"` SessionRecordEnabled bool `json:"session_record_enabled"` ClipboardEnabled bool `json:"clipboard_enabled"` FileUploadEnabled bool `json:"file_upload_enabled"` FileDownloadEnabled bool `json:"file_download_enabled"` CommandPolicyEnabled bool `json:"command_policy_enabled"` ApprovalRequired bool `json:"approval_required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, model.Response{Code: 400, Message: "请求参数错误"}) return } if !model.IsValidRetentionDays(req.RetentionDays) { c.JSON(http.StatusBadRequest, model.Response{ Code: 400, Message: "保留天数仅支持 7 / 15 / 30 / 90 / 180 / 365", }) return } s, err := h.getOrCreate() if err != nil { c.JSON(http.StatusInternalServerError, model.Response{Code: 500, Message: "读取配置失败"}) return } s.RetentionDays = req.RetentionDays s.RecordAll = req.RecordAll s.SessionWatermarkEnabled = req.SessionWatermarkEnabled s.SessionRecordEnabled = req.SessionRecordEnabled s.ClipboardEnabled = req.ClipboardEnabled s.FileUploadEnabled = req.FileUploadEnabled s.FileDownloadEnabled = req.FileDownloadEnabled s.CommandPolicyEnabled = req.CommandPolicyEnabled s.ApprovalRequired = req.ApprovalRequired cleanResult, cleanErr := auditcleaner.Run(h.db, req.RetentionDays) now := time.Now() s.LastCleanupAt = &now s.LastCleanupSummary = cleanResult.SummaryJSON() if err := h.db.Save(&s).Error; err != nil { c.JSON(http.StatusInternalServerError, model.Response{Code: 500, Message: "保存配置失败"}) return } msg := fmt.Sprintf("已应用保留 %d 天策略", req.RetentionDays) if cleanErr != nil { c.JSON(http.StatusInternalServerError, model.Response{ Code: 500, Message: "配置已保存,但立即清理失败: " + cleanErr.Error(), }) return } if cleanResult.Total > 0 { msg += fmt.Sprintf(",已清理 %d 条超期记录", cleanResult.Total) } else { msg += ",暂无超期记录需清理" } c.JSON(http.StatusOK, model.Response{ Code: 200, Message: msg, Data: gin.H{ "retention_days": s.RetentionDays, "record_all": s.RecordAll, "session_watermark_enabled": s.SessionWatermarkEnabled, "session_record_enabled": s.SessionRecordEnabled, "clipboard_enabled": s.ClipboardEnabled, "file_upload_enabled": s.FileUploadEnabled, "file_download_enabled": s.FileDownloadEnabled, "command_policy_enabled": s.CommandPolicyEnabled, "approval_required": s.ApprovalRequired, "last_cleanup_at": s.LastCleanupAt, "last_cleanup_summary": s.LastCleanupSummary, "cleanup": cleanResult, }, }) }