usermngmt/user/handle.go

266 lines
5.8 KiB
Go
Raw Normal View History

2021-11-10 01:44:22 +00:00
package user
import (
"context"
"errors"
"sync"
"github.com/Selly-Modules/logger"
"github.com/Selly-Modules/mongodb"
"github.com/Selly-Modules/usermngmt/internal"
2021-11-10 02:54:49 +00:00
"github.com/Selly-Modules/usermngmt/internal/model"
2021-11-10 01:44:22 +00:00
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
type Handle struct {
Col *mongo.Collection
RoleCol *mongo.Collection
}
// Create ...
2021-11-10 02:54:49 +00:00
func (h Handle) Create(payload model.CreateOptions) error {
2021-11-10 01:44:22 +00:00
var (
ctx = context.Background()
)
// Validate payload
if err := payload.Validate(); err != nil {
return err
}
// Find roleID exists or not
roleID, isValid := mongodb.NewIDFromString(payload.RoleID)
if !isValid {
return errors.New("invalid role id data")
}
if !h.isRoleIDExisted(ctx, roleID) {
return errors.New("role id does not exist")
}
// Find phone number,email exists or not
if h.isPhoneNumberOrEmailExisted(ctx, payload.Phone, payload.Email) {
return errors.New("phone number or email already existed")
}
// New user data from payload
2021-11-10 02:54:49 +00:00
doc, err := newUser(payload)
2021-11-10 01:44:22 +00:00
if err != nil {
return err
}
// Create user
if err = h.create(ctx, doc); err != nil {
return err
}
return nil
}
2021-11-10 02:54:49 +00:00
// newUser ...
func newUser(payload model.CreateOptions) (result model.DBUser, err error) {
timeNow := internal.Now()
roleID, _ := mongodb.NewIDFromString(payload.RoleID)
return model.DBUser{
ID: mongodb.NewObjectID(),
Name: payload.Name,
SearchString: internal.GetSearchString(payload.Name, payload.Phone, payload.Email),
Phone: payload.Phone,
Email: payload.Email,
HashedPassword: internal.HashPassword(payload.Password),
Status: payload.Status,
RoleID: roleID,
Other: payload.Other,
CreatedAt: timeNow,
UpdatedAt: timeNow,
}, nil
}
2021-11-10 01:44:22 +00:00
// All ...
2021-11-10 02:54:49 +00:00
func (h Handle) All(queryParams model.AllQuery) (r model.UserAll) {
2021-11-10 01:44:22 +00:00
var (
ctx = context.Background()
wg sync.WaitGroup
cond = bson.M{}
)
2021-11-10 02:54:49 +00:00
query := model.CommonQuery{
2021-11-10 01:44:22 +00:00
Page: queryParams.Page,
Limit: queryParams.Limit,
Keyword: queryParams.Keyword,
RoleID: queryParams.RoleID,
Status: queryParams.Status,
Sort: bson.M{"createdAt": -1},
}
// Assign condition
query.SetDefaultLimit()
query.AssignKeyword(cond)
query.AssignRoleID(cond)
query.AssignStatus(cond)
wg.Add(1)
go func() {
defer wg.Done()
docs := h.findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
r.List = h.getResponseList(ctx, docs)
}()
wg.Add(1)
go func() {
defer wg.Done()
r.Total = h.countByCondition(ctx, cond)
}()
wg.Wait()
return
}
2021-11-10 02:54:49 +00:00
func (h Handle) getResponseList(ctx context.Context, users []model.DBUser) []model.User {
res := make([]model.User, 0)
2021-11-10 01:44:22 +00:00
for _, user := range users {
roleRaw, _ := h.roleFindByID(ctx, user.RoleID)
2021-11-10 02:54:49 +00:00
res = append(res, model.User{
2021-11-10 01:44:22 +00:00
ID: user.ID.Hex(),
Name: user.Name,
Phone: user.Phone,
Email: user.Email,
Status: user.Status,
2021-11-10 02:54:49 +00:00
Role: model.RoleShort{
2021-11-10 01:44:22 +00:00
ID: roleRaw.ID.Hex(),
Name: roleRaw.Name,
IsAdmin: roleRaw.IsAdmin,
},
Other: user.Other,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
})
}
return res
}
// UpdateByUserID ...
2021-11-10 02:54:49 +00:00
func (h Handle) UpdateByUserID(userID string, payload model.UpdateOptions) error {
2021-11-10 01:44:22 +00:00
var (
ctx = context.Background()
)
// Validate payload
if err := payload.Validate(); err != nil {
return err
}
// Find roleID exists or not
roleID, isValid := mongodb.NewIDFromString(payload.RoleID)
if !isValid {
return errors.New("invalid role id data")
}
if !h.isRoleIDExisted(ctx, roleID) {
return errors.New("role id does not exist")
}
// Find phone number,email exists or not
if h.isPhoneNumberOrEmailExisted(ctx, payload.Phone, payload.Email) {
return errors.New("phone number or email already existed")
}
// Setup condition
id, _ := mongodb.NewIDFromString(userID)
cond := bson.M{
"_id": id,
}
// Setup update data
updateData := bson.M{
"$set": bson.M{
"name": payload.Name,
"searchString": internal.GetSearchString(payload.Name, payload.Phone, payload.Email),
"phone": payload.Phone,
"email": payload.Email,
"roleId": roleID,
"other": payload.Other,
"updatedAt": internal.Now(),
},
}
// Update
if err := h.updateOneByCondition(ctx, cond, updateData); err != nil {
return err
}
return nil
}
// ChangeUserPassword ...
2021-11-10 02:54:49 +00:00
func (h Handle) ChangeUserPassword(userID string, opt model.ChangePasswordOptions) error {
2021-11-10 01:44:22 +00:00
var (
ctx = context.Background()
)
// Validate payload
err := opt.Validate()
if err != nil {
return err
}
// Validate userID
if _, isValid := mongodb.NewIDFromString(userID); !isValid {
logger.Error("usermngmt - ChangePassword: invalid userID data", logger.LogData{
"payload": opt,
2021-11-10 02:54:49 +00:00
"userID": userID,
2021-11-10 01:44:22 +00:00
})
return errors.New("invalid user id data")
}
// Find user
id, _ := mongodb.NewIDFromString(userID)
user, _ := h.findByID(ctx, id)
if user.ID.IsZero() {
return errors.New("user not found")
}
// Check old password
if isValid := internal.CheckPasswordHash(opt.OldPassword, user.HashedPassword); !isValid {
return errors.New("the password is incorrect")
}
// Update password
if err = h.updateOneByCondition(ctx, bson.M{"_id": user.ID}, bson.M{
"$set": bson.M{
"hashedPassword": internal.HashPassword(opt.NewPassword),
"updatedAt": internal.Now(),
},
}); err != nil {
return err
}
return nil
}
// ChangeUserStatus ...
func (h Handle) ChangeUserStatus(userID, newStatus string) error {
var (
ctx = context.Background()
)
// Validate userID
id, isValid := mongodb.NewIDFromString(userID)
if !isValid {
return errors.New("invalid user id data")
}
// Update status
if err := h.updateOneByCondition(ctx, bson.M{"_id": id}, bson.M{
"$set": bson.M{
"status": newStatus,
"updatedAt": internal.Now(),
},
}); err != nil {
return err
}
return nil
}