add update response viError

This commit is contained in:
Hoang 2021-12-07 14:28:52 +07:00
parent 4d4bf4db8f
commit ae971f1556
11 changed files with 157 additions and 91 deletions

2
cache/role.go vendored
View File

@ -3,6 +3,7 @@ package cache
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"log"
"sync" "sync"
"github.com/Selly-Modules/logger" "github.com/Selly-Modules/logger"
@ -46,6 +47,7 @@ func Roles() {
}) })
return return
} }
log.Println("role", entry)
}(value) }(value)
} }

20
config/config.go Normal file
View File

@ -0,0 +1,20 @@
package config
type Configuration struct {
EmailIsUnique bool
PhoneNumberIsUnique bool
}
var (
c *Configuration
)
// Set ...
func Set(instance *Configuration) {
c = instance
}
// GetInstance ...
func GetInstance() *Configuration {
return c
}

32
internal/error.go Normal file
View File

@ -0,0 +1,32 @@
package internal
const (
// Invalid
ErrorInvalidName = "tên không hợp lệ"
ErrorInvalidPhoneNumber = "số điện thoại không hợp lệ"
ErrorInvalidEmail = "email không hợp lệ"
ErrorInvalidPassword = "mật khẩu không hợp lệ"
ErrorInvalidStatus = "trạng thái không hợp lệ"
ErrorInvalidRole = "vai trò không hợp lệ"
ErrorInvalidOldPassword = "mật khẩu cũ không hợp lệ"
ErrorInvalidNewPassword = "mật khẩu mới không hợp lệ"
ErrorInvalidPermission = "quyền không hợp lệ"
ErrorInvalidUser = "người dùng không hợp lệ"
ErrorInvalidAvatar = "ảnh đại diện không hợp lệ"
// NotFound
ErrorNotFoundPermission = "quyền không tồn tại"
ErrorNotFoundRole = "vai trò không tồn tại"
ErrorNotFoundUser = "người dùng không tồn tại"
// AlreadyExisted
ErrorAlreadyExistedPhoneNumber = "số điện thoại đã tồn tại"
ErrorAlreadyExistedEmail = "email đã tồn tại"
// Incorrect
ErrorIncorrectPassword = "mật khẩu không chính xác"
)

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"github.com/Selly-Modules/logger" "github.com/Selly-Modules/logger"
"github.com/Selly-Modules/usermngmt/internal"
) )
// RoleCreateOptions ... // RoleCreateOptions ...
@ -34,7 +35,7 @@ func (co RoleCreateOptions) Validate() error {
logger.Error("usermngmt - Role - Create: no name data", logger.LogData{ logger.Error("usermngmt - Role - Create: no name data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no name data") return errors.New(internal.ErrorInvalidName)
} }
return nil return nil
@ -47,7 +48,7 @@ func (co RoleUpdateOptions) Validate() error {
logger.Error("usermngmt - Role - Update: no name data", logger.LogData{ logger.Error("usermngmt - Role - Update: no name data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no name data") return errors.New(internal.ErrorInvalidName)
} }
return nil return nil

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"github.com/Selly-Modules/logger" "github.com/Selly-Modules/logger"
"github.com/Selly-Modules/usermngmt/internal"
) )
// UserCreateOptions ... // UserCreateOptions ...
@ -58,7 +59,7 @@ func (co UserCreateOptions) Validate() error {
logger.Error("usermngmt - User - Create: no name data", logger.LogData{ logger.Error("usermngmt - User - Create: no name data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no name data") return errors.New(internal.ErrorInvalidName)
} }
// Phone // Phone
@ -66,7 +67,7 @@ func (co UserCreateOptions) Validate() error {
logger.Error("usermngmt - User - Create: no phone data", logger.LogData{ logger.Error("usermngmt - User - Create: no phone data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no phone data") return errors.New(internal.ErrorInvalidPhoneNumber)
} }
// Email // Email
@ -74,7 +75,7 @@ func (co UserCreateOptions) Validate() error {
logger.Error("usermngmt - User - Create: no email data", logger.LogData{ logger.Error("usermngmt - User - Create: no email data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no email data") return errors.New(internal.ErrorInvalidEmail)
} }
// Password // Password
@ -82,7 +83,7 @@ func (co UserCreateOptions) Validate() error {
logger.Error("usermngmt - User - Create: no password data", logger.LogData{ logger.Error("usermngmt - User - Create: no password data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no password data") return errors.New(internal.ErrorInvalidPassword)
} }
// Status // Status
@ -90,7 +91,7 @@ func (co UserCreateOptions) Validate() error {
logger.Error("usermngmt - User - Create: no status data", logger.LogData{ logger.Error("usermngmt - User - Create: no status data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no status data") return errors.New(internal.ErrorInvalidStatus)
} }
// RoleID // RoleID
@ -98,7 +99,7 @@ func (co UserCreateOptions) Validate() error {
logger.Error("usermngmt - User - Create: no roleID data", logger.LogData{ logger.Error("usermngmt - User - Create: no roleID data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("no role id data") return errors.New(internal.ErrorInvalidRole)
} }
return nil return nil
@ -111,7 +112,7 @@ func (uo UserUpdateOptions) Validate() error {
logger.Error("usermngmt - User - Update: no name data", logger.LogData{ logger.Error("usermngmt - User - Update: no name data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no name data") return errors.New(internal.ErrorInvalidName)
} }
// Phone // Phone
@ -119,7 +120,7 @@ func (uo UserUpdateOptions) Validate() error {
logger.Error("usermngmt - User - Update: no phone data", logger.LogData{ logger.Error("usermngmt - User - Update: no phone data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no phone data") return errors.New(internal.ErrorInvalidPhoneNumber)
} }
// Email // Email
@ -127,7 +128,7 @@ func (uo UserUpdateOptions) Validate() error {
logger.Error("usermngmt - User - Update: no email data", logger.LogData{ logger.Error("usermngmt - User - Update: no email data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no email data") return errors.New(internal.ErrorInvalidEmail)
} }
// RoleID // RoleID
@ -135,7 +136,7 @@ func (uo UserUpdateOptions) Validate() error {
logger.Error("usermngmt - User - Update: no roleID data", logger.LogData{ logger.Error("usermngmt - User - Update: no roleID data", logger.LogData{
"payload": uo, "payload": uo,
}) })
return errors.New("no role id data") return errors.New(internal.ErrorInvalidRole)
} }
return nil return nil
@ -144,11 +145,18 @@ func (uo UserUpdateOptions) Validate() error {
// Validate ... // Validate ...
func (co ChangePasswordOptions) Validate() error { func (co ChangePasswordOptions) Validate() error {
// OldPassword, NewPassword // OldPassword, NewPassword
if co.OldPassword == "" || co.NewPassword == "" { if co.OldPassword == "" {
logger.Error("usermngmt - User - ChangePassword: old or new password cannot be empty", logger.LogData{ logger.Error("usermngmt - User - ChangePassword: no old password data", logger.LogData{
"payload": co, "payload": co,
}) })
return errors.New("old or new password cannot be empty") return errors.New(internal.ErrorInvalidOldPassword)
}
if co.NewPassword == "" {
logger.Error("usermngmt - User - ChangePassword: no new password data", logger.LogData{
"payload": co,
})
return errors.New(internal.ErrorInvalidNewPassword)
} }
return nil return nil

View File

@ -63,10 +63,10 @@ func Update(permissionID string, payload model.PermissionUpdateOptions) error {
// Find permissionID exists or not // Find permissionID exists or not
id, isValid := mongodb.NewIDFromString(permissionID) id, isValid := mongodb.NewIDFromString(permissionID)
if !isValid { if !isValid {
return errors.New("invalid permission id data") return errors.New(internal.ErrorInvalidPermission)
} }
if !isPermissionIDExisted(ctx, id) { if !isPermissionIDExisted(ctx, id) {
return errors.New("permission not found") return errors.New(internal.ErrorNotFoundPermission)
} }
// Setup condition // Setup condition
@ -103,10 +103,10 @@ func Delete(permissionID string) error {
// Find permissionID exists or not // Find permissionID exists or not
id, isValid := mongodb.NewIDFromString(permissionID) id, isValid := mongodb.NewIDFromString(permissionID)
if !isValid { if !isValid {
return errors.New("invalid permission id data") return errors.New(internal.ErrorInvalidPermission)
} }
if !isPermissionIDExisted(ctx, id) { if !isPermissionIDExisted(ctx, id) {
return errors.New("permission not found") return errors.New(internal.ErrorNotFoundPermission)
} }
// Delete // Delete

View File

@ -62,12 +62,12 @@ func Update(roleID string, payload model.RoleUpdateOptions) error {
// Validate roleID // Validate roleID
id, isValid := mongodb.NewIDFromString(roleID) id, isValid := mongodb.NewIDFromString(roleID)
if !isValid { if !isValid {
return errors.New("invalid role id data") return errors.New(internal.ErrorInvalidRole)
} }
// Find roleID exists or not // Find roleID exists or not
if !isRoleIDExisted(ctx, id) { if !isRoleIDExisted(ctx, id) {
return errors.New("role not found") return errors.New(internal.ErrorNotFoundRole)
} }
// Setup condition // Setup condition
@ -154,12 +154,12 @@ func FindRole(roleID string) (r model.Role, err error) {
// Find role exists or not // Find role exists or not
id, isValid := mongodb.NewIDFromString(roleID) id, isValid := mongodb.NewIDFromString(roleID)
if !isValid { if !isValid {
err = errors.New("invalid role id data") err = errors.New(internal.ErrorInvalidRole)
return return
} }
role, _ := findByID(ctx, id) role, _ := findByID(ctx, id)
if role.ID.IsZero() { if role.ID.IsZero() {
err = errors.New("role not found") err = errors.New(internal.ErrorNotFoundRole)
return return
} }

View File

@ -12,33 +12,6 @@ import (
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
) )
func isPhoneNumberOrEmailExisted(ctx context.Context, phone, email string) bool {
var (
col = database.GetUserCol()
)
// Find
cond := bson.M{
"deleted": false,
"$or": []bson.M{
{
"phone": phone,
},
{
"email": email,
},
},
}
total, err := col.CountDocuments(ctx, cond)
if err != nil {
logger.Error("usermngmt - User - CountDocuments", logger.LogData{
"condition": cond,
"err": err.Error(),
})
return true
}
return total != 0
}
func isPhoneNumberExisted(ctx context.Context, phone string) bool { func isPhoneNumberExisted(ctx context.Context, phone string) bool {
var ( var (
col = database.GetUserCol() col = database.GetUserCol()

View File

@ -8,6 +8,7 @@ import (
"github.com/Selly-Modules/logger" "github.com/Selly-Modules/logger"
"github.com/Selly-Modules/mongodb" "github.com/Selly-Modules/mongodb"
"github.com/Selly-Modules/usermngmt/cache" "github.com/Selly-Modules/usermngmt/cache"
"github.com/Selly-Modules/usermngmt/config"
"github.com/Selly-Modules/usermngmt/internal" "github.com/Selly-Modules/usermngmt/internal"
"github.com/Selly-Modules/usermngmt/model" "github.com/Selly-Modules/usermngmt/model"
"github.com/thoas/go-funk" "github.com/thoas/go-funk"
@ -29,18 +30,26 @@ func Create(payload model.UserCreateOptions) (result string, err error) {
// Find roleID exists or not // Find roleID exists or not
roleID, isValid := mongodb.NewIDFromString(payload.RoleID) roleID, isValid := mongodb.NewIDFromString(payload.RoleID)
if !isValid { if !isValid {
err = errors.New("invalid role id data") err = errors.New(internal.ErrorInvalidRole)
return return
} }
if !isRoleExisted(ctx, roleID) { if !isRoleExisted(ctx, roleID) {
err = errors.New("role id does not exist") err = errors.New(internal.ErrorNotFoundRole)
return return
} }
// Find phone number,email exists or not // Find phone number,email exists or not
if isPhoneNumberOrEmailExisted(ctx, payload.Phone, payload.Email) { if config.GetInstance().PhoneNumberIsUnique {
err = errors.New("phone number or email already existed") if isPhoneNumberExisted(ctx, payload.Phone) {
return err = errors.New(internal.ErrorAlreadyExistedPhoneNumber)
return
}
}
if config.GetInstance().EmailIsUnique {
if isEmailExisted(ctx, payload.Email) {
err = errors.New(internal.ErrorAlreadyExistedEmail)
return
}
} }
// New user data from payload // New user data from payload
@ -85,12 +94,12 @@ func FindUser(userID string) (r model.User, err error) {
// Find user exists or not // Find user exists or not
id, isValid := mongodb.NewIDFromString(userID) id, isValid := mongodb.NewIDFromString(userID)
if !isValid { if !isValid {
err = errors.New("invalid user id data") err = errors.New(internal.ErrorInvalidUser)
return return
} }
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
err = errors.New("user not found") err = errors.New(internal.ErrorNotFoundUser)
return return
} }
@ -106,12 +115,12 @@ func FindUserByEmail(email string) (r model.User, err error) {
// Find user exists or not // Find user exists or not
if email == "" { if email == "" {
err = errors.New("invalid email data") err = errors.New(internal.ErrorInvalidEmail)
return return
} }
user, _ := findOneByCondition(ctx, bson.M{"email": email}) user, _ := findOneByCondition(ctx, bson.M{"email": email})
if user.ID.IsZero() { if user.ID.IsZero() {
err = errors.New("user not found") err = errors.New(internal.ErrorNotFoundUser)
return return
} }
@ -128,12 +137,12 @@ func GetHashedPassword(userID string) (result string, err error) {
// Find user exists or not // Find user exists or not
id, isValid := mongodb.NewIDFromString(userID) id, isValid := mongodb.NewIDFromString(userID)
if !isValid { if !isValid {
err = errors.New("invalid email data") err = errors.New(internal.ErrorInvalidUser)
return return
} }
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
err = errors.New("user not found") err = errors.New(internal.ErrorNotFoundUser)
return return
} }
@ -244,31 +253,35 @@ func UpdateByUserID(userID string, payload model.UserUpdateOptions) error {
// Find roleID exists or not // Find roleID exists or not
roleID, isValid := mongodb.NewIDFromString(payload.RoleID) roleID, isValid := mongodb.NewIDFromString(payload.RoleID)
if !isValid { if !isValid {
return errors.New("invalid role id data") return errors.New(internal.ErrorInvalidRole)
} }
if !isRoleExisted(ctx, roleID) { if !isRoleExisted(ctx, roleID) {
return errors.New("role id does not exist") return errors.New(internal.ErrorNotFoundRole)
} }
// Find user exists or not // Find user exists or not
id, isValid := mongodb.NewIDFromString(userID) id, isValid := mongodb.NewIDFromString(userID)
if !isValid { if !isValid {
return errors.New("invalid user id data") return errors.New(internal.ErrorInvalidUser)
} }
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
return errors.New("user not found") return errors.New(internal.ErrorNotFoundUser)
} }
// Find phone number,email exists or not // Find phone number,email exists or not
if user.Phone != payload.Phone { if config.GetInstance().PhoneNumberIsUnique {
if isPhoneNumberExisted(ctx, payload.Phone) { if user.Phone != payload.Phone {
return errors.New("phone number already existed") if isPhoneNumberExisted(ctx, payload.Phone) {
return errors.New(internal.ErrorAlreadyExistedPhoneNumber)
}
} }
} }
if user.Email != payload.Email { if config.GetInstance().EmailIsUnique {
if isEmailExisted(ctx, payload.Email) { if user.Email != payload.Email {
return errors.New("email already existed") if isEmailExisted(ctx, payload.Email) {
return errors.New(internal.ErrorAlreadyExistedEmail)
}
} }
} }
@ -320,19 +333,19 @@ func ChangeUserPassword(userID string, opt model.ChangePasswordOptions) error {
"payload": opt, "payload": opt,
"userID": userID, "userID": userID,
}) })
return errors.New("invalid user id data") return errors.New(internal.ErrorInvalidUser)
} }
// Find user // Find user
id, _ := mongodb.NewIDFromString(userID) id, _ := mongodb.NewIDFromString(userID)
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
return errors.New("user not found") return errors.New(internal.ErrorNotFoundUser)
} }
// Check old password // Check old password
if isValid := internal.CheckPasswordHash(opt.OldPassword, user.HashedPassword); !isValid { if isValid := internal.CheckPasswordHash(opt.OldPassword, user.HashedPassword); !isValid {
return errors.New("the password is incorrect") return errors.New(internal.ErrorIncorrectPassword)
} }
// Update password // Update password
@ -357,19 +370,19 @@ func ResetUserPassword(userID string, password string) error {
// Validate Password // Validate Password
if password == "" { if password == "" {
return errors.New("password cannot be empty") return errors.New(internal.ErrorInvalidPassword)
} }
// Validate userID // Validate userID
if _, isValid := mongodb.NewIDFromString(userID); !isValid { if _, isValid := mongodb.NewIDFromString(userID); !isValid {
return errors.New("invalid user id data") return errors.New(internal.ErrorInvalidUser)
} }
// Find user // Find user
id, _ := mongodb.NewIDFromString(userID) id, _ := mongodb.NewIDFromString(userID)
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
return errors.New("user not found") return errors.New(internal.ErrorNotFoundUser)
} }
// Update password // Update password
@ -395,10 +408,10 @@ func ChangeUserStatus(userID, newStatus string) error {
// Validate userID // Validate userID
id, isValid := mongodb.NewIDFromString(userID) id, isValid := mongodb.NewIDFromString(userID)
if !isValid { if !isValid {
return errors.New("invalid user id data") return errors.New(internal.ErrorInvalidUser)
} }
if user, _ := findByID(ctx, id); user.ID.IsZero() { if user, _ := findByID(ctx, id); user.ID.IsZero() {
return errors.New("user not found") return errors.New(internal.ErrorNotFoundUser)
} }
// Update status // Update status
@ -423,10 +436,10 @@ func ChangeAllUsersStatus(roleID, status string) error {
// Validate roleID // Validate roleID
id, isValid := mongodb.NewIDFromString(roleID) id, isValid := mongodb.NewIDFromString(roleID)
if !isValid { if !isValid {
return errors.New("invalid role id data") return errors.New(internal.ErrorInvalidRole)
} }
if !isRoleExisted(ctx, id) { if !isRoleExisted(ctx, id) {
return errors.New("role not found") return errors.New(internal.ErrorNotFoundRole)
} }
// Setup condition // Setup condition
@ -457,8 +470,12 @@ func LoginWithEmailAndPassword(email, password string) (result model.User, err e
) )
// Validate email, password // Validate email, password
if email == "" || password == "" { if email == "" {
err = errors.New("email or password cannot be empty") err = errors.New(internal.ErrorInvalidEmail)
return
}
if password == "" {
err = errors.New(internal.ErrorInvalidPassword)
return return
} }
@ -468,13 +485,13 @@ func LoginWithEmailAndPassword(email, password string) (result model.User, err e
"deleted": false, "deleted": false,
}) })
if user.ID.IsZero() { if user.ID.IsZero() {
err = errors.New("user not found") err = errors.New(internal.ErrorNotFoundUser)
return return
} }
// Check Password // Check Password
if !internal.CheckPasswordHash(password, user.HashedPassword) { if !internal.CheckPasswordHash(password, user.HashedPassword) {
err = errors.New("the password is incorrect") err = errors.New(internal.ErrorIncorrectPassword)
return return
} }
@ -541,17 +558,17 @@ func UpdateAvatar(userID string, avatar interface{}) error {
) )
if avatar == nil { if avatar == nil {
return errors.New("no avatar data") return errors.New(internal.ErrorInvalidAvatar)
} }
// Find user exists or not // Find user exists or not
id, isValid := mongodb.NewIDFromString(userID) id, isValid := mongodb.NewIDFromString(userID)
if !isValid { if !isValid {
return errors.New("invalid role id data") return errors.New(internal.ErrorInvalidUser)
} }
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
return errors.New("user not found") return errors.New(internal.ErrorNotFoundUser)
} }
// Setup condition // Setup condition
@ -584,11 +601,11 @@ func Delete(userID string) error {
// Find user exists or not // Find user exists or not
id, isValid := mongodb.NewIDFromString(userID) id, isValid := mongodb.NewIDFromString(userID)
if !isValid { if !isValid {
return errors.New("invalid role id data") return errors.New(internal.ErrorInvalidUser)
} }
user, _ := findByID(ctx, id) user, _ := findByID(ctx, id)
if user.ID.IsZero() { if user.ID.IsZero() {
return errors.New("user not found") return errors.New(internal.ErrorNotFoundUser)
} }
// Setup condition // Setup condition

View File

@ -7,6 +7,7 @@ import (
"github.com/Selly-Modules/logger" "github.com/Selly-Modules/logger"
"github.com/Selly-Modules/mongodb" "github.com/Selly-Modules/mongodb"
"github.com/Selly-Modules/usermngmt/cache" "github.com/Selly-Modules/usermngmt/cache"
configMoudle "github.com/Selly-Modules/usermngmt/config"
"github.com/Selly-Modules/usermngmt/database" "github.com/Selly-Modules/usermngmt/database"
"github.com/Selly-Modules/usermngmt/internal" "github.com/Selly-Modules/usermngmt/internal"
) )
@ -22,6 +23,12 @@ type Config struct {
MongoDB MongoDBConfig MongoDB MongoDBConfig
// Table prefix, each service has its own prefix // Table prefix, each service has its own prefix
TablePrefix string TablePrefix string
// Email is unique
EmailIsUnique bool
// phone number is unique
PhoneNumberIsUnique bool
} }
// Service ... // Service ...
@ -61,6 +68,12 @@ func Init(config Config) (*Service, error) {
// Set database // Set database
database.Set(db, config.TablePrefix) database.Set(db, config.TablePrefix)
// Set config module
configMoudle.Set(&configMoudle.Configuration{
EmailIsUnique: config.EmailIsUnique,
PhoneNumberIsUnique: config.PhoneNumberIsUnique,
})
// Init cache // Init cache
cache.Init() cache.Init()