Files
mayfly-go/server/pkg/req/permission_handler.go

162 lines
3.9 KiB
Go
Raw Normal View History

2023-01-14 16:29:52 +08:00
package req
2021-03-24 17:18:39 +08:00
import (
2022-12-26 20:53:07 +08:00
"encoding/json"
2021-06-09 16:58:57 +08:00
"fmt"
"mayfly-go/pkg/cache"
"mayfly-go/pkg/config"
"mayfly-go/pkg/contextx"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/model"
2022-12-26 20:53:07 +08:00
"mayfly-go/pkg/rediscli"
2023-10-20 21:31:46 +08:00
"mayfly-go/pkg/utils/anyx"
2023-12-27 22:59:20 +08:00
"strings"
2021-06-09 16:58:57 +08:00
"time"
2021-03-24 17:18:39 +08:00
)
type Permission struct {
2021-06-09 16:58:57 +08:00
NeedToken bool // 是否需要token
Code string // 权限code
2021-03-24 17:18:39 +08:00
}
2021-06-09 16:58:57 +08:00
func NewPermission(code string) *Permission {
return &Permission{NeedToken: true, Code: code}
}
2022-12-26 20:53:07 +08:00
var (
permissionCodeRegistry PermissionCodeRegistry
)
2023-01-14 16:29:52 +08:00
func PermissionHandler(rc *Ctx) error {
2022-12-26 20:53:07 +08:00
if permissionCodeRegistry == nil {
if rediscli.GetCli() == nil {
permissionCodeRegistry = new(DefaultPermissionCodeRegistry)
} else {
permissionCodeRegistry = new(RedisPermissionCodeRegistry)
}
}
var permission *Permission
if rc.Conf != nil {
permission = rc.Conf.requiredPermission
}
2022-12-26 20:53:07 +08:00
// 如果需要的权限信息不为空并且不需要token则不返回错误继续后续逻辑
if permission != nil && !permission.NeedToken {
return nil
}
tokenStr := rc.F.GetHeader("Authorization")
2023-12-27 22:59:20 +08:00
// 删除前缀 Bearer, 以支持 Bearer Token
tokenStr, _ = strings.CutPrefix(tokenStr, "Bearer ")
2022-12-26 20:53:07 +08:00
// header不存在则从查询参数token中获取
if tokenStr == "" {
tokenStr = rc.F.Query("token")
2022-12-26 20:53:07 +08:00
}
if tokenStr == "" {
return errorx.PermissionErr
2022-12-26 20:53:07 +08:00
}
userId, userName, err := ParseToken(tokenStr)
if err != nil || userId == 0 {
return errorx.PermissionErr
2022-12-26 20:53:07 +08:00
}
// 权限不为nil并且permission code不为空则校验是否有权限code
if permission != nil && permission.Code != "" {
if !permissionCodeRegistry.HasCode(userId, permission.Code) {
return errorx.PermissionErr
2022-12-26 20:53:07 +08:00
}
}
rc.MetaCtx = contextx.WithLoginAccount(rc.MetaCtx, &model.LoginAccount{
Id: userId,
Username: userName,
})
2022-12-26 20:53:07 +08:00
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
}
2023-07-22 20:51:46 +08:00
func GetPermissionCodeRegistery() PermissionCodeRegistry {
return permissionCodeRegistry
}
2021-06-09 16:58:57 +08:00
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)
2021-06-09 16:58:57 +08:00
}
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) {
2023-07-22 20:51:46 +08:00
if r.cache != nil {
r.cache.Delete(fmt.Sprintf("%v", userId))
}
2021-06-09 16:58:57 +08:00
}
2022-12-26 20:53:07 +08:00
type RedisPermissionCodeRegistry struct {
2021-06-09 16:58:57 +08:00
}
2022-12-26 20:53:07 +08:00
func (r *RedisPermissionCodeRegistry) SaveCodes(userId uint64, codes []string) {
2023-10-20 21:31:46 +08:00
rediscli.Set(fmt.Sprintf("mayfly:%v:codes", userId), anyx.ToString(codes), time.Minute*time.Duration(config.Conf.Jwt.ExpireTime))
2021-06-09 16:58:57 +08:00
}
2022-12-26 20:53:07 +08:00
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
2021-03-24 17:18:39 +08:00
}
2022-12-26 20:53:07 +08:00
var codes []string
_ = json.Unmarshal([]byte(str), &codes)
for _, v := range codes {
if v == code {
return true
2021-06-09 16:58:57 +08:00
}
}
2022-12-26 20:53:07 +08:00
return false
}
2021-06-09 16:58:57 +08:00
2022-12-26 20:53:07 +08:00
func (r *RedisPermissionCodeRegistry) Remove(userId uint64) {
rediscli.Del(fmt.Sprintf("mayfly:%v:codes", userId))
2021-03-24 17:18:39 +08:00
}