mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-11 17:56:37 +08:00
fix lint
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package acme implements ACME certificate issuance and renewal.
|
||||
package acme
|
||||
|
||||
import (
|
||||
@@ -25,22 +26,27 @@ import (
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
)
|
||||
|
||||
// AcmeUser implements lego's user interface.
|
||||
type AcmeUser struct {
|
||||
const dnsChallengePrecheckDelay = 20 * time.Second
|
||||
|
||||
// User implements lego's registration.User interface for ACME account management.
|
||||
type User struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
key crypto.PrivateKey
|
||||
}
|
||||
|
||||
func (u *AcmeUser) GetEmail() string {
|
||||
// GetEmail returns the email address associated with this ACME account.
|
||||
func (u *User) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
|
||||
func (u *AcmeUser) GetRegistration() *registration.Resource {
|
||||
// GetRegistration returns the ACME account registration resource.
|
||||
func (u *User) GetRegistration() *registration.Resource {
|
||||
return u.Registration
|
||||
}
|
||||
|
||||
func (u *AcmeUser) GetPrivateKey() crypto.PrivateKey {
|
||||
// GetPrivateKey returns the private key used to authenticate with the ACME server.
|
||||
func (u *User) GetPrivateKey() crypto.PrivateKey {
|
||||
return u.key
|
||||
}
|
||||
|
||||
@@ -88,7 +94,7 @@ func encodePrivateKey(key crypto.PrivateKey) (string, error) {
|
||||
}
|
||||
|
||||
// GetOrCreateLegoClient returns a configured lego client and optional new account credentials.
|
||||
func GetOrCreateLegoClient(acmeEmail, privateKeyPEM, accountURL string, keyAlgorithm string) (*lego.Client, *AcmeUser, string, string, error) {
|
||||
func GetOrCreateLegoClient(acmeEmail, privateKeyPEM, accountURL string, keyAlgorithm string) (*lego.Client, *User, string, string, error) {
|
||||
var privateKey crypto.PrivateKey
|
||||
var err error
|
||||
var newPrivateKeyPEM string
|
||||
@@ -111,7 +117,7 @@ func GetOrCreateLegoClient(acmeEmail, privateKeyPEM, accountURL string, keyAlgor
|
||||
}
|
||||
}
|
||||
|
||||
user := &AcmeUser{
|
||||
user := &User{
|
||||
Email: acmeEmail,
|
||||
key: privateKey,
|
||||
}
|
||||
@@ -197,12 +203,12 @@ func SetupDNSProvider(client *lego.Client, dnsType, dnsAuth string, dns1, dns2 s
|
||||
}
|
||||
|
||||
if disableCNAME {
|
||||
opts = append(opts, dns01.DisableCompletePropagationRequirement())
|
||||
opts = append(opts, dns01.DisableAuthoritativeNssPropagationRequirement())
|
||||
}
|
||||
|
||||
if skipDNS {
|
||||
opts = append(opts, dns01.WrapPreCheck(func(domain, fqdn, value string, check dns01.PreCheckFunc) (bool, error) {
|
||||
time.Sleep(20 * time.Second)
|
||||
opts = append(opts, dns01.WrapPreCheck(func(_, _, _ string, _ dns01.PreCheckFunc) (bool, error) {
|
||||
time.Sleep(dnsChallengePrecheckDelay)
|
||||
return true, nil
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ func TestApplyCertificateReturnsApplying(t *testing.T) {
|
||||
Name: "Test ACME Cert",
|
||||
PrimaryDomain: "example.com",
|
||||
OtherDomains: "*.example.com",
|
||||
DnsAccountID: dnsAccount.ID,
|
||||
DNSAccountID: dnsAccount.ID,
|
||||
KeyAlgorithm: "RSA2048",
|
||||
AutoRenew: true,
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package tls defines shared error messages for certificate management.
|
||||
package tls
|
||||
|
||||
const (
|
||||
|
||||
@@ -31,7 +31,7 @@ func readMultipartFile(fileHeader *multipart.FileHeader) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer file.Close()
|
||||
defer func() { _ = file.Close() }()
|
||||
data, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -32,7 +32,7 @@ type CertificateContent struct {
|
||||
Remark string `json:"remark"`
|
||||
Provider string `json:"provider"`
|
||||
AcmeAccountID uint `json:"acme_account_id"`
|
||||
DnsAccountID uint `json:"dns_account_id"`
|
||||
DNSAccountID uint `json:"dns_account_id"`
|
||||
KeyAlgorithm string `json:"key_algorithm"`
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
PrimaryDomain string `json:"primary_domain"`
|
||||
@@ -50,7 +50,7 @@ type ApplyInput struct {
|
||||
Name string `json:"name"`
|
||||
Remark string `json:"remark"`
|
||||
AcmeAccountID uint `json:"acme_account_id"`
|
||||
DnsAccountID uint `json:"dns_account_id"`
|
||||
DNSAccountID uint `json:"dns_account_id"`
|
||||
KeyAlgorithm string `json:"key_algorithm"`
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
PrimaryDomain string `json:"primary_domain"`
|
||||
@@ -96,7 +96,7 @@ func GetCertificateContent(ctx context.Context, id uint) (*CertificateContent, e
|
||||
Remark: certificate.Remark,
|
||||
Provider: certificate.Provider,
|
||||
AcmeAccountID: certificate.AcmeAccountID,
|
||||
DnsAccountID: certificate.DnsAccountID,
|
||||
DNSAccountID: certificate.DNSAccountID,
|
||||
KeyAlgorithm: certificate.KeyAlgorithm,
|
||||
AutoRenew: certificate.AutoRenew,
|
||||
PrimaryDomain: certificate.PrimaryDomain,
|
||||
@@ -179,7 +179,7 @@ func DeleteCertificate(ctx context.Context, id uint) error {
|
||||
// ApplyCertificate 申请 ACME 证书。
|
||||
func ApplyCertificate(ctx context.Context, input ApplyInput) (*model.TLSCertificate, error) {
|
||||
cert := &model.TLSCertificate{
|
||||
Provider: "acme",
|
||||
Provider: tlsProviderACME,
|
||||
CertPEM: " ",
|
||||
KeyPEM: " ",
|
||||
}
|
||||
@@ -195,7 +195,8 @@ func ApplyCertificate(ctx context.Context, input ApplyInput) (*model.TLSCertific
|
||||
}
|
||||
|
||||
go func(c *model.TLSCertificate) {
|
||||
_ = obtainTLSCertificate(context.Background(), c)
|
||||
asyncCtx := context.WithoutCancel(ctx)
|
||||
_ = obtainTLSCertificate(asyncCtx, c)
|
||||
}(cert)
|
||||
|
||||
return sanitizeCertificateForResponse(cert), nil
|
||||
@@ -207,7 +208,7 @@ func UpdateACMECertificate(ctx context.Context, id uint, input ApplyInput) (*mod
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cert.Provider != "acme" {
|
||||
if cert.Provider != tlsProviderACME {
|
||||
return nil, errors.New(errCertificateOnlyACME)
|
||||
}
|
||||
fillAcmeCertificateFields(cert, input)
|
||||
@@ -222,7 +223,8 @@ func UpdateACMECertificate(ctx context.Context, id uint, input ApplyInput) (*mod
|
||||
}
|
||||
|
||||
go func(c *model.TLSCertificate) {
|
||||
_ = obtainTLSCertificate(context.Background(), c)
|
||||
asyncCtx := context.WithoutCancel(ctx)
|
||||
_ = obtainTLSCertificate(asyncCtx, c)
|
||||
}(cert)
|
||||
|
||||
return sanitizeCertificateForResponse(cert), nil
|
||||
@@ -237,7 +239,7 @@ func ConvertCertificateToACME(ctx context.Context, id uint, input ApplyInput) (*
|
||||
if cert.Provider != "upload" {
|
||||
return nil, errors.New(errCertificateOnlyUploadConvert)
|
||||
}
|
||||
if cert.ApplyStatus == "applying" {
|
||||
if cert.ApplyStatus == tlsApplyStatusApplying {
|
||||
return nil, errors.New(errCertificateAlreadyApplying)
|
||||
}
|
||||
fillAcmeCertificateFields(cert, input)
|
||||
@@ -253,17 +255,18 @@ func ConvertCertificateToACME(ctx context.Context, id uint, input ApplyInput) (*
|
||||
}
|
||||
|
||||
go func(c *model.TLSCertificate) {
|
||||
if err := obtainTLSCertificate(context.Background(), c); err != nil {
|
||||
asyncCtx := context.WithoutCancel(ctx)
|
||||
if err := obtainTLSCertificate(asyncCtx, c); err != nil {
|
||||
return
|
||||
}
|
||||
latest, err := model.GetTLSCertificateByID(context.Background(), c.ID)
|
||||
latest, err := model.GetTLSCertificateByID(asyncCtx, c.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
latest.Provider = "acme"
|
||||
latest.ApplyStatus = "ready"
|
||||
latest.Provider = tlsProviderACME
|
||||
latest.ApplyStatus = tlsApplyStatusReady
|
||||
latest.ApplyMessage = ""
|
||||
_ = model.SaveTLSCertificate(context.Background(), latest)
|
||||
_ = model.SaveTLSCertificate(asyncCtx, latest)
|
||||
}(cert)
|
||||
|
||||
return sanitizeCertificateForResponse(cert), nil
|
||||
@@ -275,15 +278,16 @@ func RenewCertificate(ctx context.Context, id uint) (*model.TLSCertificate, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cert.Provider != "acme" {
|
||||
if cert.Provider != tlsProviderACME {
|
||||
return nil, errors.New(errCertificateOnlyACMERenew)
|
||||
}
|
||||
|
||||
go func(c *model.TLSCertificate) {
|
||||
_ = obtainTLSCertificate(context.Background(), c)
|
||||
asyncCtx := context.WithoutCancel(ctx)
|
||||
_ = obtainTLSCertificate(asyncCtx, c)
|
||||
}(cert)
|
||||
|
||||
cert.ApplyStatus = "applying"
|
||||
cert.ApplyStatus = tlsApplyStatusApplying
|
||||
cert.ApplyMessage = ""
|
||||
if err := model.SaveTLSCertificate(ctx, cert); err != nil {
|
||||
return nil, err
|
||||
@@ -362,7 +366,7 @@ func GetDefaultAcmeAccount(ctx context.Context) (*model.AcmeAccount, error) {
|
||||
return sanitizeAcmeAccountForResponse(account), nil
|
||||
}
|
||||
|
||||
func buildCertificate(ctx context.Context, existing *model.TLSCertificate, input CertificateInput) (*model.TLSCertificate, error) {
|
||||
func buildCertificate(_ context.Context, existing *model.TLSCertificate, input CertificateInput) (*model.TLSCertificate, error) {
|
||||
name := strings.TrimSpace(input.Name)
|
||||
certPEM := strings.TrimSpace(input.CertPEM)
|
||||
keyPEM := strings.TrimSpace(input.KeyPEM)
|
||||
@@ -391,7 +395,7 @@ func buildCertificate(ctx context.Context, existing *model.TLSCertificate, input
|
||||
if existing == nil {
|
||||
existing = &model.TLSCertificate{
|
||||
Provider: "upload",
|
||||
ApplyStatus: "ready",
|
||||
ApplyStatus: tlsApplyStatusReady,
|
||||
}
|
||||
}
|
||||
existing.Name = name
|
||||
@@ -407,7 +411,7 @@ func fillAcmeCertificateFields(cert *model.TLSCertificate, input ApplyInput) {
|
||||
cert.Name = strings.TrimSpace(input.Name)
|
||||
cert.Remark = strings.TrimSpace(input.Remark)
|
||||
cert.AcmeAccountID = input.AcmeAccountID
|
||||
cert.DnsAccountID = input.DnsAccountID
|
||||
cert.DNSAccountID = input.DNSAccountID
|
||||
cert.KeyAlgorithm = input.KeyAlgorithm
|
||||
cert.AutoRenew = input.AutoRenew
|
||||
cert.PrimaryDomain = strings.TrimSpace(input.PrimaryDomain)
|
||||
@@ -416,7 +420,7 @@ func fillAcmeCertificateFields(cert *model.TLSCertificate, input ApplyInput) {
|
||||
cert.SkipDNS = input.SkipDNS
|
||||
cert.DNS1 = strings.TrimSpace(input.DNS1)
|
||||
cert.DNS2 = strings.TrimSpace(input.DNS2)
|
||||
cert.ApplyStatus = "applying"
|
||||
cert.ApplyStatus = tlsApplyStatusApplying
|
||||
}
|
||||
|
||||
func ensureCertificateNotReferenced(ctx context.Context, id uint) error {
|
||||
@@ -457,26 +461,26 @@ func sanitizeCertificateForResponse(certificate *model.TLSCertificate) *model.TL
|
||||
if certificate == nil {
|
||||
return nil
|
||||
}
|
||||
copy := *certificate
|
||||
copy.CertPEM = ""
|
||||
copy.KeyPEM = ""
|
||||
return ©
|
||||
certCopy := *certificate
|
||||
certCopy.CertPEM = ""
|
||||
certCopy.KeyPEM = ""
|
||||
return &certCopy
|
||||
}
|
||||
|
||||
func sanitizeDNSAccountForResponse(account *model.DNSAccount) *model.DNSAccount {
|
||||
if account == nil {
|
||||
return nil
|
||||
}
|
||||
copy := *account
|
||||
copy.Authorization = ""
|
||||
return ©
|
||||
certCopy := *account
|
||||
certCopy.Authorization = ""
|
||||
return &certCopy
|
||||
}
|
||||
|
||||
func sanitizeAcmeAccountForResponse(account *model.AcmeAccount) *model.AcmeAccount {
|
||||
if account == nil {
|
||||
return nil
|
||||
}
|
||||
copy := *account
|
||||
copy.PrivateKey = ""
|
||||
return ©
|
||||
certCopy := *account
|
||||
certCopy.PrivateKey = ""
|
||||
return &certCopy
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ import (
|
||||
const (
|
||||
managedDomainMatchTypeExact = "exact"
|
||||
managedDomainMatchTypeWildcard = "wildcard"
|
||||
|
||||
maxManagedDomainLength = 253
|
||||
minManagedDomainLabelCount = 2
|
||||
)
|
||||
|
||||
// ManagedDomainInput 托管域名创建/更新请求。
|
||||
@@ -182,11 +185,11 @@ func validateHostname(domain string) error {
|
||||
if domain == "" {
|
||||
return errors.New(errManagedDomainRequired)
|
||||
}
|
||||
if len(domain) > 253 {
|
||||
if len(domain) > maxManagedDomainLength {
|
||||
return errors.New(errManagedDomainInvalid)
|
||||
}
|
||||
labels := strings.Split(domain, ".")
|
||||
if len(labels) < 2 {
|
||||
if len(labels) < minManagedDomainLabelCount {
|
||||
return errors.New(errManagedDomainInvalid)
|
||||
}
|
||||
for _, label := range labels {
|
||||
|
||||
@@ -13,7 +13,12 @@ import (
|
||||
"github.com/Rain-kl/Wavelet/internal/model"
|
||||
)
|
||||
|
||||
const acmeRenewLeadTime = 7 * 24 * time.Hour
|
||||
const (
|
||||
acmeRenewLeadTime = 7 * 24 * time.Hour
|
||||
tlsProviderACME = "acme"
|
||||
tlsApplyStatusApplying = "applying"
|
||||
tlsApplyStatusReady = "ready"
|
||||
)
|
||||
|
||||
var obtainTLSCertificate = obtainCertificate
|
||||
|
||||
@@ -27,24 +32,17 @@ func SetObtainCertificateFuncForTest(fn func(context.Context, *model.TLSCertific
|
||||
}
|
||||
|
||||
func obtainCertificate(ctx context.Context, cert *model.TLSCertificate) error {
|
||||
cert.ApplyStatus = "applying"
|
||||
cert.ApplyStatus = tlsApplyStatusApplying
|
||||
if err := model.SaveTLSCertificate(ctx, cert); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
acmeAccount, err := model.GetAcmeAccountByID(ctx, cert.AcmeAccountID)
|
||||
acmeAccount, err := resolveAcmeAccount(ctx, cert)
|
||||
if err != nil {
|
||||
acmeAccount, err = model.GetDefaultAcmeAccount(ctx)
|
||||
if err != nil {
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to get ACME account: %v", err))
|
||||
}
|
||||
cert.AcmeAccountID = acmeAccount.ID
|
||||
if err := model.SaveTLSCertificate(ctx, cert); err != nil {
|
||||
return err
|
||||
}
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to get ACME account: %v", err))
|
||||
}
|
||||
|
||||
dnsAccount, err := model.GetDNSAccountByID(ctx, cert.DnsAccountID)
|
||||
dnsAccount, err := model.GetDNSAccountByID(ctx, cert.DNSAccountID)
|
||||
if err != nil {
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to get DNS account: %v", err))
|
||||
}
|
||||
@@ -75,47 +73,18 @@ func obtainCertificate(ctx context.Context, cert *model.TLSCertificate) error {
|
||||
domains,
|
||||
)
|
||||
|
||||
if (newPrivateKeyPEM != "" && acmePrivateKey != newPrivateKeyPEM) || (newAccountURL != "" && acmeAccount.URL != newAccountURL) {
|
||||
if newPrivateKeyPEM != "" {
|
||||
sealedKey, sealErr := sealSensitive(newPrivateKeyPEM)
|
||||
if sealErr != nil {
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to seal ACME account key: %v", sealErr))
|
||||
}
|
||||
acmeAccount.PrivateKey = sealedKey
|
||||
}
|
||||
if newAccountURL != "" {
|
||||
acmeAccount.URL = newAccountURL
|
||||
}
|
||||
if acmeAccount.ID == 0 {
|
||||
if dbErr := model.CreateAcmeAccountRecord(ctx, acmeAccount); dbErr != nil {
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to create ACME account: %v", dbErr))
|
||||
}
|
||||
} else if dbErr := model.SaveAcmeAccount(ctx, acmeAccount); dbErr != nil {
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to save ACME account: %v", dbErr))
|
||||
}
|
||||
cert.AcmeAccountID = acmeAccount.ID
|
||||
if err := model.SaveTLSCertificate(ctx, cert); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := persistAcmeAccountUpdates(ctx, cert, acmeAccount, newAccountURL, newPrivateKeyPEM, acmePrivateKey); err != nil {
|
||||
return updateCertError(ctx, cert, err.Error())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return updateCertError(ctx, cert, err.Error())
|
||||
}
|
||||
|
||||
sealedKey, err := sealSensitive(result.KeyPEM)
|
||||
if err != nil {
|
||||
return updateCertError(ctx, cert, fmt.Sprintf("Failed to seal certificate key: %v", err))
|
||||
if err := saveObtainedCertificate(ctx, cert, result); err != nil {
|
||||
return updateCertError(ctx, cert, err.Error())
|
||||
}
|
||||
|
||||
cert.CertPEM = result.CertPEM
|
||||
cert.KeyPEM = sealedKey
|
||||
cert.NotBefore = result.NotBefore
|
||||
cert.NotAfter = result.NotAfter
|
||||
cert.ApplyStatus = "ready"
|
||||
cert.ApplyMessage = ""
|
||||
|
||||
return model.SaveTLSCertificate(ctx, cert)
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateCertError(ctx context.Context, cert *model.TLSCertificate, message string) error {
|
||||
@@ -155,7 +124,7 @@ func splitAcmeDomains(primaryDomain, otherDomains string) []string {
|
||||
func CertificatesDueForRenewal(certificates []model.TLSCertificate, now time.Time) []model.TLSCertificate {
|
||||
due := make([]model.TLSCertificate, 0)
|
||||
for _, cert := range certificates {
|
||||
if !cert.AutoRenew || cert.Provider != "acme" || cert.ApplyStatus == "applying" {
|
||||
if !cert.AutoRenew || cert.Provider != tlsProviderACME || cert.ApplyStatus == tlsApplyStatusApplying {
|
||||
continue
|
||||
}
|
||||
if cert.NotAfter.IsZero() {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/internal/apps/openflare/tls/acme"
|
||||
"github.com/Rain-kl/Wavelet/internal/model"
|
||||
)
|
||||
|
||||
func resolveAcmeAccount(ctx context.Context, cert *model.TLSCertificate) (*model.AcmeAccount, error) {
|
||||
acmeAccount, err := model.GetAcmeAccountByID(ctx, cert.AcmeAccountID)
|
||||
if err == nil {
|
||||
return acmeAccount, nil
|
||||
}
|
||||
acmeAccount, err = model.GetDefaultAcmeAccount(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get ACME account: %w", err)
|
||||
}
|
||||
cert.AcmeAccountID = acmeAccount.ID
|
||||
if err := model.SaveTLSCertificate(ctx, cert); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return acmeAccount, nil
|
||||
}
|
||||
|
||||
func persistAcmeAccountUpdates(
|
||||
ctx context.Context,
|
||||
cert *model.TLSCertificate,
|
||||
acmeAccount *model.AcmeAccount,
|
||||
newAccountURL, newPrivateKeyPEM, acmePrivateKey string,
|
||||
) error {
|
||||
accountChanged := (newPrivateKeyPEM != "" && acmePrivateKey != newPrivateKeyPEM) ||
|
||||
(newAccountURL != "" && acmeAccount.URL != newAccountURL)
|
||||
if !accountChanged {
|
||||
return nil
|
||||
}
|
||||
if newPrivateKeyPEM != "" && acmePrivateKey != newPrivateKeyPEM {
|
||||
sealedKey, sealErr := sealSensitive(newPrivateKeyPEM)
|
||||
if sealErr != nil {
|
||||
return fmt.Errorf("failed to seal ACME account key: %w", sealErr)
|
||||
}
|
||||
acmeAccount.PrivateKey = sealedKey
|
||||
}
|
||||
if newAccountURL != "" {
|
||||
acmeAccount.URL = newAccountURL
|
||||
}
|
||||
if acmeAccount.ID == 0 {
|
||||
if dbErr := model.CreateAcmeAccountRecord(ctx, acmeAccount); dbErr != nil {
|
||||
return fmt.Errorf("failed to create ACME account: %w", dbErr)
|
||||
}
|
||||
} else if dbErr := model.SaveAcmeAccount(ctx, acmeAccount); dbErr != nil {
|
||||
return fmt.Errorf("failed to save ACME account: %w", dbErr)
|
||||
}
|
||||
cert.AcmeAccountID = acmeAccount.ID
|
||||
return model.SaveTLSCertificate(ctx, cert)
|
||||
}
|
||||
|
||||
func saveObtainedCertificate(ctx context.Context, cert *model.TLSCertificate, result *acme.CertificateResult) error {
|
||||
sealedKey, err := sealSensitive(result.KeyPEM)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to seal certificate key: %w", err)
|
||||
}
|
||||
cert.CertPEM = result.CertPEM
|
||||
cert.KeyPEM = sealedKey
|
||||
cert.NotBefore = result.NotBefore
|
||||
cert.NotAfter = result.NotAfter
|
||||
cert.ApplyStatus = tlsApplyStatusReady
|
||||
cert.ApplyMessage = ""
|
||||
return model.SaveTLSCertificate(ctx, cert)
|
||||
}
|
||||
Reference in New Issue
Block a user