package handlers import ( "context" "net/http" "strings" "github.com/gin-gonic/gin" "gorm.io/gorm" "smoop-api/internal/models" "smoop-api/internal/vault" ) type CertsAdminHandler struct { db *gorm.DB pki *vault.PKIClient } func NewCertsAdminHandler(db *gorm.DB, pki *vault.PKIClient) *CertsAdminHandler { return &CertsAdminHandler{db: db, pki: pki} } type RevokeReq struct { Serial string `json:"serial" binding:"required"` // hex Reason string `json:"reason"` } func (h *CertsAdminHandler) Revoke(c *gin.Context) { var req RevokeReq if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } serial := strings.ToUpper(strings.TrimSpace(req.Serial)) if serial == "" { c.JSON(http.StatusBadRequest, gin.H{"error": "serial required"}) return } // store locally (instant kill) if err := h.db.Create(&models.RevokedSerial{SerialHex: serial, Reason: req.Reason}).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "db save failed"}) return } // trigger CRL refresh in Vault (best-effort) _ = h.pki.RebuildCRL(context.Background()) c.JSON(http.StatusOK, gin.H{"revoked": serial}) }