1

I use the casbin with rabc with resource model, this is my conf:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _
g2 = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && g2(r.obj, p.obj) &&(r.act == p.act

this is the policy:

p, data_group_admin, data_group, write

g, alice, data_group_admin
g2, /api/:id, data_group

this is the request:

alice, /api/1, read
alice, /api/2, write

the result is false, false actually, I expect the result is true, true,I want to the resource can support restful format, how to set the conf?

M.Mike
  • 663
  • 1
  • 6
  • 12

2 Answers2

1

You can use AddMatchingFunc to make the default role manager knows how to spread the role link because by default it compares role name exactly.

the example code may look like

e.GetRoleManager().(*defaultrolemanager.RoleManager).AddMatchingFunc('matcher', util.KeyMatch)

for more information you can see https://github.com/casbin/casbin/blob/master/rbac/default-role-manager/role_manager.go#L163

updated, add sample code

package main

import (
    "github.com/casbin/casbin/v2"
    defaultrolemanager "github.com/casbin/casbin/v2/rbac/default-role-manager"
    "github.com/casbin/casbin/v2/util"
)

func main() {
    e, _ := casbin.NewEnforcer("./model.conf", "./policy.csv")

    e.GetRoleManager().(*defaultrolemanager.RoleManager).AddMatchingFunc("key_match", util.KeyMatch2)
    res1, _ := e.Enforce("alice", "/api/1", "write") // true
    res2, _ := e.Enforce("alice", "/api/2", "read")  // false
}

This will result true, because alice belongs to data_group_admin and /api/1 belongs to data_group, data_group_admin can write data_group

Since you didn't define the read policy, so the second enforce will return false.

Joey
  • 1,233
  • 3
  • 11
  • 18
  • It seems not effect with rbac with resource model: ``` m.AddDef("r", "r", "sub, obj, act") // role m.AddDef("p", "p", "sub, obj, act") m.AddDef("g", "g", "_, _") m.AddDef("g", "g2", "_, _") m.AddDef("e", "e", "some(where (p.eft == allow))") m.AddDef("m", "m", `g(r.sub, p.sub)&& g2(r.obj, p.obj) && r.act == p.act `) rm := defaultrolemanager.NewRoleManager(10) rm.(*defaultrolemanager.RoleManager).AddMatchingFunc("matcher", util.KeyMatch2) rm.(*defaultrolemanager.RoleManager).AddDomainMatchingFunc("matcher", util.KeyMatch2) ``` this is the go code, model set – M.Mike Jun 22 '20 at 06:57
  • @M.Mike plz make a github issue – hsluoyz Feb 20 '21 at 14:15
0

In my opinion.

g2, /api/:id, data_group

g2 need two sub not obj and sub.

I mean: if you want alice alice can access /api/1 You need :

p: alice, /api/1, read
p: alice, /api/2, write

or:

p: data_group_admin, /api/1, read
p: data_group_admin, /api/2, write
g: alice, data_group_admin

Summary: distinguish sub and obj in r, p and g.

PaPu
  • 731
  • 7
  • 12