2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-05 02:07:18 +08:00
Files
panel/app/http/controllers/setting_controller.go
2024-07-13 15:19:42 +08:00

290 lines
9.4 KiB
Go

package controllers
import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"github.com/goravel/framework/support/path"
"github.com/spf13/cast"
requests "github.com/TheTNB/panel/v2/app/http/requests/setting"
"github.com/TheTNB/panel/v2/app/models"
"github.com/TheTNB/panel/v2/internal"
"github.com/TheTNB/panel/v2/internal/services"
"github.com/TheTNB/panel/v2/pkg/cert"
"github.com/TheTNB/panel/v2/pkg/io"
"github.com/TheTNB/panel/v2/pkg/os"
"github.com/TheTNB/panel/v2/pkg/shell"
"github.com/TheTNB/panel/v2/pkg/tools"
)
type SettingController struct {
setting internal.Setting
}
func NewSettingController() *SettingController {
return &SettingController{
setting: services.NewSettingImpl(),
}
}
// List
//
// @Summary 设置列表
// @Tags 面板设置
// @Produce json
// @Security BearerToken
// @Success 200 {object} SuccessResponse
// @Router /panel/setting/list [get]
func (r *SettingController) List(ctx http.Context) http.Response {
var settings []models.Setting
err := facades.Orm().Query().Get(&settings)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("获取面板设置列表失败")
return ErrorSystem(ctx)
}
userID := cast.ToUint(ctx.Value("user_id"))
var user models.User
if err = facades.Orm().Query().Where("id", userID).Get(&user); err != nil {
return Error(ctx, http.StatusInternalServerError, "获取用户信息失败")
}
port, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("获取面板端口失败")
return ErrorSystem(ctx)
}
return Success(ctx, http.Json{
"name": r.setting.Get(models.SettingKeyName),
"language": facades.Config().GetString("app.locale"),
"entrance": facades.Config().GetString("panel.entrance"),
"ssl": facades.Config().GetBool("panel.ssl"),
"website_path": r.setting.Get(models.SettingKeyWebsitePath),
"backup_path": r.setting.Get(models.SettingKeyBackupPath),
"username": user.Username,
"password": "",
"email": user.Email,
"port": port,
})
}
// Update
//
// @Summary 更新设置
// @Tags 面板设置
// @Accept json
// @Produce json
// @Security BearerToken
// @Param data body requests.Update true "request"
// @Success 200 {object} SuccessResponse
// @Router /panel/setting/update [post]
func (r *SettingController) Update(ctx http.Context) http.Response {
var updateRequest requests.Update
sanitize := SanitizeRequest(ctx, &updateRequest)
if sanitize != nil {
return sanitize
}
err := r.setting.Set(models.SettingKeyName, updateRequest.Name)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("保存面板名称失败")
return ErrorSystem(ctx)
}
if !io.Exists(updateRequest.BackupPath) {
if err = io.Mkdir(updateRequest.BackupPath, 0644); err != nil {
return ErrorSystem(ctx)
}
}
err = r.setting.Set(models.SettingKeyBackupPath, updateRequest.BackupPath)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("保存备份目录失败")
return ErrorSystem(ctx)
}
if !io.Exists(updateRequest.WebsitePath) {
if err = io.Mkdir(updateRequest.WebsitePath, 0755); err != nil {
return ErrorSystem(ctx)
}
if err = io.Chown(updateRequest.WebsitePath, "www", "www"); err != nil {
return ErrorSystem(ctx)
}
}
err = r.setting.Set(models.SettingKeyWebsitePath, updateRequest.WebsitePath)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("保存建站目录失败")
return ErrorSystem(ctx)
}
userID := cast.ToUint(ctx.Value("user_id"))
var user models.User
if err = facades.Orm().Query().Where("id", userID).Get(&user); err != nil {
return Error(ctx, http.StatusInternalServerError, "获取用户信息失败")
}
user.Username = updateRequest.UserName
user.Email = updateRequest.Email
if len(updateRequest.Password) > 0 {
hash, err := facades.Hash().Make(updateRequest.Password)
if err != nil {
return ErrorSystem(ctx)
}
user.Password = hash
}
if err = facades.Orm().Query().Save(&user); err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("保存用户信息失败")
return ErrorSystem(ctx)
}
oldPort, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("获取面板端口失败")
return ErrorSystem(ctx)
}
port := cast.ToString(updateRequest.Port)
if oldPort != port {
if out, err := shell.Execf("sed -i 's/APP_PORT=%s/APP_PORT=%s/g' /www/panel/panel.conf", oldPort, port); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
if os.IsRHEL() {
if out, err := shell.Execf("firewall-cmd --remove-port=%s/tcp --permanent", oldPort); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
if out, err := shell.Execf("firewall-cmd --add-port=%s/tcp --permanent", port); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
if out, err := shell.Execf("firewall-cmd --reload"); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
} else {
if out, err := shell.Execf("ufw delete allow %s/tcp", oldPort); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
if out, err := shell.Execf("ufw allow %s/tcp", port); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
if out, err := shell.Execf("ufw reload"); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
}
}
oldEntrance, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("获取面板入口失败")
return ErrorSystem(ctx)
}
entrance := cast.ToString(updateRequest.Entrance)
if oldEntrance != entrance {
if out, err := shell.Execf("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=" + entrance + "!g' /www/panel/panel.conf"); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
}
oldLanguage, err := shell.Execf(`cat /www/panel/panel.conf | grep APP_LOCALE | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
facades.Log().Request(ctx.Request()).Tags("面板", "面板设置").With(map[string]any{
"error": err.Error(),
}).Info("获取面板语言失败")
return ErrorSystem(ctx)
}
if oldLanguage != updateRequest.Language {
if out, err := shell.Execf("sed -i 's/APP_LOCALE=" + oldLanguage + "/APP_LOCALE=" + updateRequest.Language + "/g' /www/panel/panel.conf"); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
}
if oldPort != port || oldEntrance != entrance || oldLanguage != updateRequest.Language {
tools.RestartPanel()
}
return Success(ctx, nil)
}
// GetHttps
//
// @Summary 获取面板 HTTPS 设置
// @Tags 面板设置
// @Produce json
// @Security BearerToken
// @Success 200 {object} SuccessResponse
// @Router /panel/setting/https [get]
func (r *SettingController) GetHttps(ctx http.Context) http.Response {
certPath := facades.Config().GetString("http.tls.ssl.cert")
keyPath := facades.Config().GetString("http.tls.ssl.key")
crt, err := io.Read(certPath)
if err != nil {
return ErrorSystem(ctx)
}
key, err := io.Read(keyPath)
if err != nil {
return ErrorSystem(ctx)
}
return Success(ctx, http.Json{
"https": facades.Config().GetBool("panel.ssl"),
"cert": crt,
"key": key,
})
}
// UpdateHttps
//
// @Summary 更新面板 HTTPS 设置
// @Tags 面板设置
// @Accept json
// @Produce json
// @Security BearerToken
// @Param data body requests.Https true "request"
// @Success 200 {object} SuccessResponse
// @Router /panel/setting/https [post]
func (r *SettingController) UpdateHttps(ctx http.Context) http.Response {
var httpsRequest requests.Https
sanitize := SanitizeRequest(ctx, &httpsRequest)
if sanitize != nil {
return sanitize
}
if httpsRequest.Https {
if _, err := cert.ParseCert(httpsRequest.Cert); err != nil {
return Error(ctx, http.StatusBadRequest, "证书格式错误")
}
if _, err := cert.ParseKey(httpsRequest.Key); err != nil {
return Error(ctx, http.StatusBadRequest, "密钥格式错误")
}
if err := io.Write(path.Executable("storage/ssl.crt"), httpsRequest.Cert, 0700); err != nil {
return ErrorSystem(ctx)
}
if err := io.Write(path.Executable("storage/ssl.key"), httpsRequest.Key, 0700); err != nil {
return ErrorSystem(ctx)
}
if out, err := shell.Execf("sed -i 's/APP_SSL=false/APP_SSL=true/g' /www/panel/panel.conf"); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
} else {
if out, err := shell.Execf("sed -i 's/APP_SSL=true/APP_SSL=false/g' /www/panel/panel.conf"); err != nil {
return Error(ctx, http.StatusInternalServerError, out)
}
}
tools.RestartPanel()
return Success(ctx, nil)
}