diff --git a/backend/app/dto/website.go b/backend/app/dto/website.go index 8dc7ea4e3..2a9375021 100644 --- a/backend/app/dto/website.go +++ b/backend/app/dto/website.go @@ -84,8 +84,10 @@ const ( ) type WebsiteHTTPSOp struct { - WebsiteID uint `json:"websiteId"` - Enable bool `json:"enable"` + WebsiteID uint `json:"websiteId" validate:"required"` + Enable bool `json:"enable" validate:"required"` WebsiteSSLID uint `json:"websiteSSLId"` Type SSlType `json:"type"` + PrivateKey string `json:"privateKey"` + Certificate string `json:"certificate"` } diff --git a/backend/app/dto/website_ssl.go b/backend/app/dto/website_ssl.go index 3ef56980b..31e0ff16f 100644 --- a/backend/app/dto/website_ssl.go +++ b/backend/app/dto/website_ssl.go @@ -12,6 +12,7 @@ const ( DNSAccount = "dnsAccount" DnsManual = "dnsManual" Http = "http" + Manual = "manual" ) type WebsiteSSLSearch struct { diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 343b161b2..6382eb377 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -2,6 +2,8 @@ package service import ( "context" + "crypto/x509" + "encoding/pem" "fmt" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/app/model" @@ -304,29 +306,80 @@ func (w WebsiteService) OpWebsiteHTTPS(req dto.WebsiteHTTPSOp) (dto.WebsiteHTTPS return dto.WebsiteHTTPS{}, err } - var res dto.WebsiteHTTPS + var ( + res dto.WebsiteHTTPS + websiteSSL model.WebSiteSSL + ) res.Enable = req.Enable - ssl, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(req.WebsiteSSLID)) - if err != nil { - return dto.WebsiteHTTPS{}, err - } if req.Type == dto.SSLExisted { - website.WebSiteSSLID = ssl.ID + websiteSSL, err = websiteSSLRepo.GetFirst(commonRepo.WithByID(req.WebsiteSSLID)) + if err != nil { + return dto.WebsiteHTTPS{}, err + } + website.WebSiteSSLID = websiteSSL.ID if err := websiteRepo.Save(context.TODO(), &website); err != nil { return dto.WebsiteHTTPS{}, err } - res.SSL = ssl + res.SSL = websiteSSL + } + + if req.Type == dto.Manual { + certBlock, _ := pem.Decode([]byte(req.Certificate)) + cert, err := x509.ParseCertificate(certBlock.Bytes) + if err != nil { + return dto.WebsiteHTTPS{}, err + } + websiteSSL.ExpireDate = cert.NotAfter + websiteSSL.StartDate = cert.NotBefore + websiteSSL.Type = cert.Issuer.CommonName + websiteSSL.Organization = cert.Issuer.Organization[0] + websiteSSL.PrimaryDomain = cert.Subject.CommonName + if len(cert.Subject.Names) > 0 { + var domains []string + for _, name := range cert.Subject.Names { + if v, ok := name.Value.(string); ok { + if v != cert.Subject.CommonName { + domains = append(domains, v) + } + } + } + if len(domains) > 0 { + websiteSSL.Domains = strings.Join(domains, "") + } + } + + websiteSSL.Provider = dto.Manual + websiteSSL.PrivateKey = req.PrivateKey + websiteSSL.Pem = req.Certificate + + res.SSL = websiteSSL } if req.Enable { website.Protocol = constant.ProtocolHTTPS - if err := applySSL(website, ssl); err != nil { + if err := applySSL(website, websiteSSL); err != nil { return dto.WebsiteHTTPS{}, err } } else { website.Protocol = constant.ProtocolHTTP + website.WebSiteSSLID = 0 + if err := deleteNginxConfig(website, getKeysFromStaticFile(dto.SSL)); err != nil { + return dto.WebsiteHTTPS{}, err + } } + tx, ctx := getTxAndContext() + if websiteSSL.ID == 0 { + if err := websiteSSLRepo.Create(ctx, &websiteSSL); err != nil { + return dto.WebsiteHTTPS{}, err + } + website.WebSiteSSLID = websiteSSL.ID + } + if err := websiteRepo.Save(ctx, &website); err != nil { + return dto.WebsiteHTTPS{}, err + } + + tx.Commit() return res, nil } diff --git a/backend/app/service/website_ssl.go b/backend/app/service/website_ssl.go index 1ba5e1fc6..b8a53de6c 100644 --- a/backend/app/service/website_ssl.go +++ b/backend/app/service/website_ssl.go @@ -59,25 +59,20 @@ func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCr switch create.Provider { case dto.DNSAccount: dnsAccount, err := websiteDnsRepo.GetFirst(commonRepo.WithByID(create.DnsAccountID)) - if err != nil { return res, err } - if err := client.UseDns(ssl.DnsType(dnsAccount.Type), dnsAccount.Authorization); err != nil { return res, err } case dto.Http: - appInstall, err := getAppInstallByKey("nginx") if err != nil { return dto.WebsiteSSLCreate{}, err } - if err := client.UseHTTP(path.Join(constant.AppInstallDir, "nginx", appInstall.Name, "root")); err != nil { return res, err } - case dto.DnsManual: } @@ -110,10 +105,6 @@ func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCr websiteSSL.Type = cert.Issuer.CommonName websiteSSL.Organization = cert.Issuer.Organization[0] - //if err := createPemFile(websiteSSL); err != nil { - // return dto.WebsiteSSLCreate{}, err - //} - if err := websiteSSLRepo.Create(context.TODO(), &websiteSSL); err != nil { return res, err } @@ -146,6 +137,13 @@ func (w WebSiteSSLService) Renew(sslId uint) error { return err } case dto.Http: + appInstall, err := getAppInstallByKey("nginx") + if err != nil { + return err + } + if err := client.UseHTTP(path.Join(constant.AppInstallDir, "nginx", appInstall.Name, "root")); err != nil { + return err + } case dto.DnsManual: } diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index 3427d83aa..6bc625686 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -326,6 +326,19 @@ func getNginxParamsFromStaticFile(scope dto.NginxKey) []dto.NginxParam { return nginxParams } +func getKeysFromStaticFile(scope dto.NginxKey) []string { + var res []string + newConfig := &components.Config{} + switch scope { + case dto.SSL: + newConfig = parser.NewStringParser(string(nginx_conf.SSL)).Parse() + } + for _, dir := range newConfig.GetDirectives() { + res = append(res, dir.GetName()) + } + return res +} + func deleteNginxConfig(website model.WebSite, keys []string) error { nginxConfig, err := getNginxConfig(website.Alias) if err != nil { @@ -385,6 +398,17 @@ func createPemFile(website model.WebSite, websiteSSL model.WebSiteSSL) error { func applySSL(website model.WebSite, websiteSSL model.WebSiteSSL) error { + nginxConfig, err := getNginxConfig(website.Alias) + if err != nil { + return nil + } + config := nginxConfig.Config + server := config.FindServers()[0] + server.UpdateListen("443", false) + if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil { + return err + } + if err := createPemFile(website, websiteSSL); err != nil { return err } diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 03537b946..f5477fbc2 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -172,8 +172,10 @@ export namespace WebSite { export interface HTTPSReq { websiteId: number; enable: boolean; - websiteSSLId: number; + websiteSSLId?: number; type: string; + certificate?: string; + privateKey?: string; } export interface HTTPSConfig { diff --git a/frontend/src/views/website/website/config/basic/https/index.vue b/frontend/src/views/website/website/config/basic/https/index.vue index f4173f444..533e1e081 100644 --- a/frontend/src/views/website/website/config/basic/https/index.vue +++ b/frontend/src/views/website/website/config/basic/https/index.vue @@ -1,6 +1,6 @@