Make properties roles check case-insensitive
Glance is case-insensitive when checking roles. This patch makes protected properties rules roles check also case-insensitive. Change-Id: Ib505889e12d0867f43788b815d9cbea18b8f2513 Closes-Bug: #1430804
This commit is contained in:
parent
fa7f316f6e
commit
cfad91bc7c
@ -198,6 +198,7 @@ class PropertyRules(object):
|
||||
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)):
|
||||
if set(roles).intersection(set([role.lower() for role
|
||||
in rule_roles])):
|
||||
return True
|
||||
return False
|
||||
|
@ -76,6 +76,12 @@ read = admin,member
|
||||
update = admin,member
|
||||
delete = !
|
||||
|
||||
[x_case_insensitive]
|
||||
create = admin,Member
|
||||
read = admin,Member
|
||||
update = admin,Member
|
||||
delete = admin,Member
|
||||
|
||||
[x_foo_matcher]
|
||||
create = admin
|
||||
read = admin
|
||||
|
@ -36,6 +36,7 @@ CONFIG_SECTIONS = [
|
||||
'x_none_read',
|
||||
'x_none_update',
|
||||
'x_none_delete',
|
||||
'x_case_insensitive',
|
||||
'x_foo_matcher',
|
||||
'x_foo_*',
|
||||
'.*'
|
||||
@ -310,6 +311,21 @@ class TestPropertyRulesWithRoles(base.IsolatedUnitTest):
|
||||
'x_foo_matcher', 'delete',
|
||||
create_context(self.policy, [''])))
|
||||
|
||||
def test_check_case_insensitive_property_rules(self):
|
||||
self.rules_checker = property_utils.PropertyRules()
|
||||
self.assertTrue(self.rules_checker.check_property_rules(
|
||||
'x_case_insensitive', 'create',
|
||||
create_context(self.policy, ['member'])))
|
||||
self.assertTrue(self.rules_checker.check_property_rules(
|
||||
'x_case_insensitive', 'read',
|
||||
create_context(self.policy, ['member'])))
|
||||
self.assertTrue(self.rules_checker.check_property_rules(
|
||||
'x_case_insensitive', 'update',
|
||||
create_context(self.policy, ['member'])))
|
||||
self.assertTrue(self.rules_checker.check_property_rules(
|
||||
'x_case_insensitive', 'delete',
|
||||
create_context(self.policy, ['member'])))
|
||||
|
||||
|
||||
class TestPropertyRulesWithPolicies(base.IsolatedUnitTest):
|
||||
|
||||
|
@ -4212,6 +4212,76 @@ class TestAPIProtectedProps(base.IsolatedUnitTest):
|
||||
output = another_request.get_response(self.api)
|
||||
self.assertEqual(403, output.status_int)
|
||||
|
||||
def test_create_protected_prop_check_case_insensitive(self):
|
||||
"""
|
||||
Verify that role check is case-insensitive i.e. the property
|
||||
marked with role Member is creatable by the member role
|
||||
"""
|
||||
image_id = self._create_admin_image()
|
||||
another_request = unit_test_utils.get_fake_request(
|
||||
path='/images/%s' % image_id, method='PUT')
|
||||
headers = {'x-auth-token': 'user:tenant:member',
|
||||
'x-image-meta-property-x_case_insensitive': '1'}
|
||||
for k, v in six.iteritems(headers):
|
||||
another_request.headers[k] = v
|
||||
output = another_request.get_response(self.api)
|
||||
res_body = jsonutils.loads(output.body)['image']
|
||||
self.assertEqual('1', res_body['properties']['x_case_insensitive'])
|
||||
|
||||
def test_read_protected_prop_check_case_insensitive(self):
|
||||
"""
|
||||
Verify that role check is case-insensitive i.e. the property
|
||||
marked with role Member is readable by the member role
|
||||
"""
|
||||
custom_props = {
|
||||
'x-image-meta-property-x_case_insensitive': '1'
|
||||
}
|
||||
image_id = self._create_admin_image(custom_props)
|
||||
another_request = unit_test_utils.get_fake_request(
|
||||
method='HEAD', path='/images/%s' % image_id)
|
||||
headers = {'x-auth-token': 'user:tenant:member'}
|
||||
for k, v in six.iteritems(headers):
|
||||
another_request.headers[k] = v
|
||||
output = another_request.get_response(self.api)
|
||||
self.assertEqual(200, output.status_int)
|
||||
self.assertEqual('', output.body)
|
||||
self.assertEqual(
|
||||
'1', output.headers['x-image-meta-property-x_case_insensitive'])
|
||||
|
||||
def test_update_protected_props_check_case_insensitive(self):
|
||||
"""
|
||||
Verify that role check is case-insensitive i.e. the property
|
||||
marked with role Member is updatable by the member role
|
||||
"""
|
||||
image_id = self._create_admin_image(
|
||||
{'x-image-meta-property-x_case_insensitive': '1'})
|
||||
another_request = unit_test_utils.get_fake_request(
|
||||
path='/images/%s' % image_id, method='PUT')
|
||||
headers = {'x-auth-token': 'user:tenant:member',
|
||||
'x-image-meta-property-x_case_insensitive': '2'}
|
||||
for k, v in six.iteritems(headers):
|
||||
another_request.headers[k] = v
|
||||
output = another_request.get_response(self.api)
|
||||
res_body = jsonutils.loads(output.body)['image']
|
||||
self.assertEqual('2', res_body['properties']['x_case_insensitive'])
|
||||
|
||||
def test_delete_protected_props_check_case_insensitive(self):
|
||||
"""
|
||||
Verify that role check is case-insensitive i.e. the property
|
||||
marked with role Member is deletable by the member role
|
||||
"""
|
||||
image_id = self._create_admin_image(
|
||||
{'x-image-meta-property-x_case_insensitive': '1'})
|
||||
another_request = unit_test_utils.get_fake_request(
|
||||
path='/images/%s' % image_id, method='PUT')
|
||||
headers = {'x-auth-token': 'user:tenant:member',
|
||||
'X-Glance-Registry-Purge-Props': 'True'}
|
||||
for k, v in six.iteritems(headers):
|
||||
another_request.headers[k] = v
|
||||
output = another_request.get_response(self.api)
|
||||
res_body = jsonutils.loads(output.body)['image']
|
||||
self.assertEqual({}, res_body['properties'])
|
||||
|
||||
def test_create_non_protected_prop(self):
|
||||
"""
|
||||
Verify property marked with special char '@' is creatable by an unknown
|
||||
|
@ -1193,6 +1193,86 @@ class TestImagesController(base.IsolatedUnitTest):
|
||||
self.assertRaises(webob.exc.HTTPConflict, self.controller.update,
|
||||
another_request, created_image.image_id, changes)
|
||||
|
||||
def test_create_protected_prop_case_insensitive(self):
|
||||
enforcer = glance.api.policy.Enforcer()
|
||||
self.controller = glance.api.v2.images.ImagesController(self.db,
|
||||
enforcer,
|
||||
self.notifier,
|
||||
self.store)
|
||||
self.set_property_protections()
|
||||
request = unit_test_utils.get_fake_request(roles=['admin'])
|
||||
image = {'name': 'image-1'}
|
||||
created_image = self.controller.create(request, image=image,
|
||||
extra_properties={},
|
||||
tags=[])
|
||||
another_request = unit_test_utils.get_fake_request(roles=['member'])
|
||||
changes = [
|
||||
{'op': 'add', 'path': ['x_case_insensitive'], 'value': '1'},
|
||||
]
|
||||
output = self.controller.update(another_request,
|
||||
created_image.image_id, changes)
|
||||
self.assertEqual('1', output.extra_properties['x_case_insensitive'])
|
||||
|
||||
def test_read_protected_prop_case_insensitive(self):
|
||||
enforcer = glance.api.policy.Enforcer()
|
||||
self.controller = glance.api.v2.images.ImagesController(self.db,
|
||||
enforcer,
|
||||
self.notifier,
|
||||
self.store)
|
||||
self.set_property_protections()
|
||||
request = unit_test_utils.get_fake_request(roles=['admin'])
|
||||
image = {'name': 'image-1'}
|
||||
extra_props = {'x_case_insensitive': '1'}
|
||||
created_image = self.controller.create(request, image=image,
|
||||
extra_properties=extra_props,
|
||||
tags=[])
|
||||
another_request = unit_test_utils.get_fake_request(roles=['member'])
|
||||
output = self.controller.show(another_request, created_image.image_id)
|
||||
self.assertEqual('1', output.extra_properties['x_case_insensitive'])
|
||||
|
||||
def test_update_protected_prop_case_insensitive(self):
|
||||
enforcer = glance.api.policy.Enforcer()
|
||||
self.controller = glance.api.v2.images.ImagesController(self.db,
|
||||
enforcer,
|
||||
self.notifier,
|
||||
self.store)
|
||||
self.set_property_protections()
|
||||
request = unit_test_utils.get_fake_request(roles=['admin'])
|
||||
image = {'name': 'image-1'}
|
||||
extra_props = {'x_case_insensitive': '1'}
|
||||
created_image = self.controller.create(request, image=image,
|
||||
extra_properties=extra_props,
|
||||
tags=[])
|
||||
another_request = unit_test_utils.get_fake_request(roles=['member'])
|
||||
changes = [
|
||||
{'op': 'replace', 'path': ['x_case_insensitive'], 'value': '2'},
|
||||
]
|
||||
output = self.controller.update(another_request,
|
||||
created_image.image_id, changes)
|
||||
self.assertEqual('2', output.extra_properties['x_case_insensitive'])
|
||||
|
||||
def test_delete_protected_prop_case_insensitive(self):
|
||||
enforcer = glance.api.policy.Enforcer()
|
||||
self.controller = glance.api.v2.images.ImagesController(self.db,
|
||||
enforcer,
|
||||
self.notifier,
|
||||
self.store)
|
||||
self.set_property_protections()
|
||||
request = unit_test_utils.get_fake_request(roles=['admin'])
|
||||
image = {'name': 'image-1'}
|
||||
extra_props = {'x_case_insensitive': 'bar'}
|
||||
created_image = self.controller.create(request, image=image,
|
||||
extra_properties=extra_props,
|
||||
tags=[])
|
||||
another_request = unit_test_utils.get_fake_request(roles=['member'])
|
||||
changes = [
|
||||
{'op': 'remove', 'path': ['x_case_insensitive']}
|
||||
]
|
||||
output = self.controller.update(another_request,
|
||||
created_image.image_id, changes)
|
||||
self.assertRaises(KeyError, output.extra_properties.__getitem__,
|
||||
'x_case_insensitive')
|
||||
|
||||
def test_create_non_protected_prop(self):
|
||||
"""Property marked with special char @ creatable by an unknown role"""
|
||||
self.set_property_protections()
|
||||
|
Loading…
Reference in New Issue
Block a user