bitflicker64 opened a new issue, #1759:
URL: https://github.com/apache/casbin/issues/1759
### What happened
I have a model with two policy definitions. `p` is the usual `sub, dom, obj,
act`, and `p2` puts the domain first because we group those rules per tenant.
Two things go wrong with `p2`:
1. `GetNamedPermissionsForUser("p2", "alice")` returns an empty slice.
2. `GetNamedPermissionsForUser("p2", "alice", "tenant1")` returns alice's
rule **and bob's**.
The second one is the reason I am filing this rather than just working
around it: I asked for one user's permissions and got another user's rule back.
`GetPermissionsForUser` against plain `p` behaves fine, which is why it took me
a while to realise the ptype was the thing that mattered.
### How to reproduce
No fixture files needed, this is the whole thing:
```go
package repro
import (
"fmt"
"testing"
"github.com/casbin/casbin/v3"
"github.com/casbin/casbin/v3/model"
)
// p uses the usual column order, p2 lists the domain first.
const text = `
[request_definition]
r = sub, dom, obj, act
[policy_definition]
p = sub, dom, obj, act
p2 = dom, sub, obj, act
[role_definition]
g = _, _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act ==
p.act
`
func TestNamedPermissions(t *testing.T) {
m, err := model.NewModelFromString(text)
if err != nil {
t.Fatal(err)
}
e, err := casbin.NewEnforcer(m)
if err != nil {
t.Fatal(err)
}
if _, err := e.AddNamedPolicy("p2", "tenant1", "alice", "report1",
"read"); err != nil {
t.Fatal(err)
}
if _, err := e.AddNamedPolicy("p2", "tenant1", "bob", "report2",
"read"); err != nil {
t.Fatal(err)
}
got, _ := e.GetNamedPermissionsForUser("p2", "alice")
fmt.Printf("no domain: %v\n", got)
fmt.Printf("expected: [[tenant1 alice report1 read]]\n\n")
got, _ = e.GetNamedPermissionsForUser("p2", "alice", "tenant1")
fmt.Printf("with domain: %v\n", got)
fmt.Printf("expected: [[tenant1 alice report1 read]]\n")
}
```
What I get:
```
no domain: []
expected: [[tenant1 alice report1 read]]
with domain: [[tenant1 alice report1 read] [tenant1 bob report2 read]]
expected: [[tenant1 alice report1 read]]
```
### Where it comes from
`GetNamedPermissionsForUser` sizes `args` from the requested ptype but looks
the subject index up against `"p"`:
https://github.com/apache/casbin/blob/34297a19bd65cd52d40d146452c20aea7b45c205/rbac_api.go#L199-L213
So `args` has `p2`'s shape while `subIndex` is `p`'s. Here `p_sub` is 0 and
`p2_sub` is 1, so `alice` is written into the `dom` column and nothing matches,
which explains case 1.
For case 2, `args[index] = domain[0]` then overwrites that same index 0 with
`tenant1`. The subject column is left empty, and an empty field is a wildcard
in `GetFilteredNamedPolicy`, so every rule in the domain comes back regardless
of who was asked for.
The domain lookup four lines further down already passes `ptype`, so the two
lookups in this function disagree with each other.
### Suggested fix
```diff
- subIndex, err := e.GetFieldIndex("p", constant.SubjectIndex)
+ subIndex, err := e.GetFieldIndex(ptype, constant.SubjectIndex)
```
I tried this locally: both cases above return what I expected, and `go test
./...` still passes.
Happy to send a PR with a regression test if that is welcome.
### Environment
- casbin v3, master at `34297a1`
- go1.27, darwin/arm64
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]