From 0fae7cac25818508a73494e3203294ee25552abb Mon Sep 17 00:00:00 2001 From: akrike <1625167628@qq.com> Date: Sat, 5 Jul 2025 11:50:41 +0800 Subject: [PATCH] Standardization --- internal/app/api/api.go | 34 ------- internal/app/api/config.go | 26 +++-- internal/app/api/file.go | 26 +++-- internal/app/api/log.go | 12 ++- internal/app/api/permission.go | 12 +-- internal/app/api/proc.go | 106 ++++++++++---------- internal/app/api/push.go | 33 +++--- internal/app/api/task.go | 69 ++++++------- internal/app/api/user.go | 74 ++++++++------ internal/app/api/ws.go | 69 ++++++++----- internal/app/constants/bind.go | 8 -- internal/app/model/file.go | 8 ++ internal/app/model/permission.go | 4 + internal/app/model/process.go | 4 + internal/app/model/push_msg.go | 4 + internal/app/model/task.go | 4 + internal/app/model/user.go | 9 ++ internal/app/model/{ws_share.go => ws.go} | 11 ++ internal/app/route/route.go | 116 ++++++++++++---------- 19 files changed, 343 insertions(+), 286 deletions(-) delete mode 100644 internal/app/constants/bind.go rename internal/app/model/{ws_share.go => ws.go} (65%) diff --git a/internal/app/api/api.go b/internal/app/api/api.go index 4e9cf6e..5e152b6 100644 --- a/internal/app/api/api.go +++ b/internal/app/api/api.go @@ -3,11 +3,9 @@ package api import ( "net/http" "reflect" - "strconv" "github.com/lzh-1625/go_process_manager/internal/app/constants" "github.com/lzh-1625/go_process_manager/internal/app/repository" - "github.com/lzh-1625/go_process_manager/log" "github.com/gin-gonic/gin" ) @@ -23,20 +21,6 @@ func rOk(ctx *gin.Context, message string, data any) { ctx.JSON(http.StatusOK, jsonData) } -func errCheck(ctx *gin.Context, isErr bool, errData any) { - if !isErr { - return - } - if err, ok := errData.(error); ok { - log.Logger.Warn(errData) - ctx.Set(constants.CTXFLG_ERR, err.Error()) - } - if err, ok := errData.(string); ok { - ctx.Set(constants.CTXFLG_ERR, err) - } - panic(0) -} - func getRole(ctx *gin.Context) constants.Role { if v, ok := ctx.Get(constants.CTXFLG_ROLE); ok { return v.(constants.Role) @@ -55,21 +39,3 @@ func isAdmin(ctx *gin.Context) bool { func hasOprPermission(ctx *gin.Context, uuid int, op constants.OprPermission) bool { return isAdmin(ctx) || reflect.ValueOf(repository.PermissionRepository.GetPermission(getUserName(ctx), uuid)).FieldByName(string(op)).Bool() } - -func getQueryInt(ctx *gin.Context, query string) (i int) { - i, err := strconv.Atoi(ctx.Query(query)) - errCheck(ctx, err != nil, "Invalid parameters!") - return -} - -func getQueryString(ctx *gin.Context, query string) (s string) { - s = ctx.Query(query) - errCheck(ctx, s == "", "Invalid parameters!") - return -} - -func bind[T any](ctx *gin.Context) T { - var data T - errCheck(ctx, ctx.ShouldBind(&data) != nil, "Invalid parameters!") - return data -} diff --git a/internal/app/api/config.go b/internal/app/api/config.go index 926fce2..0c8e426 100644 --- a/internal/app/api/config.go +++ b/internal/app/api/config.go @@ -1,6 +1,8 @@ package api import ( + "errors" + "github.com/lzh-1625/go_process_manager/internal/app/logic" "github.com/gin-gonic/gin" @@ -10,18 +12,26 @@ type configApi struct{} var ConfigApi = new(configApi) -func (c *configApi) GetSystemConfiguration(ctx *gin.Context) { +func (c *configApi) GetSystemConfiguration(ctx *gin.Context, _ any) error { result := logic.ConfigLogic.GetSystemConfiguration() rOk(ctx, "Operation successful!", result) + return nil } -func (c *configApi) SetSystemConfiguration(ctx *gin.Context) { - req := bind[map[string]string](ctx) - errCheck(ctx, logic.ConfigLogic.SetSystemConfiguration(req) != nil, "Set config fail!") - rOk(ctx, "Operation successful!", nil) +func (c *configApi) SetSystemConfiguration(ctx *gin.Context, _ any) (err error) { + req := map[string]string{} + if err = ctx.BindJSON(&req); err != nil { + return + } + if err = logic.ConfigLogic.SetSystemConfiguration(req); err != nil { + return + } + return } -func (c *configApi) EsConfigReload(ctx *gin.Context) { - errCheck(ctx, !logic.EsLogic.InitEs(), "Incorrect username or password!") - rOk(ctx, "Operation successful!", nil) +func (c *configApi) EsConfigReload(ctx *gin.Context, _ any) (err error) { + if !logic.EsLogic.InitEs() { + return errors.New("es init fail") + } + return } diff --git a/internal/app/api/file.go b/internal/app/api/file.go index 0c3d365..546ac8a 100644 --- a/internal/app/api/file.go +++ b/internal/app/api/file.go @@ -2,6 +2,7 @@ package api import ( "github.com/lzh-1625/go_process_manager/internal/app/logic" + "github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/gin-gonic/gin" ) @@ -10,24 +11,27 @@ type file struct{} var FileApi = new(file) -func (f *file) FilePathHandler(ctx *gin.Context) { - path := getQueryString(ctx, "path") - rOk(ctx, "Operation successful!", logic.FileLogic.GetFileAndDirByPath(path)) +func (f *file) FilePathHandler(ctx *gin.Context, req model.FilePathHandlerReq) (err error) { + rOk(ctx, "Operation successful!", logic.FileLogic.GetFileAndDirByPath(req.Path)) + return } -func (f *file) FileWriteHandler(ctx *gin.Context) { +func (f *file) FileWriteHandler(ctx *gin.Context, _ any) (err error) { path := ctx.PostForm("filePath") fi, err := ctx.FormFile("data") - errCheck(ctx, err != nil, "Read file data failed!") + if err != nil { + return + } fiReader, _ := fi.Open() err = logic.FileLogic.UpdateFileData(path, fiReader, fi.Size) - errCheck(ctx, err != nil, "Update file data operation failed!") - rOk(ctx, "Operation successful!", nil) + return } -func (f *file) FileReadHandler(ctx *gin.Context) { - path := getQueryString(ctx, "filePath") - bytes, err := logic.FileLogic.ReadFileFromPath(path) - errCheck(ctx, err != nil, "Operation failed!") +func (f *file) FileReadHandler(ctx *gin.Context, req model.FileReadHandlerReq) (err error) { + bytes, err := logic.FileLogic.ReadFileFromPath(req.FilePath) + if err != nil { + return + } rOk(ctx, "Operation successful!", string(bytes)) + return } diff --git a/internal/app/api/log.go b/internal/app/api/log.go index 75de206..1d8e6f5 100644 --- a/internal/app/api/log.go +++ b/internal/app/api/log.go @@ -1,6 +1,7 @@ package api import ( + "errors" "slices" "github.com/lzh-1625/go_process_manager/internal/app/constants" @@ -15,8 +16,7 @@ type logApi struct{} var LogApi = new(logApi) -func (a *logApi) GetLog(ctx *gin.Context) { - req := bind[model.GetLogReq](ctx) +func (a *logApi) GetLog(ctx *gin.Context, req model.GetLogReq) (err error) { if isAdmin(ctx) { rOk(ctx, "Query successful!", logic.LogLogicImpl.Search(req, req.FilterName...)) } else { @@ -27,11 +27,15 @@ func (a *logApi) GetLog(ctx *gin.Context) { if len(filterName) == 0 { filterName = processNameList } - errCheck(ctx, len(filterName) == 0, "No information found!") + if len(filterName) == 0 { + return errors.New("no information found") + } rOk(ctx, "Query successful!", logic.LogLogicImpl.Search(req, filterName...)) } + return } -func (a *logApi) GetRunningLog(ctx *gin.Context) { +func (a *logApi) GetRunningLog(ctx *gin.Context, _ any) error { rOk(ctx, "Query successful!", logic.Loghandler.GetRunning()) + return nil } diff --git a/internal/app/api/permission.go b/internal/app/api/permission.go index e031422..49e1154 100644 --- a/internal/app/api/permission.go +++ b/internal/app/api/permission.go @@ -11,14 +11,12 @@ var PermissionApi = new(permissionApi) type permissionApi struct{} -func (p *permissionApi) EditPermssion(ctx *gin.Context) { - req := bind[model.Permission](ctx) - err := repository.PermissionRepository.EditPermssion(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (p *permissionApi) EditPermssion(ctx *gin.Context, req model.Permission) (err error) { + return repository.PermissionRepository.EditPermssion(req) } -func (p *permissionApi) GetPermissionList(ctx *gin.Context) { - result := repository.PermissionRepository.GetPermssionList(getQueryString(ctx, "account")) +func (p *permissionApi) GetPermissionList(ctx *gin.Context, req model.GetPermissionListReq) (err error) { + result := repository.PermissionRepository.GetPermssionList(req.Account) rOk(ctx, "Query successful!", result) + return } diff --git a/internal/app/api/proc.go b/internal/app/api/proc.go index 3be6bac..13e5082 100644 --- a/internal/app/api/proc.go +++ b/internal/app/api/proc.go @@ -1,6 +1,7 @@ package api import ( + "errors" "time" "github.com/google/uuid" @@ -16,114 +17,117 @@ type procApi struct{} var ProcApi = new(procApi) -func (p *procApi) CreateNewProcess(ctx *gin.Context) { - req := bind[model.Process](ctx) +func (p *procApi) CreateNewProcess(ctx *gin.Context, req model.Process) (err error) { index, err := repository.ProcessRepository.AddProcessConfig(req) - errCheck(ctx, err != nil, err) + if err != nil { + return + } req.Uuid = index proc, err := logic.ProcessCtlLogic.NewProcess(req) - errCheck(ctx, err != nil, err) + if err != nil { + return + } logic.ProcessCtlLogic.AddProcess(req.Uuid, proc) rOk(ctx, "Operation successful!", gin.H{ "id": req.Uuid, }) + return } -func (p *procApi) DeleteNewProcess(ctx *gin.Context) { - uuid := getQueryInt(ctx, "uuid") - logic.ProcessCtlLogic.KillProcess(uuid) - logic.ProcessCtlLogic.DeleteProcess(uuid) - err := repository.ProcessRepository.DeleteProcessConfig(uuid) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (p *procApi) DeleteNewProcess(ctx *gin.Context, req model.ProcessUuidReq) (err error) { + logic.ProcessCtlLogic.KillProcess(req.Uuid) + logic.ProcessCtlLogic.DeleteProcess(req.Uuid) + return repository.ProcessRepository.DeleteProcessConfig(req.Uuid) } -func (p *procApi) KillProcess(ctx *gin.Context) { - uuid := getQueryInt(ctx, "uuid") - err := logic.ProcessCtlLogic.KillProcess(uuid) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (p *procApi) KillProcess(ctx *gin.Context, req model.ProcessUuidReq) (err error) { + return logic.ProcessCtlLogic.KillProcess(req.Uuid) } -func (p *procApi) StartProcess(ctx *gin.Context) { - uuid := getQueryInt(ctx, "uuid") - prod, err := logic.ProcessCtlLogic.GetProcess(uuid) +func (p *procApi) StartProcess(ctx *gin.Context, req model.ProcessUuidReq) (err error) { + prod, err := logic.ProcessCtlLogic.GetProcess(req.Uuid) if err != nil { // 进程不存在则创建 - proc, err := logic.ProcessCtlLogic.RunNewProcess(repository.ProcessRepository.GetProcessConfigById(uuid)) - errCheck(ctx, err != nil, err) - logic.ProcessCtlLogic.AddProcess(uuid, proc) + proc, err1 := logic.ProcessCtlLogic.RunNewProcess(repository.ProcessRepository.GetProcessConfigById(req.Uuid)) + if err1 != nil { + return err1 + } + logic.ProcessCtlLogic.AddProcess(req.Uuid, proc) rOk(ctx, "Operation successful!", nil) - return + return nil + } + if prod.State.State == 1 { + return errors.New("process is currently running") } - errCheck(ctx, prod.State.State == 1, "The process is currently running.") prod.ResetRestartTimes() err = prod.Start() - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) + return + } -func (p *procApi) StartAllProcess(ctx *gin.Context) { +func (p *procApi) StartAllProcess(ctx *gin.Context, _ any) (err error) { if isAdmin(ctx) { logic.ProcessCtlLogic.ProcessStartAll() } else { logic.ProcessCtlLogic.ProcesStartAllByUsername(getUserName(ctx)) } - rOk(ctx, "Operation successful!", nil) + return } -func (p *procApi) KillAllProcess(ctx *gin.Context) { +func (p *procApi) KillAllProcess(ctx *gin.Context, _ any) (err error) { if isAdmin(ctx) { logic.ProcessCtlLogic.KillAllProcess() } else { logic.ProcessCtlLogic.KillAllProcessByUserName(getUserName(ctx)) } - rOk(ctx, "Operation successful!", nil) + return } -func (p *procApi) GetProcessList(ctx *gin.Context) { +func (p *procApi) GetProcessList(ctx *gin.Context, _ any) (err error) { if isAdmin(ctx) { rOk(ctx, "Query successful!", logic.ProcessCtlLogic.GetProcessList()) } else { rOk(ctx, "Query successful!", logic.ProcessCtlLogic.GetProcessListByUser(getUserName(ctx))) } + return } -func (p *procApi) UpdateProcessConfig(ctx *gin.Context) { - req := bind[model.Process](ctx) +func (p *procApi) UpdateProcessConfig(ctx *gin.Context, req model.Process) (err error) { logic.ProcessCtlLogic.UpdateProcessConfig(req) - err := repository.ProcessRepository.UpdateProcessConfig(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) + err = repository.ProcessRepository.UpdateProcessConfig(req) + return } -func (p *procApi) GetProcessConfig(ctx *gin.Context) { - uuid := getQueryInt(ctx, "uuid") - data := repository.ProcessRepository.GetProcessConfigById(uuid) - errCheck(ctx, data.Uuid == 0, "No information found!") - rOk(ctx, "Query successful!", data) +func (p *procApi) GetProcessConfig(ctx *gin.Context, req model.ProcessUuidReq) (err error) { + data := repository.ProcessRepository.GetProcessConfigById(req.Uuid) + if data.Uuid == 0 { + return errors.New("no information found") + } + return } -func (p *procApi) ProcessControl(ctx *gin.Context) { +func (p *procApi) ProcessControl(ctx *gin.Context, req model.ProcessUuidReq) (err error) { user := getUserName(ctx) - uuid := getQueryInt(ctx, "uuid") - proc, err := logic.ProcessCtlLogic.GetProcess(uuid) - errCheck(ctx, err != nil, err) + proc, err := logic.ProcessCtlLogic.GetProcess(req.Uuid) + if err != nil { + return + } proc.ProcessControl(user) - rOk(ctx, "Operation successful!", nil) + return } -func (p *procApi) ProcessCreateShare(ctx *gin.Context) { - req := bind[model.ProcessShare](ctx) +func (p *procApi) ProcessCreateShare(ctx *gin.Context, req model.ProcessShare) (err error) { token := utils.UnwarpIgnore(uuid.NewRandom()).String() - err := repository.WsShare.AddShareData(model.WsShare{ + if err = repository.WsShare.AddShareData(model.WsShare{ ExpireTime: time.Now().Add(time.Minute * time.Duration(req.Minutes)), Write: req.Write, Token: token, Pid: req.Pid, CreateBy: getUserName(ctx), - }) - errCheck(ctx, err != nil, err) + }); err != nil { + return + } rOk(ctx, "Operation successful!", gin.H{ "token": token, }) + return } diff --git a/internal/app/api/push.go b/internal/app/api/push.go index 4ee909f..4acb58e 100644 --- a/internal/app/api/push.go +++ b/internal/app/api/push.go @@ -11,32 +11,27 @@ type pushApi struct{} var PushApi = new(pushApi) -func (p *pushApi) GetPushList(ctx *gin.Context) { +func (p *pushApi) GetPushList(ctx *gin.Context, __ any) (err error) { rOk(ctx, "Query successful!", repository.PushRepository.GetPushList()) + return } -func (p *pushApi) GetPushById(ctx *gin.Context) { - id := getQueryInt(ctx, "id") - rOk(ctx, "Query successful!", repository.PushRepository.GetPushConfigById(id)) +func (p *pushApi) GetPushById(ctx *gin.Context, req model.PushIdReq) (err error) { + rOk(ctx, "Query successful!", repository.PushRepository.GetPushConfigById(req.Id)) + return } -func (p *pushApi) AddPushConfig(ctx *gin.Context) { - req := bind[model.Push](ctx) - err := repository.PushRepository.AddPushConfig(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (p *pushApi) AddPushConfig(ctx *gin.Context, req model.Push) (err error) { + err = repository.PushRepository.AddPushConfig(req) + return } -func (p *pushApi) UpdatePushConfig(ctx *gin.Context) { - req := bind[model.Push](ctx) - err := repository.PushRepository.UpdatePushConfig(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (p *pushApi) UpdatePushConfig(ctx *gin.Context, req model.Push) (err error) { + err = repository.PushRepository.UpdatePushConfig(req) + return } -func (p *pushApi) DeletePushConfig(ctx *gin.Context) { - id := getQueryInt(ctx, "id") - err := repository.PushRepository.DeletePushConfig(id) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (p *pushApi) DeletePushConfig(ctx *gin.Context, req model.PushIdReq) (err error) { + err = repository.PushRepository.DeletePushConfig(req.Id) + return } diff --git a/internal/app/api/task.go b/internal/app/api/task.go index 3432fc6..ed3a672 100644 --- a/internal/app/api/task.go +++ b/internal/app/api/task.go @@ -1,6 +1,8 @@ package api import ( + "errors" + "github.com/lzh-1625/go_process_manager/internal/app/logic" "github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/lzh-1625/go_process_manager/internal/app/repository" @@ -12,62 +14,55 @@ type taskApi struct{} var TaskApi = new(taskApi) -func (t *taskApi) CreateTask(ctx *gin.Context) { - req := bind[model.Task](ctx) - err := logic.TaskLogic.CreateTask(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) CreateTask(ctx *gin.Context, req model.Task) (err error) { + return logic.TaskLogic.CreateTask(req) } -func (t *taskApi) GetTaskById(ctx *gin.Context) { - result, err := repository.TaskRepository.GetTaskById(getQueryInt(ctx, "id")) - errCheck(ctx, err != nil, "Query failed!") +func (t *taskApi) GetTaskById(ctx *gin.Context, req model.TaskIdReq) (err error) { + result, err := repository.TaskRepository.GetTaskById(req.Id) + if err != nil { + return + } rOk(ctx, "Operation successful!", result) + return } -func (t *taskApi) GetTaskList(ctx *gin.Context) { +func (t *taskApi) GetTaskList(ctx *gin.Context, _ any) (err error) { result := logic.TaskLogic.GetAllTaskJob() rOk(ctx, "Operation successful!", result) + return } -func (t *taskApi) DeleteTaskById(ctx *gin.Context) { - err := logic.TaskLogic.DeleteTask(getQueryInt(ctx, "id")) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) DeleteTaskById(ctx *gin.Context, req model.TaskIdReq) (err error) { + return logic.TaskLogic.DeleteTask(req.Id) + } -func (t *taskApi) StartTask(ctx *gin.Context) { - go logic.TaskLogic.RunTaskById(getQueryInt(ctx, "id")) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) StartTask(ctx *gin.Context, req model.TaskIdReq) (err error) { + go logic.TaskLogic.RunTaskById(req.Id) + return } -func (t *taskApi) StopTask(ctx *gin.Context) { - errCheck(ctx, logic.TaskLogic.StopTaskJob(getQueryInt(ctx, "id")) != nil, "Operation failed!") - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) StopTask(ctx *gin.Context, req model.TaskIdReq) (err error) { + if logic.TaskLogic.StopTaskJob(req.Id) != nil { + return errors.New("operation failed") + } + return } -func (t *taskApi) EditTask(ctx *gin.Context) { - req := bind[model.Task](ctx) - err := logic.TaskLogic.EditTask(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) EditTask(ctx *gin.Context, req model.Task) (err error) { + return logic.TaskLogic.EditTask(req) } -func (t *taskApi) EditTaskEnable(ctx *gin.Context) { - req := bind[model.Task](ctx) - err := logic.TaskLogic.EditTaskEnable(req.Id, req.Enable) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) EditTaskEnable(ctx *gin.Context, req model.Task) (err error) { + return logic.TaskLogic.EditTaskEnable(req.Id, req.Enable) } -func (t *taskApi) RunTaskByKey(ctx *gin.Context) { - err := logic.TaskLogic.RunTaskByKey(ctx.Param("key")) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) RunTaskByKey(ctx *gin.Context, _ any) (err error) { + return logic.TaskLogic.RunTaskByKey(ctx.Param("key")) + } -func (t *taskApi) CreateTaskApiKey(ctx *gin.Context) { - err := logic.TaskLogic.CreateApiKey(getQueryInt(ctx, "id")) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (t *taskApi) CreateTaskApiKey(ctx *gin.Context, req model.TaskIdReq) (err error) { + return logic.TaskLogic.CreateApiKey(req.Id) } diff --git a/internal/app/api/user.go b/internal/app/api/user.go index 31b9a6a..077c08b 100644 --- a/internal/app/api/user.go +++ b/internal/app/api/user.go @@ -1,6 +1,8 @@ package api import ( + "errors" + "github.com/lzh-1625/go_process_manager/config" "github.com/lzh-1625/go_process_manager/internal/app/constants" "github.com/lzh-1625/go_process_manager/internal/app/model" @@ -16,57 +18,65 @@ var UserApi = new(userApi) const DEFAULT_ROOT_PASSWORD = "root" -func (u *userApi) LoginHandler(ctx *gin.Context) { - req := bind[map[string]string](ctx) - account := req["account"] - password := req["password"] - errCheck(ctx, !u.checkLoginInfo(account, password), "Incorrect username or password!") - token, err := utils.GenToken(account) - errCheck(ctx, err != nil, err) +func (u *userApi) LoginHandler(ctx *gin.Context, req model.LoginHandlerReq) (err error) { + if !u.checkLoginInfo(req.Account, req.Password) { + return errors.New("incorrect username or password") + } + token, err := utils.GenToken(req.Account) + if err != nil { + return + } rOk(ctx, "Operation successful!", gin.H{ "token": token, - "username": account, - "role": repository.UserRepository.GetUserByName(account).Role, + "username": req.Account, + "role": repository.UserRepository.GetUserByName(req.Account).Role, }) + return } -func (u *userApi) CreateUser(ctx *gin.Context) { - req := bind[model.User](ctx) - errCheck(ctx, req.Role == constants.ROLE_ROOT, "Creation of root accounts is forbidden!") - errCheck(ctx, req.Account == constants.CONSOLE, "Operation failed!") - errCheck(ctx, len(req.Password) < config.CF.UserPassWordMinLength, "Password is too short") - err := repository.UserRepository.CreateUser(req) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) +func (u *userApi) CreateUser(ctx *gin.Context, req model.User) (err error) { + if req.Role == constants.ROLE_ROOT { + return errors.New("creation of root accounts is forbidden") + } + if req.Account == constants.CONSOLE { + return errors.New("operation failed") + } + if len(req.Password) < config.CF.UserPassWordMinLength { + return errors.New("password is too short") + } + err = repository.UserRepository.CreateUser(req) + return } -func (u *userApi) ChangePassword(ctx *gin.Context) { - req := bind[model.User](ctx) +func (u *userApi) ChangePassword(ctx *gin.Context, req model.User) (err error) { reqUser := getUserName(ctx) - errCheck(ctx, getRole(ctx) != constants.ROLE_ROOT && req.Account != "", "Invalid parameters!") + if getRole(ctx) != constants.ROLE_ROOT && req.Account != "" { + return errors.New("invalid parameters") + } var userName string if req.Account != "" { userName = req.Account } else { userName = reqUser } - errCheck(ctx, len(req.Password) < config.CF.UserPassWordMinLength, "Password is too short") - err := repository.UserRepository.UpdatePassword(userName, req.Password) - errCheck(ctx, err != nil, err) - rOk(ctx, "Operation successful!", nil) - + if len(req.Password) < config.CF.UserPassWordMinLength { + return errors.New("password is too short") + } + err = repository.UserRepository.UpdatePassword(userName, req.Password) + return } -func (u *userApi) DeleteUser(ctx *gin.Context) { - account := getQueryString(ctx, "account") - errCheck(ctx, account == "root", "Deletion of root accounts is forbidden!") - err := repository.UserRepository.DeleteUser(account) - errCheck(ctx, err != nil, "Deletion of root accounts failed!") - rOk(ctx, "Operation successful!", nil) +func (u *userApi) DeleteUser(ctx *gin.Context, req model.User) (err error) { + if req.Account == "root" { + return errors.New("deletion of root accounts is forbidden") + } + err = repository.UserRepository.DeleteUser(req.Account) + return } -func (u *userApi) GetUserList(ctx *gin.Context) { +func (u *userApi) GetUserList(ctx *gin.Context, _ any) error { rOk(ctx, "Query successful!", repository.UserRepository.GetUserList()) + return nil } func (u *userApi) checkLoginInfo(account, password string) bool { diff --git a/internal/app/api/ws.go b/internal/app/api/ws.go index 04b9354..834a6b3 100644 --- a/internal/app/api/ws.go +++ b/internal/app/api/ws.go @@ -2,6 +2,7 @@ package api import ( "context" + "errors" "strconv" "sync" "time" @@ -9,6 +10,7 @@ import ( "github.com/lzh-1625/go_process_manager/config" "github.com/lzh-1625/go_process_manager/internal/app/constants" "github.com/lzh-1625/go_process_manager/internal/app/logic" + "github.com/lzh-1625/go_process_manager/internal/app/model" "github.com/lzh-1625/go_process_manager/internal/app/repository" "github.com/lzh-1625/go_process_manager/log" "github.com/lzh-1625/go_process_manager/utils" @@ -47,19 +49,22 @@ var upgrader = websocket.Upgrader{ WriteBufferSize: 1024, } -func (w *wsApi) WebsocketHandle(ctx *gin.Context) { +func (w *wsApi) WebsocketHandle(ctx *gin.Context, req model.WebsocketHandleReq) (err error) { reqUser := getUserName(ctx) - uuid := getQueryInt(ctx, "uuid") - proc, err := logic.ProcessCtlLogic.GetProcess(uuid) - errCheck(ctx, err != nil, "Operation failed!") - errCheck(ctx, proc.HasWsConn(reqUser), "A connection already exists; unable to establish a new one!") - errCheck(ctx, proc.Control.Controller != reqUser && !proc.VerifyControl(), "Insufficient permissions; please check your access rights!") + proc, err := logic.ProcessCtlLogic.GetProcess(req.Uuid) + if err != nil { + return + } + if !proc.HasWsConn(reqUser) { + return errors.New("connection already exists; unable to establish a new one") + } + if proc.Control.Controller == reqUser || proc.VerifyControl() { + return errors.New("insufficient permissions; please check your access rights") + } conn, err := upgrader.Upgrade(ctx.Writer, ctx.Request, nil) - errCheck(ctx, err != nil, "WebSocket connection upgrade failed!") - - log.Logger.AddAdditionalInfo("processName", proc.Name) - log.Logger.AddAdditionalInfo("userName", reqUser) - defer log.Logger.DeleteAdditionalInfo(2) + if err != nil { + return + } log.Logger.Infow("ws连接成功") @@ -72,7 +77,7 @@ func (w *wsApi) WebsocketHandle(ctx *gin.Context) { proc.ReadCache(wci) if proc.State.State == 1 { proc.SetTerminalSize(utils.GetIntByString(ctx.Query("cols")), utils.GetIntByString(ctx.Query("rows"))) - w.startWsConnect(wci, cancel, proc, hasOprPermission(ctx, uuid, constants.OPERATION_TERMINAL_WRITE)) + w.startWsConnect(wci, cancel, proc, hasOprPermission(ctx, req.Uuid, constants.OPERATION_TERMINAL_WRITE)) proc.AddConn(reqUser, wci) defer proc.DeleteConn(reqUser) } @@ -89,21 +94,35 @@ func (w *wsApi) WebsocketHandle(ctx *gin.Context) { log.Logger.Infow("ws连接断开", "操作类型", "tcp连接建立已被关闭") } conn.Close() + return } -func (w *wsApi) WebsocketShareHandle(ctx *gin.Context) { - token := getQueryString(ctx, "token") - data, err := repository.WsShare.GetWsShareDataByToken(token) - errCheck(ctx, err != nil, "Operation failed!") - errCheck(ctx, data.ExpireTime.Unix() <= time.Now().Unix(), "Share expired!") +func (w *wsApi) WebsocketShareHandle(ctx *gin.Context, req model.WebsocketHandleReq) (err error) { + data, err := repository.WsShare.GetWsShareDataByToken(req.Token) + if err != nil { + return + } + if data.ExpireTime.Unix() <= time.Now().Unix() { + return errors.New("share expired") + } proc, err := logic.ProcessCtlLogic.GetProcess(data.Pid) - errCheck(ctx, err != nil, err) + if err != nil { + return + } guestName := "guest-" + strconv.Itoa(int(data.ID)) // 构造访客用户名 - errCheck(ctx, proc.HasWsConn(guestName), "A connection already exists; unable to establish a new one!") - errCheck(ctx, proc.State.State != 1, "The process is currently running.") - errCheck(ctx, !proc.VerifyControl(), "Insufficient permissions; please check your access rights!") + if proc.HasWsConn(guestName) { + return errors.New("connection already exists; unable to establish a new one") + } + if proc.State.State != 1 { + return errors.New("process is currently running") + } + if !proc.VerifyControl() { + return errors.New("insufficient permissions; please check your access rights") + } conn, err := upgrader.Upgrade(ctx.Writer, ctx.Request, nil) - errCheck(ctx, err != nil, "WebSocket connection upgrade failed!") + if err != nil { + return + } log.Logger.Infow("ws连接成功") data.UpdatedAt = time.Now() @@ -135,6 +154,7 @@ func (w *wsApi) WebsocketShareHandle(ctx *gin.Context) { log.Logger.Infow("ws连接断开", "操作类型", "分享时间已结束") } conn.Close() + return } func (w *wsApi) startWsConnect(wci *WsConnetInstance, cancel context.CancelFunc, proc logic.Process, write bool) { @@ -183,7 +203,8 @@ func GetWsShareList(ctx *gin.Context) { } func DeleteWsShareById(ctx *gin.Context) { - err := logic.WsSahreLogic.DeleteById(ctx.GetInt("id")) - errCheck(ctx, err != nil, err) + if err := logic.WsSahreLogic.DeleteById(ctx.GetInt("id")); err != nil { + return + } rOk(ctx, "Operation successful!", nil) } diff --git a/internal/app/constants/bind.go b/internal/app/constants/bind.go deleted file mode 100644 index a58e0a2..0000000 --- a/internal/app/constants/bind.go +++ /dev/null @@ -1,8 +0,0 @@ -package constants - -const ( - BIND_NONE = 0 - BIND_OPTION_HEADER = 1 << iota - BIND_OPTION_BODY - BIND_OPTION_QUERY -) diff --git a/internal/app/model/file.go b/internal/app/model/file.go index d0f12e7..549fcfc 100644 --- a/internal/app/model/file.go +++ b/internal/app/model/file.go @@ -4,3 +4,11 @@ type FileStruct struct { Name string `json:"name"` IsDir bool `json:"isDir"` } + +type FilePathHandlerReq struct { + Path string `form:"path"` +} + +type FileReadHandlerReq struct { + FilePath string `form:"filePath"` +} diff --git a/internal/app/model/permission.go b/internal/app/model/permission.go index f521b4c..4aaa209 100644 --- a/internal/app/model/permission.go +++ b/internal/app/model/permission.go @@ -29,3 +29,7 @@ type PermissionPo struct { Write bool `gorm:"column:write;NOT NULL" json:"write"` Log bool `gorm:"column:log;NOT NULL" json:"log"` } + +type GetPermissionListReq struct { + Account string `form:"account"` +} diff --git a/internal/app/model/process.go b/internal/app/model/process.go index 0726736..0609184 100644 --- a/internal/app/model/process.go +++ b/internal/app/model/process.go @@ -26,3 +26,7 @@ type ProcessShare struct { Pid int `json:"pid"` Write bool `json:"write"` } + +type ProcessUuidReq struct { + Uuid int `form:"uuid"` +} diff --git a/internal/app/model/push_msg.go b/internal/app/model/push_msg.go index 090dc9c..444d2b8 100644 --- a/internal/app/model/push_msg.go +++ b/internal/app/model/push_msg.go @@ -12,3 +12,7 @@ type Push struct { func (*Push) TableName() string { return "push" } + +type PushIdReq struct { + Id int `form:"id"` +} diff --git a/internal/app/model/task.go b/internal/app/model/task.go index 4115619..23b9a0c 100644 --- a/internal/app/model/task.go +++ b/internal/app/model/task.go @@ -45,3 +45,7 @@ type TaskVo struct { StartTime time.Time `json:"startTime"` Running bool `json:"running"` } + +type TaskIdReq struct { + Id int `form:"id"` +} diff --git a/internal/app/model/user.go b/internal/app/model/user.go index 57fd7fe..e8ea7d6 100644 --- a/internal/app/model/user.go +++ b/internal/app/model/user.go @@ -17,3 +17,12 @@ type User struct { func (*User) TableName() string { return "users" } + +type LoginHandlerReq struct { + Account string `form:"account"` + Password string `form:"password"` +} + +type DeleteUserReq struct { + Account string `form:"account"` +} diff --git a/internal/app/model/ws_share.go b/internal/app/model/ws.go similarity index 65% rename from internal/app/model/ws_share.go rename to internal/app/model/ws.go index 993067a..48eccd9 100644 --- a/internal/app/model/ws_share.go +++ b/internal/app/model/ws.go @@ -14,3 +14,14 @@ type WsShare struct { CreateBy string `gorm:"column:create_by" json:"createBy"` Token string `gorm:"column:token" json:"token"` } + +func (WsShare) TableName() string { + return "ws_share" +} + +type WebsocketHandleReq struct { + Uuid int `json:"uuid"` + Cols int `json:"cols"` + Rows int `json:"rows"` + Token string `json:"token"` +} diff --git a/internal/app/route/route.go b/internal/app/route/route.go index c3cdefa..547d7fb 100644 --- a/internal/app/route/route.go +++ b/internal/app/route/route.go @@ -51,6 +51,7 @@ func pprofInit(r *gin.Engine) { } func routePathInit(r *gin.Engine) { + apiGroup := r.Group("/api") apiGroup.Use(middle.CheckToken()) apiGroup.Use(middle.PanicMiddle()) @@ -58,107 +59,114 @@ func routePathInit(r *gin.Engine) { { wsGroup := apiGroup.Group("/ws") { - wsGroup.GET("", middle.OprPermission(constants.OPERATION_TERMINAL), api.WsApi.WebsocketHandle) - wsGroup.GET("/share", api.WsApi.WebsocketShareHandle) + wsGroup.GET("", middle.OprPermission(constants.OPERATION_TERMINAL), bind(api.WsApi.WebsocketHandle, Query)) + wsGroup.GET("/share", bind(api.WsApi.WebsocketShareHandle, Query)) } processGroup := apiGroup.Group("/process") { - processGroup.DELETE("", middle.OprPermission(constants.OPERATION_STOP), api.ProcApi.KillProcess) - processGroup.GET("", api.ProcApi.GetProcessList) - processGroup.GET("/wait", middle.ProcessWaitCond.WaitGetMiddel, api.ProcApi.GetProcessList) - processGroup.PUT("", middle.OprPermission(constants.OPERATION_START), api.ProcApi.StartProcess) - processGroup.PUT("/all", api.ProcApi.StartAllProcess) - processGroup.DELETE("/all", api.ProcApi.KillAllProcess) - processGroup.POST("/share", middle.RolePermission(constants.ROLE_ADMIN), api.ProcApi.ProcessCreateShare) - processGroup.GET("/control", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.ProcessControl) + processGroup.DELETE("", middle.OprPermission(constants.OPERATION_STOP), bind(api.ProcApi.KillProcess, Query)) + processGroup.GET("", bind(api.ProcApi.GetProcessList, None)) + processGroup.GET("/wait", middle.ProcessWaitCond.WaitGetMiddel, bind(api.ProcApi.GetProcessList, None)) + processGroup.PUT("", middle.OprPermission(constants.OPERATION_START), bind(api.ProcApi.StartProcess, Body)) + processGroup.PUT("/all", bind(api.ProcApi.StartAllProcess, None)) + processGroup.DELETE("/all", bind(api.ProcApi.KillAllProcess, None)) + processGroup.POST("/share", middle.RolePermission(constants.ROLE_ADMIN), bind(api.ProcApi.ProcessCreateShare, Body)) + processGroup.GET("/control", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.ProcApi.ProcessControl, Query)) proConfigGroup := processGroup.Group("/config") { - proConfigGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.CreateNewProcess) - proConfigGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.DeleteNewProcess) - proConfigGroup.PUT("", middle.RolePermission(constants.ROLE_ROOT), api.ProcApi.UpdateProcessConfig) - proConfigGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), api.ProcApi.GetProcessConfig) + proConfigGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.ProcApi.CreateNewProcess, Body)) + proConfigGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.ProcApi.DeleteNewProcess, Query)) + proConfigGroup.PUT("", middle.RolePermission(constants.ROLE_ROOT), bind(api.ProcApi.UpdateProcessConfig, Body)) + proConfigGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), bind(api.ProcApi.GetProcessConfig, Query)) } } taskGroup := apiGroup.Group("/task") { - taskGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.GetTaskById) - taskGroup.GET("/all", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.GetTaskList) - taskGroup.GET("/all/wait", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitGetMiddel, api.TaskApi.GetTaskList) - taskGroup.POST("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.CreateTask) - taskGroup.DELETE("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.DeleteTaskById) - taskGroup.PUT("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.EditTask) - taskGroup.PUT("/enable", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.EditTaskEnable) - taskGroup.GET("/start", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.StartTask) - taskGroup.GET("/stop", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.StopTask) - taskGroup.POST("/key", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.CreateTaskApiKey) - taskGroup.GET("/api-key/:key", api.TaskApi.RunTaskByKey) + taskGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.GetTaskById, Query)) + taskGroup.GET("/all", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.GetTaskList, None)) + taskGroup.GET("/all/wait", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitGetMiddel, bind(api.TaskApi.GetTaskList, None)) + taskGroup.POST("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.CreateTask, Body)) + taskGroup.DELETE("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.DeleteTaskById, Query)) + taskGroup.PUT("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.EditTask, Body)) + taskGroup.PUT("/enable", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.EditTaskEnable, Body)) + taskGroup.GET("/start", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.StartTask, Query)) + taskGroup.GET("/stop", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.StopTask, Query)) + taskGroup.POST("/key", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.CreateTaskApiKey, Body)) + taskGroup.GET("/api-key/:key", bind(api.TaskApi.RunTaskByKey, None)) } userGroup := apiGroup.Group("/user") { - userGroup.POST("/login", api.UserApi.LoginHandler) - userGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), api.UserApi.CreateUser) - userGroup.PUT("/password", middle.RolePermission(constants.ROLE_USER), api.UserApi.ChangePassword) - userGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), api.UserApi.DeleteUser) - userGroup.GET("", middle.RolePermission(constants.ROLE_ROOT), api.UserApi.GetUserList) + userGroup.POST("/login", bind(api.UserApi.LoginHandler, Body)) + userGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), bind(api.UserApi.CreateUser, Body)) + userGroup.PUT("/password", middle.RolePermission(constants.ROLE_USER), bind(api.UserApi.ChangePassword, Body)) + userGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), bind(api.UserApi.DeleteUser, Query)) + userGroup.GET("", middle.RolePermission(constants.ROLE_ROOT), bind(api.UserApi.GetUserList, None)) } pushGroup := apiGroup.Group("/push").Use(middle.RolePermission(constants.ROLE_ADMIN)) { - pushGroup.GET("/list", api.PushApi.GetPushList) - pushGroup.GET("", api.PushApi.GetPushById) - pushGroup.POST("", api.PushApi.AddPushConfig) - pushGroup.PUT("", api.PushApi.UpdatePushConfig) - pushGroup.DELETE("", api.PushApi.DeletePushConfig) + pushGroup.GET("/list", bind(api.PushApi.GetPushList, None)) + pushGroup.GET("", bind(api.PushApi.GetPushById, Query)) + pushGroup.POST("", bind(api.PushApi.AddPushConfig, Body)) + pushGroup.PUT("", bind(api.PushApi.UpdatePushConfig, Body)) + pushGroup.DELETE("", bind(api.PushApi.DeletePushConfig, Query)) } fileGroup := apiGroup.Group("/file").Use(middle.RolePermission(constants.ROLE_ADMIN)) { - fileGroup.GET("/list", api.FileApi.FilePathHandler) - fileGroup.PUT("", api.FileApi.FileWriteHandler) - fileGroup.GET("", api.FileApi.FileReadHandler) + fileGroup.GET("/list", bind(api.FileApi.FilePathHandler, Query)) + fileGroup.PUT("", bind(api.FileApi.FileWriteHandler, None)) + fileGroup.GET("", bind(api.FileApi.FileReadHandler, Query)) } permissionGroup := apiGroup.Group("/permission").Use(middle.RolePermission(constants.ROLE_ROOT)) { - permissionGroup.GET("/list", api.PermissionApi.GetPermissionList) - permissionGroup.PUT("", middle.ProcessWaitCond.WaitTriggerMiddel, api.PermissionApi.EditPermssion) + permissionGroup.GET("/list", bind(api.PermissionApi.GetPermissionList, Query)) + permissionGroup.PUT("", middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.PermissionApi.EditPermssion, Body)) } logGroup := apiGroup.Group("/log").Use(middle.RolePermission(constants.ROLE_USER)) { - logGroup.POST("", api.LogApi.GetLog) - logGroup.GET("/running", api.LogApi.GetRunningLog) + logGroup.POST("", bind(api.LogApi.GetLog, Body)) + logGroup.GET("/running", bind(api.LogApi.GetRunningLog, None)) } configGroup := apiGroup.Group("/config").Use(middle.RolePermission(constants.ROLE_ROOT)) { - configGroup.GET("", api.ConfigApi.GetSystemConfiguration) - configGroup.PUT("", api.ConfigApi.SetSystemConfiguration) - configGroup.PUT("/es", api.ConfigApi.EsConfigReload) + configGroup.GET("", bind(api.ConfigApi.GetSystemConfiguration, None)) + configGroup.PUT("", bind(api.ConfigApi.SetSystemConfiguration, None)) + configGroup.PUT("/es", bind(api.ConfigApi.EsConfigReload, None)) } } } -func bind[T any](fn func(*gin.Context, *T) error, bindOption int) func(*gin.Context) { +const ( + None = 0 + Header = 1 << iota + Body + Query +) + +func bind[T any](fn func(*gin.Context, T) error, bindOption int) func(*gin.Context) { return func(ctx *gin.Context) { - var req *T - if bindOption&constants.BIND_OPTION_BODY != 0 { + var req T + if bindOption&Body != 0 { if err := ctx.BindJSON(req); err != nil { rErr(ctx, err) return } } - if bindOption&constants.BIND_OPTION_HEADER != 0 { + if bindOption&Header != 0 { if err := ctx.BindHeader(req); err != nil { rErr(ctx, err) return } } - if bindOption&constants.BIND_OPTION_QUERY != 0 { + if bindOption&Query != 0 { if err := ctx.BindQuery(req); err != nil { rErr(ctx, err) return @@ -167,9 +175,15 @@ func bind[T any](fn func(*gin.Context, *T) error, bindOption int) func(*gin.Cont err := fn(ctx, req) if err != nil { rErr(ctx, err) + return + } + if ctx.Writer.Status() == 0 { + ctx.JSON(200, gin.H{ + "code": 0, + "message": "success", + }) } } - } func rErr(ctx *gin.Context, err error) {