|
from typing import Any, List, Optional, TypeVar, Generic, Protocol, ClassVar, Sequence, Union, Iterable |
|
from polls.models import Question |
|
|
|
|
|
class BaseAuthorizer: |
|
"""BaseAuthorizer defines how child classes should behavior |
|
when called by EntryPoints""" |
|
|
|
def __init__(self, entry_point: "BaseEntryPoint") -> None: |
|
self.entry_point = entry_point |
|
|
|
def check(self) -> None: |
|
raise NotImplementedError |
|
|
|
|
|
class ActionBase: |
|
"""ActionBase class defines how action classes behave""" |
|
|
|
def __call__(self): |
|
raise NotImplementedError |
|
|
|
|
|
class AuthorizerError(Exception): |
|
... |
|
|
|
|
|
TAuthorizer = TypeVar("TAuthorizer", bound=BaseAuthorizer) |
|
# TAuthorizer = TypeVar("TAuthorizer", covariant=True) |
|
|
|
|
|
class UserAuthorizer(BaseAuthorizer): |
|
def check(self): |
|
"""Check if the user/employee/person has permission to perform |
|
this action""" |
|
|
|
if self.entry_point.user["name"] == "Joffily": |
|
return None |
|
|
|
raise AuthorizerError("User not authorized") |
|
|
|
|
|
class PollAction(ActionBase): |
|
def __init__(self, user: dict) -> None: |
|
self.user = user |
|
|
|
def __call__(self): |
|
print(f"PollAction.call, user: {self.user}") |
|
|
|
|
|
class BaseEntryPoint: |
|
"""Base class that defines how authorizers and actions are called. |
|
|
|
Every unit that use entry point pattern should inherent from here.""" |
|
|
|
authorizers: Iterable[BaseAuthorizer] = [] |
|
action: Optional[ActionBase] = None |
|
|
|
def execute(self): |
|
self.run_authorizers() |
|
|
|
if hasattr(self, "action"): |
|
self.action() |
|
|
|
if hasattr(self, "form"): |
|
... |
|
|
|
def run_authorizers(self): |
|
for authorizer in self.authorizers: |
|
print(f"Executing authorizer <{authorizer.__name__}>") |
|
authorizer(self).check() |
|
|
|
|
|
def entry_point(cls): |
|
"""Decorates entry points classes""" |
|
|
|
class Base(cls, BaseEntryPoint): |
|
... |
|
|
|
return Base |
|
|
|
|
|
class EntryPoint(BaseEntryPoint): |
|
authorizers = [UserAuthorizer] |
|
|
|
def __init__(self, name): |
|
self.name = name |
|
self.action = PollAction(user=self.user) |
|
|
|
@property |
|
def user(self): |
|
return {"name": self.name} |