Merge pull request #7 from Selly-Modules/feature/Permission

add permisstionMethods
This commit is contained in:
Nam Huynh 2021-11-10 16:29:52 +07:00 committed by GitHub
commit d8dcfbcad4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 460 additions and 25 deletions

View File

@ -2,6 +2,7 @@ package usermngmt
import ( import (
"github.com/Selly-Modules/usermngmt/model" "github.com/Selly-Modules/usermngmt/model"
"github.com/Selly-Modules/usermngmt/permission"
"github.com/Selly-Modules/usermngmt/role" "github.com/Selly-Modules/usermngmt/role"
"github.com/Selly-Modules/usermngmt/user" "github.com/Selly-Modules/usermngmt/user"
) )
@ -42,6 +43,11 @@ func (s Service) ChangeAllUsersStatus(roleID, status string) error {
return user.ChangeAllUsersStatus(roleID, status) return user.ChangeAllUsersStatus(roleID, status)
} }
// LoginWithEmailAndPassword ...
func (s Service) LoginWithEmailAndPassword(email, password string) (model.User, error) {
return user.LoginWithEmailAndPassword(email, password)
}
// //
// Role // Role
// //
@ -62,3 +68,24 @@ func (s Service) UpdateRole(roleID string, payload model.RoleUpdateOptions) erro
func (s Service) GetAllRoles(query model.RoleAllQuery) model.RoleAll { func (s Service) GetAllRoles(query model.RoleAllQuery) model.RoleAll {
return role.All(query) return role.All(query)
} }
//
// Permission
//
// permission methods
// CreatePermission ...
func (s Service) CreatePermission(payload model.PermissionCreateOptions) error {
return permission.Create(payload)
}
// UpdatePermission ...
func (s Service) UpdatePermission(permissionID string, payload model.PermissionUpdateOptions) error {
return permission.Update(permissionID, payload)
}
// GetAllPermissions ...
func (s Service) GetAllPermissions(query model.PermissionAllQuery) model.PermissionAll {
return permission.All(query)
}

View File

