Hacking check for _ENFORCER.enforce()

In order to ensure that only registered policies are used for
authorization checks _ENFORCER.authorize should be used rather than
_ENFORCER.enforce. This adds a check to look for instances of
_ENFORCER.enforce being used.

Change-Id: Iee78e93a3e1d4c6c30681b18698b7fc9cb6fa982
Implements: bp policy-in-code
This commit is contained in:
Andrew Laski 2016-07-01 13:51:48 -04:00
parent 7ee75f638a
commit 219d970d13
3 changed files with 40 additions and 0 deletions

View File

@ -61,6 +61,7 @@ Nova Specific Commandments
- [N348] Deprecated library function os.popen()
- [N349] Check for closures in tests which are not used
- [N350] Policy registration should be in the central location ``nova/policies/``
- [N351] Do not use the oslo_policy.policy.Enforcer.enforce() method.
Creating Unit Tests
-------------------

View File

@ -40,6 +40,7 @@ cfg_re = re.compile(r".*\scfg\.")
# Excludes oslo.config OptGroup objects
cfg_opt_re = re.compile(r".*[\s\[]cfg\.[a-zA-Z]*Opt\(")
rule_default_re = re.compile(r".*RuleDefault\(")
policy_enforce_re = re.compile(r".*_ENFORCER\.enforce\(")
vi_header_re = re.compile(r"^#\s+vim?:.+")
virt_file_re = re.compile(r"\./nova/(?:tests/)?virt/(\w+)/")
virt_import_re = re.compile(
@ -666,6 +667,24 @@ def check_policy_registration_in_central_place(logical_line, filename):
yield(0, msg)
def check_policy_enforce(logical_line, filename):
"""Look for uses of nova.policy._ENFORCER.enforce()
Now that policy defaults are registered in code the _ENFORCER.authorize
method should be used. That ensures that only registered policies are used.
Uses of _ENFORCER.enforce could allow unregistered policies to be used, so
this check looks for uses of that method.
N351
"""
msg = ('N351: nova.policy._ENFORCER.enforce() should not be used. '
'Use the authorize() method instead.')
if policy_enforce_re.match(logical_line):
yield(0, msg)
def check_doubled_words(physical_line, filename):
"""Check for the common doubled-word typos
@ -813,6 +832,7 @@ def factory(register):
register(check_greenthread_spawns)
register(check_config_option_in_central_place)
register(check_policy_registration_in_central_place)
register(check_policy_enforce)
register(check_doubled_words)
register(check_python3_no_iteritems)
register(check_python3_no_iterkeys)

View File

@ -790,3 +790,22 @@ class HackingTestCase(test.NoDBTestCase):
code, checks.check_policy_registration_in_central_place,
filename="nova/api/openstack/compute/non_existent.py",
expected_errors=errors)
def test_check_policy_enforce(self):
errors = [(3, 0, "N351")]
code = """
from nova import policy
policy._ENFORCER.enforce('context_is_admin', target, credentials)
"""
self._assert_has_errors(code, checks.check_policy_enforce,
expected_errors=errors)
def test_check_policy_enforce_does_not_catch_other_enforce(self):
# Simulate a different enforce method defined in Nova
code = """
from nova import foo
foo.enforce()
"""
self._assert_has_no_errors(code, checks.check_policy_enforce)