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:
Ala Rezmerita 2015-03-11 18:49:12 +01:00 committed by Ajaya Agrawal
parent fa7f316f6e
commit cfad91bc7c
5 changed files with 174 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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()