diff --git a/app/http/controllers/cron_controller.go b/app/http/controllers/cron_controller.go index 3526821e..8c37d669 100644 --- a/app/http/controllers/cron_controller.go +++ b/app/http/controllers/cron_controller.go @@ -50,18 +50,14 @@ func (r *CronController) List(ctx http.Context) http.Response { // Add 添加计划任务 func (r *CronController) Add(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := Sanitize(ctx, map[string]string{ "name": "required|min_len:1|max_len:255", "time": "required", "script": "required", "type": "required|in:shell,backup,cutoff", "backup_type": "required_if:type,backup|in:website,mysql,postgresql", - }) - if err != nil { - return Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } // 单独验证时间格式 @@ -121,7 +117,7 @@ panel cutoff ${name} ${save} 2>&1 return Error(ctx, http.StatusInternalServerError, "计划任务日志目录不存在") } shellFile := strconv.Itoa(int(carbon.Now().Timestamp())) + tools.RandomString(16) - if err = tools.Write(shellDir+shellFile+".sh", shell, 0700); err != nil { + if err := tools.Write(shellDir+shellFile+".sh", shell, 0700); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } if out, err := tools.Exec("dos2unix " + shellDir + shellFile + ".sh"); err != nil { @@ -136,8 +132,7 @@ panel cutoff ${name} ${save} 2>&1 cron.Shell = shellDir + shellFile + ".sh" cron.Log = shellLogDir + shellFile + ".log" - err = facades.Orm().Query().Create(&cron) - if err != nil { + if err := facades.Orm().Query().Create(&cron); err != nil { facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{ "error": err.Error(), }).Info("保存计划任务失败") @@ -171,16 +166,12 @@ func (r *CronController) Script(ctx http.Context) http.Response { // Update 更新计划任务 func (r *CronController) Update(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := Sanitize(ctx, map[string]string{ "name": "required|min_len:1|max_len:255", "time": "required", "script": "required", - }) - if err != nil { - return Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } // 单独验证时间格式 @@ -189,8 +180,7 @@ func (r *CronController) Update(ctx http.Context) http.Response { } var cron models.Cron - err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron) - if err != nil { + if err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron); err != nil { return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在") } @@ -200,15 +190,14 @@ func (r *CronController) Update(ctx http.Context) http.Response { cron.Time = ctx.Request().Input("time") cron.Name = ctx.Request().Input("name") - err = facades.Orm().Query().Save(&cron) - if err != nil { + if err := facades.Orm().Query().Save(&cron); err != nil { facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{ "error": err.Error(), }).Info("更新计划任务失败") return ErrorSystem(ctx) } - if err = tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil { + if err := tools.Write(cron.Shell, ctx.Request().Input("script"), 0644); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } if out, err := tools.Exec("dos2unix " + cron.Shell); err != nil { @@ -253,25 +242,19 @@ func (r *CronController) Delete(ctx http.Context) http.Response { // Status 更新计划任务状态 func (r *CronController) Status(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := Sanitize(ctx, map[string]string{ "status": "bool", - }) - if err != nil { - return Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } var cron models.Cron - err = facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron) - if err != nil { + if err := facades.Orm().Query().Where("id", ctx.Request().Input("id")).FirstOrFail(&cron); err != nil { return Error(ctx, http.StatusUnprocessableEntity, "计划任务不存在") } cron.Status = ctx.Request().InputBool("status") - err = facades.Orm().Query().Save(&cron) - if err != nil { + if err := facades.Orm().Query().Save(&cron); err != nil { facades.Log().Request(ctx.Request()).Tags("面板", "计划任务").With(map[string]any{ "error": err.Error(), }).Info("更新计划任务状态失败") diff --git a/app/http/controllers/plugins/fail2ban_controller.go b/app/http/controllers/plugins/fail2ban_controller.go index 129ecc72..c14712d6 100644 --- a/app/http/controllers/plugins/fail2ban_controller.go +++ b/app/http/controllers/plugins/fail2ban_controller.go @@ -91,7 +91,7 @@ func (r *Fail2banController) List(ctx http.Context) http.Response { // Add 添加 Fail2ban 规则 func (r *Fail2banController) Add(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "name": "required", "type": "required|in:website,service", "maxretry": "required", @@ -100,12 +100,8 @@ func (r *Fail2banController) Add(ctx http.Context) http.Response { "website_name": "required_if:type,website", "website_mode": "required_if:type,website", "website_path": "required_if:website_mode,path", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } jailName := ctx.Request().Input("name") diff --git a/app/http/controllers/plugins/mysql_controller.go b/app/http/controllers/plugins/mysql_controller.go index 86ae141c..d12b1cfb 100644 --- a/app/http/controllers/plugins/mysql_controller.go +++ b/app/http/controllers/plugins/mysql_controller.go @@ -272,16 +272,12 @@ func (r *MySQLController) DatabaseList(ctx http.Context) http.Response { // AddDatabase 添加数据库 func (r *MySQLController) AddDatabase(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", "user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", "password": "required|min_len:8|max_len:255", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword) @@ -307,14 +303,10 @@ func (r *MySQLController) AddDatabase(ctx http.Context) http.Response { // DeleteDatabase 删除数据库 func (r *MySQLController) DeleteDatabase(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword) @@ -382,19 +374,14 @@ func (r *MySQLController) UploadBackup(ctx http.Context) http.Response { // CreateBackup 创建备份 func (r *MySQLController) CreateBackup(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } database := ctx.Request().Input("database") - err = r.backup.MysqlBackup(database) - if err != nil { + if err := r.backup.MysqlBackup(database); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -403,14 +390,10 @@ func (r *MySQLController) CreateBackup(ctx http.Context) http.Response { // DeleteBackup 删除备份 func (r *MySQLController) DeleteBackup(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "name": "required|min_len:1|max_len:255", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/mysql" @@ -424,19 +407,14 @@ func (r *MySQLController) DeleteBackup(ctx http.Context) http.Response { // RestoreBackup 还原备份 func (r *MySQLController) RestoreBackup(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "backup": "required|min_len:1|max_len:255", "database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } - err = r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup")) - if err != nil { + if err := r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup")); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, err.Error()) } @@ -528,16 +506,12 @@ func (r *MySQLController) UserList(ctx http.Context) http.Response { // AddUser 添加用户 func (r *MySQLController) AddUser(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", "user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", "password": "required|min_len:8|max_len:255", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword) @@ -559,14 +533,10 @@ func (r *MySQLController) AddUser(ctx http.Context) http.Response { // DeleteUser 删除用户 func (r *MySQLController) DeleteUser(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword) @@ -580,15 +550,11 @@ func (r *MySQLController) DeleteUser(ctx http.Context) http.Response { // SetUserPassword 设置用户密码 func (r *MySQLController) SetUserPassword(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", "password": "required|min_len:8|max_len:255", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword) @@ -606,15 +572,11 @@ func (r *MySQLController) SetUserPassword(ctx http.Context) http.Response { // SetUserPrivileges 设置用户权限 func (r *MySQLController) SetUserPrivileges(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$", "database": "required|min_len:1|max_len:255", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword) diff --git a/app/http/controllers/plugins/s3fs_controller.go b/app/http/controllers/plugins/s3fs_controller.go index 95d26977..5a91969f 100644 --- a/app/http/controllers/plugins/s3fs_controller.go +++ b/app/http/controllers/plugins/s3fs_controller.go @@ -60,18 +60,14 @@ func (r *S3fsController) List(ctx http.Context) http.Response { // Add 添加 S3fs 挂载 func (r *S3fsController) Add(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "ak": "required|regex:^[a-zA-Z0-9]*$", "sk": "required|regex:^[a-zA-Z0-9]*$", "bucket": "required|regex:^[a-zA-Z0-9_-]*$", "url": "required|full_url", "path": "required|regex:^/[a-zA-Z0-9_-]+$", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } ak := ctx.Request().Input("ak") @@ -87,7 +83,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response { // 检查挂载目录是否存在且为空 if !tools.Exists(path) { - if err = tools.Mkdir(path, 0755); err != nil { + if err := tools.Mkdir(path, 0755); err != nil { return controllers.Error(ctx, http.StatusUnprocessableEntity, "挂载目录创建失败") } } @@ -96,8 +92,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response { } var s3fsList []types.S3fsMount - err = json.UnmarshalString(r.setting.Get("s3fs", "[]"), &s3fsList) - if err != nil { + if err := json.UnmarshalString(r.setting.Get("s3fs", "[]"), &s3fsList); err != nil { return controllers.Error(ctx, http.StatusInternalServerError, "获取 S3fs 挂载失败") } @@ -109,7 +104,7 @@ func (r *S3fsController) Add(ctx http.Context) http.Response { id := carbon.Now().TimestampMilli() password := ak + ":" + sk - if err = tools.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil { + if err := tools.Write("/etc/passwd-s3fs-"+cast.ToString(id), password, 0600); err != nil { return nil } out, err := tools.Exec(`echo 's3fs#` + bucket + ` ` + path + ` fuse _netdev,allow_other,nonempty,url=` + url + `,passwd_file=/etc/passwd-s3fs-` + cast.ToString(id) + ` 0 0' >> /etc/fstab`) diff --git a/app/http/controllers/plugins/supervisor_controller.go b/app/http/controllers/plugins/supervisor_controller.go index 695557a3..04ce0d16 100644 --- a/app/http/controllers/plugins/supervisor_controller.go +++ b/app/http/controllers/plugins/supervisor_controller.go @@ -269,18 +269,14 @@ func (r *SupervisorController) SaveProcessConfig(ctx http.Context) http.Response // AddProcess 添加进程 func (r *SupervisorController) AddProcess(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := controllers.Sanitize(ctx, map[string]string{ "name": "required|alpha_dash", "user": "required|alpha_dash", "path": "required", "command": "required", "num": "required", - }) - if err != nil { - return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } name := ctx.Request().Input("name") @@ -300,6 +296,8 @@ redirect_stderr=true stdout_logfile=/var/log/supervisor/` + name + `.log stdout_logfile_maxbytes=2MB ` + + var err error if tools.IsRHEL() { err = tools.Write(`/etc/supervisord.d/`+name+`.conf`, config, 0644) } else { diff --git a/app/http/controllers/ssh_controller.go b/app/http/controllers/ssh_controller.go index cc781a60..0bc5a51e 100644 --- a/app/http/controllers/ssh_controller.go +++ b/app/http/controllers/ssh_controller.go @@ -50,33 +50,29 @@ func (r *SshController) GetInfo(ctx http.Context) http.Response { // UpdateInfo 更新 SSH 配置 func (r *SshController) UpdateInfo(ctx http.Context) http.Response { - validator, err := ctx.Request().Validate(map[string]string{ + if sanitize := Sanitize(ctx, map[string]string{ "host": "required", "port": "required", "user": "required", "password": "required", - }) - if err != nil { - return Error(ctx, http.StatusUnprocessableEntity, err.Error()) - } - if validator.Fails() { - return Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One()) + }); sanitize != nil { + return sanitize } host := ctx.Request().Input("host") port := ctx.Request().Input("port") user := ctx.Request().Input("user") password := ctx.Request().Input("password") - if err = r.setting.Set(models.SettingKeySshHost, host); err != nil { + if err := r.setting.Set(models.SettingKeySshHost, host); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err = r.setting.Set(models.SettingKeySshPort, port); err != nil { + if err := r.setting.Set(models.SettingKeySshPort, port); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err = r.setting.Set(models.SettingKeySshUser, user); err != nil { + if err := r.setting.Set(models.SettingKeySshUser, user); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) } - if err = r.setting.Set(models.SettingKeySshPassword, password); err != nil { + if err := r.setting.Set(models.SettingKeySshPassword, password); err != nil { return Error(ctx, http.StatusInternalServerError, err.Error()) }