126 lines
3.6 KiB
Go
126 lines
3.6 KiB
Go
|
package model
|
||
|
|
||
|
import (
|
||
|
"github.com/0xJacky/Nginx-UI/internal/helper"
|
||
|
"github.com/0xJacky/Nginx-UI/internal/nginx"
|
||
|
"github.com/go-acme/lego/v4/certcrypto"
|
||
|
"github.com/go-acme/lego/v4/certificate"
|
||
|
"github.com/lib/pq"
|
||
|
"gorm.io/gorm/clause"
|
||
|
"os"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
AutoCertSync = 2
|
||
|
AutoCertEnabled = 1
|
||
|
AutoCertDisabled = -1
|
||
|
CertChallengeMethodHTTP01 = "http01"
|
||
|
CertChallengeMethodDNS01 = "dns01"
|
||
|
)
|
||
|
|
||
|
type CertDomains []string
|
||
|
|
||
|
type CertificateResource struct {
|
||
|
*certificate.Resource
|
||
|
PrivateKey []byte `json:"private_key"`
|
||
|
Certificate []byte `json:"certificate"`
|
||
|
IssuerCertificate []byte `json:"issuerCertificate"`
|
||
|
CSR []byte `json:"csr"`
|
||
|
}
|
||
|
|
||
|
type Cert struct {
|
||
|
Model
|
||
|
Name string `json:"name"`
|
||
|
Domains pq.StringArray `json:"domains" gorm:"type:text[]"`
|
||
|
Filename string `json:"filename"`
|
||
|
SSLCertificatePath string `json:"ssl_certificate_path"`
|
||
|
SSLCertificateKeyPath string `json:"ssl_certificate_key_path"`
|
||
|
AutoCert int `json:"auto_cert"`
|
||
|
ChallengeMethod string `json:"challenge_method"`
|
||
|
DnsCredentialID uint64 `json:"dns_credential_id"`
|
||
|
DnsCredential *DnsCredential `json:"dns_credential,omitempty"`
|
||
|
ACMEUserID uint64 `json:"acme_user_id"`
|
||
|
ACMEUser *AcmeUser `json:"acme_user,omitempty"`
|
||
|
KeyType certcrypto.KeyType `json:"key_type"`
|
||
|
Log string `json:"log"`
|
||
|
Resource *CertificateResource `json:"-" gorm:"serializer:json"`
|
||
|
SyncNodeIds []uint64 `json:"sync_node_ids" gorm:"serializer:json"`
|
||
|
MustStaple bool `json:"must_staple"`
|
||
|
LegoDisableCNAMESupport bool `json:"lego_disable_cname_support"`
|
||
|
}
|
||
|
|
||
|
func FirstCert(confName string) (c Cert, err error) {
|
||
|
err = db.Limit(1).Where(&Cert{
|
||
|
Filename: confName,
|
||
|
}).Find(&c).Error
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func FirstOrCreateCert(confName string, keyType certcrypto.KeyType) (c Cert, err error) {
|
||
|
// Filename is used to check whether this site is enabled
|
||
|
err = db.FirstOrCreate(&c, &Cert{Name: confName, Filename: confName, KeyType: keyType}).Error
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (c *Cert) Insert() error {
|
||
|
return db.Create(c).Error
|
||
|
}
|
||
|
|
||
|
func GetAutoCertList() (c []*Cert) {
|
||
|
var t []*Cert
|
||
|
if db == nil {
|
||
|
return
|
||
|
}
|
||
|
db.Where("auto_cert", AutoCertEnabled).Find(&t)
|
||
|
|
||
|
// check if this domain is enabled
|
||
|
enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled"))
|
||
|
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
enabledConfigMap := make(map[string]bool)
|
||
|
for i := range enabledConfig {
|
||
|
enabledConfigMap[enabledConfig[i].Name()] = true
|
||
|
}
|
||
|
|
||
|
for _, v := range t {
|
||
|
if v.ChallengeMethod == CertChallengeMethodDNS01 || enabledConfigMap[v.Filename] == true {
|
||
|
c = append(c, v)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (c *Cert) Updates(n *Cert) error {
|
||
|
return db.Model(c).Clauses(clause.Returning{}).
|
||
|
Where("id", c.ID).Updates(n).Error
|
||
|
}
|
||
|
|
||
|
func (c *Cert) Remove() error {
|
||
|
if c.Filename == "" {
|
||
|
return db.Delete(c).Error
|
||
|
}
|
||
|
|
||
|
return db.Where("filename", c.Filename).Delete(c).Error
|
||
|
}
|
||
|
|
||
|
func (c *Cert) GetKeyType() certcrypto.KeyType {
|
||
|
return helper.GetKeyType(c.KeyType)
|
||
|
}
|
||
|
|
||
|
func (c *CertificateResource) GetResource() certificate.Resource {
|
||
|
return certificate.Resource{
|
||
|
Domain: c.Resource.Domain,
|
||
|
CertURL: c.Resource.CertURL,
|
||
|
CertStableURL: c.Resource.CertStableURL,
|
||
|
PrivateKey: c.PrivateKey,
|
||
|
Certificate: c.Certificate,
|
||
|
IssuerCertificate: c.IssuerCertificate,
|
||
|
CSR: c.CSR,
|
||
|
}
|
||
|
}
|