diff --git a/action_create.go b/action_create.go index c8e068f..3a59fd3 100644 --- a/action_create.go +++ b/action_create.go @@ -2,7 +2,6 @@ package usermngmt import ( "context" - "errors" "fmt" "github.com/Selly-Modules/logger" @@ -12,13 +11,13 @@ import ( // CreateOptions ... type CreateOptions struct { - Name string - Phone string - Email string - HashedPassword string - Status string - RoleID primitive.ObjectID - Other string + Name string + Phone string + Email string + Password string + Status string + RoleID primitive.ObjectID + Other string } // Create ... @@ -29,7 +28,7 @@ func (s Service) Create(payload CreateOptions) error { ) // Validate payload - err := payload.validate() + err := payload.validate(ctx) if err != nil { return err } @@ -40,20 +39,10 @@ func (s Service) Create(payload CreateOptions) error { return err } - // Find roleID exists or not - if !s.isRoleIDAlreadyExisted(ctx, userData.RoleID) { - return errors.New("roleID does not exist") - } - - // Find phone number,email exists or not - if s.isPhoneNumberOrEmailAlreadyExisted(ctx, userData.Phone, userData.Email) { - return errors.New("phone number or email already existed") - } - // Create device _, err = col.InsertOne(ctx, userData) if err != nil { - logger.Error("usermngmt - Create ", logger.LogData{ + logger.Error("usermngmt - Create", logger.LogData{ "doc": userData, "err": err.Error(), }) @@ -70,7 +59,7 @@ func (payload CreateOptions) newUser() (result User, err error) { Name: payload.Name, Phone: payload.Phone, Email: payload.Email, - HashedPassword: payload.HashedPassword, + HashedPassword: hashPassword(payload.Password), Status: payload.Status, RoleID: payload.RoleID, Other: payload.Other, diff --git a/constant.go b/constant.go index 452d4b2..6b6e124 100644 --- a/constant.go +++ b/constant.go @@ -6,4 +6,6 @@ const ( tableRole = "roles" timezoneHCM = "Asia/Ho_Chi_Minh" + + passwordHashingCost = 14 ) diff --git a/db.go b/db.go index 3204684..08eb7b1 100644 --- a/db.go +++ b/db.go @@ -12,18 +12,23 @@ import ( // getUserCollection ... func (s Service) getUserCollection() *mongo.Collection { - return s.DB.Collection(fmt.Sprintf("%s-%s", s.TablePrefix, tableUser)) + if s.TablePrefix != "" { + return s.DB.Collection(fmt.Sprintf("%s-%s", s.TablePrefix, tableUser)) + } + return s.DB.Collection(tableUser) } // getRoleCollection ... func (s Service) getRoleCollection() *mongo.Collection { - return s.DB.Collection(fmt.Sprintf("%s-%s", s.TablePrefix, tableRole)) + if s.TablePrefix != "" { + s.DB.Collection(fmt.Sprintf("%s-%s", s.TablePrefix, tableRole)) + } + return s.DB.Collection(tableRole) } -func (s Service) isPhoneNumberOrEmailAlreadyExisted(ctx context.Context, phone, email string) bool { +func (s Service) isPhoneNumberOrEmailExisted(ctx context.Context, phone, email string) bool { var ( - col = s.getUserCollection() - user = User{} + col = s.getUserCollection() ) // Find @@ -37,32 +42,33 @@ func (s Service) isPhoneNumberOrEmailAlreadyExisted(ctx context.Context, phone, }, }, } - if err := col.FindOne(ctx, cond).Decode(&user); err != nil { - logger.Error("usermngmt - findByCondition", logger.LogData{ + total, err := col.CountDocuments(ctx, cond) + if err != nil { + logger.Error("usermngmt - countUserByCondition", logger.LogData{ "condition": cond, "err": err.Error(), }) return true } - return !user.ID.IsZero() + return total != 0 } -func (s Service) isRoleIDAlreadyExisted(ctx context.Context, roleID primitive.ObjectID) bool { +func (s Service) isRoleIDExisted(ctx context.Context, roleID primitive.ObjectID) bool { var ( - col = s.getRoleCollection() - role = Role{} + col = s.getRoleCollection() ) // Find cond := bson.M{ "_id": roleID, } - if err := col.FindOne(ctx, cond).Decode(&role); err != nil { - logger.Error("usermngmt - findRoleByCondition", logger.LogData{ + total, err := col.CountDocuments(ctx, cond) + if err != nil { + logger.Error("usermngmt - countRoleByCondition", logger.LogData{ "condition": cond, "err": err.Error(), }) return false } - return !role.ID.IsZero() + return total != 0 } diff --git a/helper.go b/helper.go index 3d4670c..ca80f04 100644 --- a/helper.go +++ b/helper.go @@ -1 +1,13 @@ package usermngmt + +import "golang.org/x/crypto/bcrypt" + +func hashPassword(password string) string { + bytes, _ := bcrypt.GenerateFromPassword([]byte(password), passwordHashingCost) + return string(bytes) +} + +func checkPasswordHash(password, hash string) bool { + err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) + return err == nil +} diff --git a/model.go b/model.go index cba9c56..135b037 100644 --- a/model.go +++ b/model.go @@ -12,9 +12,9 @@ type User struct { Name string `bson:"name" json:"name"` Phone string `bson:"phone" json:"phone"` // unique Email string `bson:"email" json:"email"` // unique - HashedPassword string `bson:"hashedPassword" json:"hashedPassword"` + HashedPassword string `bson:"hashedPassword" json:"-"` Status string `bson:"status" json:"status"` - RoleID primitive.ObjectID `bson:"roleID" json:"roleId"` + RoleID primitive.ObjectID `bson:"roleId" json:"roleId"` Other string `bson:"other" json:"other"` CreatedAt time.Time `bson:"createdAt" json:"createdAt"` UpdatedAt time.Time `bson:"updatedAt" json:"updatedAt"` diff --git a/usermngmt.go b/usermngmt.go index 22034d4..ef63c29 100644 --- a/usermngmt.go +++ b/usermngmt.go @@ -31,7 +31,7 @@ var s *Service // Init ... func Init(config Config) (*Service, error) { - if config.MongoDB.Host == "" || config.TablePrefix == "" { + if config.MongoDB.Host == "" { return nil, errors.New("please provide all necessary information for init user") } diff --git a/validate.go b/validate.go index 2d5d017..13b45c4 100644 --- a/validate.go +++ b/validate.go @@ -1,12 +1,13 @@ package usermngmt import ( + "context" "errors" "github.com/Selly-Modules/logger" ) -func (co CreateOptions) validate() error { +func (co CreateOptions) validate(ctx context.Context) error { // Name if co.Name == "" { logger.Error("usermngmt - Create: no Name data", logger.LogData{ @@ -31,12 +32,12 @@ func (co CreateOptions) validate() error { return errors.New("no email data") } - // HashedPassword - if co.HashedPassword == "" { - logger.Error("usermngmt - Create: no hashedPassword data", logger.LogData{ + // Password + if co.Password == "" { + logger.Error("usermngmt - Create: no password data", logger.LogData{ "payload": co, }) - return errors.New("no hashedPassword data") + return errors.New("no password data") } // Status @@ -55,5 +56,15 @@ func (co CreateOptions) validate() error { return errors.New("invalid roleID data") } + // Find roleID exists or not + if !s.isRoleIDExisted(ctx, co.RoleID) { + return errors.New("role id does not exist") + } + + // Find phone number,email exists or not + if s.isPhoneNumberOrEmailExisted(ctx, co.Phone, co.Email) { + return errors.New("phone number or email already existed") + } + return nil }