-
Notifications
You must be signed in to change notification settings - Fork 0
/
rbac.go
126 lines (101 loc) · 2.31 KB
/
rbac.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
115
116
117
118
119
120
121
122
123
124
125
126
package rbac
import (
"errors"
"github.com/sohaha/zlsgo/zarray"
"github.com/sohaha/zlsgo/zfile"
"github.com/sohaha/zlsgo/ztype"
"github.com/zlsgo/conf"
)
type RBAC struct {
roles *zarray.Maper[string, *Role]
}
func New() *RBAC {
return &RBAC{
roles: zarray.NewHashMap[string, *Role](),
}
}
func Parse(rules ztype.Map) (r *RBAC, err error) {
r = &RBAC{
roles: zarray.NewHashMap[string, *Role](),
}
if rules == nil {
return
}
rules.ForEach(func(key string, value ztype.Type) bool {
m := value.Get("mode").Uint()
if m > uint(MatchSomeAllow) {
m = uint(MatchPriorityDeny)
}
role := NewRole(MatchMode(m))
value.Get("permission").Slice().Maps().ForEach(func(_ int, value ztype.Map) bool {
target := value.Get("target").String()
if target == "" {
err = errors.New("target is empty")
return false
}
role.AddGlobPermission(
value.Get("priority").Int(0),
value.Get("action").String("*"),
target,
value.Get("deny").Bool(),
)
return true
})
if err != nil {
return false
}
err = r.AddRole(key, role)
return err == nil
})
return
}
func ParseFile(path string) (*RBAC, error) {
c := conf.New(zfile.RealPath(path))
err := c.Read()
if err != nil {
return nil, err
}
return Parse(ztype.ToMap(c.GetAll()))
}
func (r *RBAC) AddRole(roleName string, role *Role) error {
if r.roles.Has(roleName) {
return errors.New("role already exists")
}
r.roles.Set(roleName, role)
return nil
}
func (r *RBAC) ForEachRole(fn func(key string, value *Role) bool) {
r.roles.ForEach(func(key string, value *Role) bool {
return fn(key, value)
})
}
func (r *RBAC) MergerRole(roleName string, role *Role) error {
if !r.roles.Has(roleName) {
return r.AddRole(roleName, role)
}
userRole, _ := r.roles.Get(roleName)
for i, p := range role.permissions.permission {
for _, v := range p {
userRole.permissions.add(i, v)
}
}
return nil
}
func (r *RBAC) Merge(rd *RBAC) error {
rd.roles.ForEach(func(key string, value *Role) bool {
r.MergerRole(key, value)
return true
})
return nil
}
func (r *RBAC) RemoveRole(roleName string) error {
r.roles.Delete(roleName)
return nil
}
func (r *RBAC) Can(roleName string, action, target string) (ok bool, err error) {
role, ok := r.roles.Get(roleName)
if !ok {
return false, nil
}
return role.Can(action, target)
}