This is an automated email from the ASF dual-hosted git repository. hsluoyz pushed a commit to branch docs/fix-readme-typos-and-inaccuracies in repository https://gitbox.apache.org/repos/asf/casbin-pycasbin.git
commit 34a11a2253d7c1ae8cbe9572871e70faf6cf4f69 Author: Yang Luo <[email protected]> AuthorDate: Wed Sep 23 14:08:24 2026 +0800 docs: fix typos and Go-specific inaccuracies in README and docstrings --- README.md | 46 ++++++++++++++++++++-------------------- casbin/util/builtin_operators.py | 2 +- casbin/util/expression.py | 2 +- casbin/util/util.py | 2 +- tests/test_enforcer.py | 4 ++-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 9184df8..16d392c 100644 --- a/README.md +++ b/README.md @@ -54,14 +54,14 @@ Casbin is a powerful and efficient open-source access control library for Python 1. [**ACL (Access Control List)**](https://en.wikipedia.org/wiki/Access_control_list) 2. **ACL with [superuser](https://en.wikipedia.org/wiki/Superuser)** 3. **ACL without users**: especially useful for systems that don't have authentication or user log-ins. -3. **ACL without resources**: some scenarios may target for a type of resources instead of an individual resource by using permissions like ``write-article``, ``read-log``. It doesn't control the access to a specific article or log. -4. **[RBAC (Role-Based Access Control)](https://en.wikipedia.org/wiki/Role-based_access_control)** -5. **RBAC with resource roles**: both users and resources can have roles (or groups) at the same time. -6. **RBAC with domains/tenants**: users can have different role sets for different domains/tenants. -7. **[ABAC (Attribute-Based Access Control)](https://en.wikipedia.org/wiki/Attribute-Based_Access_Control)**: syntax sugar like ``resource.Owner`` can be used to get the attribute for a resource. -8. **[RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer)**: supports paths like ``/res/*``, ``/res/:id`` and HTTP methods like ``GET``, ``POST``, ``PUT``, ``DELETE``. -9. **Deny-override**: both allow and deny authorizations are supported, deny overrides the allow. -10. **Priority**: the policy rules can be prioritized like firewall rules. +4. **ACL without resources**: some scenarios may target for a type of resources instead of an individual resource by using permissions like ``write-article``, ``read-log``. It doesn't control the access to a specific article or log. +5. **[RBAC (Role-Based Access Control)](https://en.wikipedia.org/wiki/Role-based_access_control)** +6. **RBAC with resource roles**: both users and resources can have roles (or groups) at the same time. +7. **RBAC with domains/tenants**: users can have different role sets for different domains/tenants. +8. **[ABAC (Attribute-Based Access Control)](https://en.wikipedia.org/wiki/Attribute-Based_Access_Control)**: syntax sugar like ``resource.Owner`` can be used to get the attribute for a resource. +9. **[RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer)**: supports paths like ``/res/*``, ``/res/:id`` and HTTP methods like ``GET``, ``POST``, ``PUT``, ``DELETE``. +10. **Deny-override**: both allow and deny authorizations are supported, deny overrides the allow. +11. **Priority**: the policy rules can be prioritized like firewall rules. ## How it works? @@ -100,16 +100,16 @@ It means: - alice can read data1 - bob can write data2 -We also support multi-line mode by appending '\\' in the end: +We also support multi-line mode by appending '\\' at the end: ```ini # Matchers [matchers] -m = r.sub == p.sub && r.obj == p.obj \ +m = r.sub == p.sub && r.obj == p.obj \ && r.act == p.act ``` -Further more, if you are using ABAC, you can try operator `in` like following in Casbin **golang** edition (jCasbin and Node-Casbin are not supported yet): +Furthermore, if you are using ABAC, you can use the `in` operator like the following: ```ini # Matchers @@ -117,9 +117,9 @@ Further more, if you are using ABAC, you can try operator `in` like following i m = r.obj == p.obj && r.act == p.act || r.obj in ('data2', 'data3') ``` -But you **SHOULD** make sure that the length of the array is **MORE** than **1**, otherwise there will cause it to panic. +Note: the right-hand side is a normal Python tuple, so a single-element one **MUST** keep its trailing comma, e.g. ``('data2',)``. Writing ``('data2')`` makes it a plain string, and ``in`` then silently degrades to a substring match (``data`` would match ``data2``). -For more operators, you may take a look at [govaluate](https://github.com/Knetic/govaluate) +For more operators, you may take a look at [simpleeval](https://github.com/danthedeckie/simpleeval), the expression engine used by pycasbin. ## Features @@ -128,7 +128,7 @@ What Casbin does: 1. enforce the policy in the classic ``{subject, object, action}`` form or a customized form as you defined, both allow and deny authorizations are supported. 2. handle the storage of the access control model and its policy. 3. manage the role-user mappings and role-role mappings (aka role hierarchy in RBAC). -4. support built-in superuser like ``root`` or ``administrator``. A superuser can do anything without explict permissions. +4. support built-in superuser like ``root`` or ``administrator``. A superuser can do anything without explicit permissions. 5. multiple built-in operators to support the rule matching. For example, ``keyMatch`` can map a resource key ``/foo/bar`` to the pattern ``/foo*``. What Casbin does NOT do: @@ -180,7 +180,7 @@ else: pass ``` -3. Besides the static policy file, Casbin also provides API for permission management at run-time. For example, You can get all the roles assigned to a user as below: +3. Besides the static policy file, Casbin also provides API for permission management at run-time. For example, you can get all the roles assigned to a user as below: ```python roles = e.get_roles_for_user("alice") @@ -213,7 +213,7 @@ https://casbin.org/docs/role-managers ## Async Enforcer -If your code use `async` / `await` and is heavily dependent on I/O operations, you can adopt Async Enforcer! +If your code uses `async` / `await` and is heavily dependent on I/O operations, you can adopt Async Enforcer! 1. Create an async engine and new a Casbin AsyncEnforcer with a model file and an async Pycasbin adapter (AsyncAdapter subclass): @@ -276,22 +276,22 @@ https://casbin.org/docs/benchmark ## Logging -pycasbin leverages the default Python logging mechanism. The pycasbin package makes a call to `logging.getLogger()` to set the logger. No special logging configuration is needed other than initializing the logger in the parent application. If no logging is initialized within the parent application, you will not see any log messages from pycasbin. At the same time, When you enable log in pycasbin, you can specify the logging configuration through the parameter `logging_config`. If no conf [...] +pycasbin leverages the default Python logging mechanism. The pycasbin package makes a call to `logging.getLogger()` to set the logger. No special logging configuration is needed other than initializing the logger in the parent application. If no logging is initialized within the parent application, you will not see any log messages from pycasbin. At the same time, when you enable log in pycasbin, you can specify the logging configuration through the parameter `logging_config`. If no conf [...] ## Examples | Model | Model file | Policy file | |---------------------------|----------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------| | ACL | [basic_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_model.conf) | [basic_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_policy.csv) | -| ACL with superuser | [basic_model_with_root.conf](https://github.com/casbin/casbin/blob/master/examples/basic_with_root_model.conf) | [basic_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_policy.csv) | -| ACL without users | [basic_model_without_users.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_model.conf) | [basic_policy_without_users.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_policy.csv) | -| ACL without resources | [basic_model_without_resources.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_model.conf) | [basic_policy_without_resources.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_policy.csv) | +| ACL with superuser | [basic_with_root_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_with_root_model.conf) | [basic_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_policy.csv) | +| ACL without users | [basic_without_users_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_model.conf) | [basic_without_users_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_users_policy.csv) | +| ACL without resources | [basic_without_resources_model.conf](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_model.conf) | [basic_without_resources_policy.csv](https://github.com/casbin/casbin/blob/master/examples/basic_without_resources_policy.csv) | | RBAC | [rbac_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_model.conf) | [rbac_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_policy.csv) | -| RBAC with resource roles | [rbac_model_with_resource_roles.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_model.conf) | [rbac_policy_with_resource_roles.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_policy.csv) | -| RBAC with domains/tenants | [rbac_model_with_domains.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_model.conf) | [rbac_policy_with_domains.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_policy.csv) | +| RBAC with resource roles | [rbac_with_resource_roles_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_model.conf) | [rbac_with_resource_roles_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_resource_roles_policy.csv) | +| RBAC with domains/tenants | [rbac_with_domains_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_model.conf) | [rbac_with_domains_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_domains_policy.csv) | | ABAC | [abac_model.conf](https://github.com/casbin/casbin/blob/master/examples/abac_model.conf) | N/A | | RESTful | [keymatch_model.conf](https://github.com/casbin/casbin/blob/master/examples/keymatch_model.conf) | [keymatch_policy.csv](https://github.com/casbin/casbin/blob/master/examples/keymatch_policy.csv) | -| Deny-override | [rbac_model_with_deny.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_model.conf) | [rbac_policy_with_deny.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_policy.csv) | +| Deny-override | [rbac_with_deny_model.conf](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_model.conf) | [rbac_with_deny_policy.csv](https://github.com/casbin/casbin/blob/master/examples/rbac_with_deny_policy.csv) | | Priority | [priority_model.conf](https://github.com/casbin/casbin/blob/master/examples/priority_model.conf) | [priority_policy.csv](https://github.com/casbin/casbin/blob/master/examples/priority_policy.csv) | ## Middlewares diff --git a/casbin/util/builtin_operators.py b/casbin/util/builtin_operators.py index 62e0f02..2aff2ad 100644 --- a/casbin/util/builtin_operators.py +++ b/casbin/util/builtin_operators.py @@ -107,7 +107,7 @@ def key_get2(key1, key2, path_var): def key_match3(key1, key2): - """determines determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *. + """determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *. For example, "/foo/bar" matches "/foo/*", "/resource1" matches "/{resource}" """ diff --git a/casbin/util/expression.py b/casbin/util/expression.py index 3be2015..e2abb5d 100644 --- a/casbin/util/expression.py +++ b/casbin/util/expression.py @@ -34,7 +34,7 @@ class SimpleEval(EvalWithCompoundTypes): self.ast_parsed_value = ast.parse(expr.strip()).body[0].value def eval(self, names=None): - """evaluate an expresssion, using the operators, functions and + """evaluate an expression, using the operators, functions and names previously set up.""" if names: diff --git a/casbin/util/util.py b/casbin/util/util.py index 1e13890..618f124 100644 --- a/casbin/util/util.py +++ b/casbin/util/util.py @@ -84,7 +84,7 @@ def has_eval(s): def replace_eval(expr, rules): - """replace all occurences of function eval with rules""" + """replace all occurrences of function eval with rules""" pos = 0 match = eval_reg.search(expr, pos) while match: diff --git a/tests/test_enforcer.py b/tests/test_enforcer.py index a4c5672..64f9e2f 100644 --- a/tests/test_enforcer.py +++ b/tests/test_enforcer.py @@ -287,7 +287,7 @@ class TestConfig(TestCaseBase): self.assertTrue(e.enforce("bob", "data2", "write")) self.assertTrue(e.enforce("alice", "data2", "read")) self.assertTrue(e.enforce("alice", "data2", "write")) - self.assertFalse(e.enforce("bogus", "data2", "write")) # test non-existant subject + self.assertFalse(e.enforce("bogus", "data2", "write")) # test non-existent subject def test_enforce_rbac_empty_policy(self): e = self.get_enforcer(get_examples("rbac_model.conf"), get_examples("empty_policy.csv")) @@ -883,7 +883,7 @@ class TestConfigAsync(IsolatedAsyncioTestCase): self.assertTrue(e.enforce("bob", "data2", "write")) self.assertTrue(e.enforce("alice", "data2", "read")) self.assertTrue(e.enforce("alice", "data2", "write")) - self.assertFalse(e.enforce("bogus", "data2", "write")) # test non-existant subject + self.assertFalse(e.enforce("bogus", "data2", "write")) # test non-existent subject async def test_enforce_rbac_empty_policy(self): e = self.get_enforcer(get_examples("rbac_model.conf"), get_examples("empty_policy.csv")) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
