this repo has no description
1package state
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() (*Enforcer, error) {
41 m, err := model.NewModelFromString(Model)
42 if err != nil {
43 return nil, err
44 }
45
46 // TODO: conf this
47 db, err := sql.Open("sqlite3", "appview.db")
48 if err != nil {
49 return nil, err
50 }
51
52 a, err := sqladapter.NewAdapter(db, "sqlite3", "acl")
53 if err != nil {
54 return nil, err
55 }
56
57 e, err := casbin.NewSyncedEnforcer(m, a)
58 if err != nil {
59 return nil, err
60 }
61
62 e.EnableAutoSave(true)
63 e.AddFunction("keyMatch2", keyMatch2Func)
64
65 return &Enforcer{e}, nil
66}
67
68func (e *Enforcer) AddDomain(domain string) error {
69 // Add policies with patterns
70 _, err := e.E.AddPolicies([][]string{
71 {"server:owner", domain, domain, "server:invite"},
72 {"server:member", domain, domain, "repo:create"},
73 })
74 if err != nil {
75 return err
76 }
77
78 // all owners are also members
79 _, err = e.E.AddGroupingPolicy("server:owner", "server:member", domain)
80 return err
81}
82
83func (e *Enforcer) AddOwner(domain, owner string) error {
84 _, err := e.E.AddGroupingPolicy(owner, "server:owner", domain)
85 return err
86}
87
88func (e *Enforcer) AddMember(domain, member string) error {
89 _, err := e.E.AddGroupingPolicy(member, "server:member", domain)
90 return err
91}
92
93func (e *Enforcer) AddRepo(member, domain, repo string) error {
94 _, err := e.E.AddPolicies([][]string{
95 {member, domain, repo, "repo:push"},
96 {member, domain, repo, "repo:owner"},
97 {member, domain, repo, "repo:invite"},
98 {member, domain, repo, "repo:delete"},
99 {"server:owner", domain, repo, "repo:delete"}, // server owner can delete any repo
100 })
101 return err
102}
103
104// keyMatch2Func is a wrapper for keyMatch2 to make it compatible with Casbin
105func keyMatch2Func(args ...interface{}) (interface{}, error) {
106 name1 := args[0].(string)
107 name2 := args[1].(string)
108
109 return keyMatch2(name1, name2), nil
110}