diff --git a/backend/app/api/v1/helper/helper.go b/backend/app/api/v1/helper/helper.go index 2e6f5f984..d6127da44 100644 --- a/backend/app/api/v1/helper/helper.go +++ b/backend/app/api/v1/helper/helper.go @@ -4,6 +4,8 @@ import ( "net/http" "strconv" + "github.com/pkg/errors" + "github.com/1Panel-dev/1Panel/app/dto" "github.com/1Panel-dev/1Panel/constant" "github.com/1Panel-dev/1Panel/i18n" @@ -32,7 +34,23 @@ func GeneratePaginationFromReq(c *gin.Context) (dto.PageInfo, bool) { func ErrorWithDetail(ctx *gin.Context, code int, msgKey string, err error) { res := dto.Response{ Code: code, - Msg: i18n.GetMsgWithMap(msgKey, map[string]interface{}{"detail": err}), + Msg: "", + } + if msgKey == constant.ErrTypeInternalServer { + switch { + case errors.Is(err, constant.ErrRecordExist): + res.Msg = i18n.GetMsgWithMap("ErrRecordExist", map[string]interface{}{"detail": err}) + case errors.Is(constant.ErrRecordNotFound, err): + res.Msg = i18n.GetMsgWithMap("ErrRecordNotFound", map[string]interface{}{"detail": err}) + case errors.Is(constant.ErrStructTransform, err): + res.Msg = i18n.GetMsgWithMap("ErrStructTransform", map[string]interface{}{"detail": err}) + case errors.Is(constant.ErrCaptchaCode, err): + res.Msg = i18n.GetMsgWithMap("ErrCaptchaCode", map[string]interface{}{"detail": err}) + default: + res.Msg = i18n.GetMsgWithMap(msgKey, map[string]interface{}{"detail": err}) + } + } else { + res.Msg = i18n.GetMsgWithMap(msgKey, map[string]interface{}{"detail": err}) } ctx.JSON(http.StatusOK, res) ctx.Abort() diff --git a/backend/app/api/v1/user.go b/backend/app/api/v1/user.go index 07f7046a9..a680e07b4 100644 --- a/backend/app/api/v1/user.go +++ b/backend/app/api/v1/user.go @@ -1,7 +1,7 @@ package v1 import ( - "errors" + "github.com/pkg/errors" "github.com/1Panel-dev/1Panel/app/api/v1/helper" "github.com/1Panel-dev/1Panel/app/dto" @@ -16,15 +16,15 @@ type BaseApi struct{} func (b *BaseApi) Login(c *gin.Context) { var req dto.Login if err := c.ShouldBindJSON(&req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqBody, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } if err := global.VALID.Struct(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamValid, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } if err := captcha.VerifyCode(req.CaptchaID, req.Captcha); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqBody, errors.New("captcha code error")) + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } @@ -47,11 +47,11 @@ func (b *BaseApi) Captcha(c *gin.Context) { func (b *BaseApi) Register(c *gin.Context) { var req dto.UserCreate if err := c.ShouldBindJSON(&req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqBody, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } if err := global.VALID.Struct(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamValid, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } if err := userService.Register(req); err != nil { @@ -64,7 +64,7 @@ func (b *BaseApi) Register(c *gin.Context) { func (b *BaseApi) GetUserList(c *gin.Context) { pagenation, isOK := helper.GeneratePaginationFromReq(c) if !isOK { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqQuery, constant.ErrPageParam) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, constant.ErrPageGenerate) return } @@ -83,11 +83,11 @@ func (b *BaseApi) GetUserList(c *gin.Context) { func (b *BaseApi) DeleteUser(c *gin.Context) { var req dto.OperationWithName if err := c.ShouldBindJSON(&req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqBody, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } if err := global.VALID.Struct(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamValid, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } @@ -101,11 +101,11 @@ func (b *BaseApi) DeleteUser(c *gin.Context) { func (b *BaseApi) UpdateUser(c *gin.Context) { var req dto.UserUpdate if err := c.ShouldBindJSON(&req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqBody, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } if err := global.VALID.Struct(req); err != nil { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamValid, err) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } @@ -121,7 +121,7 @@ func (b *BaseApi) UpdateUser(c *gin.Context) { func (b *BaseApi) GetUserInfo(c *gin.Context) { name, ok := c.Params.Get("name") if !ok { - helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeParamInReqQuery, errors.New("error name")) + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name")) return } diff --git a/backend/app/dto/user.go b/backend/app/dto/user.go index 53a8953c1..bf1ad0e69 100644 --- a/backend/app/dto/user.go +++ b/backend/app/dto/user.go @@ -6,7 +6,7 @@ import ( type UserCreate struct { Name string `json:"name" validate:"name,required"` - Password string `json:"password" validate:"password,required"` + Password string `json:"password" validate:"required"` Email string `json:"email" validate:"required,email"` } diff --git a/backend/app/service/user.go b/backend/app/service/user.go index 31a300951..299ad7e5b 100644 --- a/backend/app/service/user.go +++ b/backend/app/service/user.go @@ -1,7 +1,7 @@ package service import ( - "errors" + "github.com/pkg/errors" "github.com/1Panel-dev/1Panel/app/dto" "github.com/1Panel-dev/1Panel/app/model" @@ -11,8 +11,6 @@ import ( "github.com/1Panel-dev/1Panel/utils/jwt" "github.com/gin-gonic/gin" "github.com/jinzhu/copier" - - "gorm.io/gorm" ) type UserService struct{} @@ -38,7 +36,7 @@ func (u *UserService) Get(name string) (*dto.UserBack, error) { } var dtoUser dto.UserBack if err := copier.Copy(&dtoUser, &user); err != nil { - return nil, constant.ErrCopyTransform + return nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) } return &dtoUser, err } @@ -49,7 +47,7 @@ func (u *UserService) Page(page, size int) (int64, interface{}, error) { for _, user := range users { var item dto.UserBack if err := copier.Copy(&item, &user); err != nil { - return 0, nil, constant.ErrCopyTransform + return 0, nil, errors.WithMessage(constant.ErrStructTransform, err.Error()) } dtoUsers = append(dtoUsers, item) } @@ -59,10 +57,11 @@ func (u *UserService) Page(page, size int) (int64, interface{}, error) { func (u *UserService) Register(userDto dto.UserCreate) error { var user model.User if err := copier.Copy(&user, &userDto); err != nil { - return constant.ErrCopyTransform + return errors.WithMessage(constant.ErrStructTransform, err.Error()) } - if !errors.Is(global.DB.Where("name = ?", user.Name).First(&user).Error, gorm.ErrRecordNotFound) { - return constant.ErrRecordExist + _ = global.DB.Where("name = ?", user.Name).First(&user).Error + if user.ID != 0 { + return errors.Wrap(constant.ErrRecordExist, "data exist") } return userRepo.Create(&user) } @@ -70,7 +69,7 @@ func (u *UserService) Register(userDto dto.UserCreate) error { func (u *UserService) Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error) { user, err := userRepo.Get(commonRepo.WithByName(info.Name)) if err != nil { - return nil, err + return nil, errors.WithMessage(constant.ErrRecordNotFound, err.Error()) } pass, err := encrypt.StringDecrypt(user.Password) if err != nil { diff --git a/backend/constant/errs.go b/backend/constant/errs.go index a19401fc2..3163f92f8 100644 --- a/backend/constant/errs.go +++ b/backend/constant/errs.go @@ -14,24 +14,22 @@ const ( CodeErrHeader = 406 ) +// internal var ( - ErrTypeToken = "ErrToken" - ErrTypeTokenExpired = "ErrTokenExpired" + ErrCaptchaCode = errors.New("ErrCaptchaCode") + ErrRecordExist = errors.New("ErrRecordExist") + ErrRecordNotFound = errors.New("ErrRecordNotFound") + ErrStructTransform = errors.New("ErrStructTransform") - ErrTypeParamInReqBody = "ErrParamInReqBody" - ErrTypeParamInReqQuery = "ErrParamInReqQuery" - ErrTypeInternalServer = "ErrInternalServer" - ErrTypeParamValid = "ErrParamValid" + ErrTokenParse = errors.New("ErrTokenParse") + + ErrPageGenerate = errors.New("generate page info failed") ) +// api var ( - ErrTokenExpired = errors.New("token is expired") - ErrTokenNotValidYet = errors.New("token not active yet") - ErrTokenMalformed = errors.New("that's not even a token") - ErrTokenInvalid = errors.New("couldn't handle this token") - - ErrCaptchaCode = errors.New("captcha code error") - ErrPageParam = errors.New("paging parameter error") - ErrRecordExist = errors.New("record already exists") - ErrCopyTransform = errors.New("type conversion failure") + ErrTypeInternalServer = "ErrInternalServer" + ErrTypeInvalidParams = "ErrInvalidParams" + ErrTypeToken = "ErrToken" + ErrTypeTokenTimeOut = "ErrTokenTimeOut" ) diff --git a/backend/go.mod b/backend/go.mod index b999f1313..192162262 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -16,7 +16,6 @@ require ( github.com/mojocn/base64Captcha v1.3.5 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/nicksnyder/go-i18n/v2 v2.1.2 - github.com/pelletier/go-toml/v2 v2.0.2 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/viper v1.12.0 @@ -24,6 +23,7 @@ require ( github.com/swaggo/gin-swagger v1.5.1 github.com/swaggo/swag v1.8.4 golang.org/x/text v0.3.7 + gopkg.in/yaml.v2 v2.4.0 gorm.io/driver/mysql v1.3.5 gorm.io/driver/sqlite v1.3.6 gorm.io/gorm v1.23.8 @@ -57,6 +57,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.2 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -71,6 +72,5 @@ require ( google.golang.org/protobuf v1.28.0 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/backend/i18n/i18n.go b/backend/i18n/i18n.go index bb8eb02ed..5dad5ee98 100644 --- a/backend/i18n/i18n.go +++ b/backend/i18n/i18n.go @@ -6,8 +6,8 @@ import ( ginI18n "github.com/gin-contrib/i18n" "github.com/gin-gonic/gin" "github.com/nicksnyder/go-i18n/v2/i18n" - "github.com/pelletier/go-toml/v2" "golang.org/x/text/language" + "gopkg.in/yaml.v2" ) func GetMsg(msg string) string { @@ -40,8 +40,8 @@ func GinI18nLocalize() gin.HandlerFunc { RootPath: "./lang", AcceptLanguage: []language.Tag{language.Chinese, language.English}, DefaultLanguage: language.Chinese, - FormatBundleFile: "toml", - UnmarshalFunc: toml.Unmarshal, + FormatBundleFile: "yaml", + UnmarshalFunc: yaml.Unmarshal, Loader: &ginI18n.EmbedLoader{FS: fs}, }), ginI18n.WithGetLngHandle( diff --git a/backend/i18n/lang/en.toml b/backend/i18n/lang/en.toml deleted file mode 100644 index 325674de2..000000000 --- a/backend/i18n/lang/en.toml +++ /dev/null @@ -1,3 +0,0 @@ -#common -InvalidParams = "parameter validation error {.detail}" -JwtNotFound = "" \ No newline at end of file diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml new file mode 100644 index 000000000..74af8728f --- /dev/null +++ b/backend/i18n/lang/en.yaml @@ -0,0 +1,9 @@ +ErrInvalidParams: "Request parameter error: {{ .detail }}" +ErrToken: "Token information is incorrect.: {{ .detail }}" +ErrTokenParse: "Token generation error: {{ .detail }}" +ErrTokenTimeOut: "Login information is out of date: {{ .detail }}" +ErrCaptchaCode: "The verification code information is incorrect" +ErrInternalServer: "Service internal error: {{ .detail }}" +ErrRecordExist: "Record already exists: {{ .detail }}" +ErrRecordNotFound: "Records not found: {{ .detail }}" +ErrStructTransform: "Type conversion failure: {{ .detail }}" \ No newline at end of file diff --git a/backend/i18n/lang/zh.toml b/backend/i18n/lang/zh.toml deleted file mode 100644 index 226581582..000000000 --- a/backend/i18n/lang/zh.toml +++ /dev/null @@ -1,8 +0,0 @@ -#common -ErrInvalidParams = "请求参数错误: {.detail}" -ErrTokenTimeOut = "登陆信息已过期: {.detail}" -ErrCaptchaCode = "错误的验证码信息" -ErrRecordExist = "记录已存在: {.detail}" -ErrRecordNotFound = "记录未能找到: {.detail}" -ErrStructTransform = "类型转换失败: {.detail}" -ErrInternalServer = "服务内部错误: {.detail}" \ No newline at end of file diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml new file mode 100644 index 000000000..ff4c042cb --- /dev/null +++ b/backend/i18n/lang/zh.yaml @@ -0,0 +1,9 @@ +ErrInvalidParams: "请求参数错误: {{ .detail }}" +ErrToken: "Token 信息错误: {{ .detail }}" +ErrTokenParse: "Token 生成错误: {{ .detail }}" +ErrTokenTimeOut: "登陆信息已过期: {{ .detail }}" +ErrCaptchaCode: "错误的验证码信息" +ErrInternalServer: "服务内部错误: {{ .detail }}" +ErrRecordExist: "记录已存在: {{ .detail }}" +ErrRecordNotFound: "记录未能找到: {{ .detail }}" +ErrStructTransform: "类型转换失败: {{ .detail }}" \ No newline at end of file diff --git a/backend/middleware/jwt.go b/backend/middleware/jwt.go index 7b83fc498..c3f564d7d 100644 --- a/backend/middleware/jwt.go +++ b/backend/middleware/jwt.go @@ -23,7 +23,7 @@ func JwtAuth() gin.HandlerFunc { j := jwtUtils.NewJWT() claims, err := j.ParseToken(token) if err != nil { - helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeToken, err) + helper.ErrorWithDetail(c, constant.CodeErrUnauthorized, constant.ErrTypeInternalServer, err) return } if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime { diff --git a/backend/utils/jwt/jwt.go b/backend/utils/jwt/jwt.go index 896cb7aea..c494867a4 100644 --- a/backend/utils/jwt/jwt.go +++ b/backend/utils/jwt/jwt.go @@ -62,24 +62,11 @@ func (j *JWT) ParseToken(tokenStr string) (*JwtRequest, error) { token, err := jwt.ParseWithClaims(tokenStr, &JwtRequest{}, func(token *jwt.Token) (interface{}, error) { return j.SigningKey, nil }) - if err != nil { - if ve, ok := err.(*jwt.ValidationError); ok { - if ve.Errors&jwt.ValidationErrorMalformed != 0 { - return nil, constant.ErrTokenMalformed - } else if ve.Errors&jwt.ValidationErrorExpired != 0 { - return nil, constant.ErrTokenExpired - } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { - return nil, constant.ErrTokenNotValidYet - } else { - return nil, constant.ErrTokenInvalid - } - } - } - if token == nil { - return nil, constant.ErrTokenInvalid + if err != nil || token == nil { + return nil, constant.ErrTokenParse } if claims, ok := token.Claims.(*JwtRequest); ok && token.Valid { return claims, nil } - return nil, constant.ErrTokenInvalid + return nil, constant.ErrTokenParse }