fix
wangpengfei
2023-08-24 274b44fa5b934eace2fc6dbcdccbb96a032545d8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package service
 
import (
    "aps_crm/model/request"
    "aps_crm/pkg/mysqlx"
    "errors"
    "github.com/flipped-aurora/gin-vue-admin/server/global"
    "strconv"
    "sync"
 
    "github.com/casbin/casbin/v2"
    "github.com/casbin/casbin/v2/model"
    gormadapter "github.com/casbin/gorm-adapter/v3"
    _ "github.com/go-sql-driver/mysql"
    "go.uber.org/zap"
)
 
//@author: [piexlmax](https://github.com/piexlmax)
//@function: UpdateCasbin
//@description: 更新casbin权限
//@param: authorityId string, casbinInfos []request.CasbinInfo
//@return: error
 
type CasbinService struct{}
 
var CasbinServiceApp = new(CasbinService)
 
func (casbinService *CasbinService) UpdateCasbin(AuthorityID uint, casbinInfos []request.CasbinInfo) error {
    authorityId := strconv.Itoa(int(AuthorityID))
    casbinService.ClearCasbin(0, authorityId)
    rules := [][]string{}
    for _, v := range casbinInfos {
        rules = append(rules, []string{authorityId, v.Path, v.Method})
    }
    e := casbinService.Casbin()
    success, _ := e.AddPolicies(rules)
    if !success {
        return errors.New("存在相同api,添加失败,请联系管理员")
    }
    return nil
}
 
//@author: [piexlmax](https://github.com/piexlmax)
//@function: UpdateCasbinApi
//@description: API更新随动
//@param: oldPath string, newPath string, oldMethod string, newMethod string
//@return: error
 
func (casbinService *CasbinService) UpdateCasbinApi(oldPath string, newPath string, oldMethod string, newMethod string) error {
    err := global.GVA_DB.Model(&gormadapter.CasbinRule{}).Where("v1 = ? AND v2 = ?", oldPath, oldMethod).Updates(map[string]interface{}{
        "v1": newPath,
        "v2": newMethod,
    }).Error
    e := casbinService.Casbin()
    err = e.LoadPolicy()
    if err != nil {
        return err
    }
    return err
}
 
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetPolicyPathByAuthorityId
//@description: 获取权限列表
//@param: authorityId string
//@return: pathMaps []request.CasbinInfo
 
func (casbinService *CasbinService) GetPolicyPathByAuthorityId(AuthorityID uint) (pathMaps []request.CasbinInfo) {
    e := casbinService.Casbin()
    authorityId := strconv.Itoa(int(AuthorityID))
    list := e.GetFilteredPolicy(0, authorityId)
    for _, v := range list {
        pathMaps = append(pathMaps, request.CasbinInfo{
            Path:   v[1],
            Method: v[2],
        })
    }
    return pathMaps
}
 
//@author: [piexlmax](https://github.com/piexlmax)
//@function: ClearCasbin
//@description: 清除匹配的权限
//@param: v int, p ...string
//@return: bool
 
func (casbinService *CasbinService) ClearCasbin(v int, p ...string) bool {
    e := casbinService.Casbin()
    success, _ := e.RemoveFilteredPolicy(v, p...)
    return success
}
 
//@author: [piexlmax](https://github.com/piexlmax)
//@function: Casbin
//@description: 持久化到数据库  引入自定义规则
//@return: *casbin.Enforcer
 
var (
    syncedCachedEnforcer *casbin.SyncedCachedEnforcer
    once                 sync.Once
)
 
func (casbinService *CasbinService) Casbin() *casbin.SyncedCachedEnforcer {
    once.Do(func() {
        a, err := gormadapter.NewAdapterByDB(mysqlx.GetDB())
        if err != nil {
            zap.L().Error("适配数据库失败请检查casbin表是否为InnoDB引擎!", zap.Error(err))
            return
        }
        text := `
        [request_definition]
        r = sub, obj, act
        
        [policy_definition]
        p = sub, obj, act
        
        [role_definition]
        g = _, _
        
        [policy_effect]
        e = some(where (p.eft == allow))
        
        [matchers]
        m = r.sub == p.sub && keyMatch2(r.obj,p.obj) && r.act == p.act
        `
        m, err := model.NewModelFromString(text)
        if err != nil {
            zap.L().Error("字符串加载模型失败!", zap.Error(err))
            return
        }
        syncedCachedEnforcer, _ = casbin.NewSyncedCachedEnforcer(m, a)
        syncedCachedEnforcer.SetExpireTime(60 * 60)
        _ = syncedCachedEnforcer.LoadPolicy()
    })
    return syncedCachedEnforcer
}