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-pycasbin.git


The following commit(s) were added to refs/heads/master by this push:
     new 6ab2095  fix: return copies from get_policy and get_filtered_policy
6ab2095 is described below

commit 6ab2095c552725535c2550f151b9b2c91c7790f6
Author: Yang Luo <[email protected]>
AuthorDate: Tue Aug 4 14:08:34 2026 +0800

    fix: return copies from get_policy and get_filtered_policy
---
 casbin/model/policy.py     | 16 ++++++++++++----
 tests/model/test_policy.py | 25 +++++++++++++++++++++++++
 tests/test_rbac_api.py     | 23 +++++++++++++++++++++++
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/casbin/model/policy.py b/casbin/model/policy.py
index 77fd3a7..9c57cb3 100644
--- a/casbin/model/policy.py
+++ b/casbin/model/policy.py
@@ -89,14 +89,22 @@ class Policy:
                 self[sec][key].policy = []
 
     def get_policy(self, sec, ptype):
-        """gets all rules in a policy."""
+        """gets all rules in a policy.
 
-        return self[sec][ptype].policy
+        The returned rules are shallow copies, so that mutating them does not
+        corrupt the internal policy storage.
+        """
+
+        return [rule[:] for rule in self[sec][ptype].policy]
 
     def get_filtered_policy(self, sec, ptype, field_index, *field_values):
-        """gets rules based on field filters from a policy."""
+        """gets rules based on field filters from a policy.
+
+        The returned rules are shallow copies, so that mutating them does not
+        corrupt the internal policy storage.
+        """
         return [
-            rule
+            rule[:]
             for rule in self[sec][ptype].policy
             if all(
                 (callable(value) and value(rule[field_index + i])) or (value 
== "" or rule[field_index + i] == value)
diff --git a/tests/model/test_policy.py b/tests/model/test_policy.py
index 855eb84..b4d1cbf 100644
--- a/tests/model/test_policy.py
+++ b/tests/model/test_policy.py
@@ -29,6 +29,31 @@ class TestPolicy(TestCase):
 
         self.assertTrue(m.get_policy("p", "p") == [rule])
 
+    def test_get_policy_returns_copies(self):
+        m = Model()
+        m.load_model(get_examples("basic_model.conf"))
+
+        rule = ["admin", "domain1", "data1", "read"]
+        m.add_policy("p", "p", rule)
+
+        returned = m.get_policy("p", "p")
+        returned.append(["hacker", "domain1", "data1", "read"])
+        returned[0][0] = "hacker"
+
+        self.assertEqual(m.get_policy("p", "p"), [["admin", "domain1", 
"data1", "read"]])
+
+    def test_get_filtered_policy_returns_copies(self):
+        m = Model()
+        m.load_model(get_examples("basic_model.conf"))
+
+        rule = ["admin", "domain1", "data1", "read"]
+        m.add_policy("p", "p", rule)
+
+        returned = m.get_filtered_policy("p", "p", 0, "admin")
+        returned[0][0] = "hacker"
+
+        self.assertEqual(m.get_policy("p", "p"), [["admin", "domain1", 
"data1", "read"]])
+
     def test_has_policy(self):
         m = Model()
         m.load_model(get_examples("basic_model.conf"))
diff --git a/tests/test_rbac_api.py b/tests/test_rbac_api.py
index 6171fed..bd40cd4 100644
--- a/tests/test_rbac_api.py
+++ b/tests/test_rbac_api.py
@@ -206,6 +206,29 @@ class TestRbacApi(TestCaseBase):
             sorted([["bob", "data2", "write"]]),
         )
 
+    def test_implicit_permissions_api_does_not_expose_internal_rules(self):
+        e = self.get_enforcer(
+            get_examples("rbac_model.conf"),
+            get_examples("rbac_policy.csv"),
+        )
+
+        permissions = e.get_implicit_permissions_for_user("alice")
+        for permission in permissions:
+            permission[0] = "alice"
+
+        self.assertEqual(
+            sorted(e.get_policy()),
+            sorted(
+                [
+                    ["alice", "data1", "read"],
+                    ["bob", "data2", "write"],
+                    ["data2_admin", "data2", "read"],
+                    ["data2_admin", "data2", "write"],
+                ]
+            ),
+        )
+        self.assertTrue(e.enforce("alice", "data2", "read"))
+
     def test_enforce_implicit_permissions_api_with_multiple_policy(self):
         e = self.get_enforcer(
             get_examples("rbac_with_multiple_policy_model.conf"),


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to