diff --git a/cache/cache.go b/cache/cache.go index 4d694e2..63a2ba1 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -54,3 +54,14 @@ func GetValueByKey(key string) ([]byte, error) { ctx := context.Background() return c.Get(ctx, key).Bytes() } + +func GetJSON(key string, result interface{}) bool { + v, err := GetValueByKey(key) + if err != nil { + return false + } + if err = json.Unmarshal(v, result); err != nil { + return false + } + return true +} diff --git a/cache/key.go b/cache/key.go new file mode 100644 index 0000000..8e92ca2 --- /dev/null +++ b/cache/key.go @@ -0,0 +1,9 @@ +package cache + +const ( + keyPrefix = "usermngmt_" +) + +const ( + KeyLoginFailedTimes = keyPrefix + "login_failed_time" +) diff --git a/config/config.go b/config/config.go index e17739b..d207389 100644 --- a/config/config.go +++ b/config/config.go @@ -1,5 +1,12 @@ package config +import "time" + +const ( + MaximumLoginFailedTime = 5 + LoginFailedBlockedDuration = time.Hour +) + type Configuration struct { EmailIsUnique bool PhoneNumberIsUnique bool diff --git a/internal/error.go b/internal/error.go index 0798b4d..ea487da 100644 --- a/internal/error.go +++ b/internal/error.go @@ -28,5 +28,7 @@ const ( // Incorrect - ErrorIncorrectPassword = "mật khẩu không chính xác" + ErrorIncorrectPassword = "mật khẩu không chính xác" + ErrorInvalidLogin = "thông tin đăng nhập không đúng" + ErrorExceedMaximumLoginFail = "bạn đã đăng nhập sai thông tin quá số lần cho phép" ) diff --git a/user/handle.go b/user/handle.go index d4371da..8e86b3e 100644 --- a/user/handle.go +++ b/user/handle.go @@ -578,16 +578,22 @@ func ChangeAllUsersStatus(roleID, status string) error { // LoginWithEmailAndPassword ... func LoginWithEmailAndPassword(email, password string) (result model.User, err error) { var ( - ctx = context.Background() + ctx = context.Background() + numOfLoginFail int ) + k := cache.KeyLoginFailedTimes + email + // process block if reach maximum of login failed + if ok := cache.GetJSON(k, &numOfLoginFail); ok && numOfLoginFail >= config.MaximumLoginFailedTime { + return model.User{}, errors.New(internal.ErrorExceedMaximumLoginFail) + } // Validate email, password if email == "" { - err = errors.New(internal.ErrorInvalidEmail) + err = errors.New(internal.ErrorInvalidLogin) return } if password == "" { - err = errors.New(internal.ErrorInvalidPassword) + err = errors.New(internal.ErrorInvalidLogin) return } @@ -597,13 +603,14 @@ func LoginWithEmailAndPassword(email, password string) (result model.User, err e "deleted": false, }) if user.ID.IsZero() { - err = errors.New(internal.ErrorNotFoundUser) + err = errors.New(internal.ErrorInvalidLogin) return } // Check Password if !internal.CheckPasswordHash(password, user.HashedPassword) { - err = errors.New(internal.ErrorIncorrectPassword) + err = errors.New(internal.ErrorInvalidLogin) + cache.SetKeyValue(k, numOfLoginFail+1, config.LoginFailedBlockedDuration) return }