pyutils.security package
Submodules
pyutils.security.acl module
Right now this package only contains an implementation that allows you to define and evaluate Access Control Lists (ACLs) easily. For example:
even = acl.SetBasedACL(
allow_set=set([2, 4, 6, 8, 10]),
deny_set=set([1, 3, 5, 7, 9]),
order_to_check_allow_deny=acl.Order.ALLOW_DENY,
default_answer=False,
)
self.assertTrue(even(2))
self.assertFalse(even(3))
self.assertFalse(even(-4))
ACLs can also be defined based on other criteria, for example:
a_or_b = acl.StringWildcardBasedACL(
allowed_patterns=['a*', 'b*'],
order_to_check_allow_deny=acl.Order.ALLOW_DENY,
default_answer=False,
)
self.assertTrue(a_or_b('aardvark'))
self.assertTrue(a_or_b('baboon'))
self.assertFalse(a_or_b('cheetah'))
Or:
weird = acl.StringREBasedACL(
denied_regexs=[re.compile('^a.*a$'), re.compile('^b.*b$')],
order_to_check_allow_deny=acl.Order.DENY_ALLOW,
default_answer=True,
)
self.assertTrue(weird('aardvark'))
self.assertFalse(weird('anaconda'))
self.assertFalse(weird('blackneb'))
self.assertTrue(weird('crow'))
There are implementations for wildcards, sets, regular expressions,
allow lists, deny lists, sequences of user defined predicates, etc…
You can also just subclass the base SimpleACL
interface to
define your own ACLs easily. Its __call__()
simply needs to
decide whether an item is allowed or denied.
Once a SimpleACL
is defined, it can be used within a
CompoundACL
:
a_b_c = acl.StringWildcardBasedACL(
allowed_patterns=['a*', 'b*', 'c*'],
order_to_check_allow_deny=acl.Order.ALLOW_DENY,
default_answer=False,
)
c_d_e = acl.StringWildcardBasedACL(
allowed_patterns=['c*', 'd*', 'e*'],
order_to_check_allow_deny=acl.Order.ALLOW_DENY,
default_answer=False,
)
conjunction = acl.AllCompoundACL(
subacls=[a_b_c, c_d_e],
order_to_check_allow_deny=acl.Order.ALLOW_DENY,
default_answer=False,
)
self.assertFalse(conjunction('aardvark'))
self.assertTrue(conjunction('caribou'))
self.assertTrue(conjunction('condor'))
self.assertFalse(conjunction('eagle'))
self.assertFalse(conjunction('newt'))
A CompoundACL
can also be used inside another CompoundACL
so this should be a flexible framework when defining complex access control
requirements:
There are two flavors of CompoundACL
:
AllCompoundACL
and AnyCompoundAcl
. The former only
admits an item if all of its sub-acls admit it and the latter will
admit an item if any of its sub-acls admit it.:
- class pyutils.security.acl.AllCompoundACL(*, subacls: List[SimpleACL] | None = None, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
SimpleACL
An ACL that allows if all of its subacls allow.
- Parameters:
subacls (List[SimpleACL] | None) – a list of sub-ACLs that we will consult for each item. All sub-ACLs must allow an item for us to also allow that item.
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.
- class pyutils.security.acl.AllowListACL(*, allow_set: Set[Any] | None)[source]
Bases:
SetBasedACL
Convenience subclass for a list that only allows known items. i.e. an ‘allowlist’
- Parameters:
allow_set (Set[Any] | None) – a set containing the items that are allowed.
- class pyutils.security.acl.AnyCompoundACL(*, subacls: List[SimpleACL] | None = None, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
SimpleACL
An ACL that allows if any of its subacls allow.
- Parameters:
subacls (List[SimpleACL] | None) – a list of sub-ACLs we will consult for each item. If any of these sub-ACLs allow the item we will also allow it.
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.
- class pyutils.security.acl.BlockListACL(*, deny_set: Set[Any] | None)[source]
Bases:
SetBasedACL
Convenience subclass for a list that only disallows known items. i.e. a ‘blocklist’
- Parameters:
deny_set (Set[Any] | None) – a set containing the items that are denied.
- class pyutils.security.acl.DenyListACL(*, deny_set: Set[Any] | None)[source]
Bases:
SetBasedACL
Convenience subclass for a list that only disallows known items. i.e. a ‘blocklist’
- Parameters:
deny_set (Set[Any] | None) – a set containing the items that are denied.
- class pyutils.security.acl.Order(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]
Bases:
Enum
A helper to express the order of evaluation for allows/denies in an Access Control List.
- ALLOW_DENY = 1
- DENY_ALLOW = 2
- UNDEFINED = 0
- class pyutils.security.acl.PredicateListBasedACL(*, allow_predicate_list: Sequence[Callable[[Any], bool]] = None, deny_predicate_list: Sequence[Callable[[Any], bool]] = None, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
SimpleACL
An ACL that allows or denies by applying predicates.
- Parameters:
allow_predicate_list (Sequence[Callable[[Any], bool]]) – a list of callables that indicate that an item should be allowed if they return True.
deny_predicate_list (Sequence[Callable[[Any], bool]]) – a list of callables that indicate that an item should be denied if they return True.
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.
- class pyutils.security.acl.SetBasedACL(*, allow_set: Set[Any] | None = None, deny_set: Set[Any] | None = None, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
SimpleACL
An ACL that allows or denies based on membership in a set.
- Parameters:
allow_set (Set[Any] | None) – the set of items that are allowed.
deny_set (Set[Any] | None) – the set of items that are denied.
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.
- class pyutils.security.acl.SimpleACL(*, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
ABC
A simple Access Control List interface.
- Parameters:
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
- Raises:
ValueError – Invalid Order argument
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.
- class pyutils.security.acl.StringREBasedACL(*, allowed_regexs: List[Pattern] | None = None, denied_regexs: List[Pattern] | None = None, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
PredicateListBasedACL
An ACL that allows or denies by applying regexps.
- Parameters:
allowed_regexs (List[Pattern] | None) – a list of regular expressions that, if they match an item, indicate that the item should be allowed.
denied_regexs (List[Pattern] | None) – a list of regular expressions that, if they match an item, indicate that the item should be denied.
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.
- class pyutils.security.acl.StringWildcardBasedACL(*, allowed_patterns: List[str] | None = None, denied_patterns: List[str] | None = None, order_to_check_allow_deny: Order, default_answer: bool)[source]
Bases:
PredicateListBasedACL
An ACL that allows or denies based on string glob
(*, ?)
patterns.- Parameters:
allowed_patterns (List[str] | None) – a list of string, optionally containing glob-style wildcards, that, if they match an item, indicate it should be allowed.
denied_patterns (List[str] | None) – a list of string, optionally containing glob-style wildcards, that, if they match an item, indicate it should be denied.
order_to_check_allow_deny (Order) – set this argument to indicate what order to check items for allow and deny. Pass either Order.ALLOW_DENY to check allow first or Order.DENY_ALLOW to check deny first.
default_answer (bool) – pass this argument to provide the ACL with a default answer.
Note
By using order_to_check_allow_deny and default_answer you can create both allow lists and deny lists. The former uses Order.ALLOW_DENY with a default anwser of False whereas the latter uses Order.DENY_ALLOW with a default answer of True.