Compare commits
	
		
			No commits in common. "master" and "feature/isPermission" have entirely different histories.
		
	
	
		
			master
			...
			feature/is
		
	
		
							
								
								
									
										101
									
								
								action.go
								
								
								
								
							
							
						
						
									
										101
									
								
								action.go
								
								
								
								
							| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
package usermngmt
 | 
					package usermngmt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/cache"
 | 
						"github.com/Selly-Modules/usermngmt/cache"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/permission"
 | 
						"github.com/Selly-Modules/usermngmt/permission"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/role"
 | 
						"github.com/Selly-Modules/usermngmt/role"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/user"
 | 
						"github.com/Selly-Modules/usermngmt/user"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -15,25 +15,10 @@ import (
 | 
				
			||||||
// user methods
 | 
					// user methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateUser ...
 | 
					// CreateUser ...
 | 
				
			||||||
func (s Service) CreateUser(payload model.UserCreateOptions) (id string, err error) {
 | 
					func (s Service) CreateUser(payload model.UserCreateOptions) error {
 | 
				
			||||||
	return user.Create(payload)
 | 
						return user.Create(payload)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FindUser ...
 | 
					 | 
				
			||||||
func (s Service) FindUser(userID string) (model.User, error) {
 | 
					 | 
				
			||||||
	return user.FindUser(userID)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// FindUserByEmail ...
 | 
					 | 
				
			||||||
func (s Service) FindUserByEmail(email string) (model.User, error) {
 | 
					 | 
				
			||||||
	return user.FindUserByEmail(email)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetHashedPassword ...
 | 
					 | 
				
			||||||
func (s Service) GetHashedPassword(userID string) (string, error) {
 | 
					 | 
				
			||||||
	return user.GetHashedPassword(userID)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UpdateUser ...
 | 
					// UpdateUser ...
 | 
				
			||||||
func (s Service) UpdateUser(userID string, payload model.UserUpdateOptions) error {
 | 
					func (s Service) UpdateUser(userID string, payload model.UserUpdateOptions) error {
 | 
				
			||||||
	return user.UpdateByUserID(userID, payload)
 | 
						return user.UpdateByUserID(userID, payload)
 | 
				
			||||||
| 
						 | 
					@ -44,16 +29,6 @@ func (s Service) ChangeUserPassword(userID string, payload model.ChangePasswordO
 | 
				
			||||||
	return user.ChangeUserPassword(userID, payload)
 | 
						return user.ChangeUserPassword(userID, payload)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ResetUserPassword ...
 | 
					 | 
				
			||||||
func (s Service) ResetUserPassword(userID string, password string) error {
 | 
					 | 
				
			||||||
	return user.ResetUserPassword(userID, password)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ResetAndRequireToChangeUserPassword ...
 | 
					 | 
				
			||||||
func (s Service) ResetAndRequireToChangeUserPassword(userID string, password string) error {
 | 
					 | 
				
			||||||
	return user.ResetAndRequireToChangeUserPassword(userID, password)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ChangeUserStatus ...
 | 
					// ChangeUserStatus ...
 | 
				
			||||||
func (s Service) ChangeUserStatus(userID, newStatus string) error {
 | 
					func (s Service) ChangeUserStatus(userID, newStatus string) error {
 | 
				
			||||||
	return user.ChangeUserStatus(userID, newStatus)
 | 
						return user.ChangeUserStatus(userID, newStatus)
 | 
				
			||||||
| 
						 | 
					@ -64,16 +39,6 @@ func (s Service) GetAllUsers(query model.UserAllQuery) model.UserAll {
 | 
				
			||||||
	return user.All(query)
 | 
						return user.All(query)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetUsersByPermission ...
 | 
					 | 
				
			||||||
func (s Service) GetUsersByPermission(query model.UserByPermissionQuery) model.UserAll {
 | 
					 | 
				
			||||||
	return user.GetUsersByPermission(query)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CountAllUsers ...
 | 
					 | 
				
			||||||
func (s Service) CountAllUsers(query model.UserCountQuery) int64 {
 | 
					 | 
				
			||||||
	return user.Count(query)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ChangeAllUsersStatus ...
 | 
					// ChangeAllUsersStatus ...
 | 
				
			||||||
func (s Service) ChangeAllUsersStatus(roleID, status string) error {
 | 
					func (s Service) ChangeAllUsersStatus(roleID, status string) error {
 | 
				
			||||||
	return user.ChangeAllUsersStatus(roleID, status)
 | 
						return user.ChangeAllUsersStatus(roleID, status)
 | 
				
			||||||
| 
						 | 
					@ -89,16 +54,6 @@ func (s Service) HasPermission(userID, permission string) bool {
 | 
				
			||||||
	return user.HasPermission(userID, permission)
 | 
						return user.HasPermission(userID, permission)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateUserAvatar ...
 | 
					 | 
				
			||||||
func (s Service) UpdateUserAvatar(userID string, avatar interface{}) error {
 | 
					 | 
				
			||||||
	return user.UpdateAvatar(userID, avatar)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DeleteUser ...
 | 
					 | 
				
			||||||
func (s Service) DeleteUser(userID string) error {
 | 
					 | 
				
			||||||
	return user.Delete(userID)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Role
 | 
					// Role
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -106,14 +61,12 @@ func (s Service) DeleteUser(userID string) error {
 | 
				
			||||||
// role methods
 | 
					// role methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateRole ...
 | 
					// CreateRole ...
 | 
				
			||||||
func (s Service) CreateRole(payload model.RoleCreateOptions) (id string, err error) {
 | 
					func (s Service) CreateRole(payload model.RoleCreateOptions) error {
 | 
				
			||||||
	id, err = role.Create(payload)
 | 
						if err := role.Create(payload); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
							return err
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	cache.Roles()
 | 
						cache.Roles()
 | 
				
			||||||
	return
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateRole ...
 | 
					// UpdateRole ...
 | 
				
			||||||
| 
						 | 
					@ -126,11 +79,6 @@ func (s Service) GetAllRoles(query model.RoleAllQuery) model.RoleAll {
 | 
				
			||||||
	return role.All(query)
 | 
						return role.All(query)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FindRole ...
 | 
					 | 
				
			||||||
func (s Service) FindRole(roleID string) (model.Role, error) {
 | 
					 | 
				
			||||||
	return role.FindRole(roleID)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Permission
 | 
					// Permission
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					@ -138,14 +86,12 @@ func (s Service) FindRole(roleID string) (model.Role, error) {
 | 
				
			||||||
// permission methods
 | 
					// permission methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreatePermission ...
 | 
					// CreatePermission ...
 | 
				
			||||||
func (s Service) CreatePermission(payload model.PermissionCreateOptions) (id string, err error) {
 | 
					func (s Service) CreatePermission(payload model.PermissionCreateOptions) error {
 | 
				
			||||||
	id, err = permission.Create(payload)
 | 
						if err := permission.Create(payload); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
							return err
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	cache.Roles()
 | 
						cache.Roles()
 | 
				
			||||||
	return
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdatePermission ...
 | 
					// UpdatePermission ...
 | 
				
			||||||
| 
						 | 
					@ -157,25 +103,6 @@ func (s Service) UpdatePermission(permissionID string, payload model.PermissionU
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DeletePermission ...
 | 
					 | 
				
			||||||
func (s Service) DeletePermission(permissionID string) error {
 | 
					 | 
				
			||||||
	if err := permission.Delete(permissionID); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cache.Roles()
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// FindAndDeletePermission ...
 | 
					 | 
				
			||||||
func (s Service) FindAndDeletePermission(permissionID string) (*model.Permission, error) {
 | 
					 | 
				
			||||||
	p, err := permission.FindByIDAndDelete(permissionID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cache.Roles()
 | 
					 | 
				
			||||||
	return p, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetAllPermissions ...
 | 
					// GetAllPermissions ...
 | 
				
			||||||
func (s Service) GetAllPermissions(query model.PermissionAllQuery) model.PermissionAll {
 | 
					func (s Service) GetAllPermissions(query model.PermissionAllQuery) model.PermissionAll {
 | 
				
			||||||
	return permission.All(query)
 | 
						return permission.All(query)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,67 +1,29 @@
 | 
				
			||||||
package cache
 | 
					package cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/go-redis/redis/v8"
 | 
						"github.com/allegro/bigcache/v3"
 | 
				
			||||||
	"github.com/logrusorgru/aurora"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var mc *bigcache.BigCache
 | 
				
			||||||
	c *redis.Client
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Init ...
 | 
					// Init ...
 | 
				
			||||||
func Init(uri, pwd string) {
 | 
					func Init() {
 | 
				
			||||||
	c = redis.NewClient(&redis.Options{
 | 
						// The time after which entries can be evicted is 30 days
 | 
				
			||||||
		Addr:     uri,
 | 
						const cacheTime = 24 * 30 * time.Hour // 30 days
 | 
				
			||||||
		Password: pwd,
 | 
						c, err := bigcache.NewBigCache(bigcache.DefaultConfig(cacheTime))
 | 
				
			||||||
		DB:       0, // use default DB
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Test
 | 
					 | 
				
			||||||
	_, err := c.Ping(context.Background()).Result()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Fatal("Cannot connect to redis", uri, err)
 | 
							log.Fatalf("Cannot init Cache %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						mc = c
 | 
				
			||||||
	fmt.Println(aurora.Green("*** CONNECTED TO REDIS: " + uri))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Cache roles
 | 
						// Cache roles
 | 
				
			||||||
	Roles()
 | 
						Roles()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetInstance ...
 | 
					// GetInstance ...
 | 
				
			||||||
func GetInstance() *redis.Client {
 | 
					func GetInstance() *bigcache.BigCache {
 | 
				
			||||||
	return c
 | 
						return mc
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// SetKeyValue ...
 | 
					 | 
				
			||||||
func SetKeyValue(key string, value interface{}, expiration time.Duration) error {
 | 
					 | 
				
			||||||
	ctx := context.Background()
 | 
					 | 
				
			||||||
	dataByte, _ := json.Marshal(value)
 | 
					 | 
				
			||||||
	r := c.Set(ctx, key, dataByte, expiration)
 | 
					 | 
				
			||||||
	return r.Err()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetValueByKey ...
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,10 +3,10 @@ package cache
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/database"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
						"go.mongodb.org/mongo-driver/mongo/options"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/database"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func roleFindByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBRole) {
 | 
					func roleFindByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBRole) {
 | 
				
			||||||
| 
						 | 
					@ -17,10 +17,20 @@ func roleFindByCondition(ctx context.Context, cond interface{}, opts ...*options
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
						cursor, err := col.Find(ctx, cond, opts...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Role - Find", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
						defer cursor.Close(ctx)
 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
						if err = cursor.All(ctx, &docs); err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Role - Decode", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					@ -34,10 +44,20 @@ func permissionFindByCondition(ctx context.Context, cond interface{}, opts ...*o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
						cursor, err := col.Find(ctx, cond, opts...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Find", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
						defer cursor.Close(ctx)
 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
						if err = cursor.All(ctx, &docs); err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Decode", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +0,0 @@
 | 
				
			||||||
package cache
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	keyPrefix = "usermngmt_"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	KeyLoginFailedTimes = keyPrefix + "login_failed_time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -3,12 +3,11 @@ package cache
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Roles ...
 | 
					// Roles ...
 | 
				
			||||||
| 
						 | 
					@ -36,12 +35,15 @@ func Roles() {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Cache Role
 | 
								// Cache Role
 | 
				
			||||||
			entry := CachedRole{
 | 
								entry, _ := json.Marshal(CachedRole{
 | 
				
			||||||
				Role:        role.Code,
 | 
									Role:        role.Code,
 | 
				
			||||||
				IsAdmin:     role.IsAdmin,
 | 
									IsAdmin:     role.IsAdmin,
 | 
				
			||||||
				Permissions: rolePermissions,
 | 
									Permissions: rolePermissions,
 | 
				
			||||||
			}
 | 
								})
 | 
				
			||||||
			if err := SetKeyValue(role.ID.Hex(), entry, 0); err != nil {
 | 
								if err := mc.Set(role.ID.Hex(), entry); err != nil {
 | 
				
			||||||
 | 
									logger.Error("usermngmt - CacheRole", logger.LogData{
 | 
				
			||||||
 | 
										"err": err.Error(),
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}(value)
 | 
							}(value)
 | 
				
			||||||
| 
						 | 
					@ -53,16 +55,16 @@ func Roles() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetCachedRole ...
 | 
					// GetCachedRole ...
 | 
				
			||||||
func GetCachedRole(key string) CachedRole {
 | 
					func GetCachedRole(key string) CachedRole {
 | 
				
			||||||
	value, err := GetValueByKey(key)
 | 
						entry, err := mc.Get(key)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		Roles()
 | 
							Roles()
 | 
				
			||||||
		value, _ = GetValueByKey(key)
 | 
							entry, _ = mc.Get(key)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Unmarshal data
 | 
					 | 
				
			||||||
	var cachedRole CachedRole
 | 
						var cachedRole CachedRole
 | 
				
			||||||
	if err := json.Unmarshal(value, &cachedRole); err != nil {
 | 
						if err = json.Unmarshal(entry, &cachedRole); err != nil {
 | 
				
			||||||
		log.Println("usermngmt - GetCachedRole - Unmarshal: ", err)
 | 
							logger.Error("usermngmt - GetCachedRole - Unmarshal", logger.LogData{
 | 
				
			||||||
 | 
								"err": err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return cachedRole
 | 
						return cachedRole
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,27 +0,0 @@
 | 
				
			||||||
package config
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	MaximumLoginFailedTime     = 5
 | 
					 | 
				
			||||||
	LoginFailedBlockedDuration = time.Hour
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Configuration struct {
 | 
					 | 
				
			||||||
	EmailIsUnique       bool
 | 
					 | 
				
			||||||
	PhoneNumberIsUnique bool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	c *Configuration
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Set ...
 | 
					 | 
				
			||||||
func Set(instance *Configuration) {
 | 
					 | 
				
			||||||
	c = instance
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetInstance ...
 | 
					 | 
				
			||||||
func GetInstance() *Configuration {
 | 
					 | 
				
			||||||
	return c
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										51
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										51
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -1,31 +1,46 @@
 | 
				
			||||||
module git.selly.red/Selly-Modules/usermngmt
 | 
					module github.com/Selly-Modules/usermngmt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go 1.17
 | 
					go 1.17
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	git.selly.red/Selly-Modules/mongodb v1.0.6-0.20221010033754-1d897a0f9ea2
 | 
						github.com/Selly-Modules/logger v0.0.0-20210809034923-140a51f39ec9
 | 
				
			||||||
	github.com/go-redis/redis/v8 v8.11.4
 | 
						github.com/Selly-Modules/mongodb v0.0.0-20211013094205-a8ab24a96c4c
 | 
				
			||||||
	github.com/logrusorgru/aurora v2.0.3+incompatible
 | 
						github.com/allegro/bigcache/v3 v3.0.1
 | 
				
			||||||
	github.com/thoas/go-funk v0.9.1
 | 
						github.com/thoas/go-funk v0.9.1
 | 
				
			||||||
	go.mongodb.org/mongo-driver v1.10.3
 | 
						go.mongodb.org/mongo-driver v1.7.4
 | 
				
			||||||
	golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
 | 
						golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/cespare/xxhash/v2 v2.1.2 // indirect
 | 
						github.com/armon/go-radix v1.0.0 // indirect
 | 
				
			||||||
	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 | 
						github.com/elastic/go-licenser v0.3.1 // indirect
 | 
				
			||||||
	github.com/golang/snappy v0.0.4 // indirect
 | 
						github.com/elastic/go-sysinfo v1.1.1 // indirect
 | 
				
			||||||
	github.com/google/go-cmp v0.5.8 // indirect
 | 
						github.com/elastic/go-windows v1.0.0 // indirect
 | 
				
			||||||
 | 
						github.com/go-stack/stack v1.8.0 // indirect
 | 
				
			||||||
 | 
						github.com/golang/snappy v0.0.1 // indirect
 | 
				
			||||||
 | 
						github.com/jcchavezs/porto v0.1.0 // indirect
 | 
				
			||||||
 | 
						github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
 | 
				
			||||||
	github.com/klauspost/compress v1.13.6 // indirect
 | 
						github.com/klauspost/compress v1.13.6 // indirect
 | 
				
			||||||
	github.com/montanaflynn/stats v0.6.6 // indirect
 | 
						github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
 | 
				
			||||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
						github.com/pkg/errors v0.9.1 // indirect
 | 
				
			||||||
	github.com/stretchr/testify v1.8.0 // indirect
 | 
						github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0 // indirect
 | 
				
			||||||
 | 
						github.com/santhosh-tekuri/jsonschema v1.2.4 // indirect
 | 
				
			||||||
	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 | 
						github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 | 
				
			||||||
	github.com/xdg-go/scram v1.1.1 // indirect
 | 
						github.com/xdg-go/scram v1.0.2 // indirect
 | 
				
			||||||
	github.com/xdg-go/stringprep v1.0.3 // indirect
 | 
						github.com/xdg-go/stringprep v1.0.2 // indirect
 | 
				
			||||||
	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
 | 
						github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
 | 
				
			||||||
	golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
 | 
						go.elastic.co/apm v1.13.1 // indirect
 | 
				
			||||||
	golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 // indirect
 | 
						go.elastic.co/apm/module/apmzap v1.13.1 // indirect
 | 
				
			||||||
	golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec // indirect
 | 
						go.elastic.co/fastjson v1.1.0 // indirect
 | 
				
			||||||
 | 
						go.uber.org/atomic v1.7.0 // indirect
 | 
				
			||||||
 | 
						go.uber.org/multierr v1.6.0 // indirect
 | 
				
			||||||
 | 
						go.uber.org/zap v1.18.1 // indirect
 | 
				
			||||||
 | 
						golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
 | 
				
			||||||
 | 
						golang.org/x/mod v0.3.0 // indirect
 | 
				
			||||||
 | 
						golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
 | 
				
			||||||
 | 
						golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e // indirect
 | 
				
			||||||
	golang.org/x/text v0.3.7 // indirect
 | 
						golang.org/x/text v0.3.7 // indirect
 | 
				
			||||||
 | 
						golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5 // indirect
 | 
				
			||||||
 | 
						golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
 | 
				
			||||||
 | 
						howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										183
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										183
									
								
								go.sum
								
								
								
								
							| 
						 | 
					@ -1,20 +1,23 @@
 | 
				
			||||||
git.selly.red/Selly-Modules/mongodb v1.0.6-0.20221010033754-1d897a0f9ea2 h1:bePzcMN/j4V1fvz6UUrN01ey1tkE0w+m5Qj3LtoZs4E=
 | 
					 | 
				
			||||||
git.selly.red/Selly-Modules/mongodb v1.0.6-0.20221010033754-1d897a0f9ea2/go.mod h1:Xvs3E6YbTPI5I4+I1aXrY0A79XaCfw+0tqV8dihvheE=
 | 
					 | 
				
			||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
					github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
				
			||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
 | 
					github.com/Selly-Modules/logger v0.0.0-20210809034923-140a51f39ec9 h1:AuJ/IIZ7yppyP19ILEYkwz26CwGXR4xUyXANKSG0+1U=
 | 
				
			||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 | 
					github.com/Selly-Modules/logger v0.0.0-20210809034923-140a51f39ec9/go.mod h1:RWhSQ3F01an8KD00VjzRBZOMcE5eV2Cy0/l4ZkeieyU=
 | 
				
			||||||
 | 
					github.com/Selly-Modules/mongodb v0.0.0-20211013094205-a8ab24a96c4c h1:1l6QmAl43maG9zFyUXrPQVUjyVt0vy/2Saz992UR+Sc=
 | 
				
			||||||
 | 
					github.com/Selly-Modules/mongodb v0.0.0-20211013094205-a8ab24a96c4c/go.mod h1:C9O0Bgl9i6szjntMjBdEvaFSqG2UPOgHUspIWIJ93JQ=
 | 
				
			||||||
 | 
					github.com/allegro/bigcache/v3 v3.0.1 h1:Q4Xl3chywXuJNOw7NV+MeySd3zGQDj4KCpkCg0te8mc=
 | 
				
			||||||
 | 
					github.com/allegro/bigcache/v3 v3.0.1/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
 | 
				
			||||||
 | 
					github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
 | 
				
			||||||
 | 
					github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 | 
				
			||||||
 | 
					github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
					 | 
				
			||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 | 
					github.com/elastic/go-licenser v0.3.1 h1:RmRukU/JUmts+rpexAw0Fvt2ly7VVu6mw8z4HrEzObU=
 | 
				
			||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 | 
					github.com/elastic/go-licenser v0.3.1/go.mod h1:D8eNQk70FOCVBl3smCGQt/lv7meBeQno2eI1S5apiHQ=
 | 
				
			||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 | 
					github.com/elastic/go-sysinfo v1.1.1 h1:ZVlaLDyhVkDfjwPGU55CQRCRolNpc7P0BbyhhQZQmMI=
 | 
				
			||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 | 
					github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0=
 | 
				
			||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 | 
					github.com/elastic/go-windows v1.0.0 h1:qLURgZFkkrYyTTkvYpsZIgf83AUsdIHfvlJaqaZ7aSY=
 | 
				
			||||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
 | 
					github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
 | 
				
			||||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
 | 
					github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 | 
				
			||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 | 
					github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 | 
				
			||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 | 
					 | 
				
			||||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
 | 
					github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
 | 
				
			||||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
 | 
					github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
 | 
				
			||||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
 | 
					github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
 | 
				
			||||||
| 
						 | 
					@ -39,28 +42,16 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe
 | 
				
			||||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
 | 
					github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
 | 
				
			||||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
 | 
					github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
 | 
				
			||||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 | 
					github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 | 
				
			||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 | 
					github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
 | 
				
			||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 | 
					 | 
				
			||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 | 
					 | 
				
			||||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
					github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
				
			||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 | 
					 | 
				
			||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
					 | 
				
			||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
					 | 
				
			||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
					github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
				
			||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
					 | 
				
			||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
					github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
				
			||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
					 | 
				
			||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
					 | 
				
			||||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
 | 
					 | 
				
			||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 | 
					 | 
				
			||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 | 
					 | 
				
			||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 | 
					github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 | 
				
			||||||
 | 
					github.com/jcchavezs/porto v0.1.0 h1:Xmxxn25zQMmgE7/yHYmh19KcItG81hIwfbEEFnd6w/Q=
 | 
				
			||||||
 | 
					github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A=
 | 
				
			||||||
 | 
					github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 | 
				
			||||||
 | 
					github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
 | 
				
			||||||
 | 
					github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
 | 
				
			||||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 | 
					github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
 | 
				
			||||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 | 
					github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
 | 
				
			||||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 | 
					github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
 | 
				
			||||||
| 
						 | 
					@ -77,29 +68,19 @@ github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/z
 | 
				
			||||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
 | 
					github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
 | 
				
			||||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 | 
					github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 | 
				
			||||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 | 
					github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 | 
				
			||||||
github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ=
 | 
					 | 
				
			||||||
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
 | 
					 | 
				
			||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 | 
					 | 
				
			||||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 | 
					 | 
				
			||||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
 | 
					 | 
				
			||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 | 
					 | 
				
			||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 | 
					 | 
				
			||||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
 | 
					 | 
				
			||||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
 | 
					 | 
				
			||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 | 
					 | 
				
			||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 | 
					 | 
				
			||||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
 | 
					 | 
				
			||||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
 | 
					 | 
				
			||||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 | 
					github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 | 
				
			||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
					github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
				
			||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
					github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
				
			||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
					github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
				
			||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
					github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
					 | 
				
			||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
 | 
					github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0 h1:c8R11WC8m7KNMkTv/0+Be8vvwo4I3/Ut9AC2FW8fX3U=
 | 
				
			||||||
 | 
					github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 | 
				
			||||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
					github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
				
			||||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
					github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
				
			||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
					github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 | 
				
			||||||
 | 
					github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=
 | 
				
			||||||
 | 
					github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
 | 
				
			||||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 | 
					github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 | 
				
			||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 | 
					github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 | 
				
			||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 | 
					github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 | 
				
			||||||
| 
						 | 
					@ -107,121 +88,101 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
 | 
				
			||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
					github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
				
			||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
					github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
				
			||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
					github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
				
			||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 | 
					 | 
				
			||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 | 
					github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 | 
				
			||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 | 
					github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 | 
				
			||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
					github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
				
			||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 | 
					 | 
				
			||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
					github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
				
			||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
					github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
				
			||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 | 
					 | 
				
			||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 | 
					 | 
				
			||||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
 | 
					github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
 | 
				
			||||||
github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
 | 
					github.com/thoas/go-funk v0.9.1/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
 | 
				
			||||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 | 
					 | 
				
			||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 | 
					github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 | 
				
			||||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 | 
					github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
 | 
				
			||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 | 
					github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 | 
				
			||||||
 | 
					github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
 | 
				
			||||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
 | 
					github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
 | 
				
			||||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
 | 
					github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
 | 
				
			||||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
 | 
					 | 
				
			||||||
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
 | 
					github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
 | 
				
			||||||
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
 | 
					github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
 | 
				
			||||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
 | 
					 | 
				
			||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 | 
					github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 | 
				
			||||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
 | 
					github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
				
			||||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
 | 
					go.elastic.co/apm v1.13.1 h1:ICIcUcQOImg/bve9mQVyLCvm1cSUZ1afdwK6ACnxczU=
 | 
				
			||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
					go.elastic.co/apm v1.13.1/go.mod h1:dylGv2HKR0tiCV+wliJz1KHtDyuD8SPe69oV7VyK6WY=
 | 
				
			||||||
 | 
					go.elastic.co/apm/module/apmzap v1.13.1 h1:Soa4vNYYabPvOW1vm1A00C0UcEmfEzcx3YBjAgf5ue4=
 | 
				
			||||||
 | 
					go.elastic.co/apm/module/apmzap v1.13.1/go.mod h1:Tu8/TwffpBoNGmI05VcL1Ye2AC8oXrlMKNaKD1TIQy0=
 | 
				
			||||||
 | 
					go.elastic.co/fastjson v1.1.0 h1:3MrGBWWVIxe/xvsbpghtkFoPciPhOCmjsR/HfwEeQR4=
 | 
				
			||||||
 | 
					go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI=
 | 
				
			||||||
go.mongodb.org/mongo-driver v1.7.1/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
 | 
					go.mongodb.org/mongo-driver v1.7.1/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
 | 
				
			||||||
go.mongodb.org/mongo-driver v1.10.3 h1:XDQEvmh6z1EUsXuIkXE9TaVeqHw6SwS1uf93jFs0HBA=
 | 
					go.mongodb.org/mongo-driver v1.7.4 h1:sllcioag8Mec0LYkftYWq+cKNPIR4Kqq3iv9ZXY0g/E=
 | 
				
			||||||
go.mongodb.org/mongo-driver v1.10.3/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8=
 | 
					go.mongodb.org/mongo-driver v1.7.4/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
 | 
				
			||||||
 | 
					go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 | 
				
			||||||
 | 
					go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 | 
				
			||||||
 | 
					go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 | 
				
			||||||
 | 
					go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 | 
				
			||||||
 | 
					go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 | 
				
			||||||
 | 
					go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 | 
				
			||||||
 | 
					go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
 | 
				
			||||||
 | 
					go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 | 
				
			||||||
 | 
					go.uber.org/zap v1.18.1 h1:CSUJ2mjFszzEWt4CdKISEuChVIXGBn3lAPwkRGyVrc4=
 | 
				
			||||||
 | 
					go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
					golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
					golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 | 
					golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
					golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
				
			||||||
 | 
					golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
					golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
					golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
 | 
					golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 | 
					golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 | 
				
			||||||
 | 
					golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 | 
				
			||||||
 | 
					golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
				
			||||||
 | 
					golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
 | 
				
			||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
					golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
				
			||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
					golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
				
			||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
					golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
				
			||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
					golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
				
			||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 | 
					golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
				
			||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 | 
					golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
 | 
					 | 
				
			||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
 | 
					golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY=
 | 
					 | 
				
			||||||
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e h1:9vRrk9YW2BTzLP0VCB9ZDjU4cPqkg+IDWL7XgxA1yxQ=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					 | 
				
			||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 | 
					 | 
				
			||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 | 
					 | 
				
			||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
					golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
				
			||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
					 | 
				
			||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
					golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
				
			||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
					 | 
				
			||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 | 
					golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
 | 
				
			||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 | 
					golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
					golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
				
			||||||
 | 
					golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
					golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
					golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
					golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 | 
					golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 | 
				
			||||||
 | 
					golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
					golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
				
			||||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 | 
					golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 | 
				
			||||||
 | 
					golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5 h1:MeC2gMlMdkd67dn17MEby3rGXRxZtWeiRXOnISfTQ74=
 | 
				
			||||||
 | 
					golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
				
			||||||
 | 
					golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
				
			||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
					 | 
				
			||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
					 | 
				
			||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
					gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 | 
					gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 | 
				
			||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 | 
					gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 | 
					 | 
				
			||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 | 
					 | 
				
			||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
					gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
					 | 
				
			||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
					gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
					 | 
				
			||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 | 
					 | 
				
			||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 | 
					 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
					gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 | 
					gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
				
			||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 | 
					howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
 | 
				
			||||||
 | 
					howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ package internal
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	timezoneHCM = "Asia/Ho_Chi_Minh"
 | 
						timezoneHCM = "Asia/Ho_Chi_Minh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	passwordHashingCost = 12
 | 
						passwordHashingCost = 14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	TablePrefixDefault = "usermngmt"
 | 
						TablePrefixDefault = "usermngmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,34 +0,0 @@
 | 
				
			||||||
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"
 | 
					 | 
				
			||||||
	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"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -2,11 +2,9 @@ package internal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"github.com/thoas/go-funk"
 | 
					 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
	"golang.org/x/crypto/bcrypt"
 | 
						"golang.org/x/crypto/bcrypt"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,10 +46,3 @@ func GenerateCode(s string) string {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return strings.ReplaceAll(mongodb.NonAccentVietnamese(s), emptySpace, underscore)
 | 
						return strings.ReplaceAll(mongodb.NonAccentVietnamese(s), emptySpace, underscore)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// ConvertObjectIDsToStrings ...
 | 
					 | 
				
			||||||
func ConvertObjectIDsToStrings(ids []primitive.ObjectID) []string {
 | 
					 | 
				
			||||||
	return funk.Map(ids, func(item primitive.ObjectID) string {
 | 
					 | 
				
			||||||
		return item.Hex()
 | 
					 | 
				
			||||||
	}).([]string)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								model/db.go
								
								
								
								
							
							
						
						
									
										26
									
								
								model/db.go
								
								
								
								
							| 
						 | 
					@ -12,27 +12,23 @@ type DBRole struct {
 | 
				
			||||||
	Name      string             `bson:"name"`
 | 
						Name      string             `bson:"name"`
 | 
				
			||||||
	Code      string             `bson:"code"`
 | 
						Code      string             `bson:"code"`
 | 
				
			||||||
	IsAdmin   bool               `bson:"isAdmin"`
 | 
						IsAdmin   bool               `bson:"isAdmin"`
 | 
				
			||||||
	Level     int                `bson:"level"`
 | 
					 | 
				
			||||||
	CreatedAt time.Time          `bson:"createdAt"`
 | 
						CreatedAt time.Time          `bson:"createdAt"`
 | 
				
			||||||
	UpdatedAt time.Time          `bson:"updatedAt"`
 | 
						UpdatedAt time.Time          `bson:"updatedAt"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DBUser ...
 | 
					// DBUser ...
 | 
				
			||||||
type DBUser struct {
 | 
					type DBUser struct {
 | 
				
			||||||
	ID                      primitive.ObjectID `bson:"_id"`
 | 
						ID             primitive.ObjectID `bson:"_id"`
 | 
				
			||||||
	Name                    string             `bson:"name"`
 | 
						Name           string             `bson:"name"`
 | 
				
			||||||
	SearchString            string             `bson:"searchString"`
 | 
						SearchString   string             `bson:"searchString"`
 | 
				
			||||||
	Phone                   string             `bson:"phone"` // unique
 | 
						Phone          string             `bson:"phone"` // unique
 | 
				
			||||||
	Email                   string             `bson:"email"` // unique
 | 
						Email          string             `bson:"email"` // unique
 | 
				
			||||||
	HashedPassword          string             `bson:"hashedPassword"`
 | 
						HashedPassword string             `bson:"hashedPassword"`
 | 
				
			||||||
	Status                  string             `bson:"status"`
 | 
						Status         string             `bson:"status"`
 | 
				
			||||||
	RoleID                  primitive.ObjectID `bson:"roleId"`
 | 
						RoleID         primitive.ObjectID `bson:"roleId"`
 | 
				
			||||||
	RequireToChangePassword bool               `bson:"requireToChangePassword"`
 | 
						Other          string             `bson:"other"`
 | 
				
			||||||
	Avatar                  interface{}        `bson:"avatar"`
 | 
						CreatedAt      time.Time          `bson:"createdAt"`
 | 
				
			||||||
	Deleted                 bool               `bson:"deleted"`
 | 
						UpdatedAt      time.Time          `bson:"updatedAt"`
 | 
				
			||||||
	Other                   interface{}        `bson:"other"` // object
 | 
					 | 
				
			||||||
	CreatedAt               time.Time          `bson:"createdAt"`
 | 
					 | 
				
			||||||
	UpdatedAt               time.Time          `bson:"updatedAt"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DBPermission ...
 | 
					// DBPermission ...
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,13 +3,13 @@ package model
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PermissionCreateOptions ...
 | 
					// PermissionCreateOptions ...
 | 
				
			||||||
type PermissionCreateOptions struct {
 | 
					type PermissionCreateOptions struct {
 | 
				
			||||||
	Name   string
 | 
						Name   string
 | 
				
			||||||
	Code   string
 | 
					 | 
				
			||||||
	RoleID string
 | 
						RoleID string
 | 
				
			||||||
	Desc   string
 | 
						Desc   string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -17,33 +17,31 @@ type PermissionCreateOptions struct {
 | 
				
			||||||
// PermissionUpdateOptions ...
 | 
					// PermissionUpdateOptions ...
 | 
				
			||||||
type PermissionUpdateOptions struct {
 | 
					type PermissionUpdateOptions struct {
 | 
				
			||||||
	Name   string
 | 
						Name   string
 | 
				
			||||||
	Code   string
 | 
					 | 
				
			||||||
	RoleID string
 | 
						RoleID string
 | 
				
			||||||
	Desc   string
 | 
						Desc   string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PermissionAllQuery ...
 | 
					// PermissionAllQuery ...
 | 
				
			||||||
type PermissionAllQuery struct {
 | 
					type PermissionAllQuery struct {
 | 
				
			||||||
	Page   int64
 | 
						Page  int64
 | 
				
			||||||
	Limit  int64
 | 
						Limit int64
 | 
				
			||||||
	Sort   interface{}
 | 
					 | 
				
			||||||
	RoleID string
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Validate ...
 | 
					// Validate ...
 | 
				
			||||||
func (co PermissionCreateOptions) Validate() error {
 | 
					func (co PermissionCreateOptions) Validate() error {
 | 
				
			||||||
	// Name
 | 
						// Name
 | 
				
			||||||
	if co.Name == "" {
 | 
						if co.Name == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Create: no name data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return errors.New("no name data")
 | 
							return errors.New("no name data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Code
 | 
					 | 
				
			||||||
	if co.Code == "" {
 | 
					 | 
				
			||||||
		return errors.New("no code data")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// RoleID
 | 
						// RoleID
 | 
				
			||||||
	if co.RoleID == "" {
 | 
						if co.RoleID == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Create: no roleID data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return errors.New("no role id data")
 | 
							return errors.New("no role id data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, isValid := mongodb.NewIDFromString(co.RoleID); !isValid {
 | 
						if _, isValid := mongodb.NewIDFromString(co.RoleID); !isValid {
 | 
				
			||||||
| 
						 | 
					@ -52,6 +50,9 @@ func (co PermissionCreateOptions) Validate() error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Desc
 | 
						// Desc
 | 
				
			||||||
	if co.Desc == "" {
 | 
						if co.Desc == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Create: no desc data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return errors.New("no desc data")
 | 
							return errors.New("no desc data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					@ -61,16 +62,17 @@ func (co PermissionCreateOptions) Validate() error {
 | 
				
			||||||
func (co PermissionUpdateOptions) Validate() error {
 | 
					func (co PermissionUpdateOptions) Validate() error {
 | 
				
			||||||
	// Name
 | 
						// Name
 | 
				
			||||||
	if co.Name == "" {
 | 
						if co.Name == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Update: no name data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return errors.New("no name data")
 | 
							return errors.New("no name data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Code
 | 
					 | 
				
			||||||
	if co.Code == "" {
 | 
					 | 
				
			||||||
		return errors.New("no code data")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// RoleID
 | 
						// RoleID
 | 
				
			||||||
	if co.RoleID == "" {
 | 
						if co.RoleID == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Update: no roleID data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return errors.New("no role id data")
 | 
							return errors.New("no role id data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, isValid := mongodb.NewIDFromString(co.RoleID); !isValid {
 | 
						if _, isValid := mongodb.NewIDFromString(co.RoleID); !isValid {
 | 
				
			||||||
| 
						 | 
					@ -79,6 +81,9 @@ func (co PermissionUpdateOptions) Validate() error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Desc
 | 
						// Desc
 | 
				
			||||||
	if co.Desc == "" {
 | 
						if co.Desc == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Update: no desc data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return errors.New("no desc data")
 | 
							return errors.New("no desc data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,5 @@ type (
 | 
				
			||||||
	PermissionAll struct {
 | 
						PermissionAll struct {
 | 
				
			||||||
		List  []Permission `json:"list"`
 | 
							List  []Permission `json:"list"`
 | 
				
			||||||
		Total int64        `json:"total"`
 | 
							Total int64        `json:"total"`
 | 
				
			||||||
		Limit int64        `json:"limit"`
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,11 @@
 | 
				
			||||||
package model
 | 
					package model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
					 | 
				
			||||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
						"go.mongodb.org/mongo-driver/mongo/options"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const maxLimit = 500
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CommonQuery ...
 | 
					// CommonQuery ...
 | 
				
			||||||
type CommonQuery struct {
 | 
					type CommonQuery struct {
 | 
				
			||||||
	Page    int64
 | 
						Page    int64
 | 
				
			||||||
| 
						 | 
					@ -16,20 +13,7 @@ type CommonQuery struct {
 | 
				
			||||||
	Keyword string
 | 
						Keyword string
 | 
				
			||||||
	RoleID  string
 | 
						RoleID  string
 | 
				
			||||||
	Status  string
 | 
						Status  string
 | 
				
			||||||
	Deleted string
 | 
					 | 
				
			||||||
	Sort    interface{}
 | 
						Sort    interface{}
 | 
				
			||||||
	Other   map[string]interface{}
 | 
					 | 
				
			||||||
	RoleIDs []primitive.ObjectID
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AssignDeleted ...
 | 
					 | 
				
			||||||
func (q *CommonQuery) AssignDeleted(cond bson.M) {
 | 
					 | 
				
			||||||
	if q.Deleted == "true" {
 | 
					 | 
				
			||||||
		cond["deleted"] = true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if q.Deleted == "false" {
 | 
					 | 
				
			||||||
		cond["deleted"] = false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AssignKeyword ...
 | 
					// AssignKeyword ...
 | 
				
			||||||
| 
						 | 
					@ -48,17 +32,6 @@ func (q *CommonQuery) AssignRoleID(cond bson.M) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AssignRoleIDs ...
 | 
					 | 
				
			||||||
func (q *CommonQuery) AssignRoleIDs(cond bson.M) {
 | 
					 | 
				
			||||||
	if len(q.RoleIDs) == 1 {
 | 
					 | 
				
			||||||
		cond["roleId"] = q.RoleIDs[0]
 | 
					 | 
				
			||||||
	} else if len(q.RoleIDs) > 1 {
 | 
					 | 
				
			||||||
		cond["roleId"] = bson.M{
 | 
					 | 
				
			||||||
			"$in": q.RoleIDs,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AssignStatus ...
 | 
					// AssignStatus ...
 | 
				
			||||||
func (q *CommonQuery) AssignStatus(cond bson.M) {
 | 
					func (q *CommonQuery) AssignStatus(cond bson.M) {
 | 
				
			||||||
	if q.Status != "" {
 | 
						if q.Status != "" {
 | 
				
			||||||
| 
						 | 
					@ -80,31 +53,7 @@ func (q *CommonQuery) GetFindOptionsUsingPage() *options.FindOptions {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetDefaultLimit ...
 | 
					// SetDefaultLimit ...
 | 
				
			||||||
func (q *CommonQuery) SetDefaultLimit() {
 | 
					func (q *CommonQuery) SetDefaultLimit() {
 | 
				
			||||||
	if q.Limit <= 0 {
 | 
						if q.Limit <= 0 || q.Limit > 20 {
 | 
				
			||||||
		q.Limit = 20
 | 
							q.Limit = 20
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if q.Limit > maxLimit {
 | 
					 | 
				
			||||||
		q.Limit = 500
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AssignOther ...
 | 
					 | 
				
			||||||
func (q *CommonQuery) AssignOther(cond bson.M) {
 | 
					 | 
				
			||||||
	// Query fields in other object
 | 
					 | 
				
			||||||
	if len(q.Other) > 0 {
 | 
					 | 
				
			||||||
		for key, value := range q.Other {
 | 
					 | 
				
			||||||
			switch v := value.(type) {
 | 
					 | 
				
			||||||
			case []primitive.ObjectID:
 | 
					 | 
				
			||||||
				cond["other."+key] = bson.M{
 | 
					 | 
				
			||||||
					"$in": v,
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			case []string:
 | 
					 | 
				
			||||||
				cond["other."+key] = bson.M{
 | 
					 | 
				
			||||||
					"$in": v,
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				cond["other."+key] = value
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,35 +3,33 @@ package model
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RoleCreateOptions ...
 | 
					// RoleCreateOptions ...
 | 
				
			||||||
type RoleCreateOptions struct {
 | 
					type RoleCreateOptions struct {
 | 
				
			||||||
	Name    string
 | 
						Name string
 | 
				
			||||||
	Level   int
 | 
					 | 
				
			||||||
	IsAdmin bool
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RoleUpdateOptions ...
 | 
					// RoleUpdateOptions ...
 | 
				
			||||||
type RoleUpdateOptions struct {
 | 
					type RoleUpdateOptions struct {
 | 
				
			||||||
	Name    string
 | 
						Name string
 | 
				
			||||||
	Level   int
 | 
					 | 
				
			||||||
	IsAdmin bool
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RoleAllQuery ...
 | 
					// RoleAllQuery ...
 | 
				
			||||||
type RoleAllQuery struct {
 | 
					type RoleAllQuery struct {
 | 
				
			||||||
	Page  int64
 | 
						Page  int64
 | 
				
			||||||
	Limit int64
 | 
						Limit int64
 | 
				
			||||||
	Sort  interface{}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Validate ...
 | 
					// Validate ...
 | 
				
			||||||
func (co RoleCreateOptions) Validate() error {
 | 
					func (co RoleCreateOptions) Validate() error {
 | 
				
			||||||
	// Name
 | 
						// Name
 | 
				
			||||||
	if co.Name == "" {
 | 
						if co.Name == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidName)
 | 
							logger.Error("usermngmt - Role - Create: no name data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no name data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					@ -41,7 +39,10 @@ func (co RoleCreateOptions) Validate() error {
 | 
				
			||||||
func (co RoleUpdateOptions) Validate() error {
 | 
					func (co RoleUpdateOptions) Validate() error {
 | 
				
			||||||
	// Name
 | 
						// Name
 | 
				
			||||||
	if co.Name == "" {
 | 
						if co.Name == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidName)
 | 
							logger.Error("usermngmt - Role - Update: no name data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no name data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,6 @@ import (
 | 
				
			||||||
type RoleShort struct {
 | 
					type RoleShort struct {
 | 
				
			||||||
	ID      string `json:"_id"`
 | 
						ID      string `json:"_id"`
 | 
				
			||||||
	Name    string `json:"name"`
 | 
						Name    string `json:"name"`
 | 
				
			||||||
	Level   int    `json:"level"`
 | 
					 | 
				
			||||||
	IsAdmin bool   `json:"isAdmin"`
 | 
						IsAdmin bool   `json:"isAdmin"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +16,6 @@ type Role struct {
 | 
				
			||||||
	ID        string    `json:"_id"`
 | 
						ID        string    `json:"_id"`
 | 
				
			||||||
	Name      string    `json:"name"`
 | 
						Name      string    `json:"name"`
 | 
				
			||||||
	Code      string    `json:"code"`
 | 
						Code      string    `json:"code"`
 | 
				
			||||||
	Level     int       `json:"level"`
 | 
					 | 
				
			||||||
	IsAdmin   bool      `json:"isAdmin"`
 | 
						IsAdmin   bool      `json:"isAdmin"`
 | 
				
			||||||
	CreatedAt time.Time `json:"createdAt"`
 | 
						CreatedAt time.Time `json:"createdAt"`
 | 
				
			||||||
	UpdatedAt time.Time `json:"updatedAt"`
 | 
						UpdatedAt time.Time `json:"updatedAt"`
 | 
				
			||||||
| 
						 | 
					@ -28,6 +26,5 @@ type (
 | 
				
			||||||
	RoleAll struct {
 | 
						RoleAll struct {
 | 
				
			||||||
		List  []Role `json:"list"`
 | 
							List  []Role `json:"list"`
 | 
				
			||||||
		Total int64  `json:"total"`
 | 
							Total int64  `json:"total"`
 | 
				
			||||||
		Limit int64  `json:"limit"`
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,22 +3,18 @@ package model
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UserCreateOptions ...
 | 
					// UserCreateOptions ...
 | 
				
			||||||
type UserCreateOptions struct {
 | 
					type UserCreateOptions struct {
 | 
				
			||||||
	Name                    string
 | 
						Name     string
 | 
				
			||||||
	Phone                   string
 | 
						Phone    string
 | 
				
			||||||
	Email                   string
 | 
						Email    string
 | 
				
			||||||
	Password                string
 | 
						Password string
 | 
				
			||||||
	Status                  string
 | 
						Status   string
 | 
				
			||||||
	RoleID                  string
 | 
						RoleID   string
 | 
				
			||||||
	RequireToChangePassword bool
 | 
						Other    string
 | 
				
			||||||
	Other                   interface{}
 | 
					 | 
				
			||||||
	Avatar                  interface{} // if not, pass default file object
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UserUpdateOptions ...
 | 
					// UserUpdateOptions ...
 | 
				
			||||||
| 
						 | 
					@ -27,7 +23,7 @@ type UserUpdateOptions struct {
 | 
				
			||||||
	Phone  string
 | 
						Phone  string
 | 
				
			||||||
	Email  string
 | 
						Email  string
 | 
				
			||||||
	RoleID string
 | 
						RoleID string
 | 
				
			||||||
	Other  map[string]interface{}
 | 
						Other  string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChangePasswordOptions ...
 | 
					// ChangePasswordOptions ...
 | 
				
			||||||
| 
						 | 
					@ -43,59 +39,56 @@ type UserAllQuery struct {
 | 
				
			||||||
	Keyword string
 | 
						Keyword string
 | 
				
			||||||
	RoleID  string
 | 
						RoleID  string
 | 
				
			||||||
	Status  string
 | 
						Status  string
 | 
				
			||||||
	Sort    interface{}
 | 
					 | 
				
			||||||
	Other   map[string]interface{} // query fields in other object
 | 
					 | 
				
			||||||
	Cond    bson.M
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UserByPermissionQuery ...
 | 
					 | 
				
			||||||
type UserByPermissionQuery struct {
 | 
					 | 
				
			||||||
	Page       int64
 | 
					 | 
				
			||||||
	Limit      int64
 | 
					 | 
				
			||||||
	Keyword    string
 | 
					 | 
				
			||||||
	Status     string
 | 
					 | 
				
			||||||
	Permission string // permission code
 | 
					 | 
				
			||||||
	Sort       interface{}
 | 
					 | 
				
			||||||
	Other      map[string]interface{} // query fields in other object
 | 
					 | 
				
			||||||
	Cond       bson.M
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UserCountQuery ...
 | 
					 | 
				
			||||||
type UserCountQuery struct {
 | 
					 | 
				
			||||||
	RoleID string
 | 
					 | 
				
			||||||
	Other  map[string]interface{} // query fields in other object
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Validate ...
 | 
					// Validate ...
 | 
				
			||||||
func (co UserCreateOptions) Validate() error {
 | 
					func (co UserCreateOptions) Validate() error {
 | 
				
			||||||
	// Name
 | 
						// Name
 | 
				
			||||||
	if co.Name == "" {
 | 
						if co.Name == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidName)
 | 
							logger.Error("usermngmt - User - Create: no name data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no name data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Phone
 | 
						// Phone
 | 
				
			||||||
	if co.Phone == "" {
 | 
						if co.Phone == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPhoneNumber)
 | 
							logger.Error("usermngmt - User - Create: no phone data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no phone data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Email
 | 
						// Email
 | 
				
			||||||
	if co.Email == "" {
 | 
						if co.Email == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidEmail)
 | 
							logger.Error("usermngmt - User - Create: no email data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no email data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Password
 | 
						// Password
 | 
				
			||||||
	if co.Password == "" {
 | 
						if co.Password == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPassword)
 | 
							logger.Error("usermngmt - User - Create: no password data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no password data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Status
 | 
						// Status
 | 
				
			||||||
	if co.Status == "" {
 | 
						if co.Status == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidStatus)
 | 
							logger.Error("usermngmt - User - Create: no status data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no status data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// RoleID
 | 
						// RoleID
 | 
				
			||||||
	if co.RoleID == "" {
 | 
						if co.RoleID == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidRole)
 | 
							logger.Error("usermngmt - User - Create: no roleID data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no role id data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					@ -105,22 +98,34 @@ func (co UserCreateOptions) Validate() error {
 | 
				
			||||||
func (uo UserUpdateOptions) Validate() error {
 | 
					func (uo UserUpdateOptions) Validate() error {
 | 
				
			||||||
	// Name
 | 
						// Name
 | 
				
			||||||
	if uo.Name == "" {
 | 
						if uo.Name == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidName)
 | 
							logger.Error("usermngmt - User - Update: no name data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": uo,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no name data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Phone
 | 
						// Phone
 | 
				
			||||||
	if uo.Phone == "" {
 | 
						if uo.Phone == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPhoneNumber)
 | 
							logger.Error("usermngmt - User - Update: no phone data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": uo,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no phone data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Email
 | 
						// Email
 | 
				
			||||||
	if uo.Email == "" {
 | 
						if uo.Email == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidEmail)
 | 
							logger.Error("usermngmt - User - Update: no email data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": uo,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no email data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// RoleID
 | 
						// RoleID
 | 
				
			||||||
	if uo.RoleID == "" {
 | 
						if uo.RoleID == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidRole)
 | 
							logger.Error("usermngmt - User - Update: no roleID data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": uo,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("no role id data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					@ -129,22 +134,11 @@ func (uo UserUpdateOptions) Validate() error {
 | 
				
			||||||
// Validate ...
 | 
					// Validate ...
 | 
				
			||||||
func (co ChangePasswordOptions) Validate() error {
 | 
					func (co ChangePasswordOptions) Validate() error {
 | 
				
			||||||
	// OldPassword, NewPassword
 | 
						// OldPassword, NewPassword
 | 
				
			||||||
	if co.OldPassword == "" {
 | 
						if co.OldPassword == "" || co.NewPassword == "" {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidOldPassword)
 | 
							logger.Error("usermngmt - User - ChangePassword: old or new password cannot be empty", logger.LogData{
 | 
				
			||||||
	}
 | 
								"payload": co,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	if co.NewPassword == "" {
 | 
							return errors.New("old or new password cannot be empty")
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidNewPassword)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Validate ...
 | 
					 | 
				
			||||||
func (q UserByPermissionQuery) Validate() error {
 | 
					 | 
				
			||||||
	// OldPassword, NewPassword
 | 
					 | 
				
			||||||
	if q.Permission == "" {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPermission)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,51 +1,20 @@
 | 
				
			||||||
package model
 | 
					package model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
					 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
					 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// User ...
 | 
					// User ...
 | 
				
			||||||
type User struct {
 | 
					type User struct {
 | 
				
			||||||
	ID                      string      `json:"_id"`
 | 
						ID        string    `json:"_id"`
 | 
				
			||||||
	Name                    string      `json:"name"`
 | 
						Name      string    `json:"name"`
 | 
				
			||||||
	Phone                   string      `json:"phone"`
 | 
						Phone     string    `json:"phone"`
 | 
				
			||||||
	Email                   string      `json:"email"`
 | 
						Email     string    `json:"email"`
 | 
				
			||||||
	Status                  string      `json:"status"`
 | 
						Status    string    `json:"status"`
 | 
				
			||||||
	Role                    RoleShort   `json:"role"`
 | 
						Role      RoleShort `json:"role"`
 | 
				
			||||||
	RequireToChangePassword bool        `json:"requireToChangePassword"`
 | 
						Other     string    `json:"other"`
 | 
				
			||||||
	Other                   interface{} `json:"other"`
 | 
						CreatedAt time.Time `json:"createdAt"`
 | 
				
			||||||
	Avatar                  interface{} `json:"avatar"`
 | 
						UpdatedAt time.Time `json:"updatedAt"`
 | 
				
			||||||
	CreatedAt               time.Time   `json:"createdAt"`
 | 
					 | 
				
			||||||
	UpdatedAt               time.Time   `json:"updatedAt"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UserOtherBson ...
 | 
					 | 
				
			||||||
type UserOtherBson struct {
 | 
					 | 
				
			||||||
	Supplier    primitive.ObjectID   `bson:"supplier"`
 | 
					 | 
				
			||||||
	Inventories []primitive.ObjectID `bson:"inventories"`
 | 
					 | 
				
			||||||
	IsPresident bool                 `bson:"isPresident"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type UserOther struct {
 | 
					 | 
				
			||||||
	Supplier    string   `json:"supplier"`
 | 
					 | 
				
			||||||
	Inventories []string `json:"inventories"`
 | 
					 | 
				
			||||||
	IsPresident bool     `json:"isPresident"`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m User) GetUserOther() UserOther {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		userOtherBson UserOtherBson
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	bsonBytes, _ := bson.Marshal(m.Other)
 | 
					 | 
				
			||||||
	bson.Unmarshal(bsonBytes, &userOtherBson)
 | 
					 | 
				
			||||||
	return UserOther{
 | 
					 | 
				
			||||||
		Supplier:    userOtherBson.Supplier.Hex(),
 | 
					 | 
				
			||||||
		Inventories: internal.ConvertObjectIDsToStrings(userOtherBson.Inventories),
 | 
					 | 
				
			||||||
		IsPresident: userOtherBson.IsPresident,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
| 
						 | 
					@ -53,6 +22,5 @@ type (
 | 
				
			||||||
	UserAll struct {
 | 
						UserAll struct {
 | 
				
			||||||
		List  []User `json:"list"`
 | 
							List  []User `json:"list"`
 | 
				
			||||||
		Total int64  `json:"total"`
 | 
							Total int64  `json:"total"`
 | 
				
			||||||
		Limit int64  `json:"limit"`
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,14 +3,13 @@ package permission
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/database"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
						"go.mongodb.org/mongo-driver/bson/primitive"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
						"go.mongodb.org/mongo-driver/mongo/options"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/database"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func findByID(ctx context.Context, id primitive.ObjectID) (model.DBPermission, error) {
 | 
					func findByID(ctx context.Context, id primitive.ObjectID) (model.DBPermission, error) {
 | 
				
			||||||
| 
						 | 
					@ -28,6 +27,10 @@ func create(ctx context.Context, doc model.DBPermission) error {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.InsertOne(ctx, doc)
 | 
						_, err := col.InsertOne(ctx, doc)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - InsertOne", logger.LogData{
 | 
				
			||||||
 | 
								"doc": doc,
 | 
				
			||||||
 | 
								"err": err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when create permission: %s", err.Error())
 | 
							return fmt.Errorf("error when create permission: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,36 +43,17 @@ func updateOneByCondition(ctx context.Context, cond interface{}, payload interfa
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.UpdateOne(ctx, cond, payload)
 | 
						_, err := col.UpdateOne(ctx, cond, payload)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - UpdateOne", logger.LogData{
 | 
				
			||||||
 | 
								"cond":    cond,
 | 
				
			||||||
 | 
								"payload": payload,
 | 
				
			||||||
 | 
								"err":     err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when update permission: %s", err.Error())
 | 
							return fmt.Errorf("error when update permission: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func deleteOneByCondition(ctx context.Context, cond interface{}) error {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		col = database.GetPermissionCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	_, err := col.DeleteOne(ctx, cond)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("error when delete permission: %s", err.Error())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func findOneAndDelete(ctx context.Context, cond interface{}) (doc model.DBPermission, err error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		col = database.GetPermissionCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	err = col.FindOneAndDelete(ctx, cond).Decode(&doc)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return doc, fmt.Errorf("error when findOneAndDelete permission: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return doc, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func findByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBPermission) {
 | 
					func findByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBPermission) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		col = database.GetPermissionCol()
 | 
							col = database.GetPermissionCol()
 | 
				
			||||||
| 
						 | 
					@ -78,10 +62,20 @@ func findByCondition(ctx context.Context, cond interface{}, opts ...*options.Fin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
						cursor, err := col.Find(ctx, cond, opts...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Find", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
						defer cursor.Close(ctx)
 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
						if err = cursor.All(ctx, &docs); err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Permission - Decode", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					@ -94,22 +88,10 @@ func countByCondition(ctx context.Context, cond interface{}) int64 {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
						total, err := col.CountDocuments(ctx, cond)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("permission - countByCondition", err)
 | 
							logger.Error("usermngmt - Permission - CountDocuments", logger.LogData{
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return total
 | 
						return total
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func isPermissionIDExisted(ctx context.Context, permissionID primitive.ObjectID) bool {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		col = database.GetPermissionCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	// Find
 | 
					 | 
				
			||||||
	cond := bson.M{
 | 
					 | 
				
			||||||
		"_id": permissionID,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return total != 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,34 +5,32 @@ import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/internal"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create ...
 | 
					// Create ...
 | 
				
			||||||
func Create(payload model.PermissionCreateOptions) (result string, err error) {
 | 
					func Create(payload model.PermissionCreateOptions) error {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		ctx = context.Background()
 | 
							ctx = context.Background()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Validate payload
 | 
						// Validate payload
 | 
				
			||||||
	if err = payload.Validate(); err != nil {
 | 
						if err := payload.Validate(); err != nil {
 | 
				
			||||||
		return
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// New permission data from payload
 | 
						// New permission data from payload
 | 
				
			||||||
	doc := newPermission(payload)
 | 
						doc := newPermission(payload)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create permission
 | 
						// Create permission
 | 
				
			||||||
	if err = create(ctx, doc); err != nil {
 | 
						if err := create(ctx, doc); err != nil {
 | 
				
			||||||
		return
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = doc.ID.Hex()
 | 
						return nil
 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newPermission ...
 | 
					// newPermission ...
 | 
				
			||||||
| 
						 | 
					@ -42,7 +40,7 @@ func newPermission(payload model.PermissionCreateOptions) model.DBPermission {
 | 
				
			||||||
	return model.DBPermission{
 | 
						return model.DBPermission{
 | 
				
			||||||
		ID:        mongodb.NewObjectID(),
 | 
							ID:        mongodb.NewObjectID(),
 | 
				
			||||||
		Name:      payload.Name,
 | 
							Name:      payload.Name,
 | 
				
			||||||
		Code:      payload.Code,
 | 
							Code:      internal.GenerateCode(payload.Name),
 | 
				
			||||||
		RoleID:    roleID,
 | 
							RoleID:    roleID,
 | 
				
			||||||
		Desc:      payload.Desc,
 | 
							Desc:      payload.Desc,
 | 
				
			||||||
		CreatedAt: timeNow,
 | 
							CreatedAt: timeNow,
 | 
				
			||||||
| 
						 | 
					@ -61,13 +59,10 @@ func Update(permissionID string, payload model.PermissionUpdateOptions) error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find permissionID exists or not
 | 
						// Validate permissionID
 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(permissionID)
 | 
						id, isValid := mongodb.NewIDFromString(permissionID)
 | 
				
			||||||
	if !isValid {
 | 
						if !isValid {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPermission)
 | 
							return errors.New("invalid permission id data")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !isPermissionIDExisted(ctx, id) {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundPermission)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup condition
 | 
						// Setup condition
 | 
				
			||||||
| 
						 | 
					@ -80,7 +75,7 @@ func Update(permissionID string, payload model.PermissionUpdateOptions) error {
 | 
				
			||||||
	updateData := bson.M{
 | 
						updateData := bson.M{
 | 
				
			||||||
		"$set": bson.M{
 | 
							"$set": bson.M{
 | 
				
			||||||
			"name":      payload.Name,
 | 
								"name":      payload.Name,
 | 
				
			||||||
			"code":      payload.Code,
 | 
								"code":      internal.GenerateCode(payload.Name),
 | 
				
			||||||
			"roleId":    roleID,
 | 
								"roleId":    roleID,
 | 
				
			||||||
			"desc":      payload.Desc,
 | 
								"desc":      payload.Desc,
 | 
				
			||||||
			"updatedAt": internal.Now(),
 | 
								"updatedAt": internal.Now(),
 | 
				
			||||||
| 
						 | 
					@ -95,48 +90,6 @@ func Update(permissionID string, payload model.PermissionUpdateOptions) error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Delete ...
 | 
					 | 
				
			||||||
func Delete(permissionID string) error {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find permissionID exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(permissionID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPermission)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !isPermissionIDExisted(ctx, id) {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundPermission)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Delete
 | 
					 | 
				
			||||||
	if err := deleteOneByCondition(ctx, bson.M{"_id": id}); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func FindByIDAndDelete(permissionID string) (*model.Permission, error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find permissionID exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(permissionID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		return nil, errors.New(internal.ErrorInvalidPermission)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	cond := bson.M{"_id": id}
 | 
					 | 
				
			||||||
	doc, err := findOneAndDelete(ctx, cond)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	res := getResponse(doc)
 | 
					 | 
				
			||||||
	return &res, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// All ...
 | 
					// All ...
 | 
				
			||||||
func All(queryParams model.PermissionAllQuery) (r model.PermissionAll) {
 | 
					func All(queryParams model.PermissionAllQuery) (r model.PermissionAll) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
| 
						 | 
					@ -145,15 +98,13 @@ func All(queryParams model.PermissionAllQuery) (r model.PermissionAll) {
 | 
				
			||||||
		cond = bson.M{}
 | 
							cond = bson.M{}
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	query := model.CommonQuery{
 | 
						query := model.CommonQuery{
 | 
				
			||||||
		Page:   queryParams.Page,
 | 
							Page:  queryParams.Page,
 | 
				
			||||||
		Limit:  queryParams.Limit,
 | 
							Limit: queryParams.Limit,
 | 
				
			||||||
		Sort:   queryParams.Sort,
 | 
							Sort:  bson.M{"createdAt": -1},
 | 
				
			||||||
		RoleID: queryParams.RoleID,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Assign condition
 | 
						// Assign condition
 | 
				
			||||||
	query.SetDefaultLimit()
 | 
						query.SetDefaultLimit()
 | 
				
			||||||
	query.AssignRoleID(cond)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg.Add(1)
 | 
						wg.Add(1)
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
| 
						 | 
					@ -170,27 +121,22 @@ func All(queryParams model.PermissionAllQuery) (r model.PermissionAll) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg.Wait()
 | 
						wg.Wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.Limit = query.Limit
 | 
					 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getResponseList(permissions []model.DBPermission) []model.Permission {
 | 
					func getResponseList(permissions []model.DBPermission) []model.Permission {
 | 
				
			||||||
	res := make([]model.Permission, 0)
 | 
						res := make([]model.Permission, 0)
 | 
				
			||||||
	for _, permission := range permissions {
 | 
						for _, permission := range permissions {
 | 
				
			||||||
		res = append(res, getResponse(permission))
 | 
							res = append(res, model.Permission{
 | 
				
			||||||
 | 
								ID:        permission.ID.Hex(),
 | 
				
			||||||
 | 
								Name:      permission.Name,
 | 
				
			||||||
 | 
								Code:      permission.Code,
 | 
				
			||||||
 | 
								RoleID:    permission.RoleID.Hex(),
 | 
				
			||||||
 | 
								Desc:      permission.Desc,
 | 
				
			||||||
 | 
								CreatedAt: permission.CreatedAt,
 | 
				
			||||||
 | 
								UpdatedAt: permission.UpdatedAt,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return res
 | 
						return res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func getResponse(permission model.DBPermission) model.Permission {
 | 
					 | 
				
			||||||
	return model.Permission{
 | 
					 | 
				
			||||||
		ID:        permission.ID.Hex(),
 | 
					 | 
				
			||||||
		Name:      permission.Name,
 | 
					 | 
				
			||||||
		Code:      permission.Code,
 | 
					 | 
				
			||||||
		RoleID:    permission.RoleID.Hex(),
 | 
					 | 
				
			||||||
		Desc:      permission.Desc,
 | 
					 | 
				
			||||||
		CreatedAt: permission.CreatedAt,
 | 
					 | 
				
			||||||
		UpdatedAt: permission.UpdatedAt,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								role/db.go
								
								
								
								
							
							
						
						
									
										58
									
								
								role/db.go
								
								
								
								
							| 
						 | 
					@ -3,14 +3,11 @@ package role
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
						"github.com/Selly-Modules/usermngmt/database"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
						"go.mongodb.org/mongo-driver/mongo/options"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/database"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func create(ctx context.Context, doc model.DBRole) error {
 | 
					func create(ctx context.Context, doc model.DBRole) error {
 | 
				
			||||||
| 
						 | 
					@ -19,6 +16,10 @@ func create(ctx context.Context, doc model.DBRole) error {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.InsertOne(ctx, doc)
 | 
						_, err := col.InsertOne(ctx, doc)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Role - InsertOne", logger.LogData{
 | 
				
			||||||
 | 
								"doc": doc,
 | 
				
			||||||
 | 
								"err": err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when create role: %s", err.Error())
 | 
							return fmt.Errorf("error when create role: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +32,11 @@ func updateOneByCondition(ctx context.Context, cond interface{}, payload interfa
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.UpdateOne(ctx, cond, payload)
 | 
						_, err := col.UpdateOne(ctx, cond, payload)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Role - UpdateOne", logger.LogData{
 | 
				
			||||||
 | 
								"cond":    cond,
 | 
				
			||||||
 | 
								"payload": payload,
 | 
				
			||||||
 | 
								"err":     err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when update role: %s", err.Error())
 | 
							return fmt.Errorf("error when update role: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,11 +51,20 @@ func findByCondition(ctx context.Context, cond interface{}, opts ...*options.Fin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
						cursor, err := col.Find(ctx, cond, opts...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Printf("usermngmt.findByCondition - Role - Find cond: %v, opts: %v\n", cond, opts)
 | 
							logger.Error("usermngmt - Role - Find", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
						defer cursor.Close(ctx)
 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
						if err = cursor.All(ctx, &docs); err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - Role - Decode", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					@ -62,31 +77,10 @@ func countByCondition(ctx context.Context, cond interface{}) int64 {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
						total, err := col.CountDocuments(ctx, cond)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("usermngmt.countByCondition - Role: ", err)
 | 
							logger.Error("usermngmt - Role - CountDocuments", logger.LogData{
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return total
 | 
						return total
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func isRoleIDExisted(ctx context.Context, roleID primitive.ObjectID) bool {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		col = database.GetRoleCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	// Find
 | 
					 | 
				
			||||||
	cond := bson.M{
 | 
					 | 
				
			||||||
		"_id": roleID,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return false
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return total != 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func findByID(ctx context.Context, id primitive.ObjectID) (model.DBRole, error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		doc model.DBRole
 | 
					 | 
				
			||||||
		col = database.GetRoleCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc)
 | 
					 | 
				
			||||||
	return doc, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,33 +5,32 @@ import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
						"github.com/Selly-Modules/usermngmt/internal"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create ...
 | 
					// Create ...
 | 
				
			||||||
func Create(payload model.RoleCreateOptions) (result string, err error) {
 | 
					func Create(payload model.RoleCreateOptions) error {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		ctx = context.Background()
 | 
							ctx = context.Background()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Validate payload
 | 
						// Validate payload
 | 
				
			||||||
	if err = payload.Validate(); err != nil {
 | 
						if err := payload.Validate(); err != nil {
 | 
				
			||||||
		return
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// New role data from payload
 | 
						// New role data from payload
 | 
				
			||||||
	doc := newRole(payload)
 | 
						doc := newRole(payload)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create role
 | 
						// Create role
 | 
				
			||||||
	if err = create(ctx, doc); err != nil {
 | 
						if err := create(ctx, doc); err != nil {
 | 
				
			||||||
		return
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = doc.ID.Hex()
 | 
						return nil
 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newRole ...
 | 
					// newRole ...
 | 
				
			||||||
| 
						 | 
					@ -41,8 +40,6 @@ func newRole(payload model.RoleCreateOptions) model.DBRole {
 | 
				
			||||||
		ID:        mongodb.NewObjectID(),
 | 
							ID:        mongodb.NewObjectID(),
 | 
				
			||||||
		Name:      payload.Name,
 | 
							Name:      payload.Name,
 | 
				
			||||||
		Code:      internal.GenerateCode(payload.Name),
 | 
							Code:      internal.GenerateCode(payload.Name),
 | 
				
			||||||
		Level:     payload.Level,
 | 
					 | 
				
			||||||
		IsAdmin:   payload.IsAdmin,
 | 
					 | 
				
			||||||
		CreatedAt: timeNow,
 | 
							CreatedAt: timeNow,
 | 
				
			||||||
		UpdatedAt: timeNow,
 | 
							UpdatedAt: timeNow,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -62,12 +59,7 @@ 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(internal.ErrorInvalidRole)
 | 
							return errors.New("invalid role id data")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find roleID exists or not
 | 
					 | 
				
			||||||
	if !isRoleIDExisted(ctx, id) {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundRole)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup condition
 | 
						// Setup condition
 | 
				
			||||||
| 
						 | 
					@ -80,8 +72,6 @@ func Update(roleID string, payload model.RoleUpdateOptions) error {
 | 
				
			||||||
		"$set": bson.M{
 | 
							"$set": bson.M{
 | 
				
			||||||
			"name":      payload.Name,
 | 
								"name":      payload.Name,
 | 
				
			||||||
			"code":      internal.GenerateCode(payload.Name),
 | 
								"code":      internal.GenerateCode(payload.Name),
 | 
				
			||||||
			"level":     payload.Level,
 | 
					 | 
				
			||||||
			"isAdmin":   payload.IsAdmin,
 | 
					 | 
				
			||||||
			"updatedAt": internal.Now(),
 | 
								"updatedAt": internal.Now(),
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -104,7 +94,7 @@ func All(queryParams model.RoleAllQuery) (r model.RoleAll) {
 | 
				
			||||||
	query := model.CommonQuery{
 | 
						query := model.CommonQuery{
 | 
				
			||||||
		Page:  queryParams.Page,
 | 
							Page:  queryParams.Page,
 | 
				
			||||||
		Limit: queryParams.Limit,
 | 
							Limit: queryParams.Limit,
 | 
				
			||||||
		Sort:  queryParams.Sort,
 | 
							Sort:  bson.M{"createdAt": -1},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Assign condition
 | 
						// Assign condition
 | 
				
			||||||
| 
						 | 
					@ -114,11 +104,7 @@ func All(queryParams model.RoleAllQuery) (r model.RoleAll) {
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		defer wg.Done()
 | 
							defer wg.Done()
 | 
				
			||||||
		docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
 | 
							docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
 | 
				
			||||||
		res := make([]model.Role, 0)
 | 
							r.List = getResponseList(docs)
 | 
				
			||||||
		for _, doc := range docs {
 | 
					 | 
				
			||||||
			res = append(res, getResponse(doc))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		r.List = res
 | 
					 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg.Add(1)
 | 
						wg.Add(1)
 | 
				
			||||||
| 
						 | 
					@ -129,40 +115,20 @@ func All(queryParams model.RoleAllQuery) (r model.RoleAll) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg.Wait()
 | 
						wg.Wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.Limit = query.Limit
 | 
					 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getResponse(role model.DBRole) model.Role {
 | 
					func getResponseList(roles []model.DBRole) []model.Role {
 | 
				
			||||||
	return model.Role{
 | 
						res := make([]model.Role, 0)
 | 
				
			||||||
		ID:        role.ID.Hex(),
 | 
						for _, role := range roles {
 | 
				
			||||||
		Name:      role.Name,
 | 
							res = append(res, model.Role{
 | 
				
			||||||
		Code:      role.Code,
 | 
								ID:        role.ID.Hex(),
 | 
				
			||||||
		Level:     role.Level,
 | 
								Name:      role.Name,
 | 
				
			||||||
		IsAdmin:   role.IsAdmin,
 | 
								Code:      role.Code,
 | 
				
			||||||
		CreatedAt: role.CreatedAt,
 | 
								CreatedAt: role.CreatedAt,
 | 
				
			||||||
		UpdatedAt: role.UpdatedAt,
 | 
								UpdatedAt: role.UpdatedAt,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
// FindRole ...
 | 
					 | 
				
			||||||
func FindRole(roleID string) (r model.Role, err error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find role exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(roleID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidRole)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	role, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if role.ID.IsZero() {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorNotFoundRole)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r = getResponse(role)
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										113
									
								
								user/db.go
								
								
								
								
							
							
						
						
									
										113
									
								
								user/db.go
								
								
								
								
							| 
						 | 
					@ -3,49 +3,42 @@ package user
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/database"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
						"go.mongodb.org/mongo-driver/bson/primitive"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/mongo/options"
 | 
						"go.mongodb.org/mongo-driver/mongo/options"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/database"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func isPhoneNumberExisted(ctx context.Context, phone string) bool {
 | 
					func isPhoneNumberOrEmailExisted(ctx context.Context, phone, email string) bool {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		col = database.GetUserCol()
 | 
							col = database.GetUserCol()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	// Find
 | 
						// Find
 | 
				
			||||||
	cond := bson.M{
 | 
						cond := bson.M{
 | 
				
			||||||
		"phone":   phone,
 | 
							"$or": []bson.M{
 | 
				
			||||||
		"deleted": false,
 | 
								{
 | 
				
			||||||
 | 
									"phone": phone,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									"email": email,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
						total, err := col.CountDocuments(ctx, cond)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - User - CountDocuments", logger.LogData{
 | 
				
			||||||
 | 
								"condition": cond,
 | 
				
			||||||
 | 
								"err":       err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return total != 0
 | 
						return total != 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func isEmailExisted(ctx context.Context, email string) bool {
 | 
					func isRoleIDExisted(ctx context.Context, roleID primitive.ObjectID) bool {
 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		col = database.GetUserCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	// Find
 | 
					 | 
				
			||||||
	cond := bson.M{
 | 
					 | 
				
			||||||
		"email":   email,
 | 
					 | 
				
			||||||
		"deleted": false,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return total != 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isRoleExisted(ctx context.Context, roleID primitive.ObjectID) bool {
 | 
					 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		col = database.GetRoleCol()
 | 
							col = database.GetRoleCol()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
| 
						 | 
					@ -55,7 +48,11 @@ func isRoleExisted(ctx context.Context, roleID primitive.ObjectID) bool {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
						total, err := col.CountDocuments(ctx, cond)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("isRoleExisted - count: ", err)
 | 
							logger.Error("usermngmt - Role - CountDocuments", logger.LogData{
 | 
				
			||||||
 | 
								"condition": cond,
 | 
				
			||||||
 | 
								"err":       err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return total != 0
 | 
						return total != 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -69,38 +66,19 @@ func roleFindByID(ctx context.Context, id primitive.ObjectID) (model.DBRole, err
 | 
				
			||||||
	return doc, err
 | 
						return doc, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func roleFindByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBRole) {
 | 
					// permissionCountByCondition ...
 | 
				
			||||||
	var (
 | 
					func permissionCountByCondition(ctx context.Context, cond interface{}) int64 {
 | 
				
			||||||
		col = database.GetRoleCol()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	docs = make([]model.DBRole, 0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
					 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func permissionFindByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBPermission) {
 | 
					 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		col = database.GetPermissionCol()
 | 
							col = database.GetPermissionCol()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	docs = make([]model.DBPermission, 0)
 | 
						total, err := col.CountDocuments(ctx, cond)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return
 | 
							logger.Error("usermngmt - Permission - CountDocuments", logger.LogData{
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
						return total
 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func create(ctx context.Context, doc model.DBUser) error {
 | 
					func create(ctx context.Context, doc model.DBUser) error {
 | 
				
			||||||
| 
						 | 
					@ -109,6 +87,10 @@ func create(ctx context.Context, doc model.DBUser) error {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.InsertOne(ctx, doc)
 | 
						_, err := col.InsertOne(ctx, doc)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - User - InsertOne", logger.LogData{
 | 
				
			||||||
 | 
								"doc": doc,
 | 
				
			||||||
 | 
								"err": err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when create user: %s", err.Error())
 | 
							return fmt.Errorf("error when create user: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,6 +103,11 @@ func updateOneByCondition(ctx context.Context, cond interface{}, payload interfa
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.UpdateOne(ctx, cond, payload)
 | 
						_, err := col.UpdateOne(ctx, cond, payload)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - User - UpdateOne", logger.LogData{
 | 
				
			||||||
 | 
								"cond":    cond,
 | 
				
			||||||
 | 
								"payload": payload,
 | 
				
			||||||
 | 
								"err":     err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when update user: %s", err.Error())
 | 
							return fmt.Errorf("error when update user: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,6 +120,11 @@ func updateManyByCondition(ctx context.Context, cond interface{}, payload interf
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	_, err := col.UpdateMany(ctx, cond, payload)
 | 
						_, err := col.UpdateMany(ctx, cond, payload)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - User - UpdateMany", logger.LogData{
 | 
				
			||||||
 | 
								"cond":    cond,
 | 
				
			||||||
 | 
								"payload": payload,
 | 
				
			||||||
 | 
								"err":     err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return fmt.Errorf("error when update user: %s", err.Error())
 | 
							return fmt.Errorf("error when update user: %s", err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,7 +136,7 @@ func findByID(ctx context.Context, id primitive.ObjectID) (model.DBUser, error)
 | 
				
			||||||
		doc model.DBUser
 | 
							doc model.DBUser
 | 
				
			||||||
		col = database.GetUserCol()
 | 
							col = database.GetUserCol()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	err := col.FindOne(ctx, bson.M{"_id": id, "deleted": false}).Decode(&doc)
 | 
						err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc)
 | 
				
			||||||
	return doc, err
 | 
						return doc, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,10 +148,20 @@ func findByCondition(ctx context.Context, cond interface{}, opts ...*options.Fin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cursor, err := col.Find(ctx, cond, opts...)
 | 
						cursor, err := col.Find(ctx, cond, opts...)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - User - Find", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer cursor.Close(ctx)
 | 
						defer cursor.Close(ctx)
 | 
				
			||||||
	if err = cursor.All(ctx, &docs); err != nil {
 | 
						if err = cursor.All(ctx, &docs); err != nil {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - User - Decode", logger.LogData{
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
								"opts": opts,
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
| 
						 | 
					@ -172,7 +174,10 @@ func countByCondition(ctx context.Context, cond interface{}) int64 {
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	total, err := col.CountDocuments(ctx, cond)
 | 
						total, err := col.CountDocuments(ctx, cond)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Println("user - countByCondition err:", err)
 | 
							logger.Error("usermngmt - Count", logger.LogData{
 | 
				
			||||||
 | 
								"err":  err.Error(),
 | 
				
			||||||
 | 
								"cond": cond,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return total
 | 
						return total
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										527
									
								
								user/handle.go
								
								
								
								
							
							
						
						
									
										527
									
								
								user/handle.go
								
								
								
								
							| 
						 | 
					@ -5,149 +5,72 @@ import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/logger"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/cache"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/internal"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/model"
 | 
				
			||||||
	"github.com/thoas/go-funk"
 | 
						"github.com/thoas/go-funk"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson"
 | 
						"go.mongodb.org/mongo-driver/bson"
 | 
				
			||||||
	"go.mongodb.org/mongo-driver/bson/primitive"
 | 
						"go.mongodb.org/mongo-driver/bson/primitive"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/cache"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/config"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/model"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create ...
 | 
					// Create ...
 | 
				
			||||||
func Create(payload model.UserCreateOptions) (result string, err error) {
 | 
					func Create(payload model.UserCreateOptions) error {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		ctx = context.Background()
 | 
							ctx = context.Background()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Validate payload
 | 
						// Validate payload
 | 
				
			||||||
	if err = payload.Validate(); err != nil {
 | 
						if err := payload.Validate(); err != nil {
 | 
				
			||||||
		return
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//  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(internal.ErrorInvalidRole)
 | 
							return errors.New("invalid role id data")
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !isRoleExisted(ctx, roleID) {
 | 
						if !isRoleIDExisted(ctx, roleID) {
 | 
				
			||||||
		err = errors.New(internal.ErrorNotFoundRole)
 | 
							return errors.New("role id does not exist")
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find phone number,email exists or not
 | 
						// Find phone number,email exists or not
 | 
				
			||||||
	if config.GetInstance().PhoneNumberIsUnique {
 | 
						if isPhoneNumberOrEmailExisted(ctx, payload.Phone, payload.Email) {
 | 
				
			||||||
		if isPhoneNumberExisted(ctx, payload.Phone) {
 | 
							return errors.New("phone number or email already existed")
 | 
				
			||||||
			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
 | 
				
			||||||
	doc := newUser(payload)
 | 
						doc, err := newUser(payload)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create user
 | 
						// Create user
 | 
				
			||||||
	if err = create(ctx, doc); err != nil {
 | 
						if err = create(ctx, doc); err != nil {
 | 
				
			||||||
		return
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result = doc.ID.Hex()
 | 
						return nil
 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// newUser ...
 | 
					// newUser ...
 | 
				
			||||||
func newUser(payload model.UserCreateOptions) model.DBUser {
 | 
					func newUser(payload model.UserCreateOptions) (result model.DBUser, err error) {
 | 
				
			||||||
	timeNow := internal.Now()
 | 
						timeNow := internal.Now()
 | 
				
			||||||
	roleID, _ := mongodb.NewIDFromString(payload.RoleID)
 | 
						roleID, _ := mongodb.NewIDFromString(payload.RoleID)
 | 
				
			||||||
	return model.DBUser{
 | 
						return model.DBUser{
 | 
				
			||||||
		ID:                      mongodb.NewObjectID(),
 | 
							ID:             mongodb.NewObjectID(),
 | 
				
			||||||
		Name:                    payload.Name,
 | 
							Name:           payload.Name,
 | 
				
			||||||
		SearchString:            internal.GetSearchString(payload.Name, payload.Phone, payload.Email),
 | 
							SearchString:   internal.GetSearchString(payload.Name, payload.Phone, payload.Email),
 | 
				
			||||||
		Phone:                   payload.Phone,
 | 
							Phone:          payload.Phone,
 | 
				
			||||||
		Email:                   payload.Email,
 | 
							Email:          payload.Email,
 | 
				
			||||||
		HashedPassword:          internal.HashPassword(payload.Password),
 | 
							HashedPassword: internal.HashPassword(payload.Password),
 | 
				
			||||||
		RequireToChangePassword: payload.RequireToChangePassword,
 | 
							Status:         payload.Status,
 | 
				
			||||||
		Status:                  payload.Status,
 | 
							RoleID:         roleID,
 | 
				
			||||||
		RoleID:                  roleID,
 | 
							Other:          payload.Other,
 | 
				
			||||||
		Other:                   payload.Other,
 | 
							CreatedAt:      timeNow,
 | 
				
			||||||
		Avatar:                  payload.Avatar,
 | 
							UpdatedAt:      timeNow,
 | 
				
			||||||
		CreatedAt:               timeNow,
 | 
						}, nil
 | 
				
			||||||
		UpdatedAt:               timeNow,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// FindUser ...
 | 
					 | 
				
			||||||
func FindUser(userID string) (r model.User, err error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r = getResponse(ctx, user)
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// FindUserByEmail ...
 | 
					 | 
				
			||||||
func FindUserByEmail(email string) (r model.User, err error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user exists or not
 | 
					 | 
				
			||||||
	if email == "" {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidEmail)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	user, _ := findOneByCondition(ctx, bson.M{"email": email})
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r = getResponse(ctx, user)
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetHashedPassword ...
 | 
					 | 
				
			||||||
func GetHashedPassword(userID string) (result string, err error) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	result = user.HashedPassword
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// All ...
 | 
					// All ...
 | 
				
			||||||
| 
						 | 
					@ -157,18 +80,13 @@ func All(queryParams model.UserAllQuery) (r model.UserAll) {
 | 
				
			||||||
		wg   sync.WaitGroup
 | 
							wg   sync.WaitGroup
 | 
				
			||||||
		cond = bson.M{}
 | 
							cond = bson.M{}
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if queryParams.Cond != nil {
 | 
					 | 
				
			||||||
		cond = queryParams.Cond
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	query := model.CommonQuery{
 | 
						query := model.CommonQuery{
 | 
				
			||||||
		Page:    queryParams.Page,
 | 
							Page:    queryParams.Page,
 | 
				
			||||||
		Limit:   queryParams.Limit,
 | 
							Limit:   queryParams.Limit,
 | 
				
			||||||
		Keyword: queryParams.Keyword,
 | 
							Keyword: queryParams.Keyword,
 | 
				
			||||||
		RoleID:  queryParams.RoleID,
 | 
							RoleID:  queryParams.RoleID,
 | 
				
			||||||
		Status:  queryParams.Status,
 | 
							Status:  queryParams.Status,
 | 
				
			||||||
		Sort:    queryParams.Sort,
 | 
							Sort:    bson.M{"createdAt": -1},
 | 
				
			||||||
		Other:   queryParams.Other,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Assign condition
 | 
						// Assign condition
 | 
				
			||||||
| 
						 | 
					@ -176,9 +94,6 @@ func All(queryParams model.UserAllQuery) (r model.UserAll) {
 | 
				
			||||||
	query.AssignKeyword(cond)
 | 
						query.AssignKeyword(cond)
 | 
				
			||||||
	query.AssignRoleID(cond)
 | 
						query.AssignRoleID(cond)
 | 
				
			||||||
	query.AssignStatus(cond)
 | 
						query.AssignStatus(cond)
 | 
				
			||||||
	query.AssignDeleted(cond)
 | 
					 | 
				
			||||||
	query.AssignOther(cond)
 | 
					 | 
				
			||||||
	cond["deleted"] = false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg.Add(1)
 | 
						wg.Add(1)
 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
| 
						 | 
					@ -199,103 +114,9 @@ func All(queryParams model.UserAllQuery) (r model.UserAll) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg.Wait()
 | 
						wg.Wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.Limit = query.Limit
 | 
					 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetUsersByPermission ...
 | 
					 | 
				
			||||||
func GetUsersByPermission(queryParams model.UserByPermissionQuery) (r model.UserAll) {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx   = context.Background()
 | 
					 | 
				
			||||||
		wg    sync.WaitGroup
 | 
					 | 
				
			||||||
		cond  = bson.M{}
 | 
					 | 
				
			||||||
		roles = make([]primitive.ObjectID, 0)
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	// Validate query
 | 
					 | 
				
			||||||
	if err := queryParams.Validate(); err != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if queryParams.Cond != nil {
 | 
					 | 
				
			||||||
		cond = queryParams.Cond
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get role by permission
 | 
					 | 
				
			||||||
	permissions := permissionFindByCondition(ctx, bson.M{"code": queryParams.Permission})
 | 
					 | 
				
			||||||
	for _, value := range permissions {
 | 
					 | 
				
			||||||
		roles = append(roles, value.RoleID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Get admin role
 | 
					 | 
				
			||||||
	adminRoles := roleFindByCondition(ctx, bson.M{"isAdmin": true})
 | 
					 | 
				
			||||||
	for _, value := range adminRoles {
 | 
					 | 
				
			||||||
		roles = append(roles, value.ID)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(roles) < 0 {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	query := model.CommonQuery{
 | 
					 | 
				
			||||||
		Page:    queryParams.Page,
 | 
					 | 
				
			||||||
		Limit:   queryParams.Limit,
 | 
					 | 
				
			||||||
		Keyword: queryParams.Keyword,
 | 
					 | 
				
			||||||
		Status:  queryParams.Status,
 | 
					 | 
				
			||||||
		Sort:    queryParams.Sort,
 | 
					 | 
				
			||||||
		Other:   queryParams.Other,
 | 
					 | 
				
			||||||
		RoleIDs: roles,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Assign condition
 | 
					 | 
				
			||||||
	query.SetDefaultLimit()
 | 
					 | 
				
			||||||
	query.AssignKeyword(cond)
 | 
					 | 
				
			||||||
	query.AssignRoleIDs(cond)
 | 
					 | 
				
			||||||
	query.AssignStatus(cond)
 | 
					 | 
				
			||||||
	query.AssignDeleted(cond)
 | 
					 | 
				
			||||||
	query.AssignOther(cond)
 | 
					 | 
				
			||||||
	cond["deleted"] = false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wg.Add(1)
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		defer wg.Done()
 | 
					 | 
				
			||||||
		docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
 | 
					 | 
				
			||||||
		res := make([]model.User, 0)
 | 
					 | 
				
			||||||
		for _, doc := range docs {
 | 
					 | 
				
			||||||
			res = append(res, getResponse(ctx, doc))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		r.List = res
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wg.Add(1)
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		defer wg.Done()
 | 
					 | 
				
			||||||
		r.Total = countByCondition(ctx, cond)
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wg.Wait()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r.Limit = query.Limit
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Count  ...
 | 
					 | 
				
			||||||
func Count(queryParams model.UserCountQuery) int64 {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx  = context.Background()
 | 
					 | 
				
			||||||
		cond = bson.M{}
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
	query := model.CommonQuery{
 | 
					 | 
				
			||||||
		RoleID: queryParams.RoleID,
 | 
					 | 
				
			||||||
		Other:  queryParams.Other,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Assign condition
 | 
					 | 
				
			||||||
	query.AssignRoleID(cond)
 | 
					 | 
				
			||||||
	query.AssignOther(cond)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return countByCondition(ctx, cond)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getResponse(ctx context.Context, user model.DBUser) model.User {
 | 
					func getResponse(ctx context.Context, user model.DBUser) model.User {
 | 
				
			||||||
	roleRaw, _ := roleFindByID(ctx, user.RoleID)
 | 
						roleRaw, _ := roleFindByID(ctx, user.RoleID)
 | 
				
			||||||
	return model.User{
 | 
						return model.User{
 | 
				
			||||||
| 
						 | 
					@ -307,14 +128,11 @@ func getResponse(ctx context.Context, user model.DBUser) model.User {
 | 
				
			||||||
		Role: model.RoleShort{
 | 
							Role: model.RoleShort{
 | 
				
			||||||
			ID:      roleRaw.ID.Hex(),
 | 
								ID:      roleRaw.ID.Hex(),
 | 
				
			||||||
			Name:    roleRaw.Name,
 | 
								Name:    roleRaw.Name,
 | 
				
			||||||
			Level:   roleRaw.Level,
 | 
					 | 
				
			||||||
			IsAdmin: roleRaw.IsAdmin,
 | 
								IsAdmin: roleRaw.IsAdmin,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		RequireToChangePassword: user.RequireToChangePassword,
 | 
							Other:     user.Other,
 | 
				
			||||||
		Avatar:                  user.Avatar,
 | 
							CreatedAt: user.CreatedAt,
 | 
				
			||||||
		Other:                   user.Other,
 | 
							UpdatedAt: user.UpdatedAt,
 | 
				
			||||||
		CreatedAt:               user.CreatedAt,
 | 
					 | 
				
			||||||
		UpdatedAt:               user.UpdatedAt,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -332,62 +150,38 @@ 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(internal.ErrorInvalidRole)
 | 
							return errors.New("invalid role id data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !isRoleExisted(ctx, roleID) {
 | 
						if !isRoleIDExisted(ctx, roleID) {
 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundRole)
 | 
							return errors.New("role id does not exist")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find phone number,email exists or not
 | 
						// Find phone number,email exists or not
 | 
				
			||||||
	if config.GetInstance().PhoneNumberIsUnique {
 | 
						if isPhoneNumberOrEmailExisted(ctx, payload.Phone, payload.Email) {
 | 
				
			||||||
		if user.Phone != payload.Phone {
 | 
							return errors.New("phone number or email already existed")
 | 
				
			||||||
			if isPhoneNumberExisted(ctx, payload.Phone) {
 | 
					 | 
				
			||||||
				return errors.New(internal.ErrorAlreadyExistedPhoneNumber)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if config.GetInstance().EmailIsUnique {
 | 
					 | 
				
			||||||
		if user.Email != payload.Email {
 | 
					 | 
				
			||||||
			if isEmailExisted(ctx, payload.Email) {
 | 
					 | 
				
			||||||
				return errors.New(internal.ErrorAlreadyExistedEmail)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup condition
 | 
						// Setup condition
 | 
				
			||||||
 | 
						id, _ := mongodb.NewIDFromString(userID)
 | 
				
			||||||
	cond := bson.M{
 | 
						cond := bson.M{
 | 
				
			||||||
		"_id": id,
 | 
							"_id": id,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup Set operator
 | 
						// Setup update data
 | 
				
			||||||
	setOperator := bson.M{
 | 
						updateData := bson.M{
 | 
				
			||||||
		"name":         payload.Name,
 | 
							"$set": bson.M{
 | 
				
			||||||
		"searchString": internal.GetSearchString(payload.Name, payload.Phone, payload.Email),
 | 
								"name":         payload.Name,
 | 
				
			||||||
		"phone":        payload.Phone,
 | 
								"searchString": internal.GetSearchString(payload.Name, payload.Phone, payload.Email),
 | 
				
			||||||
		"email":        payload.Email,
 | 
								"phone":        payload.Phone,
 | 
				
			||||||
		"roleId":       roleID,
 | 
								"email":        payload.Email,
 | 
				
			||||||
		"updatedAt":    internal.Now(),
 | 
								"roleId":       roleID,
 | 
				
			||||||
	}
 | 
								"other":        payload.Other,
 | 
				
			||||||
	if len(payload.Other) > 0 {
 | 
								"updatedAt":    internal.Now(),
 | 
				
			||||||
		for key, value := range payload.Other {
 | 
							},
 | 
				
			||||||
			setOperator["other."+key] = value
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update
 | 
						// Update
 | 
				
			||||||
	if err := updateOneByCondition(ctx, cond, bson.M{
 | 
						if err := updateOneByCondition(ctx, cond, updateData); err != nil {
 | 
				
			||||||
		"$set": setOperator,
 | 
					 | 
				
			||||||
	}); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -408,101 +202,30 @@ func ChangeUserPassword(userID string, opt model.ChangePasswordOptions) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Validate userID
 | 
						// Validate userID
 | 
				
			||||||
	if _, isValid := mongodb.NewIDFromString(userID); !isValid {
 | 
						if _, isValid := mongodb.NewIDFromString(userID); !isValid {
 | 
				
			||||||
		return errors.New(internal.ErrorInvalidUser)
 | 
							logger.Error("usermngmt - ChangePassword: invalid userID data", logger.LogData{
 | 
				
			||||||
 | 
								"payload": opt,
 | 
				
			||||||
 | 
								"userID":  userID,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							return errors.New("invalid user id data")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 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(internal.ErrorNotFoundUser)
 | 
							return errors.New("user not found")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 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(internal.ErrorIncorrectPassword)
 | 
							return errors.New("the password is incorrect")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update password
 | 
						// Update password
 | 
				
			||||||
	if err = updateOneByCondition(ctx, bson.M{"_id": user.ID}, bson.M{
 | 
						if err = updateOneByCondition(ctx, bson.M{"_id": user.ID}, bson.M{
 | 
				
			||||||
		"$set": bson.M{
 | 
							"$set": bson.M{
 | 
				
			||||||
			"hashedPassword":          internal.HashPassword(opt.NewPassword),
 | 
								"hashedPassword": internal.HashPassword(opt.NewPassword),
 | 
				
			||||||
			"requireToChangePassword": false,
 | 
								"updatedAt":      internal.Now(),
 | 
				
			||||||
			"updatedAt":               internal.Now(),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ResetUserPassword ...
 | 
					 | 
				
			||||||
func ResetUserPassword(userID string, password string) error {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Validate Password
 | 
					 | 
				
			||||||
	if password == "" {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPassword)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Validate userID
 | 
					 | 
				
			||||||
	if _, isValid := mongodb.NewIDFromString(userID); !isValid {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user
 | 
					 | 
				
			||||||
	id, _ := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update password
 | 
					 | 
				
			||||||
	if err := updateOneByCondition(ctx, bson.M{"_id": user.ID}, bson.M{
 | 
					 | 
				
			||||||
		"$set": bson.M{
 | 
					 | 
				
			||||||
			"hashedPassword":          internal.HashPassword(password),
 | 
					 | 
				
			||||||
			"requireToChangePassword": false,
 | 
					 | 
				
			||||||
			"updatedAt":               internal.Now(),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ResetAndRequireToChangeUserPassword ...
 | 
					 | 
				
			||||||
func ResetAndRequireToChangeUserPassword(userID string, password string) error {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Validate Password
 | 
					 | 
				
			||||||
	if password == "" {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidPassword)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Validate userID
 | 
					 | 
				
			||||||
	if _, isValid := mongodb.NewIDFromString(userID); !isValid {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user
 | 
					 | 
				
			||||||
	id, _ := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update password
 | 
					 | 
				
			||||||
	if err := updateOneByCondition(ctx, bson.M{"_id": user.ID}, bson.M{
 | 
					 | 
				
			||||||
		"$set": bson.M{
 | 
					 | 
				
			||||||
			"hashedPassword":          internal.HashPassword(password),
 | 
					 | 
				
			||||||
			"requireToChangePassword": true,
 | 
					 | 
				
			||||||
			"updatedAt":               internal.Now(),
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}); err != nil {
 | 
						}); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
| 
						 | 
					@ -520,10 +243,7 @@ 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(internal.ErrorInvalidUser)
 | 
							return errors.New("invalid user id data")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if user, _ := findByID(ctx, id); user.ID.IsZero() {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Update status
 | 
						// Update status
 | 
				
			||||||
| 
						 | 
					@ -548,10 +268,7 @@ 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(internal.ErrorInvalidRole)
 | 
							return errors.New("invalid role id data")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !isRoleExisted(ctx, id) {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundRole)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Setup condition
 | 
						// Setup condition
 | 
				
			||||||
| 
						 | 
					@ -578,39 +295,27 @@ func ChangeAllUsersStatus(roleID, status string) error {
 | 
				
			||||||
// LoginWithEmailAndPassword ...
 | 
					// LoginWithEmailAndPassword ...
 | 
				
			||||||
func LoginWithEmailAndPassword(email, password string) (result model.User, err error) {
 | 
					func LoginWithEmailAndPassword(email, password string) (result model.User, err error) {
 | 
				
			||||||
	var (
 | 
						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
 | 
						// Validate email, password
 | 
				
			||||||
	if email == "" {
 | 
						if email == "" || password == "" {
 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidLogin)
 | 
							err = errors.New("email or password cannot be empty")
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if password == "" {
 | 
					 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidLogin)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find user
 | 
						// Find user
 | 
				
			||||||
	user, _ := findOneByCondition(ctx, bson.M{
 | 
						user, _ := findOneByCondition(ctx, bson.M{
 | 
				
			||||||
		"email":   email,
 | 
							"email": email,
 | 
				
			||||||
		"deleted": false,
 | 
					 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if user.ID.IsZero() {
 | 
						if user.ID.IsZero() {
 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidLogin)
 | 
							err = errors.New("user not found")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check Password
 | 
						// Check Password
 | 
				
			||||||
	if !internal.CheckPasswordHash(password, user.HashedPassword) {
 | 
						if !internal.CheckPasswordHash(password, user.HashedPassword) {
 | 
				
			||||||
		err = errors.New(internal.ErrorInvalidLogin)
 | 
							err = errors.New("the password is incorrect")
 | 
				
			||||||
		cache.SetKeyValue(k, numOfLoginFail+1, config.LoginFailedBlockedDuration)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -626,16 +331,28 @@ func HasPermission(userID, permission string) (result bool) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Validate userID, permission
 | 
						// Validate userID, permission
 | 
				
			||||||
	if userID == "" || permission == "" {
 | 
						if userID == "" || permission == "" {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - HasPermission: email or password cannot be empty", logger.LogData{
 | 
				
			||||||
 | 
								"userID":     userID,
 | 
				
			||||||
 | 
								"permission": permission,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
						id, isValid := mongodb.NewIDFromString(userID)
 | 
				
			||||||
	if !isValid {
 | 
						if !isValid {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - HasPermission: invalid user id", logger.LogData{
 | 
				
			||||||
 | 
								"userID":     userID,
 | 
				
			||||||
 | 
								"permission": permission,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find user
 | 
						// Find user
 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
						user, _ := findByID(ctx, id)
 | 
				
			||||||
	if user.ID.IsZero() {
 | 
						if user.ID.IsZero() {
 | 
				
			||||||
 | 
							logger.Error("usermngmt - HasPermission: user not found", logger.LogData{
 | 
				
			||||||
 | 
								"userID":     userID,
 | 
				
			||||||
 | 
								"permission": permission,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -657,81 +374,3 @@ func checkUserHasPermissionFromCache(roleID primitive.ObjectID, permission strin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return false
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// UpdateAvatar ...
 | 
					 | 
				
			||||||
func UpdateAvatar(userID string, avatar interface{}) error {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if avatar == nil {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidAvatar)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Setup condition
 | 
					 | 
				
			||||||
	cond := bson.M{
 | 
					 | 
				
			||||||
		"_id": id,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Setup update data
 | 
					 | 
				
			||||||
	updateData := bson.M{
 | 
					 | 
				
			||||||
		"$set": bson.M{
 | 
					 | 
				
			||||||
			"avatar":    avatar,
 | 
					 | 
				
			||||||
			"updatedAt": internal.Now(),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update
 | 
					 | 
				
			||||||
	if err := updateOneByCondition(ctx, cond, updateData); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Delete ...
 | 
					 | 
				
			||||||
func Delete(userID string) error {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		ctx = context.Background()
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Find user exists or not
 | 
					 | 
				
			||||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
					 | 
				
			||||||
	if !isValid {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorInvalidUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	user, _ := findByID(ctx, id)
 | 
					 | 
				
			||||||
	if user.ID.IsZero() {
 | 
					 | 
				
			||||||
		return errors.New(internal.ErrorNotFoundUser)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Setup condition
 | 
					 | 
				
			||||||
	cond := bson.M{
 | 
					 | 
				
			||||||
		"_id": id,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Setup update data
 | 
					 | 
				
			||||||
	updateData := bson.M{
 | 
					 | 
				
			||||||
		"$set": bson.M{
 | 
					 | 
				
			||||||
			"deleted":   true,
 | 
					 | 
				
			||||||
			"updatedAt": internal.Now(),
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Update
 | 
					 | 
				
			||||||
	if err := updateOneByCondition(ctx, cond, updateData); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										59
									
								
								usermngmt.go
								
								
								
								
							
							
						
						
									
										59
									
								
								usermngmt.go
								
								
								
								
							| 
						 | 
					@ -4,35 +4,23 @@ import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.selly.red/Selly-Modules/mongodb"
 | 
						"github.com/Selly-Modules/mongodb"
 | 
				
			||||||
 | 
						"github.com/Selly-Modules/usermngmt/cache"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/cache"
 | 
						"github.com/Selly-Modules/usermngmt/database"
 | 
				
			||||||
	configMoudle "git.selly.red/Selly-Modules/usermngmt/config"
 | 
						"github.com/Selly-Modules/usermngmt/internal"
 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/database"
 | 
					 | 
				
			||||||
	"git.selly.red/Selly-Modules/usermngmt/internal"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RedisConfig ...
 | 
					// MongoDBConfig ...
 | 
				
			||||||
type RedisConfig struct {
 | 
					type MongoDBConfig struct {
 | 
				
			||||||
	URI, Password string
 | 
						Host, User, Password, DBName, Mechanism, Source string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Config ...
 | 
					// Config ...
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
	// MongoDB config, for save documents
 | 
						// MongoDB config, for save documents
 | 
				
			||||||
	MongoDB mongodb.Config
 | 
						MongoDB MongoDBConfig
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Redis
 | 
					 | 
				
			||||||
	Redis RedisConfig
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 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 ...
 | 
				
			||||||
| 
						 | 
					@ -54,24 +42,25 @@ func Init(config Config) (*Service, error) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Connect MongoDB
 | 
						// Connect MongoDB
 | 
				
			||||||
	db, err := mongodb.Connect(config.MongoDB)
 | 
						db, err := mongodb.Connect(
 | 
				
			||||||
 | 
							config.MongoDB.Host,
 | 
				
			||||||
 | 
							config.MongoDB.User,
 | 
				
			||||||
 | 
							config.MongoDB.Password,
 | 
				
			||||||
 | 
							config.MongoDB.DBName,
 | 
				
			||||||
 | 
							config.MongoDB.Mechanism,
 | 
				
			||||||
 | 
							config.MongoDB.Source,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("Cannot init module User MANAGEMENT", err)
 | 
							fmt.Println("Cannot init module User MANAGEMENT", err)
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Init cache
 | 
				
			||||||
 | 
						cache.Init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 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
 | 
					 | 
				
			||||||
	cache.Init(config.Redis.URI, config.Redis.Password)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s = &Service{
 | 
						s = &Service{
 | 
				
			||||||
		config: config,
 | 
							config: config,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -83,13 +72,3 @@ func Init(config Config) (*Service, error) {
 | 
				
			||||||
func GetInstance() *Service {
 | 
					func GetInstance() *Service {
 | 
				
			||||||
	return s
 | 
						return s
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// GetConnectOptions ...
 | 
					 | 
				
			||||||
func GetConnectOptions(Host, DBName string) mongodb.Config {
 | 
					 | 
				
			||||||
	return mongodb.Config{
 | 
					 | 
				
			||||||
		Host:       Host,
 | 
					 | 
				
			||||||
		DBName:     DBName,
 | 
					 | 
				
			||||||
		Standalone: &mongodb.ConnectStandaloneOpts{},
 | 
					 | 
				
			||||||
		TLS:        &mongodb.ConnectTLSOpts{},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue