/
casbin.go
114 lines (92 loc) · 2.55 KB
/
casbin.go
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
/**
* @Time : 2019-07-12 11:06
* @Author : ygqbasic@gmail.com
* @File : base
* @Software: VS Code
*/
package casbin
import (
"context"
"fmt"
"github.com/casbin/casbin"
"github.com/casbin/casbin/persist"
"github.com/casbin/casbin/util"
"github.com/casbin/gorm-adapter"
kitcasbin "github.com/go-kit/kit/auth/casbin"
"github.com/jinzhu/gorm"
wrds "github.com/fuhsicloud/fuhsicloud/src/casbin/watcher/redis"
"github.com/fuhsicloud/fuhsicloud/src/config"
"github.com/fuhsicloud/fuhsicloud/src/redis"
"regexp"
"strings"
)
type Casbin interface {
GetContext() context.Context
GetEnforcer() *casbin.Enforcer
}
type service struct {
context context.Context
enforcer *casbin.Enforcer
watcher persist.Watcher
}
var getCasbin *service
func GetCasbin() *service {
return getCasbin
}
func NewCasbin(cf *config.Config, db *gorm.DB, rds redis.RedisInterface) (Casbin, error) {
m := casbin.NewModel()
m.AddDef("r", "r", "sub, obj, act")
m.AddDef("p", "p", "sub, obj, act")
m.AddDef("g", "g", "_, _")
m.AddDef("e", "e", "some(where (p.eft == allow))")
m.AddDef("m", "m", "r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch3(r.obj, p.obj)) && keyMatch2(r.act, p.act)")
watcher, err := wrds.NewWatcher(rds)
if err != nil {
return nil, err
}
adapter := gormadapter.NewAdapterByDB(db)
e, err := casbin.NewEnforcerSafe(m, adapter)
if err != nil {
return nil, err
}
e.AddFunction("keyMatch3", util.KeyMatch3Func)
e.SetWatcher(watcher)
_ = watcher.SetUpdateCallback(func(string) {
if err = e.LoadPolicy(); err != nil {
_ = fmt.Errorf("err: %v", err)
}
})
//ctx := context.WithValue(context.Background(), kitcasbin.CasbinModelContextKey, m)
//ctx = context.WithValue(ctx, kitcasbin.CasbinPolicyContextKey, adapter)
//ctx = context.WithValue(ctx, kitcasbin.CasbinEnforcerContextKey, e)
ctx := context.WithValue(context.Background(), kitcasbin.CasbinEnforcerContextKey, e)
e.EnableLog(cf.GetBool("server", "debug"))
getCasbin = &service{context: ctx, enforcer: e}
return getCasbin, nil
}
func (c *service) GetContext() context.Context {
return c.context
}
func (c *service) GetEnforcer() *casbin.Enforcer {
return c.enforcer
}
func (c *service) Close() {
c.watcher.Close()
}
func KeyMatch3(key1 string, key2 string) bool {
re := regexp.MustCompile(`(.*)\{[^/]+\}(.*)`)
for {
if !strings.Contains(key2, "/{") {
break
}
key2 = re.ReplaceAllString(key2, "$1[^/]+$2")
}
return RegexMatch(key1, key2)
}
func RegexMatch(key1 string, key2 string) bool {
res, err := regexp.MatchString(key2, key1)
if err != nil {
panic(err)
}
return res
}