breken-ai opened a new pull request, #1765:
URL: https://github.com/apache/casbin/pull/1765

   ## Description
   
   With a domain matching function (for example 
`e.AddNamedDomainMatchingFunc("g", "KeyMatch", util.KeyMatch)`), removing one 
grouping rule can revoke a role that another rule still grants. `Enforce` then 
denies requests the policy allows, and keeps doing so until `LoadPolicy()` runs.
   
   Using `examples/rbac_with_domain_pattern_*`:
   
   ```go
   // policy already has: g, alice, admin, *    and    g, bob, admin, domain2
   e.AddGroupingPolicy("alice", "admin", "domain1")
   e.RemoveGroupingPolicy("alice", "admin", "domain1")
   e.Enforce("alice", "domain1", "data1", "read") // false, but "g, alice, 
admin, *" still grants it
   
   e.AddGroupingPolicy("bob", "admin", "*")
   e.RemoveGroupingPolicy("bob", "admin", "*")
   e.Enforce("bob", "domain2", "data2", "read")   // false, but "g, bob, admin, 
domain2" is still there
   
   e.LoadPolicy()                                  // both are true again
   ```
   
   Any code path that calls `DeleteLink` does this: `RemoveGroupingPolicy`, 
`DeleteRoleForUserInDomain`, `UpdateGroupingPolicy` and 
`RemoveFilteredGroupingPolicy`, as well as watcher updates on other nodes.
   
   **Cause:** `DomainManager.getRoleManager` copies the links of every matching 
pattern domain into a concrete domain's role manager, and `AddLink` adds a 
pattern link to every domain that already exists. After that copy, a domain's 
role manager can't tell its own links from the ones it inherited. 
`DomainManager.DeleteLink` deleted the link from the domain itself and from 
every domain the deleted pattern matches, without checking whether another link 
still granted it there.
   
   **Fix:** `DomainManager` now records each link with the domain it was added 
in. `DeleteLink` removes that record first, then deletes the link from a domain 
only when no remaining record grants it there: neither the domain itself nor a 
pattern that matches it. `rebuild()` (run by `AddDomainMatchingFunc`) replays 
these records. Before, it replayed the per-domain role managers, and those also 
hold the copied pattern links, so each copied link would be recorded as the 
domain's own. `Clear` resets the records, and `DeleteDomain` drops the records 
for that domain.
   
   `ConditionalDomainManager` has its own `AddLink`/`DeleteLink`/`rebuild`, so 
this change doesn't touch it.
   
   ## Testing
   
   - `TestRemoveGroupingPolicyWithDomainPattern` 
(`rbac_api_with_domains_test.go`) runs the scenario above through the enforcer 
and checks that `LoadPolicy()` gives the same answers.
   - `TestDomainPatternDeleteLinkKeepsLinksStillGranted` 
(`rbac/default-role-manager/role_manager_test.go`) covers both directions at 
the role manager level, and checks that a link is gone once no rule grants it 
any more.
   - `TestDomainPatternRebuildUsesAddedLinks` guards the `rebuild()` change. A 
`"*"` link copied into `domain1` must not become a `domain1` link of its own 
when the matching function is set again.
   
   Results:
   
   - On `master` @ `524f3f2`: the first two tests fail (`alice, domain1, data1, 
read: false, supposed to be true`; `bob, domain2, data2, read: false, supposed 
to be true`).
   - With the fix: all three pass.
   - The full `go test ./...` suite passes, `go test -race ./rbac/... .` 
passes, and `gofmt` and `golangci-lint run ./...` (v2, repo config) report 0 
issues.
   
   ---
   
   I found this bug with AI assistance (Claude, per the [ASF generative tooling 
guidance](https://www.apache.org/legal/generative-tooling.html)) and used it to 
write the fix and tests; I reviewed the change and ran the tests above.
   


-- 
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]

Reply via email to