certificate.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package certificate
  2. import (
  3. "github.com/0xJacky/Nginx-UI/api"
  4. "github.com/0xJacky/Nginx-UI/internal/cert"
  5. "github.com/0xJacky/Nginx-UI/internal/cosy"
  6. "github.com/0xJacky/Nginx-UI/model"
  7. "github.com/0xJacky/Nginx-UI/query"
  8. "github.com/gin-gonic/gin"
  9. "github.com/go-acme/lego/v4/certcrypto"
  10. "github.com/spf13/cast"
  11. "net/http"
  12. "os"
  13. )
  14. type APICertificate struct {
  15. *model.Cert
  16. SSLCertificate string `json:"ssl_certificate,omitempty"`
  17. SSLCertificateKey string `json:"ssl_certificate_key,omitempty"`
  18. CertificateInfo *cert.Info `json:"certificate_info,omitempty"`
  19. }
  20. func Transformer(certModel *model.Cert) (certificate *APICertificate) {
  21. var sslCertificationBytes, sslCertificationKeyBytes []byte
  22. var certificateInfo *cert.Info
  23. if certModel.SSLCertificatePath != "" {
  24. if _, err := os.Stat(certModel.SSLCertificatePath); err == nil {
  25. sslCertificationBytes, _ = os.ReadFile(certModel.SSLCertificatePath)
  26. if !cert.IsCertificate(string(sslCertificationBytes)) {
  27. sslCertificationBytes = []byte{}
  28. }
  29. }
  30. certificateInfo, _ = cert.GetCertInfo(certModel.SSLCertificatePath)
  31. }
  32. if certModel.SSLCertificateKeyPath != "" {
  33. if _, err := os.Stat(certModel.SSLCertificateKeyPath); err == nil {
  34. sslCertificationKeyBytes, _ = os.ReadFile(certModel.SSLCertificateKeyPath)
  35. if !cert.IsPrivateKey(string(sslCertificationKeyBytes)) {
  36. sslCertificationKeyBytes = []byte{}
  37. }
  38. }
  39. }
  40. return &APICertificate{
  41. Cert: certModel,
  42. SSLCertificate: string(sslCertificationBytes),
  43. SSLCertificateKey: string(sslCertificationKeyBytes),
  44. CertificateInfo: certificateInfo,
  45. }
  46. }
  47. func GetCertList(c *gin.Context) {
  48. cosy.Core[model.Cert](c).SetFussy("name", "domain").SetTransformer(func(m *model.Cert) any {
  49. info, _ := cert.GetCertInfo(m.SSLCertificatePath)
  50. return APICertificate{
  51. Cert: m,
  52. CertificateInfo: info,
  53. }
  54. }).PagingList()
  55. }
  56. func GetCert(c *gin.Context) {
  57. q := query.Cert
  58. certModel, err := q.FirstByID(cast.ToInt(c.Param("id")))
  59. if err != nil {
  60. api.ErrHandler(c, err)
  61. return
  62. }
  63. c.JSON(http.StatusOK, Transformer(certModel))
  64. }
  65. type certJson struct {
  66. Name string `json:"name" binding:"required"`
  67. SSLCertificatePath string `json:"ssl_certificate_path" binding:"required,certificate_path"`
  68. SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required,privatekey_path"`
  69. SSLCertificate string `json:"ssl_certificate" binding:"omitempty,certificate"`
  70. SSLCertificateKey string `json:"ssl_certificate_key" binding:"omitempty,privatekey"`
  71. KeyType certcrypto.KeyType `json:"key_type" binding:"omitempty,auto_cert_key_type"`
  72. ChallengeMethod string `json:"challenge_method"`
  73. DnsCredentialID int `json:"dns_credential_id"`
  74. ACMEUserID int `json:"acme_user_id"`
  75. }
  76. func AddCert(c *gin.Context) {
  77. var json certJson
  78. if !api.BindAndValid(c, &json) {
  79. return
  80. }
  81. certModel := &model.Cert{
  82. Name: json.Name,
  83. SSLCertificatePath: json.SSLCertificatePath,
  84. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  85. KeyType: json.KeyType,
  86. ChallengeMethod: json.ChallengeMethod,
  87. DnsCredentialID: json.DnsCredentialID,
  88. ACMEUserID: json.ACMEUserID,
  89. }
  90. err := certModel.Insert()
  91. if err != nil {
  92. api.ErrHandler(c, err)
  93. return
  94. }
  95. content := &cert.Content{
  96. SSLCertificatePath: json.SSLCertificatePath,
  97. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  98. SSLCertificate: json.SSLCertificate,
  99. SSLCertificateKey: json.SSLCertificateKey,
  100. }
  101. err = content.WriteFile()
  102. if err != nil {
  103. api.ErrHandler(c, err)
  104. return
  105. }
  106. c.JSON(http.StatusOK, Transformer(certModel))
  107. }
  108. func ModifyCert(c *gin.Context) {
  109. id := cast.ToInt(c.Param("id"))
  110. var json certJson
  111. if !api.BindAndValid(c, &json) {
  112. return
  113. }
  114. q := query.Cert
  115. certModel, err := q.FirstByID(id)
  116. if err != nil {
  117. api.ErrHandler(c, err)
  118. return
  119. }
  120. err = certModel.Updates(&model.Cert{
  121. Name: json.Name,
  122. SSLCertificatePath: json.SSLCertificatePath,
  123. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  124. ChallengeMethod: json.ChallengeMethod,
  125. KeyType: json.KeyType,
  126. DnsCredentialID: json.DnsCredentialID,
  127. ACMEUserID: json.ACMEUserID,
  128. })
  129. if err != nil {
  130. api.ErrHandler(c, err)
  131. return
  132. }
  133. content := &cert.Content{
  134. SSLCertificatePath: json.SSLCertificatePath,
  135. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  136. SSLCertificate: json.SSLCertificate,
  137. SSLCertificateKey: json.SSLCertificateKey,
  138. }
  139. err = content.WriteFile()
  140. if err != nil {
  141. api.ErrHandler(c, err)
  142. return
  143. }
  144. GetCert(c)
  145. }
  146. func RemoveCert(c *gin.Context) {
  147. cosy.Core[model.Cert](c).Destroy()
  148. }