@ -8,8 +8,9 @@ import (
// Table // Table
var ( var (
tableUser = "users" tableUser = "users"
tableRole = "roles" tableRole = "roles"
tablePermission = "permissions"
) )
var ( var (
@ -32,3 +33,8 @@ func GetUserCol() *mongo.Collection {
func GetRoleCol() *mongo.Collection { func GetRoleCol() *mongo.Collection {
return db.Collection(fmt.Sprintf("%s-%s", prefix, tableRole)) return db.Collection(fmt.Sprintf("%s-%s", prefix, tableRole))
} }
// GetPermissionCol ...
func GetPermissionCol() *mongo.Collection {
return db.Collection(fmt.Sprintf("%s-%s", prefix, tablePermission))
}

View File

@ -30,3 +30,14 @@ type DBUser struct {
CreatedAt time.Time `bson:"createdAt"` CreatedAt time.Time `bson:"createdAt"`
UpdatedAt time.Time `bson:"updatedAt"` UpdatedAt time.Time `bson:"updatedAt"`
} }
// DBPermission ...
type DBPermission struct {
ID primitive.ObjectID `bson:"_id"`
Name string `bson:"name"`
Code string `bson:"code"`
RoleID primitive.ObjectID `bson:"roleId"`
Desc string `bson:"desc"`
CreatedAt time.Time `bson:"createdAt"`
UpdatedAt time.Time `bson:"updatedAt"`
}

View File

@ -0,0 +1,90 @@
package model
import (
"errors"
"github.com/Selly-Modules/logger"
"github.com/Selly-Modules/mongodb"
)
// PermissionCreateOptions ...
type PermissionCreateOptions struct {
Name string
RoleID string
Desc string
}
// PermissionUpdateOptions ...
type PermissionUpdateOptions struct {
Name string
RoleID string
Desc string
}
// PermissionAllQuery ...
type PermissionAllQuery struct {
Page int64
Limit int64
}
// Validate ...
func (co PermissionCreateOptions) Validate() error {
// Name
if co.Name == "" {
logger.Error("usermngmt - Permission - Create: no name data", logger.LogData{
"payload": co,
})
return errors.New("no name data")
}
// RoleID
if co.RoleID == "" {
logger.Error("usermngmt - Permission - Create: no roleID data", logger.LogData{
"payload": co,
})
return errors.New("no role id data")
}
if _, isValid := mongodb.NewIDFromString(co.RoleID); !isValid {
return errors.New("invalid role id data")
}
// Desc
if co.Desc == "" {
logger.Error("usermngmt - Permission - Create: no desc data", logger.LogData{
"payload": co,
})
return errors.New("no desc data")
}
return nil
}
// Validate ...
func (co PermissionUpdateOptions) Validate() error {
// Name
if co.Name == "" {
logger.Error("usermngmt - Permission - Update: no name data", logger.LogData{
"payload": co,
})
return errors.New("no name data")
}
// RoleID
if co.RoleID == "" {
logger.Error("usermngmt - Permission - Update: no roleID data", logger.LogData{
"payload": co,
})
return errors.New("no role id data")
}
if _, isValid := mongodb.NewIDFromString(co.RoleID); !isValid {
return errors.New("invalid role id data")
}
// Desc
if co.Desc == "" {
logger.Error("usermngmt - Permission - Update: no desc data", logger.LogData{
"payload": co,
})
return errors.New("no desc data")
}
return nil
}

View File

@ -0,0 +1,24 @@
package model
import (
"time"
)
// Permission ...
type Permission struct {
ID string `json:"_id"`
Name string `json:"name"`
Code string `json:"code"`
RoleID string `json:"roleId"`
Desc string `json:"desc"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
type (
// PermissionAll ...
PermissionAll struct {
List []Permission `json:"list"`
Total int64 `json:"total"`
}
)

97
permission/db.go Normal file
View File

@ -0,0 +1,97 @@
package permission
import (
"context"
"fmt"
"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/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
func findByID(ctx context.Context, id primitive.ObjectID) (model.DBPermission, error) {
var (
doc model.DBPermission
col = database.GetPermissionCol()
)
err := col.FindOne(ctx, bson.M{"_id": id}).Decode(&doc)
return doc, err
}
func create(ctx context.Context, doc model.DBPermission) error {
var (
col = database.GetPermissionCol()
)
_, err := col.InsertOne(ctx, doc)
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 nil
}
func updateOneByCondition(ctx context.Context, cond interface{}, payload interface{}) error {
var (
col = database.GetPermissionCol()
)
_, err := col.UpdateOne(ctx, cond, payload)
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 err
}
func findByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBPermission) {
var (
col = database.GetPermissionCol()
)
docs = make([]model.DBPermission, 0)
cursor, err := col.Find(ctx, cond, opts...)
if err != nil {
logger.Error("usermngmt - Permission - Find", logger.LogData{
"cond": cond,
"opts": opts,
"err": err.Error(),
})
return
}
defer cursor.Close(ctx)
if err = cursor.All(ctx, &docs); err != nil {
logger.Error("usermngmt - Permission - Decode", logger.LogData{
"cond": cond,
"opts": opts,
"err": err.Error(),
})
return
}
return
}
// countByCondition ...
func countByCondition(ctx context.Context, cond interface{}) int64 {
var (
col = database.GetPermissionCol()
)
total, err := col.CountDocuments(ctx, cond)
if err != nil {
logger.Error("usermngmt - Permission - CountDocuments", logger.LogData{
"err": err.Error(),
"cond": cond,
})
}
return total
}

142
permission/handle.go Normal file
View File

@ -0,0 +1,142 @@
package permission
import (
"context"
"errors"
"sync"
"github.com/Selly-Modules/mongodb"
"github.com/Selly-Modules/usermngmt/internal"
"github.com/Selly-Modules/usermngmt/model"
"go.mongodb.org/mongo-driver/bson"
)
// Create ...
func Create(payload model.PermissionCreateOptions) error {
var (
ctx = context.Background()
)
// Validate payload
if err := payload.Validate(); err != nil {
return err
}
// New permission data from payload
doc := newPermission(payload)
// Create permission
if err := create(ctx, doc); err != nil {
return err
}
return nil
}
// newPermission ...
func newPermission(payload model.PermissionCreateOptions) model.DBPermission {
timeNow := internal.Now()
roleID, _ := mongodb.NewIDFromString(payload.RoleID)
return model.DBPermission{
ID: mongodb.NewObjectID(),
Name: payload.Name,
Code: internal.GenerateCode(payload.Name),
RoleID: roleID,
Desc: payload.Desc,
CreatedAt: timeNow,
UpdatedAt: timeNow,
}
}
// Update ...
func Update(permissionID string, payload model.PermissionUpdateOptions) error {
var (
ctx = context.Background()
)
// Validate payload
if err := payload.Validate(); err != nil {
return err
}
// Validate permissionID
id, isValid := mongodb.NewIDFromString(permissionID)
if !isValid {
return errors.New("invalid permission id data")
}
// Setup condition
cond := bson.M{
"_id": id,
}
// Setup update data
roleID, _ := mongodb.NewIDFromString(payload.RoleID)
updateData := bson.M{
"$set": bson.M{
"name": payload.Name,
"code": internal.GenerateCode(payload.Name),
"roleId": roleID,
"desc": payload.Desc,
"updatedAt": internal.Now(),
},
}
// Update
if err := updateOneByCondition(ctx, cond, updateData); err != nil {
return err
}
return nil
}
// All ...
func All(queryParams model.PermissionAllQuery) (r model.PermissionAll) {
var (
ctx = context.Background()
wg sync.WaitGroup
cond = bson.M{}
)
query := model.CommonQuery{
Page: queryParams.Page,
Limit: queryParams.Limit,
Sort: bson.M{"createdAt": -1},
}
// Assign condition
query.SetDefaultLimit()
wg.Add(1)
go func() {
defer wg.Done()
docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
r.List = getResponseList(docs)
}()
wg.Add(1)
go func() {
defer wg.Done()
r.Total = countByCondition(ctx, cond)
}()
wg.Wait()
return
}
func getResponseList(permissions []model.DBPermission) []model.Permission {
res := make([]model.Permission, 0)
for _, permission := range permissions {
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
}

View File

@ -166,3 +166,12 @@ func countByCondition(ctx context.Context, cond interface{}) int64 {
} }
return total return total
} }
func findOneByCondition(ctx context.Context, cond interface{}) (model.DBUser, error) {
var (
col = database.GetUserCol()
doc model.DBUser
)
err := col.FindOne(ctx, cond).Decode(&doc)
return doc, err
}

View File

@ -96,7 +96,11 @@ func All(queryParams model.UserAllQuery) (r model.UserAll) {
go func() { go func() {
defer wg.Done() defer wg.Done()
docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage()) docs := findByCondition(ctx, cond, query.GetFindOptionsUsingPage())
r.List = getResponseList(ctx, docs) res := make([]model.User, 0)
for _, doc := range docs {
res = append(res, getResponse(ctx, doc))
}
r.List = res
}() }()
wg.Add(1) wg.Add(1)
@ -110,29 +114,23 @@ func All(queryParams model.UserAllQuery) (r model.UserAll) {
return return
} }
func getResponseList(ctx context.Context, users []model.DBUser) []model.User { func getResponse(ctx context.Context, user model.DBUser) model.User {
res := make([]model.User, 0) roleRaw, _ := roleFindByID(ctx, user.RoleID)
return model.User{
for _, user := range users { ID: user.ID.Hex(),
roleRaw, _ := roleFindByID(ctx, user.RoleID) Name: user.Name,
res = append(res, model.User{ Phone: user.Phone,
ID: user.ID.Hex(), Email: user.Email,
Name: user.Name, Status: user.Status,
Phone: user.Phone, Role: model.RoleShort{
Email: user.Email, ID: roleRaw.ID.Hex(),
Status: user.Status, Name: roleRaw.Name,
Role: model.RoleShort{ IsAdmin: roleRaw.IsAdmin,
ID: roleRaw.ID.Hex(), },
Name: roleRaw.Name, Other: user.Other,
IsAdmin: roleRaw.IsAdmin, CreatedAt: user.CreatedAt,
}, UpdatedAt: user.UpdatedAt,
Other: user.Other,
CreatedAt: user.CreatedAt,
UpdatedAt: user.UpdatedAt,
})
} }
return res
} }
// UpdateByUserID ... // UpdateByUserID ...
@ -290,3 +288,34 @@ func ChangeAllUsersStatus(roleID, status string) error {
return nil return nil
} }
// LoginWithEmailAndPassword ...
func LoginWithEmailAndPassword(email, password string) (result model.User, err error) {
var (
ctx = context.Background()
)
// Validate email, password
if email == "" || password == "" {
err = errors.New("email or password cannot be empty")
return
}
// Find user
user, _ := findOneByCondition(ctx, bson.M{
"email": email,
})
if user.ID.IsZero() {
err = errors.New("user not found")
return
}
// Check Password
if !internal.CheckPasswordHash(password, user.HashedPassword) {
err = errors.New("the password is incorrect")
return
}
result = getResponse(ctx, user)
return
}