Skip to content

Commit 09ac2bd

Browse files
zhengkunwang223ssongliu
authored andcommitted
feat: 证书增加编辑功能 (#4901)
1 parent b15ecfb commit 09ac2bd

File tree

9 files changed

+202
-70
lines changed

9 files changed

+202
-70
lines changed

backend/app/dto/request/website_ssl.go

+15-5
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ type WebsiteSSLRenew struct {
3232
}
3333

3434
type WebsiteSSLApply struct {
35-
ID uint `json:"ID" validate:"required"`
36-
SkipDNSCheck bool `json:"SkipDNSCheck"`
35+
ID uint `json:"ID" validate:"required"`
36+
SkipDNSCheck bool `json:"skipDNSCheck"`
37+
Nameservers []string `json:"nameservers"`
3738
}
3839

3940
type WebsiteAcmeAccountCreate struct {
@@ -66,9 +67,18 @@ type WebsiteBatchDelReq struct {
6667
}
6768

6869
type WebsiteSSLUpdate struct {
69-
ID uint `json:"id" validate:"required"`
70-
AutoRenew bool `json:"autoRenew"`
71-
Description string `json:"description"`
70+
ID uint `json:"id" validate:"required"`
71+
AutoRenew bool `json:"autoRenew"`
72+
Description string `json:"description"`
73+
PrimaryDomain string `json:"primaryDomain" validate:"required"`
74+
OtherDomains string `json:"otherDomains"`
75+
Provider string `json:"provider" validate:"required"`
76+
AcmeAccountID uint `json:"acmeAccountId" validate:"required"`
77+
DnsAccountID uint `json:"dnsAccountId"`
78+
KeyType string `json:"keyType"`
79+
Apply bool `json:"apply"`
80+
PushDir bool `json:"pushDir"`
81+
Dir string `json:"dir"`
7282
}
7383

7484
type WebsiteSSLUpload struct {

backend/app/model/website_ssl.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,24 @@ import (
99

1010
type WebsiteSSL struct {
1111
BaseModel
12-
PrimaryDomain string `gorm:"type:varchar(256);not null" json:"primaryDomain"`
13-
PrivateKey string `gorm:"type:longtext;not null" json:"privateKey"`
14-
Pem string `gorm:"type:longtext;not null" json:"pem"`
15-
Domains string `gorm:"type:varchar(256);not null" json:"domains"`
16-
CertURL string `gorm:"type:varchar(256);not null" json:"certURL"`
17-
Type string `gorm:"type:varchar(64);not null" json:"type"`
18-
Provider string `gorm:"type:varchar(64);not null" json:"provider"`
19-
Organization string `gorm:"type:varchar(64);not null" json:"organization"`
20-
DnsAccountID uint `gorm:"type:integer;not null" json:"dnsAccountId"`
21-
AcmeAccountID uint `gorm:"type:integer;not null" json:"acmeAccountId"`
22-
CaID uint `gorm:"type:integer;not null;default:0" json:"caId"`
23-
AutoRenew bool `gorm:"type:varchar(64);not null" json:"autoRenew"`
12+
PrimaryDomain string `json:"primaryDomain"`
13+
PrivateKey string `json:"privateKey"`
14+
Pem string `json:"pem"`
15+
Domains string `json:"domains"`
16+
CertURL string `json:"certURL"`
17+
Type string `json:"type"`
18+
Provider string `json:"provider"`
19+
Organization string `json:"organization"`
20+
DnsAccountID uint `json:"dnsAccountId"`
21+
AcmeAccountID uint `gorm:"column:acme_account_id" json:"acmeAccountId" `
22+
CaID uint `json:"caId"`
23+
AutoRenew bool `json:"autoRenew"`
2424
ExpireDate time.Time `json:"expireDate"`
2525
StartDate time.Time `json:"startDate"`
26-
Status string `gorm:"not null;default:ready" json:"status"`
26+
Status string `json:"status"`
2727
Message string `json:"message"`
28-
KeyType string `gorm:"not null;default:2048" json:"keyType"`
29-
PushDir bool `gorm:"not null;default:0" json:"pushDir"`
28+
KeyType string `json:"keyType"`
29+
PushDir bool `json:"pushDir"`
3030
Dir string `json:"dir"`
3131
Description string `json:"description"`
3232

backend/app/repo/website_ssl.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type ISSLRepo interface {
2121
Create(ctx context.Context, ssl *model.WebsiteSSL) error
2222
Save(ssl *model.WebsiteSSL) error
2323
DeleteBy(opts ...DBOption) error
24+
SaveByMap(ssl *model.WebsiteSSL, params map[string]interface{}) error
2425
}
2526

2627
type WebsiteSSLRepo struct {
@@ -82,7 +83,15 @@ func (w WebsiteSSLRepo) Create(ctx context.Context, ssl *model.WebsiteSSL) error
8283
}
8384

8485
func (w WebsiteSSLRepo) Save(ssl *model.WebsiteSSL) error {
85-
return getDb().Save(&ssl).Error
86+
return getDb().Model(&model.WebsiteSSL{BaseModel: model.BaseModel{
87+
ID: ssl.ID,
88+
}}).Save(&ssl).Error
89+
}
90+
91+
func (w WebsiteSSLRepo) SaveByMap(ssl *model.WebsiteSSL, params map[string]interface{}) error {
92+
return getDb().Model(&model.WebsiteSSL{BaseModel: model.BaseModel{
93+
ID: ssl.ID,
94+
}}).Updates(params).Error
8695
}
8796

8897
func (w WebsiteSSLRepo) DeleteBy(opts ...DBOption) error {

backend/app/service/website_ca.go

+1
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) (*model.Website
346346
websiteSSL.StartDate = cert.NotBefore
347347
websiteSSL.Type = cert.Issuer.CommonName
348348
websiteSSL.Organization = rootCsr.Subject.Organization[0]
349+
websiteSSL.Status = constant.SSLReady
349350

350351
if req.Renew {
351352
if err := websiteSSLRepo.Save(websiteSSL); err != nil {

backend/app/service/website_ssl.go

+44-4
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func (w WebsiteSSLService) ObtainSSL(apply request.WebsiteSSLApply) error {
191191
if err != nil {
192192
return err
193193
}
194-
if err = client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization, apply.SkipDNSCheck); err != nil {
194+
if err = client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization, apply.SkipDNSCheck, apply.Nameservers); err != nil {
195195
return err
196196
}
197197
case constant.Http:
@@ -368,9 +368,49 @@ func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error {
368368
if err != nil {
369369
return err
370370
}
371-
websiteSSL.AutoRenew = update.AutoRenew
372-
websiteSSL.Description = update.Description
373-
return websiteSSLRepo.Save(websiteSSL)
371+
updateParams := make(map[string]interface{})
372+
updateParams["primary_domain"] = update.PrimaryDomain
373+
updateParams["description"] = update.Description
374+
updateParams["provider"] = update.Provider
375+
updateParams["key_type"] = update.KeyType
376+
updateParams["push_dir"] = update.PushDir
377+
378+
acmeAccount, err := websiteAcmeRepo.GetFirst(commonRepo.WithByID(update.AcmeAccountID))
379+
if err != nil {
380+
return err
381+
}
382+
updateParams["acme_account_id"] = acmeAccount.ID
383+
384+
if update.PushDir {
385+
if !files.NewFileOp().Stat(update.Dir) {
386+
return buserr.New(constant.ErrLinkPathNotFound)
387+
}
388+
updateParams["dir"] = update.Dir
389+
}
390+
var domains []string
391+
if update.OtherDomains != "" {
392+
otherDomainArray := strings.Split(update.OtherDomains, "\n")
393+
for _, domain := range otherDomainArray {
394+
if !common.IsValidDomain(domain) {
395+
return buserr.WithName("ErrDomainFormat", domain)
396+
}
397+
domains = append(domains, domain)
398+
}
399+
}
400+
updateParams["domains"] = strings.Join(domains, ",")
401+
if update.Provider == constant.DNSAccount || update.Provider == constant.Http {
402+
updateParams["auto_renew"] = update.AutoRenew
403+
} else {
404+
updateParams["auto_renew"] = false
405+
}
406+
if update.Provider == constant.DNSAccount {
407+
dnsAccount, err := websiteDnsRepo.GetFirst(commonRepo.WithByID(update.DnsAccountID))
408+
if err != nil {
409+
return err
410+
}
411+
updateParams["dns_account_id"] = dnsAccount.ID
412+
}
413+
return websiteSSLRepo.SaveByMap(websiteSSL, updateParams)
374414
}
375415

376416
func (w WebsiteSSLService) Upload(req request.WebsiteSSLUpload) error {

backend/utils/ssl/client.go

+22-19
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ type DNSParam struct {
8484
SecretID string `json:"secretID"`
8585
}
8686

87-
func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool) error {
87+
func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool, nameservers []string) error {
8888
var (
8989
param DNSParam
9090
p challenge.Provider
@@ -99,74 +99,77 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string, skipDNSCheck bool) e
9999
case DnsPod:
100100
dnsPodConfig := dnspod.NewDefaultConfig()
101101
dnsPodConfig.LoginToken = param.ID + "," + param.Token
102-
dnsPodConfig.PropagationTimeout = 60 * time.Minute
103-
dnsPodConfig.PollingInterval = 5 * time.Second
102+
dnsPodConfig.PropagationTimeout = 15 * time.Minute
103+
dnsPodConfig.PollingInterval = 10 * time.Second
104104
dnsPodConfig.TTL = 3600
105105
p, err = dnspod.NewDNSProviderConfig(dnsPodConfig)
106106
case AliYun:
107107
alidnsConfig := alidns.NewDefaultConfig()
108108
alidnsConfig.SecretKey = param.SecretKey
109109
alidnsConfig.APIKey = param.AccessKey
110-
alidnsConfig.PropagationTimeout = 60 * time.Minute
110+
alidnsConfig.PropagationTimeout = 15 * time.Minute
111111
alidnsConfig.PollingInterval = 5 * time.Second
112112
alidnsConfig.TTL = 3600
113113
p, err = alidns.NewDNSProviderConfig(alidnsConfig)
114114
case CloudFlare:
115115
cloudflareConfig := cloudflare.NewDefaultConfig()
116116
cloudflareConfig.AuthEmail = param.Email
117117
cloudflareConfig.AuthToken = param.APIkey
118-
cloudflareConfig.PropagationTimeout = 60 * time.Minute
119-
cloudflareConfig.PollingInterval = 5 * time.Second
118+
cloudflareConfig.PropagationTimeout = 15 * time.Minute
119+
cloudflareConfig.PollingInterval = 10 * time.Second
120120
cloudflareConfig.TTL = 3600
121121
p, err = cloudflare.NewDNSProviderConfig(cloudflareConfig)
122122
case NameCheap:
123123
namecheapConfig := namecheap.NewDefaultConfig()
124124
namecheapConfig.APIKey = param.APIkey
125125
namecheapConfig.APIUser = param.APIUser
126-
namecheapConfig.PropagationTimeout = 60 * time.Minute
126+
namecheapConfig.PropagationTimeout = 15 * time.Minute
127127
namecheapConfig.PollingInterval = 5 * time.Second
128128
namecheapConfig.TTL = 3600
129129
p, err = namecheap.NewDNSProviderConfig(namecheapConfig)
130130
case NameSilo:
131131
nameSiloConfig := namesilo.NewDefaultConfig()
132132
nameSiloConfig.APIKey = param.APIkey
133-
nameSiloConfig.PropagationTimeout = 60 * time.Minute
134-
nameSiloConfig.PollingInterval = 5 * time.Second
133+
nameSiloConfig.PropagationTimeout = 15 * time.Minute
134+
nameSiloConfig.PollingInterval = 10 * time.Second
135135
nameSiloConfig.TTL = 3600
136136
p, err = namesilo.NewDNSProviderConfig(nameSiloConfig)
137137
case Godaddy:
138138
godaddyConfig := godaddy.NewDefaultConfig()
139139
godaddyConfig.APIKey = param.APIkey
140140
godaddyConfig.APISecret = param.APISecret
141-
godaddyConfig.PropagationTimeout = 60 * time.Minute
142-
godaddyConfig.PollingInterval = 5 * time.Second
141+
godaddyConfig.PropagationTimeout = 15 * time.Minute
142+
godaddyConfig.PollingInterval = 10 * time.Second
143143
godaddyConfig.TTL = 3600
144144
p, err = godaddy.NewDNSProviderConfig(godaddyConfig)
145145
case NameCom:
146146
nameComConfig := namedotcom.NewDefaultConfig()
147147
nameComConfig.APIToken = param.Token
148148
nameComConfig.Username = param.APIUser
149-
nameComConfig.PropagationTimeout = 30 * time.Minute
150-
nameComConfig.PollingInterval = 30 * time.Second
149+
nameComConfig.PropagationTimeout = 15 * time.Minute
150+
nameComConfig.PollingInterval = 10 * time.Second
151151
nameComConfig.TTL = 3600
152152
p, err = namedotcom.NewDNSProviderConfig(nameComConfig)
153153
case TencentCloud:
154154
tencentCloudConfig := tencentcloud.NewDefaultConfig()
155155
tencentCloudConfig.SecretID = param.SecretID
156156
tencentCloudConfig.SecretKey = param.SecretKey
157-
tencentCloudConfig.PropagationTimeout = 30 * time.Minute
158-
tencentCloudConfig.PollingInterval = 30 * time.Second
157+
tencentCloudConfig.PropagationTimeout = 15 * time.Minute
158+
tencentCloudConfig.PollingInterval = 10 * time.Second
159159
tencentCloudConfig.TTL = 3600
160160
p, err = tencentcloud.NewDNSProviderConfig(tencentCloudConfig)
161161
}
162162
if err != nil {
163163
return err
164164
}
165-
if skipDNSCheck {
166-
return c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(10*time.Minute), dns01.DisableCompletePropagationRequirement())
167-
}
168165

169-
return c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(10*time.Minute))
166+
return c.Client.Challenge.SetDNS01Provider(p,
167+
dns01.CondOption(len(nameservers) > 0,
168+
dns01.AddRecursiveNameservers(nameservers)),
169+
dns01.CondOption(skipDNSCheck,
170+
dns01.DisableCompletePropagationRequirement()),
171+
dns01.AddDNSTimeout(10*time.Minute),
172+
)
170173
}
171174

172175
func (c *AcmeClient) UseManualDns() error {

frontend/src/api/interface/website.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,14 @@ export namespace Website {
165165
provider: string;
166166
websites?: Website.Website[];
167167
autoRenew: boolean;
168-
acmeAccountId?: number;
168+
acmeAccountId: number;
169169
status: string;
170170
domains: string;
171171
description: string;
172+
dnsAccountId?: number;
173+
pushDir: boolean;
174+
dir: string;
175+
keyType: string;
172176
}
173177

174178
export interface SSLDTO extends SSL {
@@ -198,6 +202,14 @@ export namespace Website {
198202
id: number;
199203
autoRenew: boolean;
200204
description: string;
205+
primaryDomain: string;
206+
otherDomains: string;
207+
acmeAccountId: number;
208+
provider: string;
209+
dnsAccountId?: number;
210+
keyType: string;
211+
pushDir: boolean;
212+
dir: string;
201213
}
202214

203215
export interface AcmeAccount extends CommonModel {

0 commit comments

Comments
 (0)