Finally:
p, 1, /something, GET, sol-*
Why if there are zero groups does it pass. There should be nothing to match right?
But if I do:
p, r1, /something, GET, sol-*
It again gives false as it should be
Not the most efficient but gaurantee that I get the latest data
Yeah currently not worrying about perfomance
I am not using the default structure like in this adapter:
https://github.com/casbin/xorm-adapter
So I can gather the data I need efficiently and generate the policy + role group at runtime
My example is just an example to make it understandable. In the end it will all just be id's that are matched
In my case only the model is static all others things are loaded from db or cache at runtime per request
I went from this model:
const stringModel = `
[request_definition]
r = user, dom, obj, act, tag
[policy_definition]
p = role, dom, obj, act, tag
[policy_effect]
e = some(where (p.eft == allow))
[role_definition]
g = _, _, _
g2 = _, _
[matchers]
m = g(r.user, p.role, r.tag) && g2(p.role, r.dom) && keyMatch(r.tag, p.tag) && keyMatch(r.act, p.act) && (keyMatch(r.obj, p.obj) || keyMatch2(r.obj, p.obj))
`
func TestDefaultRbac(t *testing.T) {
m, _ := model.NewModelFromString(stringModel)
e, _ := casbin.NewEnforcer(m, false)
e.AddPolicies([][]string{
{"reader", "org1", "/project", "GET", "project_*"},
{"editor", "org1", "/project", "DELETE", "project_*"},
{"reader2", "org2", "/project", "GET", "project_*"},
})
e.AddNamedGroupingPolicies("g", [][]string{
{"tom", "reader", "project_1"},
{"tom", "reader", "project_2"},
{"tom", "reader", "project_3"},
{"tom", "editor", "project_5"},
{"henk", "reader2", "project_6"},
})
e.AddNamedGroupingPolicies("g2", [][]string{
{"reader", "org1"},
{"reader2", "org2"},
{"editor", "org1"},
})
enforcer := func(user, dom, obj, act, tag string, expect bool) {
resp, _ := e.Enforce(user, dom, obj, act, tag)
if resp != expect {
t.Errorf("Response is for %s %s %s %s %s %t expected to be %t", user, dom, obj, act, tag, resp, expect)
}
}
enforcer("tom", "org1", "/project", "GET", "project_1", true)
enforcer("tom", "org1", "/project", "DELETE", "project_1", false)
enforcer("tom", "org1", "/project", "DELETE", "project_5", true)
enforcer("tom", "org2", "/project", "GET", "project_6", false)
enforcer("henk", "org2", "/project", "GET", "project_6", true)
}
to this, I left out the whole org part since the roles will be unique per org and are therefore implicity tied to an org:
const stringModel2 = `
[request_definition]
r = user, obj, act, tag
[policy_definition]
p = role, obj, act, tag
[policy_effect]
e = some(where (p.eft == allow))
[role_definition]
g = _, _, _
[matchers]
m = g(r.user, p.role, r.tag) && keyMatch(r.tag, p.tag) && keyMatch(r.act, p.act) && (keyMatch(r.obj, p.obj) || keyMatch2(r.obj, p.obj))
`
func TestDefaultRbac2(t *testing.T) {
m, _ := model.NewModelFromString(stringModel2)
e, _ := casbin.NewEnforcer(m, false)
e.AddPolicies([][]string{
{"reader", "/project", "GET", "project_*"},
{"editor", "/project", "DELETE", "project_*"},
{"reader2", "/project", "GET", "project_*"},
})
e.AddNamedGroupingPolicies("g", [][]string{
{"tom", "reader", "project_1"},
{"tom", "reader", "project_2"},
{"tom", "reader", "project_3"},
{"tom", "editor", "project_5"},
{"henk", "reader2", "project_6"},
})
enforcer := func(user, obj, act, tag string, expect bool) {
resp, _ := e.Enforce(user, obj, act, tag)
if resp != expect {
t.Errorf("Response is for %s %s %s %s %t expected to be %t", user, obj, act, tag, resp, expect)
}
}
enforcer("tom", "/project", "GET", "project_1", true)
enforcer("tom", "/project", "DELETE", "project_1", false)
enforcer("tom", "/project", "DELETE", "project_5", true)
enforcer("tom", "/project", "GET", "project_6", false)
enforcer("henk", "/project", "GET", "project_6", true)
}
Both do the same thing one is explicit with role + org combination and the other is implicit. E.g. reader is part of org1 and reader2 is part of org2
I plan to make a custom adapter https://casbin.org/docs/adapters/ that loads the filtered policy for each request and checks it.
that loads the filtered policy for each request and checks it. for endpoints that need it

