代码拉取完成,页面将自动刷新
package permission
import (
"context"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"sync"
fileadapter "github.com/casbin/casbin/v2/persist/file-adapter"
gormadapter "github.com/casbin/gorm-adapter/v3"
)
type Permission struct {
mu sync.RWMutex
enforcer *casbin.Enforcer
opts *OptionsFunc
}
type OptionsFunc struct {
Render func(ctx *gin.Context, err error)
GetRole func(context.Context, int64) (string, error)
GetMenu func(context.Context) ([]*SysMenu, error)
GetMenuOwned func(context.Context, int64) ([]string, error)
GetLimited func(context.Context) (map[string]struct{}, error)
}
// InitPermission 初始化 casbin
func InitPermission(source interface{}, tx ...*gorm.DB) {
// 防止外部多次调用init, once.Do只初始化一次
once.Do(func() {
Auth = &Permission{
mu: sync.RWMutex{},
}
// 初始化sql
initSQL(source, tx...)
// 创建model
m, err := model.NewModelFromString(modelText)
if err != nil {
panic(err)
}
// 根据传入参数类型, 创建数据adapter
a, err := getAdapter(source)
if err != nil {
panic(err)
}
// 创建鉴权器
Auth.enforcer, err = casbin.NewEnforcer(m, a)
if err != nil {
panic(err)
}
// 加载策略
err = Auth.LoadPolicy()
if err != nil {
panic(err)
}
})
}
// Middleware 中间件
func (p *Permission) Middleware(userKey ...string) gin.HandlerFunc {
return func(ctx *gin.Context) {
var userID int64
userID = ctx.GetInt64("userId")
if len(userKey) > 0 && userKey[0] != "" {
userID = ctx.GetInt64(userKey[0])
}
if userID == 0 {
p.opts.Render(ctx, ErrorJWTPermission)
ctx.Abort()
return
}
// 获取用户对应角色
key, err := p.opts.GetRole(ctx, userID)
if err != nil {
p.opts.Render(ctx, ErrorJWTPermission)
ctx.Abort()
return
}
// 根据访问路由、角色鉴权
url, act := ctx.Request.URL.Path, ctx.Request.Method
ok, err := p.auth(key, url, act)
if err != nil || !ok {
p.opts.Render(ctx, ErrorJWTPermission)
ctx.Abort()
return
}
ctx.Next()
}
}
// Auth 单次鉴权
func (p *Permission) Auth(role, path, method string) (bool, error) {
return p.auth(role, path, method)
}
// auth 鉴权
func (p *Permission) auth(role, path, method string) (bool, error) {
p.mu.RLock()
defer p.mu.RUnlock()
return p.enforcer.Enforce(role, path, method)
}
// LoadPolicy 加载策略
func (p *Permission) LoadPolicy() error {
p.mu.Lock()
defer p.mu.Unlock()
return p.enforcer.LoadPolicy()
}
func (p *Permission) WithOptions(opts OptionsFunc) {
p.mu.Lock()
defer p.mu.Unlock()
p.opts = &opts
}
func getAdapter(input interface{}) (interface{}, error) {
switch input.(type) {
case string:
return fileadapter.NewAdapter(input.(string)), nil
case *gorm.DB:
return gormadapter.NewAdapterByDBUseTableName(
input.(*gorm.DB), "sys", "rule",
)
default:
}
return nil, ErrorJWTPermission
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。