summaryrefslogtreecommitdiffstats
path: root/openstack/common/policy.py
diff options
context:
space:
mode:
Diffstat (limited to 'openstack/common/policy.py')
-rw-r--r--openstack/common/policy.py207
1 files changed, 87 insertions, 120 deletions
diff --git a/openstack/common/policy.py b/openstack/common/policy.py
index f3e62ba..40e5a6e 100644
--- a/openstack/common/policy.py
+++ b/openstack/common/policy.py
@@ -94,15 +94,11 @@ class PolicyNotAuthorized(Exception):
class Rules(dict):
- """
- A store for rules. Handles the default_rule setting directly.
- """
+ """A store for rules. Handles the default_rule setting directly."""
@classmethod
def load_json(cls, data, default_rule=None):
- """
- Allow loading of JSON rule data.
- """
+ """Allow loading of JSON rule data."""
# Suck in the JSON data and parse the rules
rules = dict((k, parse_rule(v)) for k, v in
@@ -143,8 +139,7 @@ class Rules(dict):
class Enforcer(object):
- """
- Responsible for loading and enforcing rules
+ """Responsible for loading and enforcing rules.
:param policy_file: Custom policy file to use, if none is
specified, `CONF.policy_file` will be
@@ -165,8 +160,7 @@ class Enforcer(object):
self.policy_file = policy_file or CONF.policy_file
def set_rules(self, rules, overwrite=True):
- """
- Create a new Rules object based on the provided dict of rules
+ """Create a new Rules object based on the provided dict of rules.
:param rules: New rules to use. It should be an instance of dict.
:param overwrite: Whether to overwrite current rules or update them
@@ -183,17 +177,14 @@ class Enforcer(object):
self.update(rules)
def clear(self):
- """
- Clears Enforcer rules, policy's cache
- and policy's path.
- """
+ """Clears Enforcer rules, policy's cache and policy's path."""
self.set_rules({})
self.policy_path = None
def load_rules(self, force_reload=False):
- """
- Loads policy_path's rules. Policy file is cached
- and will be reloaded if modified.
+ """Loads policy_path's rules.
+
+ Policy file is cached and will be reloaded if modified.
:param force_reload: Whether to overwrite current rules.
"""
@@ -210,8 +201,7 @@ class Enforcer(object):
LOG.debug(_("Rules successfully reloaded"))
def _get_policy_path(self):
- """
- Locate the policy json data file
+ """Locate the policy json data file.
:param policy_file: Custom policy file to locate.
@@ -229,8 +219,7 @@ class Enforcer(object):
def enforce(self, rule, target, creds, do_raise=False,
exc=None, *args, **kwargs):
- """
- Checks authorization of a rule against the target and credentials.
+ """Checks authorization of a rule against the target and credentials.
:param rule: A string or BaseCheck instance specifying the rule
to evaluate.
@@ -285,25 +274,21 @@ class Enforcer(object):
class BaseCheck(object):
- """
- Abstract base class for Check classes.
- """
+ """Abstract base class for Check classes."""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def __str__(self):
- """
- Retrieve a string representation of the Check tree rooted at
- this node.
- """
+ """String representation of the Check tree rooted at this node."""
pass
@abc.abstractmethod
def __call__(self, target, cred):
- """
- Perform the check. Returns False to reject the access or a
+ """Triggers if instance of the class is called.
+
+ Performs the check. Returns False to reject the access or a
true value (not necessary True) to accept the access.
"""
@@ -311,9 +296,7 @@ class BaseCheck(object):
class FalseCheck(BaseCheck):
- """
- A policy check that always returns False (disallow).
- """
+ """A policy check that always returns False (disallow)."""
def __str__(self):
"""Return a string representation of this check."""
@@ -327,9 +310,7 @@ class FalseCheck(BaseCheck):
class TrueCheck(BaseCheck):
- """
- A policy check that always returns True (allow).
- """
+ """A policy check that always returns True (allow)."""
def __str__(self):
"""Return a string representation of this check."""
@@ -343,12 +324,11 @@ class TrueCheck(BaseCheck):
class Check(BaseCheck):
- """
- A base class to allow for user-defined policy checks.
- """
+ """A base class to allow for user-defined policy checks."""
def __init__(self, kind, match):
- """
+ """Initiates Check instance.
+
:param kind: The kind of the check, i.e., the field before the
':'.
:param match: The match of the check, i.e., the field after
@@ -365,14 +345,13 @@ class Check(BaseCheck):
class NotCheck(BaseCheck):
- """
+ """Implements the "not" logical operator.
+
A policy check that inverts the result of another policy check.
- Implements the "not" operator.
"""
def __init__(self, rule):
- """
- Initialize the 'not' check.
+ """Initialize the 'not' check.
:param rule: The rule to negate. Must be a Check.
"""
@@ -385,23 +364,22 @@ class NotCheck(BaseCheck):
return "not %s" % self.rule
def __call__(self, target, cred):
- """
- Check the policy. Returns the logical inverse of the wrapped
- check.
+ """Check the policy.
+
+ Returns the logical inverse of the wrapped check.
"""
return not self.rule(target, cred)
class AndCheck(BaseCheck):
- """
- A policy check that requires that a list of other checks all
- return True. Implements the "and" operator.
+ """Implements the "and" logical operator.
+
+ A policy check that requires that a list of other checks all return True.
"""
def __init__(self, rules):
- """
- Initialize the 'and' check.
+ """Initialize the 'and' check.
:param rules: A list of rules that will be tested.
"""
@@ -414,9 +392,9 @@ class AndCheck(BaseCheck):
return "(%s)" % ' and '.join(str(r) for r in self.rules)
def __call__(self, target, cred):
- """
- Check the policy. Requires that all rules accept in order to
- return True.
+ """Check the policy.
+
+ Requires that all rules accept in order to return True.
"""
for rule in self.rules:
@@ -426,7 +404,8 @@ class AndCheck(BaseCheck):
return True
def add_check(self, rule):
- """
+ """Adds rule to be tested.
+
Allows addition of another rule to the list of rules that will
be tested. Returns the AndCheck object for convenience.
"""
@@ -436,14 +415,14 @@ class AndCheck(BaseCheck):
class OrCheck(BaseCheck):
- """
+ """Implements the "or" operator.
+
A policy check that requires that at least one of a list of other
- checks returns True. Implements the "or" operator.
+ checks returns True.
"""
def __init__(self, rules):
- """
- Initialize the 'or' check.
+ """Initialize the 'or' check.
:param rules: A list of rules that will be tested.
"""
@@ -456,9 +435,9 @@ class OrCheck(BaseCheck):
return "(%s)" % ' or '.join(str(r) for r in self.rules)
def __call__(self, target, cred):
- """
- Check the policy. Requires that at least one rule accept in
- order to return True.
+ """Check the policy.
+
+ Requires that at least one rule accept in order to return True.
"""
for rule in self.rules:
@@ -468,7 +447,8 @@ class OrCheck(BaseCheck):
return False
def add_check(self, rule):
- """
+ """Adds rule to be tested.
+
Allows addition of another rule to the list of rules that will
be tested. Returns the OrCheck object for convenience.
"""
@@ -478,9 +458,7 @@ class OrCheck(BaseCheck):
def _parse_check(rule):
- """
- Parse a single base check rule into an appropriate Check object.
- """
+ """Parse a single base check rule into an appropriate Check object."""
# Handle the special checks
if rule == '!':
@@ -506,9 +484,9 @@ def _parse_check(rule):
def _parse_list_rule(rule):
- """
- Provided for backwards compatibility. Translates the old
- list-of-lists syntax into a tree of Check objects.
+ """Translates the old list-of-lists syntax into a tree of Check objects.
+
+ Provided for backwards compatibility.
"""
# Empty rule defaults to True
@@ -549,8 +527,7 @@ _tokenize_re = re.compile(r'\s+')
def _parse_tokenize(rule):
- """
- Tokenizer for the policy language.
+ """Tokenizer for the policy language.
Most of the single-character tokens are specified in the
_tokenize_re; however, parentheses need to be handled specially,
@@ -599,16 +576,16 @@ def _parse_tokenize(rule):
class ParseStateMeta(type):
- """
- Metaclass for the ParseState class. Facilitates identifying
- reduction methods.
+ """Metaclass for the ParseState class.
+
+ Facilitates identifying reduction methods.
"""
def __new__(mcs, name, bases, cls_dict):
- """
- Create the class. Injects the 'reducers' list, a list of
- tuples matching token sequences to the names of the
- corresponding reduction methods.
+ """Create the class.
+
+ Injects the 'reducers' list, a list of tuples matching token sequences
+ to the names of the corresponding reduction methods.
"""
reducers = []
@@ -625,10 +602,10 @@ class ParseStateMeta(type):
def reducer(*tokens):
- """
- Decorator for reduction methods. Arguments are a sequence of
- tokens, in order, which should trigger running this reduction
- method.
+ """Decorator for reduction methods.
+
+ Arguments are a sequence of tokens, in order, which should trigger running
+ this reduction method.
"""
def decorator(func):
@@ -645,10 +622,10 @@ def reducer(*tokens):
class ParseState(object):
- """
- Implement the core of parsing the policy language. Uses a greedy
- reduction algorithm to reduce a sequence of tokens into a single
- terminal, the value of which will be the root of the Check tree.
+ """Implement the core of parsing the policy language.
+
+ Uses a greedy reduction algorithm to reduce a sequence of tokens into
+ a single terminal, the value of which will be the root of the Check tree.
Note: error reporting is rather lacking. The best we can get with
this parser formulation is an overall "parse failed" error.
@@ -665,11 +642,11 @@ class ParseState(object):
self.values = []
def reduce(self):
- """
- Perform a greedy reduction of the token stream. If a reducer
- method matches, it will be executed, then the reduce() method
- will be called recursively to search for any more possible
- reductions.
+ """Perform a greedy reduction of the token stream.
+
+ If a reducer method matches, it will be executed, then the
+ reduce() method will be called recursively to search for any more
+ possible reductions.
"""
for reduction, methname in self.reducers:
@@ -699,9 +676,9 @@ class ParseState(object):
@property
def result(self):
- """
- Obtain the final result of the parse. Raises ValueError if
- the parse failed to reduce to a single result.
+ """Obtain the final result of the parse.
+
+ Raises ValueError if the parse failed to reduce to a single result.
"""
if len(self.values) != 1:
@@ -718,35 +695,31 @@ class ParseState(object):
@reducer('check', 'and', 'check')
def _make_and_expr(self, check1, _and, check2):
- """
- Create an 'and_expr' from two checks joined by the 'and'
- operator.
+ """Create an 'and_expr'.
+
+ Join two checks by the 'and' operator.
"""
return [('and_expr', AndCheck([check1, check2]))]
@reducer('and_expr', 'and', 'check')
def _extend_and_expr(self, and_expr, _and, check):
- """
- Extend an 'and_expr' by adding one more check.
- """
+ """Extend an 'and_expr' by adding one more check."""
return [('and_expr', and_expr.add_check(check))]
@reducer('check', 'or', 'check')
def _make_or_expr(self, check1, _or, check2):
- """
- Create an 'or_expr' from two checks joined by the 'or'
- operator.
+ """Create an 'or_expr'.
+
+ Join two checks by the 'or' operator.
"""
return [('or_expr', OrCheck([check1, check2]))]
@reducer('or_expr', 'or', 'check')
def _extend_or_expr(self, or_expr, _or, check):
- """
- Extend an 'or_expr' by adding one more check.
- """
+ """Extend an 'or_expr' by adding one more check."""
return [('or_expr', or_expr.add_check(check))]
@@ -758,7 +731,8 @@ class ParseState(object):
def _parse_text_rule(rule):
- """
+ """Parses policy to the tree.
+
Translates a policy written in the policy language into a tree of
Check objects.
"""
@@ -783,9 +757,7 @@ def _parse_text_rule(rule):
def parse_rule(rule):
- """
- Parses a policy rule into a tree of Check objects.
- """
+ """Parses a policy rule into a tree of Check objects."""
# If the rule is a string, it's in the policy language
if isinstance(rule, basestring):
@@ -794,8 +766,7 @@ def parse_rule(rule):
def register(name, func=None):
- """
- Register a function or Check class as a policy check.
+ """Register a function or Check class as a policy check.
:param name: Gives the name of the check type, e.g., 'rule',
'role', etc. If name is None, a default check type
@@ -823,9 +794,7 @@ def register(name, func=None):
@register("rule")
class RuleCheck(Check):
def __call__(self, target, creds, enforcer):
- """
- Recursively checks credentials based on the defined rules.
- """
+ """Recursively checks credentials based on the defined rules."""
try:
return enforcer.rules[self.match](target, creds, enforcer)
@@ -845,8 +814,7 @@ class RoleCheck(Check):
@register('http')
class HttpCheck(Check):
def __call__(self, target, creds, enforcer):
- """
- Check http: rules by calling to a remote server.
+ """Check http: rules by calling to a remote server.
This example implementation simply verifies that the response
is exactly 'True'.
@@ -863,8 +831,7 @@ class HttpCheck(Check):
@register(None)
class GenericCheck(Check):
def __call__(self, target, creds, enforcer):
- """
- Check an individual match.
+ """Check an individual match.
Matches look like: