return metadata_refs
-def _dict_with_extra_specs(inst_type_query):
+def _dict_with_extra_specs_if_authorized(context, inst_type_query):
"""Convert type query result to dict with extra_spec and rate_limit.
Takes a volume type query returned by sqlalchemy and returns it
as a dictionary, converting the extra_specs entry from a list
- of dicts:
+ of dicts. NOTE the contents of extra-specs are admin readable
+ only. If the context passed in for this request is not admin
+ then we will return an empty extra-specs dict rather than
+ providing the admin only details.
+
+ Example response with admin context:
'extra_specs' : [{'key': 'k1', 'value': 'v1', ...}, ...]
to a single dict:
'extra_specs' : {'k1': 'v1'}
+
"""
+
inst_type_dict = dict(inst_type_query)
- extra_specs = {x['key']: x['value']
- for x in inst_type_query['extra_specs']}
- inst_type_dict['extra_specs'] = extra_specs
+ if not is_admin_context(context):
+ del(inst_type_dict['extra_specs'])
+ else:
+ extra_specs = {x['key']: x['value']
+ for x in inst_type_query['extra_specs']}
+ inst_type_dict['extra_specs'] = extra_specs
return inst_type_dict
result = {}
for row in rows:
- result[row['name']] = _dict_with_extra_specs(row)
+ result[row['name']] = _dict_with_extra_specs_if_authorized(context,
+ row)
return result
if not result:
raise exception.VolumeTypeNotFound(volume_type_id=id)
- vtype = _dict_with_extra_specs(result)
+ vtype = _dict_with_extra_specs_if_authorized(context, result)
if 'projects' in expected_fields:
vtype['projects'] = [p['project_id'] for p in result['projects']]
if not result:
raise exception.VolumeTypeNotFoundByName(volume_type_name=name)
- return _dict_with_extra_specs(result)
+ return _dict_with_extra_specs_if_authorized(context, result)
@require_context
volume_type_id = volume_type.get('id')
self.assertFalse(volume_types.is_public_volume_type(self.ctxt,
volume_type_id))
+
+ def test_ensure_no_extra_specs_for_non_admin(self):
+ # non-admin users shouldn't get extra-specs back in type-get/list etc
+ ctxt = context.RequestContext('average-joe',
+ 'd802f078-0af1-4e6b-8c02-7fac8d4339aa',
+ auth_token='token',
+ is_admin=False)
+ volume_types.create(self.ctxt, "type-test", is_public=False)
+ vtype = volume_types.get_volume_type_by_name(ctxt, 'type-test')
+ self.assertIsNone(vtype.get('extra_specs', None))
+
+ def test_ensure_extra_specs_for_admin(self):
+ # admin users should get extra-specs back in type-get/list etc
+ volume_types.create(self.ctxt, "type-test", is_public=False)
+ vtype = volume_types.get_volume_type_by_name(self.ctxt, 'type-test')
+ self.assertIsNotNone(vtype.get('extra_specs', None))