This is an automated email from the ASF dual-hosted git repository.
hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin.git
The following commit(s) were added to refs/heads/master by this push:
new d3e9928 fix: preserve policy order in Model.RemovePolicy
d3e9928 is described below
commit d3e9928ab07b200efa0132f99fa095c084597897
Author: Yang Luo <[email protected]>
AuthorDate: Tue Aug 4 16:11:57 2026 +0800
fix: preserve policy order in Model.RemovePolicy
---
model/policy.go | 15 ++++++++-------
model_test.go | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/model/policy.go b/model/policy.go
index d4e4899..7669dfe 100644
--- a/model/policy.go
+++ b/model/policy.go
@@ -267,14 +267,15 @@ func (model Model) RemovePolicy(sec string, ptype string,
rule []string) (bool,
return false, nil
}
- lastIdx := len(ast.Policy) - 1
- if index != lastIdx {
- ast.Policy[index] = ast.Policy[lastIdx]
- lastPolicyKey := strings.Join(ast.Policy[index], DefaultSep)
- ast.PolicyMap[lastPolicyKey] = index
- }
- ast.Policy = ast.Policy[:lastIdx]
+ // The order of Policy is significant: it carries the priority
semantics of
+ // the "priority(p_eft)" effector, both for explicit priority models
and for
+ // implicit ones where the priority is the policy order itself. So the
rule
+ // has to be shifted out instead of being swapped with the last one.
+ ast.Policy = append(ast.Policy[:index], ast.Policy[index+1:]...)
delete(ast.PolicyMap, key)
+ for i := index; i < len(ast.Policy); i++ {
+ ast.PolicyMap[strings.Join(ast.Policy[i], DefaultSep)] = i
+ }
return true, nil
}
diff --git a/model_test.go b/model_test.go
index 2cb155b..bd0a293 100644
--- a/model_test.go
+++ b/model_test.go
@@ -639,6 +639,26 @@ func TestPriorityModel(t *testing.T) {
testEnforce(t, e, "bob", "data2", "write", false)
}
+func TestPriorityExplicitRemovePolicyKeepsOrder(t *testing.T) {
+ e, _ := NewEnforcer("examples/priority_model_explicit.conf")
+
+ if _, err := e.AddPolicies([][]string{
+ {"1", "carol", "data9", "read", "allow"},
+ {"2", "alice", "data1", "read", "deny"},
+ {"3", "alice", "data1", "read", "allow"},
+ }); err != nil {
+ t.Fatalf("AddPolicies: %v", err)
+ }
+ testEnforce(t, e, "alice", "data1", "read", false)
+
+ // Removing an unrelated rule must not reorder the remaining ones,
otherwise
+ // the priority 3 rule would take precedence over the priority 2 one.
+ if _, err := e.RemovePolicy("1", "carol", "data9", "read", "allow");
err != nil {
+ t.Fatalf("RemovePolicy: %v", err)
+ }
+ testEnforce(t, e, "alice", "data1", "read", false)
+}
+
func TestPriorityModelIndeterminate(t *testing.T) {
e, _ := NewEnforcer("examples/priority_model.conf",
"examples/priority_indeterminate_policy.csv")
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]