package handlers import ( "net/http" "strconv" "ezops/internal/models" "ezops/pkg/crypto" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // CredentialHandler 凭据管理处理器 // Logan.Li type CredentialHandler struct { db *gorm.DB crypt *crypto.SecretBox } func NewCredentialHandler(db *gorm.DB, masterKey string) *CredentialHandler { return &CredentialHandler{ db: db, crypt: crypto.NewSecretBox(masterKey), } } // preview 内容脱敏预览:前8字符 + ... + 后4字符 func preview(s string) string { if len(s) <= 12 { return "****" } return s[:8] + "..." + s[len(s)-4:] } // ListCredentials 凭据列表 func (h *CredentialHandler) ListCredentials(c *gin.Context) { var creds []models.Credential if err := h.db.Order("updated_at DESC").Find(&creds).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "查询失败"}) return } items := make([]models.CredentialListResponse, 0, len(creds)) for _, cred := range creds { items = append(items, models.CredentialListResponse{ ID: cred.ID, Name: cred.Name, Type: cred.Type, Preview: preview(cred.Content), Description: cred.Description, CreatedAt: cred.CreatedAt, UpdatedAt: cred.UpdatedAt, }) } c.JSON(http.StatusOK, models.Response{Code: 200, Data: models.ListResponse{ List: items, Total: int64(len(items)), }}) } // CreateCredential 创建凭据 func (h *CredentialHandler) CreateCredential(c *gin.Context) { var req models.CredentialCreateRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "参数错误: " + err.Error()}) return } encrypted, err := h.crypt.Encrypt(req.Content) if err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "加密失败"}) return } cred := models.Credential{ Name: req.Name, Type: req.Type, Content: encrypted, Description: req.Description, } if err := h.db.Create(&cred).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "创建失败"}) return } c.JSON(http.StatusOK, models.Response{ Code: 200, Message: "创建成功", Data: models.CredentialListResponse{ ID: cred.ID, Name: cred.Name, Type: cred.Type, Preview: preview(cred.Content), Description: cred.Description, CreatedAt: cred.CreatedAt, UpdatedAt: cred.UpdatedAt, }, }) } // UpdateCredential 更新凭据 func (h *CredentialHandler) UpdateCredential(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效ID"}) return } var req models.CredentialUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "参数错误: " + err.Error()}) return } var cred models.Credential if h.db.First(&cred, id).Error != nil { c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "凭据不存在"}) return } cred.Name = req.Name cred.Type = req.Type cred.Description = req.Description if req.Content != "" { encrypted, err := h.crypt.Encrypt(req.Content) if err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "加密失败"}) return } cred.Content = encrypted } if err := h.db.Save(&cred).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "更新失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "更新成功"}) } // DeleteCredential 删除凭据 func (h *CredentialHandler) DeleteCredential(c *gin.Context) { id, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效ID"}) return } var cred models.Credential if h.db.First(&cred, id).Error != nil { c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "凭据不存在"}) return } if err := h.db.Delete(&cred).Error; err != nil { c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "删除失败"}) return } c.JSON(http.StatusOK, models.Response{Code: 200, Message: "删除成功"}) }