def __call__(self, x: Any) -> bool:
"""Returns True if x is allowed, False otherwise."""
+ logger.debug(f'SimpleACL checking {x}')
if self.order_to_check_allow_deny == ACL_ORDER_ALLOW_DENY:
+ logger.debug('Checking allowed first...')
if self.check_allowed(x):
+ logger.debug(f'{x} was allowed explicitly.')
return True
+ logger.debug('Checking denied next...')
if self.check_denied(x):
+ logger.debug(f'{x} was denied explicitly.')
return False
- return self.default_answer
elif self.order_to_check_allow_deny == ACL_ORDER_DENY_ALLOW:
+ logger.debug('Checking denied first...')
if self.check_denied(x):
+ logger.debug(f'{x} was denied explicitly.')
return False
if self.check_allowed(x):
+ logger.debug(f'{x} was allowed explicitly.')
return True
- return self.default_answer
- raise Exception('Should never get here.')
+
+ logger.debug(
+ f'{x} was not explicitly allowed or denied; ' +
+ f'using default answer ({self.default_answer})'
+ )
+ return self.default_answer
@abstractmethod
def check_allowed(self, x: Any) -> bool:
- """Return True if x is allowed, False otherwise."""
+ """Return True if x is explicitly allowed, False otherwise."""
pass
@abstractmethod
def check_denied(self, x: Any) -> bool:
- """Return True if x is denied, False otherwise."""
+ """Return True if x is explicitly denied, False otherwise."""
pass
class SetBasedACL(SimpleACL):
+ """An ACL that allows or denies based on membership in a set."""
def __init__(self,
*,
allow_set: Optional[Set[Any]] = None,
class PredicateListBasedACL(SimpleACL):
+ """An ACL that allows or denies by applying predicates."""
def __init__(self,
*,
allow_predicate_list: List[Callable[[Any], bool]] = None,
class StringWildcardBasedACL(PredicateListBasedACL):
+ """An ACL that allows or denies based on string glob (*, ?) patterns."""
def __init__(self,
*,
allowed_patterns: Optional[List[str]] = None,
class StringREBasedACL(PredicateListBasedACL):
+ """An ACL that allows or denies by applying regexps."""
def __init__(self,
*,
allowed_regexs: Optional[List[re.Pattern]] = None,
)
-class CompoundACL(object):
- ANY = 1
- ALL = 2
+class AnyCompoundACL(object):
+ """An ACL that allows if any of its subacls allow."""
+ def __init__(self, subacls: List[SimpleACL]):
+ assert subacls is not None
+ self.subacls = subacls
- def __init__(
- self,
- *,
- subacls: Optional[List[SimpleACL]],
- match_requirement: int = ALL
- ) -> None:
+ def __call__(self, x: Any):
+ return any(acl(x) for acl in self.subacls)
+
+
+class AllCompoundACL(object):
+ """An ACL that allows if all of its subacls allow."""
+ def __init__(self, subacls: List[SimpleACL]):
+ assert subacls is not None
self.subacls = subacls
- if match_requirement not in (CompoundACL.ANY, CompoundACL.ALL):
- raise Exception(
- 'match_requirement must be CompoundACL.ANY or CompoundACL.ALL'
- )
- self.match_requirement = match_requirement
- def __call__(self, x: Any) -> bool:
- if self.match_requirement == CompoundACL.ANY:
- return any(acl(x) for acl in self.subacls)
- elif self.match_requirement == CompoundACL.ALL:
- return all(acl(x) for acl in self.subacls)
- raise Exception('Should never get here.')
+ def __call__(self, x: Any):
+ return all(acl(x) for acl in self.subacls)