Skip to content

Commit 65e1273

Browse files
author
m-bigaignon
committed
WIP
1 parent a49e412 commit 65e1273

File tree

2 files changed

+40
-42
lines changed

2 files changed

+40
-42
lines changed

entitled/policiesv1.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import Any
2+
3+
from entitled.rulesv1 import Actor, Rule, RuleProto
4+
5+
6+
class Client:
7+
def __init__(self):
8+
self._rule_registry: dict[str, Rule[Any]] = {}
9+
10+
def define_rule(self, name: str, callable: RuleProto[Actor]) -> Rule[Actor]:
11+
rule = Rule(name, callable)
12+
self._rule_registry[rule.name] = rule
13+
return rule
14+
15+
def allows(self, name: str, actor: Actor, *args: Any, **kwargs: Any):
16+
if name in self._rule_registry:
17+
return self._rule_registry[name].allows(actor, *args, **kwargs)
18+
return False
19+
20+
def allows(self, name: str, actor: Actor, *args: Any, **kwargs: Any):
21+
if name in self._rule_registry:
22+
return self._rule_registry[name].allows(actor, *args, **kwargs)
23+
return False
24+
25+
def denies()

entitled/rulesv1.py

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,37 @@
1-
from typing import Any, ClassVar, Protocol, TypeVar
1+
from typing import Any, Protocol, TypeVar
22

33

44
Actor = TypeVar("Actor", contravariant=True)
55

66

77
class RuleProto(Protocol[Actor]):
8-
async def __call__(self, actor: Actor, *args: Any, **kwargs: Any) -> bool: ...
8+
async def __call__(
9+
self, actor: Actor, *args: Any, **kwargs: Any
10+
) -> bool | None: ...
911

1012

1113
class Rule[Actor]:
12-
_registry: ClassVar[dict[str, RuleProto[Any]]] = {}
13-
_before_callback: RuleProto[Any] | None = None
14+
def __init__(self, name: str, callable: RuleProto[Actor]) -> None:
15+
self.name = name
16+
self.callable = callable
17+
self._before_callbacks: list[RuleProto[Actor]] = []
1418

15-
@classmethod
16-
def define(cls, name: str, closure: RuleProto[Actor]) -> None:
17-
cls._registry[name] = closure
19+
def before(self, *rule: RuleProto[Actor]):
20+
self._before_callbacks = list(rule)
1821

19-
@classmethod
20-
def before(cls, rule: RuleProto[Actor] | None):
21-
cls._before_callback = rule
22-
23-
@classmethod
2422
async def allows(
25-
cls,
26-
name: str,
23+
self,
2724
actor: Actor,
2825
*args: Any,
2926
**kwargs: Any,
3027
) -> bool:
31-
if name in cls._registry:
32-
return await cls._registry[name](actor, args, kwargs)
33-
34-
return False
28+
response = await self.callable(actor, args, kwargs)
29+
return response if response is not None else False
3530

36-
@classmethod
3731
async def denies(
38-
cls,
39-
name: str,
40-
actor: Actor,
41-
*args: Any,
42-
**kwargs: Any,
43-
) -> bool:
44-
return not await cls.allows(name, actor)
45-
46-
@classmethod
47-
async def any(
48-
cls,
49-
names: list[str],
50-
actor: Actor,
51-
*args: Any,
52-
**kwargs: Any,
53-
) -> bool:
54-
return any([await cls.allows(name, actor, args, kwargs) for name in names])
55-
56-
@classmethod
57-
async def none(
58-
cls,
59-
names: list[str],
32+
self,
6033
actor: Actor,
6134
*args: Any,
6235
**kwargs: Any,
6336
) -> bool:
64-
return not await cls.any(names, actor, args, kwargs)
37+
return not await self.allows(actor)

0 commit comments

Comments
 (0)