Check first matching rule for protected properties

When using roles to define protected properties, the first matching rule
in the config file should be used to grant/deny access. This change
enforces that behaviour.

Fixes bug 1271426

Change-Id: I11ece25ae85ff868516bcd1839a4e430e9c51370
This commit is contained in:
Thomas Leaman 2014-01-22 16:02:56 +00:00
parent 35bf0af69c
commit b6dd538569
4 changed files with 72 additions and 12 deletions

View File

@ -173,16 +173,20 @@ class PropertyRules(object):
for rule_exp, rule in self.rules:
if rule_exp.search(str(property_name)):
rule_roles = rule.get(action)
if rule_roles:
if '!' in rule_roles:
return False
elif '@' in rule_roles:
return True
if self.prop_prot_rule_format == 'policies':
prop_exp_key = self.prop_exp_mapping[rule_exp]
return self._check_policy(prop_exp_key, action,
context)
if set(roles).intersection(set(rule_roles)):
return True
break
else: # no matching rules
return False
rule_roles = rule.get(action)
if rule_roles:
if '!' in rule_roles:
return False
elif '@' in rule_roles:
return True
if self.prop_prot_rule_format == 'policies':
prop_exp_key = self.prop_exp_mapping[rule_exp]
return self._check_policy(prop_exp_key, action,
context)
if set(roles).intersection(set(rule_roles)):
return True
return False

View File

@ -40,6 +40,18 @@ read = context_is_admin
update = context_is_admin
delete = !
[x_foo_matcher]
create = context_is_admin
read = context_is_admin
update = context_is_admin
delete = context_is_admin
[x_foo_*]
create = @
read = @
update = @
delete = @
[.*]
create = context_is_admin
read = context_is_admin

View File

@ -70,6 +70,18 @@ read = admin,member
update = admin,member
delete = !
[x_foo_matcher]
create = admin
read = admin
update = admin
delete = admin
[x_foo_*]
create = @
read = @
update = @
delete = @
[.*]
create = admin
read = admin

View File

@ -32,6 +32,8 @@ CONFIG_SECTIONS = [
'x_none_read',
'x_none_update',
'x_none_delete',
'x_foo_matcher',
'x_foo_*',
'.*'
]
@ -287,6 +289,21 @@ class TestPropertyRulesWithRoles(base.IsolatedUnitTest):
'x_none_delete', 'delete',
create_context(self.policy, [''])))
def test_check_return_first_match(self):
self.rules_checker = property_utils.PropertyRules()
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'create',
create_context(self.policy, [''])))
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'read',
create_context(self.policy, [''])))
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'update',
create_context(self.policy, [''])))
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'delete',
create_context(self.policy, [''])))
class TestPropertyRulesWithPolicies(base.IsolatedUnitTest):
@ -441,3 +458,18 @@ class TestPropertyRulesWithPolicies(base.IsolatedUnitTest):
self.assertFalse(self.rules_checker.check_property_rules(
'x_none_delete', 'delete',
create_context(self.policy, [''])))
def test_check_return_first_match(self):
self.rules_checker = property_utils.PropertyRules()
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'create',
create_context(self.policy, [''])))
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'read',
create_context(self.policy, [''])))
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'update',
create_context(self.policy, [''])))
self.assertFalse(self.rules_checker.check_property_rules(
'x_foo_matcher', 'delete',
create_context(self.policy, [''])))