summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-08-17 04:55:07 +0000
committerGerrit Code Review <review@openstack.org>2017-08-17 04:55:07 +0000
commite2d33c2819b1f52e7ee651d06d0ed50fd54fad15 (patch)
tree2da6c6192fcf7c30df5349fa202c8cd2435c6240
parent15811bf2c8430bc69993e7450746ec7fc2d1eb67 (diff)
parent10a9ef511dffb2e7dd19a075039e66fbf307ca85 (diff)
Merge "Remove duplicate roles from federated auth" into stable/pike12.0.0.0rc212.0.0
-rw-r--r--keystone/tests/unit/test_v3_federation.py23
-rw-r--r--keystone/token/providers/common.py24
-rw-r--r--releasenotes/notes/bug-1701324-739a31f38037f77b.yaml5
3 files changed, 47 insertions, 5 deletions
diff --git a/keystone/tests/unit/test_v3_federation.py b/keystone/tests/unit/test_v3_federation.py
index 1fe5c46..23934ab 100644
--- a/keystone/tests/unit/test_v3_federation.py
+++ b/keystone/tests/unit/test_v3_federation.py
@@ -2087,6 +2087,29 @@ class FederatedTokenTests(test_v3.RestfulTestCase, FederatedSetupMixin):
2087 self._check_project_scoped_token_attributes(token_resp, 2087 self._check_project_scoped_token_attributes(token_resp,
2088 project_id_ref) 2088 project_id_ref)
2089 2089
2090 def test_scope_to_project_with_duplicate_roles_returns_single_role(self):
2091 r = self.v3_create_token(self.TOKEN_SCOPE_PROJECT_EMPLOYEE_FROM_ADMIN)
2092
2093 # Even though the process of obtaining a token shows that there is a
2094 # role assignment on a project, we should attempt to create a duplicate
2095 # assignment somewhere. Do this by creating a direct role assignment
2096 # with each role against the project the token was scoped to.
2097 user_id = r.json_body['token']['user']['id']
2098 project_id = r.json_body['token']['project']['id']
2099 for role in r.json_body['token']['roles']:
2100 self.assignment_api.create_grant(
2101 role_id=role['id'], user_id=user_id, project_id=project_id
2102 )
2103
2104 # Ensure all roles in the token are unique even though we know there
2105 # should be duplicate role assignment from the assertions and the
2106 # direct role assignments we just created.
2107 r = self.v3_create_token(self.TOKEN_SCOPE_PROJECT_EMPLOYEE_FROM_ADMIN)
2108 known_role_ids = []
2109 for role in r.json_body['token']['roles']:
2110 self.assertNotIn(role['id'], known_role_ids)
2111 known_role_ids.append(role['id'])
2112
2090 def test_scope_to_project_with_only_inherited_roles(self): 2113 def test_scope_to_project_with_only_inherited_roles(self):
2091 """Try to scope token whose only roles are inherited.""" 2114 """Try to scope token whose only roles are inherited."""
2092 r = self.v3_create_token( 2115 r = self.v3_create_token(
diff --git a/keystone/token/providers/common.py b/keystone/token/providers/common.py
index d29d6f8..7b4e1b1 100644
--- a/keystone/token/providers/common.py
+++ b/keystone/token/providers/common.py
@@ -192,11 +192,25 @@ class V3TokenDataHelper(object):
192 roles = roles + self._get_roles_for_user(user_id, domain_id, 192 roles = roles + self._get_roles_for_user(user_id, domain_id,
193 project_id) 193 project_id)
194 194
195 # remove duplicates 195 # NOTE(lbragstad): Remove duplicate role references from a list of
196 roles = [dict(t) for t in set([tuple(d.items()) for d in roles])] 196 # roles. It is often suggested that this be done with:
197 197 #
198 check_roles(roles, user_id, project_id, domain_id) 198 # roles = [dict(t) for t in set([tuple(d.items()) for d in roles])]
199 token_data['roles'] = roles 199 #
200 # But that doesn't actually remove duplicates in all cases and causes
201 # transient failures because dictionaries are unordered objects. This
202 # means {'id': 1, 'foo': 'bar'} and {'foo': 'bar', 'id': 1} won't
203 # actually resolve to a single entity in the above logic since they are
204 # both considered unique. By using `in` we're performing a containment
205 # check, which also does a deep comparison of the objects, which is
206 # what we want.
207 unique_roles = []
208 for role in roles:
209 if role not in unique_roles:
210 unique_roles.append(role)
211
212 check_roles(unique_roles, user_id, project_id, domain_id)
213 token_data['roles'] = unique_roles
200 214
201 def _populate_user(self, token_data, user_id, trust): 215 def _populate_user(self, token_data, user_id, trust):
202 if 'user' in token_data: 216 if 'user' in token_data:
diff --git a/releasenotes/notes/bug-1701324-739a31f38037f77b.yaml b/releasenotes/notes/bug-1701324-739a31f38037f77b.yaml
new file mode 100644
index 0000000..d47e5ae
--- /dev/null
+++ b/releasenotes/notes/bug-1701324-739a31f38037f77b.yaml
@@ -0,0 +1,5 @@
1---
2fixes:
3 - |
4 [`bug 1701324 <https://bugs.launchpad.net/keystone/+bug/1701324>`_]
5 Token bodies now contain only unique roles in the authentication response.