this repo has no description
1package rbac 2 3import ( 4 "database/sql" 5 "path" 6 "strings" 7 8 sqladapter "github.com/Blank-Xu/sql-adapter" 9 "github.com/casbin/casbin/v2" 10 "github.com/casbin/casbin/v2/model" 11) 12 13const ( 14 Model = ` 15[request_definition] 16r = sub, dom, obj, act 17 18[policy_definition] 19p = sub, dom, obj, act 20 21[role_definition] 22g = _, _, _ 23 24[policy_effect] 25e = some(where (p.eft == allow)) 26 27[matchers] 28m = r.act == p.act && r.dom == p.dom && keyMatch2(r.obj, p.obj) && g(r.sub, p.sub, r.dom) 29` 30) 31 32type Enforcer struct { 33 E *casbin.SyncedEnforcer 34} 35 36func keyMatch2(key1 string, key2 string) bool { 37 matched, _ := path.Match(key2, key1) 38 return matched 39} 40 41func NewEnforcer(path string) (*Enforcer, error) { 42 m, err := model.NewModelFromString(Model) 43 if err != nil { 44 return nil, err 45 } 46 47 db, err := sql.Open("sqlite3", path) 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 104func (e *Enforcer) GetUserByRole(role, domain string) ([]string, error) { 105 var membersWithoutRoles []string 106 107 // this includes roles too, casbin does not differentiate. 108 // the filtering criteria is to remove strings not starting with `did:` 109 members, err := e.E.Enforcer.GetImplicitUsersForRole(role, domain) 110 for _, m := range members { 111 if strings.HasPrefix(m, "did:") { 112 membersWithoutRoles = append(membersWithoutRoles, m) 113 } 114 } 115 if err != nil { 116 return nil, err 117 } 118 119 return membersWithoutRoles, nil 120} 121 122func (e *Enforcer) isRole(user, role, domain string) (bool, error) { 123 return e.E.HasGroupingPolicy(user, role, domain) 124} 125 126func (e *Enforcer) IsServerOwner(user, domain string) (bool, error) { 127 return e.isRole(user, "server:owner", domain) 128} 129 130func (e *Enforcer) IsServerMember(user, domain string) (bool, error) { 131 return e.isRole(user, "server:member", domain) 132} 133 134func (e *Enforcer) IsPushAllowed(user, domain, repo string) (bool, error) { 135 return e.E.Enforce(user, domain, repo, "repo:push") 136} 137 138// keyMatch2Func is a wrapper for keyMatch2 to make it compatible with Casbin 139func keyMatch2Func(args ...interface{}) (interface{}, error) { 140 name1 := args[0].(string) 141 name2 := args[1].(string) 142 143 return keyMatch2(name1, name2), nil 144}