From efea2ada1cfdcfc6b58b09e4b812be90aadfc5cd Mon Sep 17 00:00:00 2001 From: Akira Yoshiyama Date: Mon, 14 Dec 2015 15:05:49 +0900 Subject: [PATCH] Add string format rendering to RoleCheck.__call__() RoleCheck.__call__() doesn't render string format with target dict. So, it couldn't handle rules like below: "identity:create_grant": "role: %{target.role.name}s" This patch adds string format rendering code to it. If target_dict has a key specified at %()s in the rule, __call__() will render its value and evaluate the rule. If not, the method will return False. Change-Id: I82d677301ca2c764230ed9b3e3e9d82056afcea2 Closes-Bug: #1527055 --- oslo_policy/_checks.py | 8 +++++++- oslo_policy/tests/test_checks.py | 17 +++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/oslo_policy/_checks.py b/oslo_policy/_checks.py index 2daf37fe..8038b6c1 100644 --- a/oslo_policy/_checks.py +++ b/oslo_policy/_checks.py @@ -212,7 +212,13 @@ class RoleCheck(Check): """Check that there is a matching role in the ``creds`` dict.""" def __call__(self, target, creds, enforcer): - return self.match.lower() in [x.lower() for x in creds['roles']] + try: + match = self.match % target + except KeyError: + # While doing RoleCheck if key not + # present in Target return false + return False + return match.lower() in [x.lower() for x in creds['roles']] @register('http') diff --git a/oslo_policy/tests/test_checks.py b/oslo_policy/tests/test_checks.py index e685f622..f438b642 100644 --- a/oslo_policy/tests/test_checks.py +++ b/oslo_policy/tests/test_checks.py @@ -72,12 +72,25 @@ class RoleCheckTestCase(base.PolicyBaseTestCase): def test_accept(self): check = _checks.RoleCheck('role', 'sPaM') - self.assertTrue(check('target', dict(roles=['SpAm']), self.enforcer)) + self.assertTrue(check({}, dict(roles=['SpAm']), self.enforcer)) def test_reject(self): check = _checks.RoleCheck('role', 'spam') - self.assertFalse(check('target', dict(roles=[]), self.enforcer)) + self.assertFalse(check({}, dict(roles=[]), self.enforcer)) + + def test_format_value(self): + check = _checks.RoleCheck('role', '%(target.role.name)s') + + target_dict = {'target.role.name': 'a'} + cred_dict = dict(user='user', roles=['a', 'b', 'c']) + self.assertTrue(check(target_dict, cred_dict, self.enforcer)) + + target_dict = {'target.role.name': 'd'} + self.assertFalse(check(target_dict, cred_dict, self.enforcer)) + + target_dict = dict(target=dict(role=dict())) + self.assertFalse(check(target_dict, cred_dict, self.enforcer)) class HttpCheckTestCase(base.PolicyBaseTestCase):