Want to prioritize this issue? Try:
Describe the bug
keyGet2 in matchers is not evaluated correctly
To Reproduce
Steps to reproduce the behavior:
I want to implement RBAC with domain.
What I tried is,
p, admin, /workspaces/:workspace_id, (GET)|(PUT)|(DELETE), allow
p, member, /workspaces/:workspace_id, GET, allow
g, alice, admin, workspace1
g, alice, member, workspace2
g, bob, admin, workspace2
[request_definition]
r = sub, dom, obj, act
[policy_definition]
p = sub, obj, act, eft
[role_definition]
g = _, _, _
[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
[matchers]
m = g(r.sub, p.sub, r.dom) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act) && getKey2(r.obj, p.obj, 'workspace_id') == r.dom
Expected behavior
request alice, workspace1, /workspaces/workspace1, GET
expects true
, but actually false
returns.
Desktop (please complete the following information):
- OS: Windows
- Browser: Microsoft Edge (editor ceased working in chrome)
- Version: Online Editor
Additional context
Registering custom function solved my issue already, but I still don't understand why the above implementation didn't go.
[request_definition]
r = sub, dom, obj, act
[policy_definition]
p = sub, obj, act, eft
[role_definition]
g = _, _, _
[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
[matchers]
m = g(r.sub, p.sub, r.dom) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act) && parseWorkspace(r.obj, p.obj, r.dom)
package main
import (
"fmt"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/util"
"log"
)
func main() {
e, err := casbin.NewEnforcer("./model.conf", "./policy.csv")
if err != nil {
log.Fatal(err)
}
e.AddFunction("parseWorkspace", ParseWorkspace)
enforce, err := e.Enforce("alice", "workspace1", "/workspaces/workspace1", "GET")
if err != nil {
return
}
fmt.Println(enforce)
}
func parseWorkspace(requestObj string, policyObj string, dom string) bool {
return util.KeyGet2(requestObj, policyObj, "workspace_id") == dom
}
func ParseWorkspace(args ...interface{}) (interface{}, error) {
name1 := args[0].(string)
name2 := args[1].(string)
name3 := args[2].(string)
return parseWorkspace(name1, name2, name3), nil
}