Map system_scope in creds dictionary

An earlier patch[1] added a mapping for context 'system_scope'
to 'system' when enforce was called with a RequestContext
object. However, enforce can also be called with a creds dictionary
that may contain the context 'system_scope' element. When this
occured, 'system_scope' was not mapped to 'system' and the enforce
would fail with an InvalidScope exception.
This patch moves the 'system_scope' mapping from only occuring
with RequestContext objects to also map it when a creds dictonary
is passed to enforce.

[1] https://review.opendev.org/c/openstack/oslo.policy/+/578995

Change-Id: I83a22c3f825bad0c88018118f8630a20a445965e
(cherry picked from commit 9774108cf9)
(cherry picked from commit ff2a39fc61)
This commit is contained in:
Michael Johnson 2021-07-15 21:42:54 +00:00
parent 4fe282b727
commit 639b47198b
3 changed files with 30 additions and 28 deletions

View File

@ -972,6 +972,17 @@ class Enforcer(object):
)
raise InvalidContextObject(msg)
# NOTE(lbragstad): We unfortunately have to special case this
# attribute. Originally when the system scope when into oslo.policy, we
# checked for a key called 'system' in creds. The oslo.context library
# uses `system_scope` instead, and the compatibility between
# oslo.policy and oslo.context was an afterthought. We'll have to
# support services who've been setting creds['system'], but we can do
# that by making sure we populate it with what's in the context object
# if it has a system_scope attribute.
if creds.get('system_scope'):
creds['system'] = creds.get('system_scope')
if LOG.isEnabledFor(logging.DEBUG):
try:
creds_dict = strutils.mask_dict_password(creds)
@ -1078,17 +1089,6 @@ class Enforcer(object):
for k, v in context_values.items():
creds[k] = v
# NOTE(lbragstad): We unfortunately have to special case this
# attribute. Originally when the system scope when into oslo.policy, we
# checked for a key called 'system' in creds. The oslo.context library
# uses `system_scope` instead, and the compatibility between
# oslo.policy and oslo.context was an afterthought. We'll have to
# support services who've been setting creds['system'], but we can do
# that by making sure we populate it with what's in the context object
# if it has a system_scope attribute.
if context.system_scope:
creds['system'] = context.system_scope
return creds
def register_default(self, default):

View File

@ -881,23 +881,6 @@ class EnforcerTest(base.PolicyBaseTestCase):
for k, v in expected_creds.items():
self.assertEqual(expected_creds[k], creds[k])
@mock.patch('warnings.warn', new=mock.Mock())
def test_map_context_attributes_populated_system(self):
request_context = context.RequestContext(system_scope='all')
expected_creds = request_context.to_policy_values()
expected_creds['system'] = 'all'
creds = self.enforcer._map_context_attributes_into_creds(
request_context
)
# We don't use self.assertDictEqual here because to_policy_values
# actaully returns a non-dict object that just behaves like a
# dictionary, but does some special handling when people access
# deprecated policy values.
for k, v in expected_creds.items():
self.assertEqual(expected_creds[k], creds[k])
def test_enforcer_accepts_policy_values_from_context(self):
rule = policy.RuleDefault(name='fake_rule', check_str='role:test')
self.enforcer.register_default(rule)
@ -918,6 +901,20 @@ class EnforcerTest(base.PolicyBaseTestCase):
target_dict = {}
self.enforcer.enforce('fake_rule', target_dict, ctx)
def test_enforcer_understands_system_scope_creds_dict(self):
self.conf.set_override('enforce_scope', True, group='oslo_policy')
rule = policy.RuleDefault(
name='fake_rule', check_str='role:test', scope_types=['system']
)
self.enforcer.register_default(rule)
ctx = context.RequestContext()
creds = ctx.to_dict()
creds['system_scope'] = 'all'
target_dict = {}
self.enforcer.enforce('fake_rule', target_dict, creds)
def test_enforcer_raises_invalid_scope_with_system_scope_type(self):
self.conf.set_override('enforce_scope', True, group='oslo_policy')
rule = policy.RuleDefault(

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fixes the mapping of 'system_scope' to 'system' when enforce is called
with a 'creds' dictionary instead of a RequestContext.