Fix a code logic while doing cyclical reference check to the policy

While there is same rule_check in different branchs of a rule, it shouln't
be judged to having cyclical reference.

For example:
'get_properties': 'rule:is_admin or rule:is_observer'
'is_admin': 'rule:is_member'
'is_observer': 'rule:is_member'

In this situation, it shouldn't be judged to haveing cyclical reference.
So that the parameter 'seen' should be passed like this to prevent it from
missing judgement:
                      get_properties(seen)
                                |
               ---------------  Or -------------------
              |                                       |
        rule:is_admin(seen')                  rule:is_observer(seen'')
              |                                       |
        rule:is_member(seen')                 rule:is_member(seen'')

Change-Id: I904dc60c40b11699c9087e6ebae7aba4d0113dd8
Closes-bug: #1637419
This commit is contained in:
Xu Ao 2016-10-28 15:47:48 +08:00
parent e487d48ee6
commit 4ed29c221b
2 changed files with 14 additions and 2 deletions

View File

@ -596,7 +596,10 @@ class Enforcer(object):
rules = getattr(check, 'rules', None) rules = getattr(check, 'rules', None)
if rules: if rules:
for rule in rules: for rule in rules:
if self._cycle_check(rule, seen): # As there being an OrCheck or AndCheck, a copy of the father's
# seen should be called here. In order that the checks in
# different branchs are seperated.
if self._cycle_check(rule, seen.copy()):
return True return True
return False return False

View File

@ -857,7 +857,7 @@ class EnforcerCheckRulesTest(base.PolicyBaseTestCase):
self.assertFalse(self.enforcer.check_rules()) self.assertFalse(self.enforcer.check_rules())
def test_complex_cyclical_rules(self): def test_complex_cyclical_rules_false(self):
rules = jsonutils.dumps({'foo': 'rule:bar', rules = jsonutils.dumps({'foo': 'rule:bar',
'bar': 'rule:baz and role:admin', 'bar': 'rule:baz and role:admin',
'baz': 'rule:foo or role:user'}) 'baz': 'rule:foo or role:user'})
@ -865,3 +865,12 @@ class EnforcerCheckRulesTest(base.PolicyBaseTestCase):
self.enforcer.load_rules(True) self.enforcer.load_rules(True)
self.assertFalse(self.enforcer.check_rules()) self.assertFalse(self.enforcer.check_rules())
def test_complex_cyclical_rules_true(self):
rules = jsonutils.dumps({'foo': 'rule:bar or rule:baz',
'bar': 'role:admin',
'baz': 'rule:bar or role:user'})
self.create_config_file('policy.json', rules)
self.enforcer.load_rules(True)
self.assertTrue(self.enforcer.check_rules())