add isPermissionMethod #8
			
				
			
		
		
		
	
							
								
								
									
										18
									
								
								action.go
								
								
								
								
							
							
						
						| 
						 | 
				
			
			@ -61,7 +61,11 @@ func (s Service) HasPermission(userID, permission string) bool {
 | 
			
		|||
 | 
			
		||||
// CreateRole ...
 | 
			
		||||
func (s Service) CreateRole(payload model.RoleCreateOptions) error {
 | 
			
		||||
	return role.Create(payload)
 | 
			
		||||
	err := role.Create(payload)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		role.CacheRoles()
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateRole ...
 | 
			
		||||
| 
						 | 
				
			
			@ -82,12 +86,20 @@ func (s Service) GetAllRoles(query model.RoleAllQuery) model.RoleAll {
 | 
			
		|||
 | 
			
		||||
// CreatePermission ...
 | 
			
		||||
func (s Service) CreatePermission(payload model.PermissionCreateOptions) error {
 | 
			
		||||
	return permission.Create(payload)
 | 
			
		||||
	err := permission.Create(payload)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		role.CacheRoles()
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdatePermission ...
 | 
			
		||||
func (s Service) UpdatePermission(permissionID string, payload model.PermissionUpdateOptions) error {
 | 
			
		||||
	return permission.Update(permissionID, payload)
 | 
			
		||||
	err := permission.Update(permissionID, payload)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		role.CacheRoles()
 | 
			
		||||
	}
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetAllPermissions ...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
| 
					
 | 
			||||
package cache
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
import (
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	"log"
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	"time"
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	"github.com/allegro/bigcache/v3"
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
)
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
var cache *bigcache.BigCache
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
// Init ...
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
func Init() {
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	// The time after which entries can be evicted is 5 years
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	c, err := bigcache.NewBigCache(bigcache.DefaultConfig(43800 * time.Hour))
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	if err != nil {
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
		log.Fatalf("Cannot init Cache %v", err)
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	}
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	cache = c
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
}
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
// GetInstance ...
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
func GetInstance() *bigcache.BigCache {
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
	return cache
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
}
 | 
			
		||||
| 
					
 đặt constant phía trên luôn 
			
			đặt constant phía trên luôn
```go
const cacheTime = 24 * 30 * time.Hour // 30 days
``` 
			
		done done 
			
		đặt tên biến lại chớ trùng với tên package rồi,  đặt tên biến lại chớ trùng với tên package rồi, `mc` (mem-cache) 
			
		done done 
			
		 | 
			||||
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						| 
						 | 
				
			
			@ -5,7 +5,10 @@ go 1.17
 | 
			
		|||
require (
 | 
			
		||||
	github.com/Selly-Modules/logger v0.0.0-20210809034923-140a51f39ec9
 | 
			
		||||
	github.com/Selly-Modules/mongodb v0.0.0-20211013094205-a8ab24a96c4c
 | 
			
		||||
	github.com/allegro/bigcache/v3 v3.0.1
 | 
			
		||||
	github.com/thoas/go-funk v0.9.1
 | 
			
		||||
	go.mongodb.org/mongo-driver v1.7.4
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +35,6 @@ require (
 | 
			
		|||
	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/crypto v0.0.0-20200302210943-78000ba7a073 // 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								go.sum
								
								
								
								
							
							
						
						| 
						 | 
				
			
			@ -3,6 +3,8 @@ github.com/Selly-Modules/logger v0.0.0-20210809034923-140a51f39ec9 h1:AuJ/IIZ7yp
 | 
			
		|||
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=
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +93,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 | 
			
		|||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
			
		||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
			
		||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 | 
			
		||||
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/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/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,4 +7,6 @@ const (
 | 
			
		|||
	passwordHashingCost = 14
 | 
			
		||||
 | 
			
		||||
	TablePrefixDefault = "usermngmt"
 | 
			
		||||
 | 
			
		||||
	RoleTypeAdmin = "admin"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								role/db.go
								
								
								
								
							
							
						
						| 
						 | 
				
			
			@ -54,6 +54,33 @@ func updateOneByCondition(ctx context.Context, cond interface{}, payload interfa
 | 
			
		|||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func permissionFindByCondition(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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func findByCondition(ctx context.Context, cond interface{}, opts ...*options.FindOptions) (docs []model.DBRole) {
 | 
			
		||||
	var (
 | 
			
		||||
		col = database.GetRoleCol()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,15 @@ package role
 | 
			
		|||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"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"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,3 +136,49 @@ func getResponseList(roles []model.DBRole) []model.Role {
 | 
			
		|||
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CacheRoles ...
 | 
			
		||||
func CacheRoles() {
 | 
			
		||||
	var (
 | 
			
		||||
		ctx = context.Background()
 | 
			
		||||
		wg  sync.WaitGroup
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// Find
 | 
			
		||||
	roles := findByCondition(ctx, bson.M{})
 | 
			
		||||
 | 
			
		||||
	wg.Add(len(roles))
 | 
			
		||||
	for _, value := range roles {
 | 
			
		||||
		go func(role model.DBRole) {
 | 
			
		||||
			defer wg.Done()
 | 
			
		||||
 | 
			
		||||
			// Check and set role admin: admin
 | 
			
		||||
			if role.IsAdmin {
 | 
			
		||||
				if err := cache.GetInstance().Set(role.ID.Hex(), []byte(internal.RoleTypeAdmin)); err != nil {
 | 
			
		||||
					logger.Error("usermngmt - CacheRole", logger.LogData{
 | 
			
		||||
						"err": err.Error(),
 | 
			
		||||
					})
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Set role by permission with format: permissionCode,permissionCode,...
 | 
			
		||||
			permissions := permissionFindByCondition(ctx, bson.M{
 | 
			
		||||
				"roleId": role.ID,
 | 
			
		||||
			})
 | 
			
		||||
			permissionCodes := funk.Map(permissions, func(i model.DBPermission) string {
 | 
			
		||||
				return i.Code
 | 
			
		||||
			}).([]string)
 | 
			
		||||
			permissionCodeString := strings.Join(permissionCodes, ",")
 | 
			
		||||
			if err := cache.GetInstance().Set(role.ID.Hex(), []byte(permissionCodeString)); err != nil {
 | 
			
		||||
				logger.Error("usermngmt - CacheRole", logger.LogData{
 | 
			
		||||
					"err": err.Error(),
 | 
			
		||||
				})
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}(value)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wg.Done()
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,15 @@ package user
 | 
			
		|||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"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"
 | 
			
		||||
	"go.mongodb.org/mongo-driver/bson"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -328,7 +331,7 @@ func HasPermission(userID, permission string) (result bool) {
 | 
			
		|||
 | 
			
		||||
	// Validate userID, permission
 | 
			
		||||
	if userID == "" || permission == "" {
 | 
			
		||||
		logger.Error("usermngmt - IsPermission: email or password cannot be empty", logger.LogData{
 | 
			
		||||
		logger.Error("usermngmt - HasPermission: email or password cannot be empty", logger.LogData{
 | 
			
		||||
			"userID":     userID,
 | 
			
		||||
			"permission": permission,
 | 
			
		||||
		})
 | 
			
		||||
| 
					
 func này muốn nhanh thì làm thêm in-memory cache (https://github.com/allegro/bigcache) như sau: 
 func này muốn nhanh thì làm thêm in-memory cache (https://github.com/allegro/bigcache) như sau:
- init thì call func A query hết role và permission ra lưu vào mem
- khi có thay đổi (CRUD) thì call lại func A
- khi cần check thì chỉ cần lấy từ mem lên để check 
			
		done done 
			
		 | 
			||||
| 
						 | 
				
			
			@ -336,7 +339,7 @@ func HasPermission(userID, permission string) (result bool) {
 | 
			
		|||
	}
 | 
			
		||||
	id, isValid := mongodb.NewIDFromString(userID)
 | 
			
		||||
	if !isValid {
 | 
			
		||||
		logger.Error("usermngmt - IsPermission: invalid user id", logger.LogData{
 | 
			
		||||
		logger.Error("usermngmt - HasPermission: invalid user id", logger.LogData{
 | 
			
		||||
			"userID":     userID,
 | 
			
		||||
			"permission": permission,
 | 
			
		||||
		})
 | 
			
		||||
| 
						 | 
				
			
			@ -346,26 +349,23 @@ func HasPermission(userID, permission string) (result bool) {
 | 
			
		|||
	// Find user
 | 
			
		||||
	user, _ := findByID(ctx, id)
 | 
			
		||||
	if user.ID.IsZero() {
 | 
			
		||||
		logger.Error("usermngmt - IsPermission: user not found", logger.LogData{
 | 
			
		||||
		logger.Error("usermngmt - HasPermission: user not found", logger.LogData{
 | 
			
		||||
			"userID":     userID,
 | 
			
		||||
			"permission": permission,
 | 
			
		||||
		})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check isAdmin
 | 
			
		||||
	if role, _ := roleFindByID(ctx, user.RoleID); role.IsAdmin {
 | 
			
		||||
		result = true
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// Get rolePermissions
 | 
			
		||||
	// Role is saved with the value "admin" or "permissionCode,permissionCode,..."
 | 
			
		||||
	entry, _ := cache.GetInstance().Get(user.RoleID.Hex())
 | 
			
		||||
	rolePermissions := strings.Split(string(entry), ",")
 | 
			
		||||
 | 
			
		||||
	// Check permission
 | 
			
		||||
	if total := permissionCountByCondition(ctx, bson.M{
 | 
			
		||||
		"roleId": user.RoleID,
 | 
			
		||||
		"code":   permission,
 | 
			
		||||
	}); total > 0 {
 | 
			
		||||
		result = true
 | 
			
		||||
		return
 | 
			
		||||
	// Check Permission
 | 
			
		||||
	if _, isValid = funk.FindString(rolePermissions, func(s string) bool {
 | 
			
		||||
		return s == permission || s == internal.RoleTypeAdmin
 | 
			
		||||
	}); isValid {
 | 
			
		||||
		return isValid
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
| 
					
 chỗ này thiếu 
 2 bước 2,3 nên đưa ra 1 func  chỗ này thiếu
1. trong package ` cache` phải có 1 hàm `GetCachedRoles` trả về `CachedRoles`, trong hàm đó nếu check `cachedRoles = nil` thì phải call hàm `Roles` để tạo cache mới
2. ở chỗ này gọi hàm `GetCachedRoles`
3. dựa vào user.RoleID để pick ra data của role đó, sau đó check mảng permission
----
2 bước 2,3 nên đưa ra 1 func `checkUserHasPermissionFromCache` để làm cho gọn code 
			
		done done 
			
		 | 
			||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,8 +5,10 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/Selly-Modules/mongodb"
 | 
			
		||||
	"github.com/Selly-Modules/usermngmt/cache"
 | 
			
		||||
	"github.com/Selly-Modules/usermngmt/database"
 | 
			
		||||
	"github.com/Selly-Modules/usermngmt/internal"
 | 
			
		||||
	"github.com/Selly-Modules/usermngmt/role"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MongoDBConfig ...
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +56,9 @@ func Init(config Config) (*Service, error) {
 | 
			
		|||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Init cache
 | 
			
		||||
	cache.Init()
 | 
			
		||||
 | 
			
		||||
	// Set database
 | 
			
		||||
	database.Set(db, config.TablePrefix)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +66,9 @@ func Init(config Config) (*Service, error) {
 | 
			
		|||
		config: config,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Cache role
 | 
			
		||||
	role.CacheRoles()
 | 
			
		||||
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
đặt constant phía trên luôn
đặt constant phía trên luôn
done
done
đặt tên biến lại chớ trùng với tên package rồi,
mc(mem-cache)đặt tên biến lại chớ trùng với tên package rồi,
mc(mem-cache)done
done