this repo has no description
1package rbac
2
3import (
4 "database/sql"
5 "path"
6
7 sqladapter "github.com/Blank-Xu/sql-adapter"
8 "github.com/casbin/casbin/v2"
9 "github.com/casbin/casbin/v2/model"
10)
11
12const (
13 Model = `
14[request_definition]
15r = sub, dom, obj, act
16
17[policy_definition]
18p = sub, dom, obj, act
19
20[role_definition]
21g = _, _, _
22
23[policy_effect]
24e = some(where (p.eft == allow))
25
26[matchers]
27m = r.act == p.act && r.dom == p.dom && keyMatch2(r.obj, p.obj) && g(r.sub, p.sub, r.dom)
28`
29)
30
31type Enforcer struct {
32 E *casbin.SyncedEnforcer
33}
34
35func keyMatch2(key1 string, key2 string) bool {
36 matched, _ := path.Match(key2, key1)
37 return matched
38}
39
40func NewEnforcer(path string) (*Enforcer, error) {
41 m, err := model.NewModelFromString(Model)
42 if err != nil {
43 return nil, err
44 }
45
46 db, err := sql.Open("sqlite3", path)
47 if err != nil {
48 return nil, err
49 }
50
51 a, err := sqladapter.NewAdapter(db, "sqlite3", "acl")
52 if err != nil {
53 return nil, err
54 }
55
56 e, err := casbin.NewSyncedEnforcer(m, a)
57 if err != nil {
58 return nil, err
59 }
60
61 e.EnableAutoSave(true)
62 e.AddFunction("keyMatch2", keyMatch2Func)
63
64 return &Enforcer{e}, nil
65}
66
67func (e *Enforcer) AddDomain(domain string) error {
68 // Add policies with patterns
69 _, err := e.E.AddPolicies([][]string{
70 {"server:owner", domain, domain, "server:invite"},
71 {"server:member", domain, domain, "repo:create"},
72 })
73 if err != nil {
74 return err
75 }
76
77 // all owners are also members
78 _, err = e.E.AddGroupingPolicy("server:owner", "server:member", domain)
79 return err
80}
81
82func (e *Enforcer) AddOwner(domain, owner string) error {
83 _, err := e.E.AddGroupingPolicy(owner, "server:owner", domain)
84 return err
85}
86
87func (e *Enforcer) AddMember(domain, member string) error {
88 _, err := e.E.AddGroupingPolicy(member, "server:member", domain)
89 return err
90}
91
92func (e *Enforcer) AddRepo(member, domain, repo string) error {
93 _, err := e.E.AddPolicies([][]string{
94 {member, domain, repo, "repo:push"},
95 {member, domain, repo, "repo:owner"},
96 {member, domain, repo, "repo:invite"},
97 {member, domain, repo, "repo:delete"},
98 {"server:owner", domain, repo, "repo:delete"}, // server owner can delete any repo
99 })
100 return err
101}
102
103// keyMatch2Func is a wrapper for keyMatch2 to make it compatible with Casbin
104func keyMatch2Func(args ...interface{}) (interface{}, error) {
105 name1 := args[0].(string)
106 name2 := args[1].(string)
107
108 return keyMatch2(name1, name2), nil
109}