Remove parent_id in v2 token response

Identity v2 api should be not be aware of hierarchical projects,
so the parent_id should not be included in the token response.
This is unnecessary data being sent making the token larger.

Change-Id: I9cc5a00d4bd9f4c5232393c8dfb19a44fd121721
Closes-Bug: #1421668
This commit is contained in:
lin-hua-cheng 2015-02-17 18:41:09 -08:00
parent 3a1d263930
commit 253c13f9f0
4 changed files with 107 additions and 2 deletions

View File

@ -62,7 +62,7 @@ class TenantAssignment(controller.V2Controller):
tenant_refs = (
self.assignment_api.list_projects_for_user(token_ref.user_id))
tenant_refs = [self.filter_domain_id(ref) for ref in tenant_refs
tenant_refs = [self.v3_to_v2_project(ref) for ref in tenant_refs
if ref['domain_id'] == CONF.identity.default_domain_id]
params = {
'limit': context['query_string'].get('limit'),

View File

@ -238,6 +238,12 @@ class V2Controller(wsgi.Application):
del ref['domain']
return ref
@staticmethod
def filter_project_parent_id(ref):
"""Remove parent_id since v2 calls are not hierarchy-aware."""
ref.pop('parent_id', None)
return ref
@staticmethod
def normalize_username_in_response(ref):
"""Adds username to outgoing user refs to match the v2 spec.
@ -304,6 +310,34 @@ class V2Controller(wsgi.Application):
else:
raise ValueError(_('Expected dict or list: %s') % type(ref))
@staticmethod
def v3_to_v2_project(ref):
"""Convert a project_ref from v3 to v2.
* v2.0 projects are not domain aware, and should have domain_id removed
* v2.0 projects are not hierarchy aware, and should have parent_id
removed
This method should only be applied to project_refs being returned from
the v2.0 controller(s).
If ref is a list type, we will iterate through each element and do the
conversion.
"""
def _filter_project_properties(ref):
"""Run through the various filter methods."""
V2Controller.filter_domain_id(ref)
V2Controller.filter_project_parent_id(ref)
return ref
if isinstance(ref, dict):
return _filter_project_properties(ref)
elif isinstance(ref, list):
return [_filter_project_properties(x) for x in ref]
else:
raise ValueError(_('Expected dict or list: %s') % type(ref))
def format_project_list(self, tenant_refs, **kwargs):
"""Format a v2 style project list, including marker/limits."""
marker = kwargs.get('marker')

View File

@ -2898,6 +2898,27 @@ class AssignmentInheritanceDisabledTestCase(test_v3.RestfulTestCase):
class AssignmentV3toV2MethodsTestCase(tests.TestCase):
"""Test domain V3 to V2 conversion methods."""
def _setup_initial_projects(self):
self.project_id = uuid.uuid4().hex
self.domain_id = uuid.uuid4().hex
self.parent_id = uuid.uuid4().hex
# Project with only domain_id in ref
self.project1 = {'id': self.project_id,
'name': self.project_id,
'domain_id': self.domain_id}
# Project with both domain_id and parent_id in ref
self.project2 = {'id': self.project_id,
'name': self.project_id,
'domain_id': self.domain_id,
'parent_id': self.parent_id}
# Project with no domain_id and parent_id in ref
self.project3 = {'id': self.project_id,
'name': self.project_id,
'domain_id': self.domain_id,
'parent_id': self.parent_id}
# Expected result with no domain_id and parent_id
self.expected_project = {'id': self.project_id,
'name': self.project_id}
def test_v2controller_filter_domain_id(self):
# V2.0 is not domain aware, ensure domain_id is popped off the ref.
@ -2941,3 +2962,52 @@ class AssignmentV3toV2MethodsTestCase(tests.TestCase):
self.assertRaises(exception.Unauthorized,
controller.V2Controller.filter_domain,
non_default_domain_ref)
def test_v2controller_filter_project_parent_id(self):
# V2.0 is not project hierarchy aware, ensure parent_id is popped off.
other_data = uuid.uuid4().hex
parent_id = uuid.uuid4().hex
ref = {'parent_id': parent_id,
'other_data': other_data}
ref_no_parent = {'other_data': other_data}
expected_ref = ref_no_parent.copy()
updated_ref = controller.V2Controller.filter_project_parent_id(ref)
self.assertIs(ref, updated_ref)
self.assertDictEqual(ref, expected_ref)
# Make sure we don't error/muck up data if parent_id isn't present
updated_ref = controller.V2Controller.filter_project_parent_id(
ref_no_parent)
self.assertIs(ref_no_parent, updated_ref)
self.assertDictEqual(ref_no_parent, expected_ref)
def test_v3_to_v2_project_method(self):
self._setup_initial_projects()
updated_project1 = controller.V2Controller.v3_to_v2_project(
self.project1)
self.assertIs(self.project1, updated_project1)
self.assertDictEqual(self.project1, self.expected_project)
updated_project2 = controller.V2Controller.v3_to_v2_project(
self.project2)
self.assertIs(self.project2, updated_project2)
self.assertDictEqual(self.project2, self.expected_project)
updated_project3 = controller.V2Controller.v3_to_v2_project(
self.project3)
self.assertIs(self.project3, updated_project3)
self.assertDictEqual(self.project3, self.expected_project)
def test_v3_to_v2_project_method_list(self):
self._setup_initial_projects()
project_list = [self.project1, self.project2, self.project3]
updated_list = controller.V2Controller.v3_to_v2_project(project_list)
self.assertEqual(len(updated_list), len(project_list))
for i, ref in enumerate(updated_list):
# Order should not change.
self.assertIs(ref, project_list[i])
self.assertDictEqual(self.project1, self.expected_project)
self.assertDictEqual(self.project2, self.expected_project)
self.assertDictEqual(self.project3, self.expected_project)

View File

@ -118,7 +118,8 @@ class Auth(controller.V2Controller):
# format.
user_ref = self.v3_to_v2_user(user_ref)
if tenant_ref:
tenant_ref = self.filter_domain_id(tenant_ref)
tenant_ref = self.v3_to_v2_project(tenant_ref)
auth_token_data = self._get_auth_token_data(user_ref,
tenant_ref,
metadata_ref,