mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			146 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package req
 | 
						||
 | 
						||
import (
 | 
						||
	"encoding/json"
 | 
						||
	"fmt"
 | 
						||
	"mayfly-go/pkg/biz"
 | 
						||
	"mayfly-go/pkg/cache"
 | 
						||
	"mayfly-go/pkg/config"
 | 
						||
	"mayfly-go/pkg/rediscli"
 | 
						||
	"mayfly-go/pkg/utils"
 | 
						||
	"time"
 | 
						||
)
 | 
						||
 | 
						||
type Permission struct {
 | 
						||
	NeedToken bool   // 是否需要token
 | 
						||
	Code      string // 权限code
 | 
						||
}
 | 
						||
 | 
						||
func NewPermission(code string) *Permission {
 | 
						||
	return &Permission{NeedToken: true, Code: code}
 | 
						||
}
 | 
						||
 | 
						||
var (
 | 
						||
	permissionCodeRegistry PermissionCodeRegistry
 | 
						||
)
 | 
						||
 | 
						||
func PermissionHandler(rc *Ctx) error {
 | 
						||
	if permissionCodeRegistry == nil {
 | 
						||
		if rediscli.GetCli() == nil {
 | 
						||
			permissionCodeRegistry = new(DefaultPermissionCodeRegistry)
 | 
						||
		} else {
 | 
						||
			permissionCodeRegistry = new(RedisPermissionCodeRegistry)
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	permission := rc.RequiredPermission
 | 
						||
	// 如果需要的权限信息不为空,并且不需要token,则不返回错误,继续后续逻辑
 | 
						||
	if permission != nil && !permission.NeedToken {
 | 
						||
		return nil
 | 
						||
	}
 | 
						||
	tokenStr := rc.GinCtx.Request.Header.Get("Authorization")
 | 
						||
	// header不存在则从查询参数token中获取
 | 
						||
	if tokenStr == "" {
 | 
						||
		tokenStr = rc.GinCtx.Query("token")
 | 
						||
	}
 | 
						||
	if tokenStr == "" {
 | 
						||
		return biz.PermissionErr
 | 
						||
	}
 | 
						||
	loginAccount, err := ParseToken(tokenStr)
 | 
						||
	if err != nil || loginAccount == nil {
 | 
						||
		return biz.PermissionErr
 | 
						||
	}
 | 
						||
	// 权限不为nil,并且permission code不为空,则校验是否有权限code
 | 
						||
	if permission != nil && permission.Code != "" {
 | 
						||
		if !permissionCodeRegistry.HasCode(loginAccount.Id, permission.Code) {
 | 
						||
			return biz.PermissionErr
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	rc.LoginAccount = loginAccount
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// 保存用户权限code
 | 
						||
func SavePermissionCodes(userId uint64, codes []string) {
 | 
						||
	permissionCodeRegistry.SaveCodes(userId, codes)
 | 
						||
}
 | 
						||
 | 
						||
// 删除用户权限code
 | 
						||
func DeletePermissionCodes(userId uint64) {
 | 
						||
	permissionCodeRegistry.Remove(userId)
 | 
						||
}
 | 
						||
 | 
						||
// 设置权限code注册器
 | 
						||
func SetPermissionCodeRegistery(pcr PermissionCodeRegistry) {
 | 
						||
	permissionCodeRegistry = pcr
 | 
						||
}
 | 
						||
 | 
						||
type PermissionCodeRegistry interface {
 | 
						||
	// 保存用户权限code
 | 
						||
	SaveCodes(userId uint64, codes []string)
 | 
						||
 | 
						||
	// 判断用户是否拥有该code的权限
 | 
						||
	HasCode(userId uint64, code string) bool
 | 
						||
 | 
						||
	Remove(userId uint64)
 | 
						||
}
 | 
						||
 | 
						||
type DefaultPermissionCodeRegistry struct {
 | 
						||
	cache *cache.TimedCache
 | 
						||
}
 | 
						||
 | 
						||
func (r *DefaultPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
 | 
						||
	if r.cache == nil {
 | 
						||
		r.cache = cache.NewTimedCache(time.Minute*time.Duration(config.Conf.Jwt.ExpireTime), 5*time.Second)
 | 
						||
	}
 | 
						||
	r.cache.Put(fmt.Sprintf("%v", userId), codes)
 | 
						||
}
 | 
						||
 | 
						||
func (r *DefaultPermissionCodeRegistry) HasCode(userId uint64, code string) bool {
 | 
						||
	if r.cache == nil {
 | 
						||
		return false
 | 
						||
	}
 | 
						||
	codes, found := r.cache.Get(fmt.Sprintf("%v", userId))
 | 
						||
	if !found {
 | 
						||
		return false
 | 
						||
	}
 | 
						||
	for _, v := range codes.([]string) {
 | 
						||
		if v == code {
 | 
						||
			return true
 | 
						||
		}
 | 
						||
	}
 | 
						||
	return false
 | 
						||
}
 | 
						||
 | 
						||
func (r *DefaultPermissionCodeRegistry) Remove(userId uint64) {
 | 
						||
	r.cache.Delete(fmt.Sprintf("%v", userId))
 | 
						||
}
 | 
						||
 | 
						||
type RedisPermissionCodeRegistry struct {
 | 
						||
}
 | 
						||
 | 
						||
func (r *RedisPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
 | 
						||
	rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), utils.ToString(codes), time.Minute*time.Duration(config.Conf.Jwt.ExpireTime))
 | 
						||
}
 | 
						||
 | 
						||
func (r *RedisPermissionCodeRegistry) HasCode(userId uint64, code string) bool {
 | 
						||
	str, err := rediscli.Get(fmt.Sprintf("mayfly:%v:codes", userId))
 | 
						||
	if err != nil || str == "" {
 | 
						||
		return false
 | 
						||
	}
 | 
						||
 | 
						||
	var codes []string
 | 
						||
	_ = json.Unmarshal([]byte(str), &codes)
 | 
						||
	for _, v := range codes {
 | 
						||
		if v == code {
 | 
						||
			return true
 | 
						||
		}
 | 
						||
	}
 | 
						||
	return false
 | 
						||
}
 | 
						||
 | 
						||
func (r *RedisPermissionCodeRegistry) Remove(userId uint64) {
 | 
						||
	rediscli.Del(fmt.Sprintf("mayfly:%v:codes", userId))
 | 
						||
}
 |