mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-09-06 22:55:38 +08:00
feat: 增加acme账号管理
This commit is contained in:
parent
6d2e372a07
commit
ac864ff4e7
36 changed files with 705 additions and 76 deletions
|
@ -32,7 +32,10 @@ var (
|
|||
|
||||
operationService = service.ServiceGroupApp.OperationService
|
||||
commandService = service.ServiceGroupApp.CommandService
|
||||
|
||||
websiteGroupService = service.ServiceGroupApp.WebsiteGroupService
|
||||
websiteService = service.ServiceGroupApp.WebsiteService
|
||||
webSiteDnsAccountService = service.ServiceGroupApp.WebSiteDnsAccountService
|
||||
websiteDnsAccountService = service.ServiceGroupApp.WebSiteDnsAccountService
|
||||
websiteSSLService = service.ServiceGroupApp.WebSiteSSLService
|
||||
websiteAcmeAccountService = service.ServiceGroupApp.WebSiteAcmeAccountService
|
||||
)
|
||||
|
|
54
backend/app/api/v1/website_acme_account.go
Normal file
54
backend/app/api/v1/website_acme_account.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (b *BaseApi) PageWebsiteAcmeAccount(c *gin.Context) {
|
||||
var req dto.PageInfo
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
total, accounts, err := websiteAcmeAccountService.Page(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: accounts,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
|
||||
var req dto.WebsiteAcmeAccountCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteAcmeAccountService.Create(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteWebsiteAcmeAccount(c *gin.Context) {
|
||||
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := websiteAcmeAccountService.Delete(id); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
|
@ -13,7 +13,7 @@ func (b *BaseApi) PageWebsiteDnsAccount(c *gin.Context) {
|
|||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
total, accounts, err := webSiteDnsAccountService.Page(req)
|
||||
total, accounts, err := websiteDnsAccountService.Page(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@ -30,7 +30,7 @@ func (b *BaseApi) CreateWebsiteDnsAccount(c *gin.Context) {
|
|||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if _, err := webSiteDnsAccountService.Create(req); err != nil {
|
||||
if _, err := websiteDnsAccountService.Create(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
|
|||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if _, err := webSiteDnsAccountService.Update(req); err != nil {
|
||||
if _, err := websiteDnsAccountService.Update(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ func (b *BaseApi) DeleteWebsiteDnsAccount(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := webSiteDnsAccountService.Delete(id); err != nil {
|
||||
if err := websiteDnsAccountService.Delete(id); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
|
66
backend/app/api/v1/website_ssl.go
Normal file
66
backend/app/api/v1/website_ssl.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
|
||||
var req dto.PageInfo
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
total, accounts, err := websiteSSLService.Page(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: accounts,
|
||||
})
|
||||
}
|
||||
|
||||
//func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
|
||||
// var req dto.WebsiteSSLCreate
|
||||
// if err := c.ShouldBindJSON(&req); err != nil {
|
||||
// helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
// return
|
||||
// }
|
||||
// if _, err := WebsiteSSLService.Create(req); err != nil {
|
||||
// helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
// return
|
||||
// }
|
||||
// helper.SuccessWithData(c, nil)
|
||||
//}
|
||||
//
|
||||
//func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
|
||||
// var req dto.WebsiteSSLUpdate
|
||||
// if err := c.ShouldBindJSON(&req); err != nil {
|
||||
// helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
// return
|
||||
// }
|
||||
// if _, err := WebsiteSSLService.Update(req); err != nil {
|
||||
// helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
// return
|
||||
// }
|
||||
// helper.SuccessWithData(c, nil)
|
||||
//}
|
||||
//
|
||||
//func (b *BaseApi) DeleteWebsiteSSL(c *gin.Context) {
|
||||
//
|
||||
// id, err := helper.GetParamID(c)
|
||||
// if err != nil {
|
||||
// helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if err := WebsiteSSLService.Delete(id); err != nil {
|
||||
// helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
// return
|
||||
// }
|
||||
// helper.SuccessWithData(c, nil)
|
||||
//}
|
11
backend/app/dto/website_acme_account.go
Normal file
11
backend/app/dto/website_acme_account.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package dto
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
|
||||
type WebsiteAcmeAccountDTO struct {
|
||||
model.WebsiteAcmeAccount
|
||||
}
|
||||
|
||||
type WebsiteAcmeAccountCreate struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
}
|
13
backend/app/dto/website_ssl.go
Normal file
13
backend/app/dto/website_ssl.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package dto
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
|
||||
type WebsiteSSLDTO struct {
|
||||
model.WebSiteSSL
|
||||
}
|
||||
|
||||
type WebsiteSSLCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Authorization map[string]string `json:"authorization" validate:"required"`
|
||||
}
|
|
@ -4,13 +4,19 @@ import "time"
|
|||
|
||||
type WebSite struct {
|
||||
BaseModel
|
||||
PrimaryDomain string `gorm:"type:varchar(128);not null" json:"primaryDomain"`
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Alias string `gorm:"type:varchar(128);not null" json:"alias"`
|
||||
Remark string `gorm:"type:longtext;" json:"remark"`
|
||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||
ExpireDate time.Time `json:"expireDate"`
|
||||
AppInstallID uint `gorm:"type:integer" json:"appInstallID"`
|
||||
WebSiteGroupID uint `gorm:"type:integer" json:"webSiteGroupID"`
|
||||
WebSiteSSLID uint `gorm:"type:integer" json:"webSiteSSLID"`
|
||||
PrimaryDomain string `gorm:"type:varchar(128);not null" json:"primaryDomain"`
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Alias string `gorm:"type:varchar(128);not null" json:"alias"`
|
||||
Remark string `gorm:"type:longtext;" json:"remark"`
|
||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||
ExpireDate time.Time `json:"expireDate"`
|
||||
AppInstallID uint `gorm:"type:integer" json:"appInstallId"`
|
||||
WebSiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"`
|
||||
WebSiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"`
|
||||
WebsiteDnsAccountID uint `gorm:"type:integer" json:"websiteDnsAccountId"`
|
||||
WebsiteAcmeAccountID uint `gorm:"type:integer" json:"websiteAcmeAccountId"`
|
||||
}
|
||||
|
||||
func (w WebSite) TableName() string {
|
||||
return "websites"
|
||||
}
|
||||
|
|
12
backend/app/model/website_acme_account.go
Normal file
12
backend/app/model/website_acme_account.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package model
|
||||
|
||||
type WebsiteAcmeAccount struct {
|
||||
BaseModel
|
||||
Email string `gorm:"type:varchar(256);not null" json:"email"`
|
||||
URL string `gorm:"type:varchar(256);not null" json:"url"`
|
||||
PrivateKey string `gorm:"type:longtext;not null" json:"_"`
|
||||
}
|
||||
|
||||
func (w WebsiteAcmeAccount) TableName() string {
|
||||
return "website_acme_accounts"
|
||||
}
|
|
@ -6,3 +6,7 @@ type WebsiteDnsAccount struct {
|
|||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Authorization string `gorm:"type:varchar(256);not null" json:"_"`
|
||||
}
|
||||
|
||||
func (w WebsiteDnsAccount) TableName() string {
|
||||
return "website_dns_accounts"
|
||||
}
|
||||
|
|
|
@ -6,3 +6,7 @@ type WebSiteDomain struct {
|
|||
Domain string `gorm:"type:varchar(256);not null" json:"domain"`
|
||||
Port int `gorm:"type:integer" json:"port"`
|
||||
}
|
||||
|
||||
func (w WebSiteDomain) TableName() string {
|
||||
return "website_domains"
|
||||
}
|
||||
|
|
|
@ -5,3 +5,7 @@ type WebSiteGroup struct {
|
|||
Name string `gorm:"type:varchar(64);not null" json:"name"`
|
||||
Default bool `json:"default"`
|
||||
}
|
||||
|
||||
func (w WebSiteGroup) TableName() string {
|
||||
return "website_groups"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type WebSiteSSL struct {
|
||||
BaseModel
|
||||
PrivateKey string `gorm:"type:longtext;not null" json:"privateKey"`
|
||||
Pem string `gorm:"type:longtext;not null" json:"pem"`
|
||||
Domain string `gorm:"type:varchar(256);not null" json:"domain"`
|
||||
CertURL string `gorm:"type:varchar(256);not null" json:"certURL"`
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
IssuerName string `gorm:"type:varchar(64);not null" json:"issuerName"`
|
||||
ExpireDate time.Time `json:"expireDate"`
|
||||
StartDate time.Time `json:"startDate"`
|
||||
}
|
||||
|
||||
func (w WebSiteSSL) TableName() string {
|
||||
return "website_ssls"
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ type RepoGroup struct {
|
|||
WebSiteDomainRepo
|
||||
WebSiteGroupRepo
|
||||
WebsiteDnsAccountRepo
|
||||
WebsiteSSLRepo
|
||||
WebsiteAcmeAccountRepo
|
||||
}
|
||||
|
||||
var RepoGroupApp = new(RepoGroup)
|
||||
|
|
27
backend/app/repo/website_acme_account.go
Normal file
27
backend/app/repo/website_acme_account.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package repo
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
|
||||
type WebsiteAcmeAccountRepo struct {
|
||||
}
|
||||
|
||||
func (w WebsiteAcmeAccountRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebsiteAcmeAccount, error) {
|
||||
var accounts []model.WebsiteAcmeAccount
|
||||
db := getDb(opts...).Model(&model.WebsiteAcmeAccount{})
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Debug().Limit(size).Offset(size * (page - 1)).Find(&accounts).Error
|
||||
return count, accounts, err
|
||||
}
|
||||
|
||||
func (w WebsiteAcmeAccountRepo) Create(account model.WebsiteAcmeAccount) error {
|
||||
return getDb().Create(&account).Error
|
||||
}
|
||||
|
||||
func (w WebsiteAcmeAccountRepo) Save(account model.WebsiteAcmeAccount) error {
|
||||
return getDb().Save(&account).Error
|
||||
}
|
||||
|
||||
func (w WebsiteAcmeAccountRepo) DeleteBy(opts ...DBOption) error {
|
||||
return getDb(opts...).Debug().Delete(&model.WebsiteAcmeAccount{}).Error
|
||||
}
|
27
backend/app/repo/website_ssl.go
Normal file
27
backend/app/repo/website_ssl.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package repo
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
|
||||
type WebsiteSSLRepo struct {
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebSiteSSL, error) {
|
||||
var sslList []model.WebSiteSSL
|
||||
db := getDb(opts...).Model(&model.WebSiteSSL{})
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Debug().Limit(size).Offset(size * (page - 1)).Find(&sslList).Error
|
||||
return count, sslList, err
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) Create(ssl model.WebSiteSSL) error {
|
||||
return getDb().Create(&ssl).Error
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) Save(ssl model.WebSiteSSL) error {
|
||||
return getDb().Save(&ssl).Error
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) DeleteBy(opts ...DBOption) error {
|
||||
return getDb(opts...).Delete(&model.WebSiteSSL{}).Error
|
||||
}
|
|
@ -29,6 +29,8 @@ type ServiceGroup struct {
|
|||
WebsiteGroupService
|
||||
WebsiteService
|
||||
WebSiteDnsAccountService
|
||||
WebSiteSSLService
|
||||
WebSiteAcmeAccountService
|
||||
}
|
||||
|
||||
var ServiceGroupApp = new(ServiceGroup)
|
||||
|
@ -64,4 +66,6 @@ var (
|
|||
websiteGroupRepo = repo.RepoGroupApp.WebSiteGroupRepo
|
||||
websiteDomainRepo = repo.RepoGroupApp.WebSiteDomainRepo
|
||||
websiteDnsRepo = repo.RepoGroupApp.WebsiteDnsAccountRepo
|
||||
websiteSSLRepo = repo.RepoGroupApp.WebsiteSSLRepo
|
||||
websiteAcmeRepo = repo.RepoGroupApp.WebsiteAcmeAccountRepo
|
||||
)
|
||||
|
|
41
backend/app/service/website_acme_account.go
Normal file
41
backend/app/service/website_acme_account.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
|
||||
)
|
||||
|
||||
type WebSiteAcmeAccountService struct {
|
||||
}
|
||||
|
||||
func (w WebSiteAcmeAccountService) Page(search dto.PageInfo) (int64, []dto.WebsiteAcmeAccountDTO, error) {
|
||||
total, accounts, err := websiteAcmeRepo.Page(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc"))
|
||||
var accountDTOs []dto.WebsiteAcmeAccountDTO
|
||||
for _, account := range accounts {
|
||||
accountDTOs = append(accountDTOs, dto.WebsiteAcmeAccountDTO{
|
||||
WebsiteAcmeAccount: account,
|
||||
})
|
||||
}
|
||||
return total, accountDTOs, err
|
||||
}
|
||||
|
||||
func (w WebSiteAcmeAccountService) Create(create dto.WebsiteAcmeAccountCreate) (dto.WebsiteAcmeAccountDTO, error) {
|
||||
client, err := ssl.NewAcmeClient(create.Email, "")
|
||||
if err != nil {
|
||||
return dto.WebsiteAcmeAccountDTO{}, err
|
||||
}
|
||||
acmeAccount := model.WebsiteAcmeAccount{
|
||||
Email: create.Email,
|
||||
URL: client.User.Registration.URI,
|
||||
PrivateKey: string(ssl.GetPrivateKey(client.User.GetPrivateKey())),
|
||||
}
|
||||
if err := websiteAcmeRepo.Create(acmeAccount); err != nil {
|
||||
return dto.WebsiteAcmeAccountDTO{}, err
|
||||
}
|
||||
return dto.WebsiteAcmeAccountDTO{WebsiteAcmeAccount: acmeAccount}, nil
|
||||
}
|
||||
|
||||
func (w WebSiteAcmeAccountService) Delete(id uint) error {
|
||||
return websiteAcmeRepo.DeleteBy(commonRepo.WithByID(id))
|
||||
}
|
62
backend/app/service/website_ssl.go
Normal file
62
backend/app/service/website_ssl.go
Normal file
|
@ -0,0 +1,62 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
)
|
||||
|
||||
type WebSiteSSLService struct {
|
||||
}
|
||||
|
||||
func (w WebSiteSSLService) Page(search dto.PageInfo) (int64, []dto.WebsiteSSLDTO, error) {
|
||||
total, sslList, err := websiteSSLRepo.Page(search.Page, search.PageSize, commonRepo.WithOrderBy("created_at desc"))
|
||||
var sslDTOs []dto.WebsiteSSLDTO
|
||||
for _, ssl := range sslList {
|
||||
sslDTOs = append(sslDTOs, dto.WebsiteSSLDTO{
|
||||
WebSiteSSL: ssl,
|
||||
})
|
||||
}
|
||||
return total, sslDTOs, err
|
||||
}
|
||||
|
||||
//func (w WebSiteSSLService) Create(create dto.WebsiteSSLCreate) (dto.WebsiteSSLCreate, error) {
|
||||
//
|
||||
// authorization, err := json.Marshal(create.Authorization)
|
||||
// if err != nil {
|
||||
// return dto.WebsiteSSLCreate{}, err
|
||||
// }
|
||||
//
|
||||
// if err := websiteSSLRepo.Create(model.WebsiteDnsAccount{
|
||||
// Name: create.Name,
|
||||
// Type: create.Type,
|
||||
// Authorization: string(authorization),
|
||||
// }); err != nil {
|
||||
// return dto.WebsiteSSLCreate{}, err
|
||||
// }
|
||||
//
|
||||
// return create, nil
|
||||
//}
|
||||
//
|
||||
//func (w WebSiteSSLService) Update(update dto.WebsiteDnsAccountUpdate) (dto.WebsiteDnsAccountUpdate, error) {
|
||||
//
|
||||
// authorization, err := json.Marshal(update.Authorization)
|
||||
// if err != nil {
|
||||
// return dto.WebsiteDnsAccountUpdate{}, err
|
||||
// }
|
||||
//
|
||||
// if err := websiteSSLRepo.Save(model.WebsiteDnsAccount{
|
||||
// BaseModel: model.BaseModel{
|
||||
// ID: update.ID,
|
||||
// },
|
||||
// Name: update.Name,
|
||||
// Type: update.Type,
|
||||
// Authorization: string(authorization),
|
||||
// }); err != nil {
|
||||
// return dto.WebsiteDnsAccountUpdate{}, err
|
||||
// }
|
||||
//
|
||||
// return update, nil
|
||||
//}
|
||||
|
||||
func (w WebSiteSSLService) Delete(id uint) error {
|
||||
return websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
|
||||
}
|
|
@ -18,7 +18,6 @@ func Init() {
|
|||
migrations.AddTableApp,
|
||||
migrations.AddTableImageRepo,
|
||||
migrations.AddTableWebsite,
|
||||
migrations.AddTableDnsAccount,
|
||||
migrations.AddTableDatabaseMysql,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
|
|
|
@ -181,7 +181,7 @@ var AddTableDatabaseMysql = &gormigrate.Migration{
|
|||
var AddTableWebsite = &gormigrate.Migration{
|
||||
ID: "20201009-add-table-website",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.WebSite{}, &model.WebSiteDomain{}, &model.WebSiteGroup{}); err != nil {
|
||||
if err := tx.AutoMigrate(&model.WebSite{}, &model.WebSiteDomain{}, &model.WebSiteGroup{}, &model.WebsiteDnsAccount{}, &model.WebSiteSSL{}, &model.WebsiteAcmeAccount{}); err != nil {
|
||||
return err
|
||||
}
|
||||
item := &model.WebSiteGroup{
|
||||
|
@ -194,13 +194,3 @@ var AddTableWebsite = &gormigrate.Migration{
|
|||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var AddTableDnsAccount = &gormigrate.Migration{
|
||||
ID: "20201009-add-table-dns",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.WebsiteDnsAccount{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ func Routers() *gin.Engine {
|
|||
systemRouter.InitWebsiteGroupRouter(PrivateGroup)
|
||||
systemRouter.InitWebsiteDnsAccountRouter(PrivateGroup)
|
||||
systemRouter.InitDatabaseRouter(PrivateGroup)
|
||||
systemRouter.InitWebsiteAcmeAccountRouter(PrivateGroup)
|
||||
}
|
||||
|
||||
return Router
|
||||
|
|
|
@ -17,6 +17,7 @@ type RouterGroup struct {
|
|||
WebsiteRouter
|
||||
WebsiteGroupRouter
|
||||
WebsiteDnsAccountRouter
|
||||
WebsiteAcmeAccountRouter
|
||||
DatabaseRouter
|
||||
}
|
||||
|
||||
|
|
22
backend/router/ro_website_acme_account.go
Normal file
22
backend/router/ro_website_acme_account.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1"
|
||||
"github.com/1Panel-dev/1Panel/backend/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type WebsiteAcmeAccountRouter struct {
|
||||
}
|
||||
|
||||
func (a *WebsiteAcmeAccountRouter) InitWebsiteAcmeAccountRouter(Router *gin.RouterGroup) {
|
||||
groupRouter := Router.Group("websites/acme")
|
||||
groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth())
|
||||
|
||||
baseApi := v1.ApiGroupApp.BaseApi
|
||||
{
|
||||
groupRouter.POST("/search", baseApi.PageWebsiteAcmeAccount)
|
||||
groupRouter.POST("", baseApi.CreateWebsiteAcmeAccount)
|
||||
groupRouter.DELETE("/:id", baseApi.DeleteWebsiteAcmeAccount)
|
||||
}
|
||||
}
|
21
backend/router/ro_website_ssl.go
Normal file
21
backend/router/ro_website_ssl.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
v1 "github.com/1Panel-dev/1Panel/backend/app/api/v1"
|
||||
"github.com/1Panel-dev/1Panel/backend/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type WebsiteSSLRouter struct {
|
||||
}
|
||||
|
||||
func (a *WebsiteSSLRouter) InitWebsiteSSLRouter(Router *gin.RouterGroup) {
|
||||
groupRouter := Router.Group("websites/ssl")
|
||||
groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth())
|
||||
|
||||
baseApi := v1.ApiGroupApp.BaseApi
|
||||
{
|
||||
groupRouter.POST("", baseApi.PageWebsiteSSL)
|
||||
|
||||
}
|
||||
}
|
|
@ -1,27 +1,27 @@
|
|||
-----BEGIN privateKey-----
|
||||
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
|
||||
-----END privateKey-----
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ssl
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
|
@ -10,8 +11,9 @@ import (
|
|||
"github.com/go-acme/lego/v4/registration"
|
||||
)
|
||||
|
||||
func GetPrivateKey(priKey *rsa.PrivateKey) []byte {
|
||||
derStream := x509.MarshalPKCS1PrivateKey(priKey)
|
||||
func GetPrivateKey(priKey crypto.PrivateKey) []byte {
|
||||
rsaKey := priKey.(*rsa.PrivateKey)
|
||||
derStream := x509.MarshalPKCS1PrivateKey(rsaKey)
|
||||
block := &pem.Block{
|
||||
Type: "privateKey",
|
||||
Bytes: derStream,
|
||||
|
@ -25,9 +27,10 @@ func NewRegisterClient(email string) (*AcmeClient, error) {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
myUser := &AcmeUser{
|
||||
Email: email,
|
||||
key: priKey,
|
||||
Key: priKey,
|
||||
}
|
||||
config := newConfig(myUser)
|
||||
client, err := lego.NewClient(config)
|
||||
|
@ -58,7 +61,7 @@ func NewPrivateKeyClient(email string, privateKey string) (*AcmeClient, error) {
|
|||
}
|
||||
myUser := &AcmeUser{
|
||||
Email: email,
|
||||
key: priKey,
|
||||
Key: priKey,
|
||||
}
|
||||
config := newConfig(myUser)
|
||||
client, err := lego.NewClient(config)
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
type AcmeUser struct {
|
||||
Email string
|
||||
Registration *registration.Resource
|
||||
key crypto.PrivateKey
|
||||
Key crypto.PrivateKey
|
||||
}
|
||||
|
||||
func (u *AcmeUser) GetEmail() string {
|
||||
|
@ -27,7 +27,7 @@ func (u *AcmeUser) GetRegistration() *registration.Resource {
|
|||
return u.Registration
|
||||
}
|
||||
func (u *AcmeUser) GetPrivateKey() crypto.PrivateKey {
|
||||
return u.key
|
||||
return u.Key
|
||||
}
|
||||
|
||||
type AcmeClient struct {
|
||||
|
|
|
@ -8,15 +8,15 @@ export namespace WebSite {
|
|||
remark: string;
|
||||
domains: string[];
|
||||
appType: string;
|
||||
appInstallID?: number;
|
||||
webSiteGroupID: number;
|
||||
appInstallId?: number;
|
||||
webSiteGroupId: number;
|
||||
otherDomains: string;
|
||||
appinstall?: NewAppInstall;
|
||||
}
|
||||
|
||||
export interface NewAppInstall {
|
||||
name: string;
|
||||
appDetailID: number;
|
||||
appDetailId: number;
|
||||
params: any;
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,8 @@ export namespace WebSite {
|
|||
alias: string;
|
||||
remark: string;
|
||||
appType: string;
|
||||
appInstallID: number;
|
||||
webSiteGroupID: number;
|
||||
appInstallId: number;
|
||||
webSiteGroupId: number;
|
||||
otherDomains: string;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ export namespace WebSite {
|
|||
id: number;
|
||||
primaryDomain: string;
|
||||
remark: string;
|
||||
webSiteGroupID: number;
|
||||
webSiteGroupId: number;
|
||||
}
|
||||
|
||||
export interface Group extends CommonModel {
|
||||
|
@ -103,4 +103,24 @@ export namespace WebSite {
|
|||
type: string;
|
||||
authorization: Object;
|
||||
}
|
||||
|
||||
export interface SSL extends CommonModel {
|
||||
privateKey: string;
|
||||
pem: string;
|
||||
domain: string;
|
||||
certURL: string;
|
||||
type: string;
|
||||
issuerName: string;
|
||||
expireDate: string;
|
||||
startDate: string;
|
||||
}
|
||||
|
||||
export interface AcmeAccount extends CommonModel {
|
||||
email: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface AcmeAccountCreate {
|
||||
email: string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,3 +73,19 @@ export const UpdateDnsAccount = (req: WebSite.DnsAccountUpdate) => {
|
|||
export const DeleteDnsAccount = (id: number) => {
|
||||
return http.delete<any>(`/websites/dns/${id}`);
|
||||
};
|
||||
|
||||
export const SearchSSL = (req: ReqPage) => {
|
||||
return http.post<ResPage<WebSite.SSL>>(`/websites/ssl`, req);
|
||||
};
|
||||
|
||||
export const SearchAcmeAccount = (req: ReqPage) => {
|
||||
return http.post<ResPage<WebSite.AcmeAccount>>(`/websites/acme/search`, req);
|
||||
};
|
||||
|
||||
export const CreateAcmeAccount = (req: WebSite.AcmeAccountCreate) => {
|
||||
return http.post<WebSite.AcmeAccount>(`/websites/acme`, req);
|
||||
};
|
||||
|
||||
export const DeleteAcmeAccount = (id: number) => {
|
||||
return http.delete<any>(`/websites/acme/${id}`);
|
||||
};
|
||||
|
|
|
@ -704,5 +704,8 @@ export default {
|
|||
manual: '手动解析',
|
||||
key: '密钥',
|
||||
check: '查看',
|
||||
accountManage: '账户管理',
|
||||
email: '邮箱',
|
||||
addAccount: '新增账户',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<el-input v-model="form.primaryDomain"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.group')" prop="webSiteGroupID">
|
||||
<el-select v-model="form.webSiteGroupID">
|
||||
<el-select v-model="form.webSiteGroupId">
|
||||
<el-option
|
||||
v-for="(group, index) in groups"
|
||||
:key="index"
|
||||
|
@ -59,11 +59,11 @@ let form = reactive({
|
|||
id: websiteId.value,
|
||||
primaryDomain: '',
|
||||
remark: '',
|
||||
webSiteGroupID: 0,
|
||||
webSiteGroupId: 0,
|
||||
});
|
||||
let rules = ref({
|
||||
primaryDomain: [Rules.requiredInput],
|
||||
webSiteGroupID: [Rules.requiredSelect],
|
||||
webSiteGroupId: [Rules.requiredSelect],
|
||||
});
|
||||
let groups = ref<WebSite.Group[]>([]);
|
||||
|
||||
|
@ -91,7 +91,7 @@ const search = () => {
|
|||
// form.id = res.data.id;
|
||||
form.primaryDomain = res.data.primaryDomain;
|
||||
form.remark = res.data.remark;
|
||||
form.webSiteGroupID = res.data.webSiteGroupID;
|
||||
form.webSiteGroupId = res.data.webSiteGroupId;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -59,10 +59,6 @@ const accountData = ref<AccountProps>({
|
|||
});
|
||||
|
||||
const types = [
|
||||
{
|
||||
label: i18n.global.t('website.manual'),
|
||||
value: 'Manual',
|
||||
},
|
||||
{
|
||||
label: 'DnsPod',
|
||||
value: 'DnsPod',
|
||||
|
@ -93,7 +89,7 @@ let rules = ref({
|
|||
let account = ref({
|
||||
id: 0,
|
||||
name: '',
|
||||
type: '',
|
||||
type: 'DnsPod',
|
||||
authorization: {},
|
||||
});
|
||||
const em = defineEmits(['close']);
|
||||
|
@ -108,14 +104,13 @@ const resetForm = () => {
|
|||
account.value = {
|
||||
id: 0,
|
||||
name: '',
|
||||
type: '',
|
||||
type: 'DnsPod',
|
||||
authorization: {},
|
||||
};
|
||||
accountForm.value?.resetFields();
|
||||
};
|
||||
|
||||
const acceptParams = async (props: AccountProps) => {
|
||||
resetForm();
|
||||
accountData.value.mode = props.mode;
|
||||
if (props.mode === 'edit') {
|
||||
account.value = props.form;
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
<el-tab-pane :label="$t('website.dnsAccount')">
|
||||
<Account :id="id" v-if="index == '1'"></Account>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.applySSL')"></el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.SSLList')"></el-tab-pane>
|
||||
<el-tab-pane :label="$t('website.applySSL')">
|
||||
<SSL v-if="index == '2'"></SSL>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
|
@ -15,6 +16,7 @@
|
|||
import { computed, ref } from 'vue';
|
||||
import Current from './current/index.vue';
|
||||
import Account from './account/index.vue';
|
||||
import SSL from './ssl/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<el-dialog v-model="open" :title="$t('commons.button.create')" width="30%" :before-close="handleClose">
|
||||
<el-form
|
||||
ref="accountForm"
|
||||
label-position="right"
|
||||
:model="account"
|
||||
label-width="100px"
|
||||
:rules="rules"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-form-item :label="$t('website.email')" prop="email">
|
||||
<el-input v-model="account.email"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit(accountForm)" :loading="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage, FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { CreateAcmeAccount } from '@/api/modules/website';
|
||||
import i18n from '@/lang';
|
||||
|
||||
let open = ref();
|
||||
let loading = ref(false);
|
||||
let accountForm = ref<FormInstance>();
|
||||
let rules = ref({
|
||||
email: [Rules.requiredInput],
|
||||
});
|
||||
let account = ref({
|
||||
email: '',
|
||||
});
|
||||
|
||||
const em = defineEmits(['close']);
|
||||
|
||||
const handleClose = () => {
|
||||
resetForm();
|
||||
open.value = false;
|
||||
em('close', false);
|
||||
};
|
||||
|
||||
const resetForm = () => {};
|
||||
|
||||
const acceptParams = () => {
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
|
||||
CreateAcmeAccount(account.value)
|
||||
.then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.createSuccess'));
|
||||
handleClose();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,78 @@
|
|||
<template>
|
||||
<el-dialog v-model="open" :title="$t('website.accountManage')">
|
||||
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()" v-loading="loading">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain @click="openCreate">{{ $t('commons.button.create') }}</el-button>
|
||||
</template>
|
||||
<el-table-column :label="$t('website.email')" fix show-overflow-tooltip prop="email"></el-table-column>
|
||||
<el-table-column label="URL" show-overflow-tooltip prop="url"></el-table-column>
|
||||
<fu-table-operations
|
||||
:ellipsis="1"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fixed="right"
|
||||
fix
|
||||
/>
|
||||
</ComplexTable>
|
||||
<Create ref="createRef" @close="search()"></Create>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { WebSite } from '@/api/interface/website';
|
||||
import { DeleteAcmeAccount, SearchAcmeAccount } from '@/api/modules/website';
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||
import i18n from '@/lang';
|
||||
import { reactive, ref } from 'vue';
|
||||
import Create from './create/index.vue';
|
||||
|
||||
let open = ref(false);
|
||||
let loading = ref(false);
|
||||
let data = ref();
|
||||
let createRef = ref();
|
||||
const paginationConfig = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('app.delete'),
|
||||
click: function (row: WebSite.AcmeAccount) {
|
||||
deleteAccount(row.id);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const acceptParams = () => {
|
||||
search();
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
const req = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
};
|
||||
await SearchAcmeAccount(req).then((res) => {
|
||||
data.value = res.data.items;
|
||||
paginationConfig.total = res.data.total;
|
||||
});
|
||||
};
|
||||
|
||||
const openCreate = () => {
|
||||
createRef.value.acceptParams();
|
||||
};
|
||||
|
||||
const deleteAccount = async (id: number) => {
|
||||
loading.value = true;
|
||||
await useDeleteData(DeleteAcmeAccount, id, 'commons.msg.delete', false);
|
||||
loading.value = false;
|
||||
search();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
46
frontend/src/views/website/project/config/ssl/ssl/index.vue
Normal file
46
frontend/src/views/website/project/config/ssl/ssl/index.vue
Normal file
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<div>
|
||||
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" plain>{{ $t('commons.button.create') }}</el-button>
|
||||
<el-button type="primary" plain @click="openAccount()">{{ $t('website.accountManage') }}</el-button>
|
||||
</template>
|
||||
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="name"></el-table-column>
|
||||
</ComplexTable>
|
||||
<Account ref="accountRef"></Account>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComplexTable from '@/components/complex-table/index.vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { SearchSSL } from '@/api/modules/website';
|
||||
import Account from './account/index.vue';
|
||||
|
||||
const paginationConfig = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
total: 0,
|
||||
});
|
||||
const accountRef = ref();
|
||||
let data = ref();
|
||||
|
||||
const search = () => {
|
||||
const req = {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
};
|
||||
SearchSSL(req).then((res) => {
|
||||
data.value = res.data.items;
|
||||
paginationConfig.total = res.data.total;
|
||||
});
|
||||
};
|
||||
|
||||
const openAccount = () => {
|
||||
accountRef.value.acceptParams();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
search();
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue