diff --git a/oslo_policy/policy.py b/oslo_policy/policy.py index 44c0c557..50f6a258 100644 --- a/oslo_policy/policy.py +++ b/oslo_policy/policy.py @@ -596,7 +596,10 @@ class Enforcer(object): rules = getattr(check, 'rules', None) if 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 False diff --git a/oslo_policy/tests/test_policy.py b/oslo_policy/tests/test_policy.py index 6b077bf9..56d8f76a 100644 --- a/oslo_policy/tests/test_policy.py +++ b/oslo_policy/tests/test_policy.py @@ -857,7 +857,7 @@ class EnforcerCheckRulesTest(base.PolicyBaseTestCase): 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', 'bar': 'rule:baz and role:admin', 'baz': 'rule:foo or role:user'}) @@ -865,3 +865,12 @@ class EnforcerCheckRulesTest(base.PolicyBaseTestCase): self.enforcer.load_rules(True) 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())