mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
feat: 添加用于更新证书的接口
This commit is contained in:
@@ -37,6 +37,7 @@ type SettingRepo interface {
|
||||
Set(key SettingKey, value string) error
|
||||
SetSlice(key SettingKey, value []string) error
|
||||
Delete(key SettingKey) error
|
||||
GetPanelSetting() (*request.PanelSetting, error)
|
||||
UpdatePanelSetting(req *request.PanelSetting) (bool, error)
|
||||
GetPanel() (*request.SettingPanel, error)
|
||||
UpdatePanel(req *request.SettingPanel) (bool, error)
|
||||
UpdateCert(req *request.SettingCert) error
|
||||
}
|
||||
|
||||
@@ -35,5 +35,6 @@ type WebsiteRepo interface {
|
||||
UpdateRemark(id uint, remark string) error
|
||||
ResetConfig(id uint) error
|
||||
UpdateStatus(id uint, status bool) error
|
||||
UpdateCert(req *request.WebsiteUpdateCert) error
|
||||
ObtainCert(ctx context.Context, id uint) error
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ func (r *settingRepo) Delete(key biz.SettingKey) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *settingRepo) GetPanelSetting() (*request.PanelSetting, error) {
|
||||
func (r *settingRepo) GetPanel() (*request.SettingPanel, error) {
|
||||
name, err := r.Get(biz.SettingKeyName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -232,7 +232,7 @@ func (r *settingRepo) GetPanelSetting() (*request.PanelSetting, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &request.PanelSetting{
|
||||
return &request.SettingPanel{
|
||||
Name: name,
|
||||
Channel: channel,
|
||||
Locale: r.conf.String("app.locale"),
|
||||
@@ -252,7 +252,7 @@ func (r *settingRepo) GetPanelSetting() (*request.PanelSetting, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *settingRepo) UpdatePanelSetting(req *request.PanelSetting) (bool, error) {
|
||||
func (r *settingRepo) UpdatePanel(req *request.SettingPanel) (bool, error) {
|
||||
if err := r.Set(biz.SettingKeyName, req.Name); err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -350,3 +350,24 @@ func (r *settingRepo) UpdatePanelSetting(req *request.PanelSetting) (bool, error
|
||||
|
||||
return restartFlag, nil
|
||||
}
|
||||
|
||||
func (r *settingRepo) UpdateCert(req *request.SettingCert) error {
|
||||
if r.task.HasRunningTask() {
|
||||
return errors.New(r.t.Get("background task is running, modifying some settings is prohibited, please try again later"))
|
||||
}
|
||||
if _, err := cert.ParseCert(req.Cert); err != nil {
|
||||
return errors.New(r.t.Get("failed to parse certificate: %v", err))
|
||||
}
|
||||
if _, err := cert.ParseKey(req.Key); err != nil {
|
||||
return errors.New(r.t.Get("failed to parse private key: %v", err))
|
||||
}
|
||||
|
||||
if err := io.Write(filepath.Join(app.Root, "panel/storage/cert.pem"), req.Cert, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := io.Write(filepath.Join(app.Root, "panel/storage/cert.key"), req.Key, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -469,6 +469,12 @@ func (r *websiteRepo) Update(req *request.WebsiteUpdate) error {
|
||||
}
|
||||
website.Https = req.HTTPS
|
||||
if req.HTTPS {
|
||||
if _, err = cert.ParseCert(req.SSLCertificate); err != nil {
|
||||
return errors.New(r.t.Get("failed to parse certificate: %v", err))
|
||||
}
|
||||
if _, err = cert.ParseKey(req.SSLCertificateKey); err != nil {
|
||||
return errors.New(r.t.Get("failed to parse private key: %v", err))
|
||||
}
|
||||
if err = p.SetHTTPS(certPath, keyPath); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -746,6 +752,38 @@ func (r *websiteRepo) UpdateStatus(id uint, status bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *websiteRepo) UpdateCert(req *request.WebsiteUpdateCert) error {
|
||||
website := new(biz.Website)
|
||||
if err := r.db.Where("name", req.Name).First(&website).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := cert.ParseCert(req.Cert); err != nil {
|
||||
return errors.New(r.t.Get("failed to parse certificate: %v", err))
|
||||
}
|
||||
if _, err := cert.ParseKey(req.Key); err != nil {
|
||||
return errors.New(r.t.Get("failed to parse private key: %v", err))
|
||||
}
|
||||
|
||||
certPath := filepath.Join(app.Root, "server/vhost/cert", website.Name+".pem")
|
||||
keyPath := filepath.Join(app.Root, "server/vhost/cert", website.Name+".key")
|
||||
if err := io.Write(certPath, req.Cert, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := io.Write(keyPath, req.Key, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if website.Https {
|
||||
if err := systemctl.Reload("nginx"); err != nil {
|
||||
_, err = shell.Execf("nginx -t")
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *websiteRepo) ObtainCert(ctx context.Context, id uint) error {
|
||||
website, err := r.Get(id)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,7 +2,7 @@ package request
|
||||
|
||||
import "net/http"
|
||||
|
||||
type PanelSetting struct {
|
||||
type SettingPanel struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Channel string `json:"channel" validate:"required|in:stable,beta"`
|
||||
Locale string `json:"locale" validate:"required"`
|
||||
@@ -22,10 +22,15 @@ type PanelSetting struct {
|
||||
Key string `json:"key" validate:"required"`
|
||||
}
|
||||
|
||||
func (r *PanelSetting) Rules(_ *http.Request) map[string]string {
|
||||
func (r *SettingPanel) Rules(_ *http.Request) map[string]string {
|
||||
return map[string]string{
|
||||
"BindDomain.*": "required",
|
||||
"BindIP.*": "required|ip",
|
||||
"BindUA.*": "required",
|
||||
}
|
||||
}
|
||||
|
||||
type SettingCert struct {
|
||||
Cert string `json:"cert" validate:"required"`
|
||||
Key string `json:"key" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -55,3 +55,9 @@ type WebsiteUpdateStatus struct {
|
||||
ID uint `json:"id" form:"id" validate:"required|exists:websites,id"`
|
||||
Status bool `json:"status" form:"status"`
|
||||
}
|
||||
|
||||
type WebsiteUpdateCert struct {
|
||||
Name uint `json:"name" validate:"required|exists:websites,name"`
|
||||
Cert string `json:"cert" validate:"required"`
|
||||
Key string `json:"key" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ func (route *Http) Register(r *chi.Mux) {
|
||||
r.Post("/{id}/update_remark", route.website.UpdateRemark)
|
||||
r.Post("/{id}/reset_config", route.website.ResetConfig)
|
||||
r.Post("/{id}/status", route.website.UpdateStatus)
|
||||
r.Post("/{id}/cert", route.website.UpdateCert)
|
||||
r.Post("/{id}/obtain_cert", route.website.ObtainCert)
|
||||
})
|
||||
|
||||
@@ -366,6 +367,7 @@ func (route *Http) Register(r *chi.Mux) {
|
||||
r.Route("/setting", func(r chi.Router) {
|
||||
r.Get("/", route.setting.Get)
|
||||
r.Post("/", route.setting.Update)
|
||||
r.Post("/cert", route.setting.UpdateCert)
|
||||
})
|
||||
|
||||
r.Route("/systemctl", func(r chi.Router) {
|
||||
|
||||
@@ -19,7 +19,7 @@ func NewSettingService(setting biz.SettingRepo) *SettingService {
|
||||
}
|
||||
|
||||
func (s *SettingService) Get(w http.ResponseWriter, r *http.Request) {
|
||||
setting, err := s.settingRepo.GetPanelSetting()
|
||||
setting, err := s.settingRepo.GetPanel()
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
@@ -29,14 +29,14 @@ func (s *SettingService) Get(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *SettingService) Update(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.PanelSetting](r)
|
||||
req, err := Bind[request.SettingPanel](r)
|
||||
if err != nil {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
restart := false
|
||||
if restart, err = s.settingRepo.UpdatePanelSetting(req); err != nil {
|
||||
if restart, err = s.settingRepo.UpdatePanel(req); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
@@ -47,3 +47,21 @@ func (s *SettingService) Update(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// UpdateCert 用于自动化工具更新证书
|
||||
func (s *SettingService) UpdateCert(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.SettingCert](r)
|
||||
if err != nil {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.settingRepo.UpdateCert(req); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
tools.RestartPanel()
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
@@ -212,6 +212,22 @@ func (s *WebsiteService) UpdateStatus(w http.ResponseWriter, r *http.Request) {
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
// UpdateCert 用于自动化工具更新证书
|
||||
func (s *WebsiteService) UpdateCert(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.WebsiteUpdateCert](r)
|
||||
if err != nil {
|
||||
Error(w, http.StatusUnprocessableEntity, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = s.websiteRepo.UpdateCert(req); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
func (s *WebsiteService) ObtainCert(w http.ResponseWriter, r *http.Request) {
|
||||
req, err := Bind[request.ID](r)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user