mirror of
https://github.com/veops/oneterm.git
synced 2025-10-18 21:24:46 +08:00
feat(backend): errors move to pkg
This commit is contained in:
@@ -39,21 +39,16 @@ func initDB() {
|
||||
|
||||
}
|
||||
|
||||
// 初始化服务
|
||||
func initServices() {
|
||||
// 初始化授权服务
|
||||
service.InitAuthorizationService()
|
||||
|
||||
// 初始化文件服务
|
||||
service.InitFileService()
|
||||
|
||||
// 其他服务初始化...
|
||||
}
|
||||
|
||||
func RunApi() error {
|
||||
initDB()
|
||||
|
||||
// 初始化服务层
|
||||
initServices()
|
||||
|
||||
r := gin.New()
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
myErrors "github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -20,7 +21,7 @@ var (
|
||||
// Validate public key
|
||||
func(ctx *gin.Context, data *model.Account) {
|
||||
if err := accountService.ValidatePublicKey(data); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrWrongPvk, Data: nil})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrWrongPvk, Data: nil})
|
||||
return
|
||||
}
|
||||
},
|
||||
@@ -51,7 +52,7 @@ var (
|
||||
return
|
||||
}
|
||||
code := lo.Ternary(err == nil, http.StatusBadRequest, http.StatusInternalServerError)
|
||||
err = lo.Ternary[error](err == nil, &ApiError{Code: ErrHasDepency, Data: map[string]any{"name": assetName}}, err)
|
||||
err = lo.Ternary[error](err == nil, &myErrors.ApiError{Code: myErrors.ErrHasDepency, Data: map[string]any{"name": assetName}}, err)
|
||||
ctx.AbortWithError(code, err)
|
||||
},
|
||||
}
|
||||
@@ -116,7 +117,7 @@ func (c *Controller) GetAccounts(ctx *gin.Context) {
|
||||
if !acl.IsAdmin(currentUser) {
|
||||
assetIds, err := GetAssetIdsByAuthorization(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
"github.com/veops/oneterm/pkg/logger"
|
||||
)
|
||||
|
||||
@@ -110,7 +111,7 @@ func (c *Controller) GetAssets(ctx *gin.Context) {
|
||||
// Build base query using service layer
|
||||
db, err := assetService.BuildQuery(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ func (c *Controller) GetAssets(ctx *gin.Context) {
|
||||
db, err = assetService.FilterByParentId(db, cast.ToInt(q))
|
||||
if err != nil {
|
||||
logger.L().Error("parent id filtering failed", zap.Error(err))
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -132,7 +133,7 @@ func (c *Controller) GetAssets(ctx *gin.Context) {
|
||||
if !acl.IsAdmin(currentUser) {
|
||||
ids, err := GetAssetIdsByAuthorization(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
db = db.Where("id IN ?", ids)
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
gsession "github.com/veops/oneterm/internal/session"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
myErrors "github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
// UpsertAuthorization godoc
|
||||
@@ -26,12 +27,12 @@ func (c *Controller) UpsertAuthorization(ctx *gin.Context) {
|
||||
auth := &model.Authorization{}
|
||||
err := ctx.ShouldBindBodyWithJSON(auth)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if !service.DefaultAuthService.HasPermAuthorization(ctx, auth, acl.GRANT) {
|
||||
err = &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}}
|
||||
err = &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}}
|
||||
ctx.AbortWithError(http.StatusForbidden, err)
|
||||
return
|
||||
}
|
||||
@@ -42,7 +43,7 @@ func (c *Controller) UpsertAuthorization(ctx *gin.Context) {
|
||||
if ctx.IsAborted() {
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -66,21 +67,21 @@ func (c *Controller) DeleteAuthorization(ctx *gin.Context) {
|
||||
auth, err := service.DefaultAuthService.GetAuthorizationById(ctx, authId)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
} else {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !service.DefaultAuthService.HasPermAuthorization(ctx, auth, acl.GRANT) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
return
|
||||
}
|
||||
|
||||
// Delete authorization
|
||||
if err := service.DefaultAuthService.DeleteAuthorization(ctx, auth); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -113,13 +114,13 @@ func (c *Controller) GetAuthorizations(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if !service.DefaultAuthService.HasPermAuthorization(ctx, auth, acl.GRANT) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
return
|
||||
}
|
||||
|
||||
auths, count, err := service.DefaultAuthService.GetAuthorizations(ctx, nodeId, assetId, accountId)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
myErrors "github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -25,7 +26,7 @@ var (
|
||||
}
|
||||
_, err := regexp.Compile(data.Cmd)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrBadRequest, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrBadRequest, Data: map[string]any{"err": err}})
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -36,12 +37,12 @@ var (
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if assetName != "" {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrHasDepency, Data: map[string]any{"name": assetName}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrHasDepency, Data: map[string]any{"name": assetName}})
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -98,7 +99,7 @@ func (c *Controller) GetCommands(ctx *gin.Context) {
|
||||
|
||||
db, err := commandService.BuildQuery(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/acl"
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
myErrors "github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -26,13 +27,13 @@ var (
|
||||
func (c *Controller) PostConfig(ctx *gin.Context) {
|
||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||
if !acl.IsAdmin(currentUser) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.WRITE}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.WRITE}})
|
||||
return
|
||||
}
|
||||
|
||||
cfg := &model.Config{}
|
||||
if err := ctx.ShouldBindBodyWithJSON(cfg); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -40,7 +41,7 @@ func (c *Controller) PostConfig(ctx *gin.Context) {
|
||||
cfg.UpdaterId = currentUser.GetUid()
|
||||
|
||||
if err := configService.SaveConfig(ctx, cfg); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -56,14 +57,14 @@ func (c *Controller) PostConfig(ctx *gin.Context) {
|
||||
func (c *Controller) GetConfig(ctx *gin.Context) {
|
||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||
if !cast.ToBool(ctx.Query("info")) && !acl.IsAdmin(currentUser) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.READ}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.READ}})
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := configService.GetConfig(ctx)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@@ -37,6 +37,7 @@ import (
|
||||
gsession "github.com/veops/oneterm/internal/session"
|
||||
"github.com/veops/oneterm/internal/tunneling"
|
||||
dbpkg "github.com/veops/oneterm/pkg/db"
|
||||
myErrors "github.com/veops/oneterm/pkg/errors"
|
||||
"github.com/veops/oneterm/pkg/logger"
|
||||
)
|
||||
|
||||
@@ -163,7 +164,7 @@ func HandleTerm(sess *gsession.Session) (err error) {
|
||||
return
|
||||
case <-sess.IdleTk.C:
|
||||
writeErrMsg(sess, "idle timeout\n\n")
|
||||
return &ApiError{Code: ErrIdleTimeout, Data: map[string]any{"second": model.GlobalConfig.Load().Timeout}}
|
||||
return &myErrors.ApiError{Code: myErrors.ErrIdleTimeout, Data: map[string]any{"second": model.GlobalConfig.Load().Timeout}}
|
||||
case <-tk1m.C:
|
||||
if dbpkg.DB.Model(asset).Where("id = ?", sess.AssetId).First(asset).Error != nil {
|
||||
continue
|
||||
@@ -171,11 +172,11 @@ func HandleTerm(sess *gsession.Session) (err error) {
|
||||
if checkTime(asset.AccessAuth) && (sess.ShareId == 0 || time.Now().Before(sess.ShareEnd)) {
|
||||
continue
|
||||
}
|
||||
return &ApiError{Code: ErrAccessTime}
|
||||
return &myErrors.ApiError{Code: myErrors.ErrAccessTime}
|
||||
case closeBy := <-chs.CloseChan:
|
||||
writeErrMsg(sess, "closed by admin\n\n")
|
||||
logger.L().Info("closed by", zap.String("admin", closeBy))
|
||||
return &ApiError{Code: ErrAdminClose, Data: map[string]any{"admin": closeBy}}
|
||||
return &myErrors.ApiError{Code: myErrors.ErrAdminClose, Data: map[string]any{"admin": closeBy}}
|
||||
case err = <-chs.ErrChan:
|
||||
writeErrMsg(sess, err.Error())
|
||||
return
|
||||
@@ -257,7 +258,7 @@ func handleGuacd(sess *gsession.Session) (err error) {
|
||||
case <-sess.Gctx.Done():
|
||||
return nil
|
||||
case <-sess.IdleTk.C:
|
||||
return &ApiError{Code: ErrIdleTimeout, Data: map[string]any{"second": model.GlobalConfig.Load().Timeout}}
|
||||
return &myErrors.ApiError{Code: myErrors.ErrIdleTimeout, Data: map[string]any{"second": model.GlobalConfig.Load().Timeout}}
|
||||
case <-tk.C:
|
||||
if dbpkg.DB.Model(asset).Where("id = ?", sess.AssetId).First(asset).Error != nil {
|
||||
continue
|
||||
@@ -265,9 +266,9 @@ func handleGuacd(sess *gsession.Session) (err error) {
|
||||
if checkTime(asset.AccessAuth) && (sess.ShareId == 0 || time.Now().Before(sess.ShareEnd)) {
|
||||
continue
|
||||
}
|
||||
return &ApiError{Code: ErrAccessTime}
|
||||
return &myErrors.ApiError{Code: myErrors.ErrAccessTime}
|
||||
case closeBy := <-chs.CloseChan:
|
||||
return &ApiError{Code: ErrAdminClose, Data: map[string]any{"admin": closeBy}}
|
||||
return &myErrors.ApiError{Code: myErrors.ErrAdminClose, Data: map[string]any{"admin": closeBy}}
|
||||
case err := <-chs.ErrChan:
|
||||
return err
|
||||
case out := <-chs.OutChan:
|
||||
@@ -350,11 +351,11 @@ func DoConnect(ctx *gin.Context, ws *websocket.Conn) (sess *gsession.Session, er
|
||||
}
|
||||
|
||||
if !checkTime(asset.AccessAuth) {
|
||||
err = &ApiError{Code: ErrAccessTime}
|
||||
err = &myErrors.ApiError{Code: myErrors.ErrAccessTime}
|
||||
return
|
||||
}
|
||||
if !hasAuthorization(ctx, sess) {
|
||||
err = &ApiError{Code: ErrUnauthorized}
|
||||
err = &myErrors.ApiError{Code: myErrors.ErrUnauthorized}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -371,7 +372,7 @@ func DoConnect(ctx *gin.Context, ws *websocket.Conn) (sess *gsession.Session, er
|
||||
|
||||
if err = <-sess.Chans.ErrChan; err != nil {
|
||||
logger.L().Error("failed to connect", zap.Error(err))
|
||||
err = &ApiError{Code: ErrConnectServer, Data: map[string]any{"err": err}}
|
||||
err = &myErrors.ApiError{Code: myErrors.ErrConnectServer, Data: map[string]any{"err": err}}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -754,12 +755,12 @@ func (c *Controller) ConnectMonitor(ctx *gin.Context) {
|
||||
}()
|
||||
|
||||
if !acl.IsAdmin(currentUser) {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": "monitor session"}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": "monitor session"}})
|
||||
return
|
||||
}
|
||||
|
||||
if sess = gsession.GetOnlineSessionById(sessionId); sess == nil {
|
||||
err = &ApiError{Code: ErrInvalidSessionId, Data: map[string]any{"sessionId": sessionId}}
|
||||
err = &myErrors.ApiError{Code: myErrors.ErrInvalidSessionId, Data: map[string]any{"sessionId": sessionId}}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -860,7 +861,7 @@ func monitGuacd(ctx *gin.Context, sess *gsession.Session, chs *gsession.SessionC
|
||||
func (c *Controller) ConnectClose(ctx *gin.Context) {
|
||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||
if !acl.IsAdmin(currentUser) {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": "close session"}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": "close session"}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -876,7 +877,7 @@ func (c *Controller) ConnectClose(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": "invalid session id"}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": "invalid session id"}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -961,9 +962,9 @@ func handleError(ctx *gin.Context, sess *gsession.Session, err error, ws *websoc
|
||||
return
|
||||
}
|
||||
logger.L().Debug("", zap.String("session_id", sess.SessionId), zap.Error(err))
|
||||
ae, ok := err.(*ApiError)
|
||||
ae, ok := err.(*myErrors.ApiError)
|
||||
if sess.IsGuacd() {
|
||||
ws.WriteMessage(websocket.TextMessage, guacd.NewInstruction("error", lo.Ternary(ok, (ae).MessageBase64(ctx), err.Error()), cast.ToString(ErrAdminClose)).Bytes())
|
||||
ws.WriteMessage(websocket.TextMessage, guacd.NewInstruction("error", lo.Ternary(ok, (ae).MessageBase64(ctx), err.Error()), cast.ToString(myErrors.ErrAdminClose)).Bytes())
|
||||
} else {
|
||||
writeErrMsg(sess, lo.Ternary(ok, ae.MessageWithCtx(ctx), err.Error()))
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
@@ -20,6 +19,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/repository"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
dbpkg "github.com/veops/oneterm/pkg/db"
|
||||
myErrors "github.com/veops/oneterm/pkg/errors"
|
||||
"github.com/veops/oneterm/pkg/remote"
|
||||
)
|
||||
|
||||
@@ -66,7 +66,7 @@ func doCreate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
currentUser, _ := acl.GetSessionFromCtx(ctx)
|
||||
|
||||
if err = ctx.ShouldBindBodyWithJSON(md); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -128,10 +128,10 @@ func doCreate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
return
|
||||
}); err != nil {
|
||||
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrDuplicateName, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrDuplicateName, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ func doDelete[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
|
||||
id, err := cast.ToIntE(ctx.Param("id"))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -164,11 +164,11 @@ func doDelete[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
})
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
if needAcl && !hasPerm(ctx, md, resourceType, acl.DELETE) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.DELETE}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.DELETE}})
|
||||
return
|
||||
}
|
||||
for _, dc := range dcs {
|
||||
@@ -212,10 +212,10 @@ func doDelete[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
return
|
||||
}); err != nil {
|
||||
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrDuplicateName, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrDuplicateName, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -235,12 +235,12 @@ func doUpdate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
|
||||
id, err := cast.ToIntE(ctx.Param("id"))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if err = ctx.ShouldBindBodyWithJSON(md); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
md.SetUpdaterId(currentUser.Uid)
|
||||
@@ -261,7 +261,7 @@ func doUpdate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
ctx.JSON(http.StatusOK, defaultHttpResponse)
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
if needAcl {
|
||||
@@ -269,7 +269,7 @@ func doUpdate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
// fmt.Printf("%+v\n", old)
|
||||
// fmt.Printf("%+v\n", md)
|
||||
if !hasPerm(ctx, md, resourceType, acl.WRITE) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.WRITE}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &myErrors.ApiError{Code: myErrors.ErrNoPerm, Data: map[string]any{"perm": acl.WRITE}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -316,10 +316,10 @@ func doUpdate[T model.Model](ctx *gin.Context, needAcl bool, md T, resourceType
|
||||
return
|
||||
}); err != nil {
|
||||
if errors.Is(err, gorm.ErrDuplicatedKey) {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrDuplicateName, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrDuplicateName, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ func doGet[T any](ctx *gin.Context, needAcl bool, dbFind *gorm.DB, resourceType
|
||||
|
||||
if needAcl && !acl.IsAdmin(currentUser) {
|
||||
if dbFind, err = handleAcl[T](ctx, dbFind, resourceType); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -365,7 +365,7 @@ func doGet[T any](ctx *gin.Context, needAcl bool, dbFind *gorm.DB, resourceType
|
||||
Error
|
||||
})
|
||||
if err = eg.Wait(); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -404,76 +404,15 @@ func handleRemoteErr(ctx *gin.Context, err error) {
|
||||
switch e := err.(type) {
|
||||
case *remote.RemoteError:
|
||||
if e.HttpCode == http.StatusBadRequest {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrRemoteClient, Data: e.Resp})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &myErrors.ApiError{Code: myErrors.ErrRemoteClient, Data: e.Resp})
|
||||
return
|
||||
}
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrRemoteServer, Data: e.Resp})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrRemoteServer, Data: e.Resp})
|
||||
default:
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
}
|
||||
}
|
||||
|
||||
func filterSearch(ctx *gin.Context, db *gorm.DB, fields ...string) *gorm.DB {
|
||||
q, ok := ctx.GetQuery("search")
|
||||
if !ok || len(fields) <= 0 {
|
||||
return db
|
||||
}
|
||||
|
||||
d := dbpkg.DB
|
||||
for _, f := range fields {
|
||||
d = d.Or(fmt.Sprintf("%s LIKE ?", f), fmt.Sprintf("%%%s%%", q))
|
||||
}
|
||||
|
||||
db = db.Where(d)
|
||||
|
||||
return db
|
||||
}
|
||||
func filterStartEnd(ctx *gin.Context, db *gorm.DB) (*gorm.DB, error) {
|
||||
if q, ok := ctx.GetQuery("start"); ok {
|
||||
t, err := time.Parse(time.RFC3339, q)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, err)
|
||||
return db, err
|
||||
}
|
||||
db = db.Where("created_at >= ?", t)
|
||||
}
|
||||
if q, ok := ctx.GetQuery("end"); ok {
|
||||
t, err := time.Parse(time.RFC3339, q)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, err)
|
||||
return db, err
|
||||
}
|
||||
db = db.Where("created_at <= ?", t)
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
func filterEqual(ctx *gin.Context, db *gorm.DB, fields ...string) *gorm.DB {
|
||||
for _, f := range fields {
|
||||
if q, ok := ctx.GetQuery(f); ok {
|
||||
db = db.Where(fmt.Sprintf("%s = ?", f), q)
|
||||
}
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
func filterLike(ctx *gin.Context, db *gorm.DB, fields ...string) *gorm.DB {
|
||||
likes := false
|
||||
d := dbpkg.DB
|
||||
for _, f := range fields {
|
||||
if q, ok := ctx.GetQuery(f); ok && q != "" {
|
||||
d = d.Or(fmt.Sprintf("%s LIKE ?", f), fmt.Sprintf("%%%s%%", q))
|
||||
likes = true
|
||||
}
|
||||
}
|
||||
if !likes {
|
||||
return db
|
||||
}
|
||||
db = db.Where(d)
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
func toMap(data any) model.Map[string, any] {
|
||||
bs, _ := json.Marshal(data)
|
||||
res := make(map[string]any)
|
||||
@@ -542,7 +481,7 @@ func handlePermissions[T any](ctx *gin.Context, data []T, resourceTypeName strin
|
||||
case []*model.Node:
|
||||
resId2perms, err = handleSelfChildPerms(ctx, resId2perms)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
case []*model.Asset:
|
||||
@@ -553,7 +492,7 @@ func handlePermissions[T any](ctx *gin.Context, data []T, resourceTypeName strin
|
||||
}
|
||||
nodeResId2perms := lo.SliceToMap(res, func(r *acl.Resource) (int, []string) { return r.ResourceId, r.Permissions })
|
||||
if nodeResId2perms, err = handleSelfChildPerms(ctx, nodeResId2perms); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &myErrors.ApiError{Code: myErrors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
var nodeId2ResId map[int]int
|
||||
|
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
gsession "github.com/veops/oneterm/internal/session"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
"github.com/veops/oneterm/pkg/logger"
|
||||
)
|
||||
|
||||
@@ -85,7 +86,7 @@ func (c *Controller) GetFileHistory(ctx *gin.Context) {
|
||||
// Use global file service
|
||||
histories, count, err := service.DefaultFileService.GetFileHistory(ctx, filters)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -122,14 +123,14 @@ func (c *Controller) FileLS(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if !hasAuthorization(ctx, sess) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &errors.ApiError{Code: errors.ErrNoPerm, Data: map[string]any{}})
|
||||
return
|
||||
}
|
||||
|
||||
// Use global file service
|
||||
info, err := service.DefaultFileService.ReadDir(ctx, sess.Session.AssetId, sess.Session.AccountId, ctx.Query("dir"))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -166,13 +167,13 @@ func (c *Controller) FileMkdir(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if !hasAuthorization(ctx, sess) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &errors.ApiError{Code: errors.ErrNoPerm, Data: map[string]any{}})
|
||||
return
|
||||
}
|
||||
|
||||
// Use global file service
|
||||
if err := service.DefaultFileService.MkdirAll(ctx, sess.Session.AssetId, sess.Session.AccountId, ctx.Query("dir")); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -213,31 +214,31 @@ func (c *Controller) FileUpload(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if !hasAuthorization(ctx, sess) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &errors.ApiError{Code: errors.ErrNoPerm, Data: map[string]any{}})
|
||||
return
|
||||
}
|
||||
|
||||
f, fh, err := ctx.Request.FormFile("file")
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
content, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
// Use global file service
|
||||
rf, err := service.DefaultFileService.Create(ctx, sess.Session.AssetId, sess.Session.AccountId, filepath.Join(ctx.Query("dir"), fh.Filename))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = rf.Write(content); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -281,14 +282,14 @@ func (c *Controller) FileDownload(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if !hasAuthorization(ctx, sess) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &errors.ApiError{Code: errors.ErrNoPerm, Data: map[string]any{}})
|
||||
return
|
||||
}
|
||||
|
||||
// Use global file service
|
||||
rf, err := service.DefaultFileService.Open(ctx, sess.Session.AssetId, sess.Session.AccountId, filepath.Join(ctx.Query("dir"), ctx.Query("filename")))
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -296,7 +297,7 @@ func (c *Controller) FileDownload(ctx *gin.Context) {
|
||||
|
||||
content, err := io.ReadAll(rf)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -20,7 +21,7 @@ var (
|
||||
// Validate public key
|
||||
func(ctx *gin.Context, data *model.Gateway) {
|
||||
if err := gatewayService.ValidatePublicKey(data); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrWrongPk, Data: nil})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrWrongPk, Data: nil})
|
||||
return
|
||||
}
|
||||
},
|
||||
@@ -51,7 +52,7 @@ var (
|
||||
return
|
||||
}
|
||||
code := lo.Ternary(err == nil, http.StatusBadRequest, http.StatusInternalServerError)
|
||||
err = lo.Ternary[error](err == nil, &ApiError{Code: ErrHasDepency, Data: map[string]any{"name": assetName}}, err)
|
||||
err = lo.Ternary[error](err == nil, &errors.ApiError{Code: errors.ErrHasDepency, Data: map[string]any{"name": assetName}}, err)
|
||||
ctx.AbortWithError(code, err)
|
||||
},
|
||||
}
|
||||
@@ -112,7 +113,7 @@ func (c *Controller) GetGateways(ctx *gin.Context) {
|
||||
if info && !acl.IsAdmin(currentUser) {
|
||||
assetIds, err := GetAssetIdsByAuthorization(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -30,7 +31,7 @@ var (
|
||||
func (c *Controller) GetHistories(ctx *gin.Context) {
|
||||
db, err := historyService.BuildQuery(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -45,7 +46,7 @@ func (c *Controller) GetHistories(ctx *gin.Context) {
|
||||
func (c *Controller) GetHistoryTypeMapping(ctx *gin.Context) {
|
||||
mapping, err := historyService.GetTypeMapping(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/repository"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/config"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,7 +32,7 @@ var (
|
||||
// @Router /node [post]
|
||||
func (c *Controller) CreateNode(ctx *gin.Context) {
|
||||
if err := nodeService.ClearCache(ctx); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
doCreate(ctx, true, &model.Node{}, config.RESOURCE_NODE)
|
||||
@@ -45,7 +46,7 @@ func (c *Controller) CreateNode(ctx *gin.Context) {
|
||||
// @Router /node/:id [delete]
|
||||
func (c *Controller) DeleteNode(ctx *gin.Context) {
|
||||
if err := nodeService.ClearCache(ctx); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
doDelete(ctx, true, &model.Node{}, config.RESOURCE_NODE, nodeDcs...)
|
||||
@@ -60,7 +61,7 @@ func (c *Controller) DeleteNode(ctx *gin.Context) {
|
||||
// @Router /node/:id [put]
|
||||
func (c *Controller) UpdateNode(ctx *gin.Context) {
|
||||
if err := nodeService.ClearCache(ctx); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
doUpdate(ctx, true, &model.Node{}, config.RESOURCE_NODE, nodePreHooks...)
|
||||
@@ -85,7 +86,7 @@ func (c *Controller) GetNodes(ctx *gin.Context) {
|
||||
|
||||
db, err := nodeService.BuildQuery(ctx, currentUser, info)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -94,7 +95,7 @@ func (c *Controller) GetNodes(ctx *gin.Context) {
|
||||
|
||||
func nodePreHookCheckCycle(ctx *gin.Context, data *model.Node) {
|
||||
if err := nodeService.CheckCycle(ctx, data, cast.ToInt(ctx.Param("id"))); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,12 +114,12 @@ func nodePostHookHasChild(ctx *gin.Context, data []*model.Node) {
|
||||
func nodeDelHook(ctx *gin.Context, id int) {
|
||||
assetName, err := nodeService.CheckDependencies(ctx, id)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if assetName != "" {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrHasDepency, Data: map[string]any{"name": assetName}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrHasDepency, Data: map[string]any{"name": assetName}})
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -15,7 +16,7 @@ var (
|
||||
publicKeyPreHooks = []preHook[*model.PublicKey]{
|
||||
func(ctx *gin.Context, data *model.PublicKey) {
|
||||
if err := publicKeyService.ValidatePublicKey(data); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrWrongPk, Data: nil})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrWrongPk, Data: nil})
|
||||
}
|
||||
},
|
||||
func(ctx *gin.Context, data *model.PublicKey) {
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -16,7 +17,6 @@ var (
|
||||
sessionPostHooks = []postHook[*model.Session]{
|
||||
func(ctx *gin.Context, data []*model.Session) {
|
||||
if err := sessionService.AttachCmdCounts(ctx, data); err != nil {
|
||||
// Error already logged in service
|
||||
}
|
||||
},
|
||||
func(ctx *gin.Context, data []*model.Session) {
|
||||
@@ -34,12 +34,12 @@ var (
|
||||
func (c *Controller) CreateSessionCmd(ctx *gin.Context) {
|
||||
data := &model.SessionCmd{}
|
||||
if err := ctx.BindJSON(data); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if err := sessionService.CreateSessionCmd(ctx, data); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func (c *Controller) CreateSessionCmd(ctx *gin.Context) {
|
||||
func (c *Controller) GetSessions(ctx *gin.Context) {
|
||||
db, err := sessionService.BuildQuery(ctx)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -123,13 +123,13 @@ func (c *Controller) GetSessionOptionClientIp(ctx *gin.Context) {
|
||||
func (c *Controller) CreateSessionReplay(ctx *gin.Context) {
|
||||
file, _, err := ctx.Request.FormFile("replay.cast")
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
sessionId := ctx.Param("session_id")
|
||||
if err := sessionService.CreateSessionReplay(ctx, sessionId, file); err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ func (c *Controller) GetSessionReplay(ctx *gin.Context) {
|
||||
|
||||
filename, err := sessionService.GetSessionReplayFilename(ctx, sessionId)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/veops/oneterm/internal/acl"
|
||||
"github.com/veops/oneterm/internal/model"
|
||||
"github.com/veops/oneterm/internal/service"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -26,13 +27,13 @@ func (c *Controller) CreateShare(ctx *gin.Context) {
|
||||
shares := make([]*model.Share, 0)
|
||||
|
||||
if err := ctx.ShouldBindBodyWithJSON(&shares); err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range shares {
|
||||
if !shareService.HasPermission(ctx, s, acl.GRANT) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &errors.ApiError{Code: errors.ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
return
|
||||
}
|
||||
s.CreatorId = currentUser.GetUid()
|
||||
@@ -41,7 +42,7 @@ func (c *Controller) CreateShare(ctx *gin.Context) {
|
||||
|
||||
uuids, err := shareService.CreateShares(ctx, shares)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -58,12 +59,12 @@ func (c *Controller) DeleteShare(ctx *gin.Context) {
|
||||
id := cast.ToInt(ctx.Param("id"))
|
||||
share, err := shareService.GetShareByID(ctx, id)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusBadRequest, &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusBadRequest, &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
if !shareService.HasPermission(ctx, share, acl.GRANT) {
|
||||
ctx.AbortWithError(http.StatusForbidden, &ApiError{Code: ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
ctx.AbortWithError(http.StatusForbidden, &errors.ApiError{Code: errors.ErrNoPerm, Data: map[string]any{"perm": acl.GRANT}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ func (c *Controller) GetShare(ctx *gin.Context) {
|
||||
|
||||
db, err := shareService.BuildQuery(ctx, isAdmin)
|
||||
if err != nil {
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &ApiError{Code: ErrInternal, Data: map[string]any{"err": err}})
|
||||
ctx.AbortWithError(http.StatusInternalServerError, &errors.ApiError{Code: errors.ErrInternal, Data: map[string]any{"err": err}})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -108,7 +109,7 @@ func (c *Controller) ConnectShare(ctx *gin.Context) {
|
||||
uuid := ctx.Param("uuid")
|
||||
share, err := shareService.ValidateShareForConnection(ctx, uuid)
|
||||
if err != nil {
|
||||
ctx.Set("shareErr", &ApiError{Code: ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
ctx.Set("shareErr", &errors.ApiError{Code: errors.ErrInvalidArgument, Data: map[string]any{"err": err}})
|
||||
}
|
||||
|
||||
shareService.SetupConnectionParams(ctx, share)
|
||||
|
@@ -7,12 +7,12 @@ import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/veops/oneterm/internal/acl"
|
||||
"github.com/veops/oneterm/internal/api/controller"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
"github.com/veops/oneterm/pkg/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnauthorized = &controller.ApiError{Code: controller.ErrUnauthorized}
|
||||
errUnauthorized = &errors.ApiError{Code: errors.ErrUnauthorized}
|
||||
)
|
||||
|
||||
func AuthMiddleware() gin.HandlerFunc {
|
||||
|
@@ -8,8 +8,8 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
|
||||
"github.com/veops/oneterm/internal/api/controller"
|
||||
myi18n "github.com/veops/oneterm/internal/i18n"
|
||||
"github.com/veops/oneterm/pkg/errors"
|
||||
)
|
||||
|
||||
type bodyWriter struct {
|
||||
@@ -47,7 +47,7 @@ func Error2RespMiddleware() gin.HandlerFunc {
|
||||
e := ctx.Errors.Last().Err
|
||||
obj["message"] = e.Error()
|
||||
|
||||
ae, ok := e.(*controller.ApiError)
|
||||
ae, ok := e.(*errors.ApiError)
|
||||
if ok {
|
||||
lang := ctx.PostForm("lang")
|
||||
accept := ctx.GetHeader("Accept-Language")
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package controller
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
Reference in New Issue
Block a user