Skip to content

Commit

Permalink
feat: async adapter interface stubs
Browse files Browse the repository at this point in the history
  • Loading branch information
thearchitector committed Dec 20, 2023
1 parent f03539f commit 5e1c9d7
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 7 deletions.
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -232,7 +232,7 @@ https://casbin.org/docs/role-managers

If your code use `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:
1. Create an async engine and new a Casbin AsyncEnforcer with a model file and an async Pycasbin adapter (AsyncAdapter subclass):

```python
import asyncio
Expand Down Expand Up @@ -266,6 +266,8 @@ async def get_enforcer():

Note: you can see all supported adapters in [Adapters | Casbin](https://casbin.org/docs/adapters).

Built-in async adapters are available in `casbin.persist.adapters.asyncio`.

2. Add an enforcement hook into your code right before the access happens:

```python
Expand Down
5 changes: 2 additions & 3 deletions casbin/async_internal_enforcer.py
Expand Up @@ -15,8 +15,7 @@

from casbin.core_enforcer import CoreEnforcer
from casbin.model import Model, FunctionMap
from casbin.persist import Adapter
from casbin.persist.adapters.asyncio import AsyncFileAdapter
from casbin.persist.adapters.asyncio import AsyncFileAdapter, AsyncAdapter


class AsyncInternalEnforcer(CoreEnforcer):
Expand All @@ -32,7 +31,7 @@ def init_with_file(self, model_path, policy_path):
def init_with_model_and_adapter(self, m, adapter=None):
"""initializes an enforcer with a model and a database adapter."""

if not isinstance(m, Model) or adapter is not None and not isinstance(adapter, Adapter):
if not isinstance(m, Model) or adapter is not None and not isinstance(adapter, AsyncAdapter):
raise RuntimeError("Invalid parameters for enforcer.")

self.adapter = adapter
Expand Down
14 changes: 13 additions & 1 deletion casbin/persist/adapters/asyncio/__init__.py
@@ -1 +1,13 @@
from .async_file_adapter import AsyncFileAdapter
from .async_adapter import AsyncAdapter
from .async_adapter_filtered import AsyncFilteredAdapter
from .async_batch_adapter import AsyncBatchAdapter
from .async_file_adapter import AsyncFileAdapter
from .async_update_adapter import AsyncUpdateAdapter

__all__ = [
"AsyncAdapter",
"AsyncFilteredAdapter",
"AsyncBatchAdapter",
"AsyncFileAdapter",
"AsyncUpdateAdapter",
]
32 changes: 32 additions & 0 deletions casbin/persist/adapters/asyncio/async_adapter.py
@@ -0,0 +1,32 @@
from abc import ABCMeta, abstractmethod


class AsyncAdapter(metaclass=ABCMeta):
"""The interface for async Casbin adapters."""

@abstractmethod
async def load_policy(self, model):
"""loads all policy rules from the storage."""
pass

@abstractmethod
async def save_policy(self, model):
"""saves all policy rules to the storage."""
pass

@abstractmethod
async def add_policy(self, sec, ptype, rule):
"""adds a policy rule to the storage."""
pass

@abstractmethod
async def remove_policy(self, sec, ptype, rule):
"""removes a policy rule from the storage."""
pass

@abstractmethod
async def remove_filtered_policy(self, sec, ptype, field_index, *field_values):
"""removes policy rules that match the filter from the storage.
This is part of the Auto-Save feature.
"""
pass
17 changes: 17 additions & 0 deletions casbin/persist/adapters/asyncio/async_adapter_filtered.py
@@ -0,0 +1,17 @@
from abc import ABCMeta, abstractmethod


class AsyncFilteredAdapter(metaclass=ABCMeta):
"""AsyncFilteredAdapter is the interface for async Casbin adapters supporting filtered policies."""

@abstractmethod
async def is_filtered(self):
"""IsFiltered returns true if the loaded policy has been filtered
Marks if the loaded policy is filtered or not
"""
pass

@abstractmethod
async def load_filtered_policy(self, model, filter):
"""Loads policy rules that match the filter from the storage."""
pass
15 changes: 15 additions & 0 deletions casbin/persist/adapters/asyncio/async_batch_adapter.py
@@ -0,0 +1,15 @@
from abc import ABCMeta, abstractmethod


class AsyncBatchAdapter(metaclass=ABCMeta):
"""AsyncBatchAdapter is the interface for async Casbin adapters with multiple add and remove policy functions."""

@abstractmethod
async def add_policies(self, sec, ptype, rules):
"""AddPolicies adds policy rules to the storage."""
pass

@abstractmethod
async def remove_policies(self, sec, ptype, rules):
"""RemovePolicies removes policy rules from the storage."""
pass
6 changes: 4 additions & 2 deletions casbin/persist/adapters/asyncio/async_file_adapter.py
Expand Up @@ -12,11 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from ..adapter import Adapter, load_policy_line
import os

from ..adapter import load_policy_line
from .async_adapter import AsyncAdapter

class AsyncFileAdapter(Adapter):

class AsyncFileAdapter(AsyncAdapter):
"""the async file adapter for Casbin.
It can load policy from file or save policy to file.
"""
Expand Down
29 changes: 29 additions & 0 deletions casbin/persist/adapters/asyncio/async_update_adapter.py
@@ -0,0 +1,29 @@
from abc import ABCMeta, abstractmethod


class AsyncUpdateAdapter(metaclass=ABCMeta):
"""AsyncUpdateAdapter is the interface for async Casbin adapters with add update policy function."""

@abstractmethod
async def update_policy(self, sec, ptype, old_rule, new_policy):
"""
update_policy updates a policy rule from storage.
This is part of the Auto-Save feature.
"""
pass

@abstractmethod
async def update_policies(self, sec, ptype, old_rules, new_rules):
"""
UpdatePolicies updates some policy rules to storage, like db, redis.
"""
pass

@abstractmethod
async def update_filtered_policies(
self, sec, ptype, new_rules, field_index, *field_values
):
"""
update_filtered_policies deletes old rules and adds new rules.
"""
pass

0 comments on commit 5e1c9d7

Please sign in to comment.