feat: add validate for user signup

This commit is contained in:
Muyao CHEN 2024-10-06 21:54:29 +02:00
parent 344485d082
commit ba8570857d
6 changed files with 31 additions and 12 deletions

View File

@ -93,7 +93,7 @@ components:
properties: properties:
code: code:
type: string type: string
example: FailedOperation.UserAlreadyExists example: FailedOperation.UserExisted
message: message:
type: string type: string
example: "User already exists." example: "Email already existed."

1
go.mod
View File

@ -3,6 +3,7 @@ module git.vinchent.xyz/vinchent/howmuch
go 1.23.1 go 1.23.1
require ( require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0
github.com/gin-contrib/cors v1.7.2 github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=

View File

@ -29,6 +29,7 @@ import (
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/usecase" "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/usecase"
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/core" "git.vinchent.xyz/vinchent/howmuch/internal/pkg/core"
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno" "git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno"
"github.com/asaskevich/govalidator"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -66,9 +67,15 @@ func (uc *UserController) Signup(ctx core.Context) {
return return
} }
// TODO: check params validity (govalidator) _, err := govalidator.ValidateStruct(params)
if err != nil {
errno := UserParamsErr
errno.Message = err.Error()
core.WriteResponse(ctx, errno, nil)
return
}
_, err := uc.userUsecase.Create(ctx, &params) _, err = uc.userUsecase.Create(ctx, &params)
if err != nil { if err != nil {
core.WriteResponse(ctx, err, nil) core.WriteResponse(ctx, err, nil)
return return

View File

@ -27,10 +27,10 @@ import "time"
// User model // User model
type User struct { type User struct {
ID int `json:"id"` ID int `json:"id"`
Email string `json:"email"` Email string `json:"email" valid:"email"`
FirstName string `json:"first_name"` FirstName string `json:"first_name" valid:"required"`
LastName string `json:"last_name"` LastName string `json:"last_name" valid:"required"`
Password string `json:"password"` Password string `json:"password" valid:"required"`
CreatedAt time.Time `json:"created_at"` CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"` UpdatedAt time.Time `json:"updated_at"`
} }

View File

@ -25,12 +25,21 @@ package usecase
import ( import (
"context" "context"
"fmt" "fmt"
"net/http"
"regexp"
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model" "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/model"
"git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo" "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/repo"
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno"
"git.vinchent.xyz/vinchent/howmuch/internal/pkg/log" "git.vinchent.xyz/vinchent/howmuch/internal/pkg/log"
) )
var UserExisted = &errno.Errno{
HTTP: http.StatusBadRequest,
Code: errno.ErrorCode(errno.FailedOperationCode, "UserExisted"),
Message: "email already existed.",
}
type userUsecase struct { type userUsecase struct {
userRepo repo.UserRepository userRepo repo.UserRepository
dbRepo repo.DBRepository dbRepo repo.DBRepository
@ -51,12 +60,12 @@ func (uuc *userUsecase) Create(ctx context.Context, u *model.User) (*model.User,
data, err := uuc.dbRepo.Transaction( data, err := uuc.dbRepo.Transaction(
ctx, ctx,
func(txCtx context.Context, tx interface{}) (interface{}, error) { func(txCtx context.Context, tx interface{}) (interface{}, error) {
// TODO: should check if the user exists
// DB will return an error since we have set email to UNIQUE.
// But we may not want to expose the exact db error.
u, err := uuc.userRepo.Create(txCtx, tx, u) u, err := uuc.userRepo.Create(txCtx, tx, u)
if err != nil { if err != nil {
match, _ := regexp.MatchString("SQLSTATE 23505", err.Error())
if match {
return nil, UserExisted
}
return nil, err return nil, err
} }