feat: revoke certificate #293

This commit is contained in:
Jacky 2025-04-10 16:15:07 +08:00
parent 52a23750b5
commit c073801794
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
35 changed files with 1785 additions and 550 deletions

View file

@ -92,6 +92,7 @@ type certJson struct {
DnsCredentialID uint64 `json:"dns_credential_id"`
ACMEUserID uint64 `json:"acme_user_id"`
SyncNodeIds []uint64 `json:"sync_node_ids"`
RevokeOld bool `json:"revoke_old"`
}
func AddCert(c *gin.Context) {
@ -192,6 +193,7 @@ func ModifyCert(c *gin.Context) {
DnsCredentialID: json.DnsCredentialID,
ACMEUserID: json.ACMEUserID,
SyncNodeIds: json.SyncNodeIds,
RevokeOld: json.RevokeOld,
}
content := &cert.Content{

View file

@ -82,6 +82,8 @@ func IssueCert(c *gin.Context) {
return
}
payload.CertID = certModel.ID
if certModel.SSLCertificatePath != "" {
certInfo, _ := cert.GetCertInfo(certModel.SSLCertificatePath)
if certInfo != nil {
@ -130,6 +132,7 @@ func IssueCert(c *gin.Context) {
MustStaple: payload.MustStaple,
LegoDisableCNAMESupport: payload.LegoDisableCNAMESupport,
Log: log.ToString(),
RevokeOld: payload.RevokeOld,
})).FirstOrCreate()
if err != nil {
logger.Error(err)

122
api/certificate/revoke.go Normal file
View file

@ -0,0 +1,122 @@
package certificate
import (
"net/http"
"github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/spf13/cast"
"github.com/uozi-tech/cosy/logger"
)
type RevokeCertResponse struct {
Status string `json:"status"`
Message string `json:"message"`
}
func handleRevokeCertLogChan(conn *websocket.Conn, logChan chan string) {
defer func() {
if err := recover(); err != nil {
logger.Error(err)
}
}()
for logString := range logChan {
err := conn.WriteJSON(RevokeCertResponse{
Status: Info,
Message: logString,
})
if err != nil {
logger.Error(err)
return
}
}
}
// RevokeCert handles certificate revocation through websocket connection
func RevokeCert(c *gin.Context) {
id := cast.ToUint64(c.Param("id"))
var upGrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// upgrade http to websocket
ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
logger.Error(err)
return
}
defer func(ws *websocket.Conn) {
_ = ws.Close()
}(ws)
// Get certificate from database
certQuery := query.Cert
certModel, err := certQuery.FirstByID(id)
if err != nil {
logger.Error(err)
_ = ws.WriteJSON(RevokeCertResponse{
Status: Error,
Message: "Certificate not found: " + err.Error(),
})
return
}
// Create payload for revocation
payload := &cert.ConfigPayload{
CertID: id,
ServerName: certModel.Domains,
ChallengeMethod: certModel.ChallengeMethod,
DNSCredentialID: certModel.DnsCredentialID,
ACMEUserID: certModel.ACMEUserID,
KeyType: certModel.KeyType,
Resource: certModel.Resource,
}
logChan := make(chan string, 1)
errChan := make(chan error, 1)
go cert.RevokeCert(payload, logChan, errChan)
go handleRevokeCertLogChan(ws, logChan)
// block, until errChan closes
for err = range errChan {
logger.Error(err)
err = ws.WriteJSON(RevokeCertResponse{
Status: Error,
Message: err.Error(),
})
if err != nil {
logger.Error(err)
return
}
return
}
// Update certificate status in database
err = certModel.Remove()
if err != nil {
logger.Error(err)
_ = ws.WriteJSON(RevokeCertResponse{
Status: Error,
Message: "Failed to delete certificate from database: " + err.Error(),
})
return
}
err = ws.WriteJSON(RevokeCertResponse{
Status: Success,
Message: "Certificate revoked successfully",
})
if err != nil {
logger.Error(err)
return
}
}

View file

@ -23,6 +23,7 @@ func InitCertificateRouter(r *gin.RouterGroup) {
func InitCertificateWebSocketRouter(r *gin.RouterGroup) {
r.GET("domain/:name/cert", IssueCert)
r.GET("certs/:id/revoke", RevokeCert)
}
func InitAcmeUserRouter(r *gin.RouterGroup) {