certificate.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package certificate
  2. import (
  3. "github.com/0xJacky/Nginx-UI/api"
  4. "github.com/0xJacky/Nginx-UI/api/cosy"
  5. "github.com/0xJacky/Nginx-UI/internal/cert"
  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. }
  75. func AddCert(c *gin.Context) {
  76. var json certJson
  77. if !api.BindAndValid(c, &json) {
  78. return
  79. }
  80. certModel := &model.Cert{
  81. Name: json.Name,
  82. SSLCertificatePath: json.SSLCertificatePath,
  83. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  84. KeyType: json.KeyType,
  85. ChallengeMethod: json.ChallengeMethod,
  86. DnsCredentialID: json.DnsCredentialID,
  87. }
  88. err := certModel.Insert()
  89. if err != nil {
  90. api.ErrHandler(c, err)
  91. return
  92. }
  93. content := &cert.Content{
  94. SSLCertificatePath: json.SSLCertificatePath,
  95. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  96. SSLCertificate: json.SSLCertificate,
  97. SSLCertificateKey: json.SSLCertificateKey,
  98. }
  99. err = content.WriteFile()
  100. if err != nil {
  101. api.ErrHandler(c, err)
  102. return
  103. }
  104. c.JSON(http.StatusOK, Transformer(certModel))
  105. }
  106. func ModifyCert(c *gin.Context) {
  107. id := cast.ToInt(c.Param("id"))
  108. var json certJson
  109. if !api.BindAndValid(c, &json) {
  110. return
  111. }
  112. q := query.Cert
  113. certModel, err := q.FirstByID(id)
  114. if err != nil {
  115. api.ErrHandler(c, err)
  116. return
  117. }
  118. err = certModel.Updates(&model.Cert{
  119. Name: json.Name,
  120. SSLCertificatePath: json.SSLCertificatePath,
  121. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  122. ChallengeMethod: json.ChallengeMethod,
  123. KeyType: json.KeyType,
  124. DnsCredentialID: json.DnsCredentialID,
  125. })
  126. if err != nil {
  127. api.ErrHandler(c, err)
  128. return
  129. }
  130. content := &cert.Content{
  131. SSLCertificatePath: json.SSLCertificatePath,
  132. SSLCertificateKeyPath: json.SSLCertificateKeyPath,
  133. SSLCertificate: json.SSLCertificate,
  134. SSLCertificateKey: json.SSLCertificateKey,
  135. }
  136. err = content.WriteFile()
  137. if err != nil {
  138. api.ErrHandler(c, err)
  139. return
  140. }
  141. GetCert(c)
  142. }
  143. func RemoveCert(c *gin.Context) {
  144. cosy.Core[model.Cert](c).Destroy()
  145. }