From be2b89c54dcda9f556f0d59dadc8643bd89ea5dc Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 20 Jan 2015 19:21:14 +0300 Subject: [PATCH] Chain a trust with a role specified by name This patch adds an opportunity to specify roles by id or name upon trust redelegataion. Change-Id: I887d6cb1a1b55ae59f95b74bf69184818d8f6246 Closes-bug: 1412846 --- keystone/tests/unit/test_v3_auth.py | 30 +++++++++++++++++++++++++++++ keystone/trust/controllers.py | 15 +++++++++------ 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/keystone/tests/unit/test_v3_auth.py b/keystone/tests/unit/test_v3_auth.py index 210eb7d1cb..bb52b808ad 100644 --- a/keystone/tests/unit/test_v3_auth.py +++ b/keystone/tests/unit/test_v3_auth.py @@ -2827,6 +2827,36 @@ class TestTrustRedelegation(test_v3.RestfulTestCase): role_id_set2 = set(r['id'] for r in trust2['roles']) self.assertThat(role_id_set1, matchers.GreaterThan(role_id_set2)) + def test_redelegate_with_role_by_name(self): + # For role by name testing + ref = self.new_trust_ref( + trustor_user_id=self.user_id, + trustee_user_id=self.trustee_user['id'], + project_id=self.project_id, + impersonation=True, + expires=dict(minutes=1), + role_names=[self.role['name']], + allow_redelegation=True) + r = self.post('/OS-TRUST/trusts', + body={'trust': ref}) + trust = self.assertValidTrustResponse(r) + # Ensure we can get a token with this trust + trust_token = self._get_trust_token(trust) + # Chain second trust with roles subset + ref = self.new_trust_ref( + trustor_user_id=self.user_id, + trustee_user_id=self.trustee_user['id'], + project_id=self.project_id, + impersonation=True, + role_names=[self.role['name']], + allow_redelegation=True) + r = self.post('/OS-TRUST/trusts', + body={'trust': ref}, + token=trust_token) + trust = self.assertValidTrustResponse(r) + # Ensure we can get a token with this trust + self._get_trust_token(trust) + def test_redelegate_new_role_fails(self): r = self.post('/OS-TRUST/trusts', body={'trust': self.redelegated_trust_ref}) diff --git a/keystone/trust/controllers.py b/keystone/trust/controllers.py index 427abc1c92..0c92b10afd 100644 --- a/keystone/trust/controllers.py +++ b/keystone/trust/controllers.py @@ -104,7 +104,7 @@ class TrustV3(controller.V3Controller): 'next': None, 'previous': None} - def _clean_role_list(self, context, trust, all_roles): + def _normalize_role_list(self, trust, all_roles): trust_roles = [] all_role_names = dict((r['name'], r) for r in all_roles) for role in trust.get('roles', []): @@ -155,12 +155,15 @@ class TrustV3(controller.V3Controller): self._require_user_is_trustor(context, trust) self._require_trustee_exists(trust['trustee_user_id']) all_roles = self.role_api.list_roles() - clean_roles = self._clean_role_list(context, trust, all_roles) - self._require_trustor_has_role_in_project(trust, clean_roles) + # Normalize roles + normalized_roles = self._normalize_role_list(trust, all_roles) + trust['roles'] = normalized_roles + self._require_trustor_has_role_in_project(trust) trust['expires_at'] = self._parse_expiration_date( trust.get('expires_at')) trust_id = uuid.uuid4().hex - new_trust = self.trust_api.create_trust(trust_id, trust, clean_roles, + new_trust = self.trust_api.create_trust(trust_id, trust, + normalized_roles, redelegated_trust) self._fill_in_roles(context, new_trust, all_roles) return TrustV3.wrap_member(context, new_trust) @@ -186,9 +189,9 @@ class TrustV3(controller.V3Controller): else: return [] - def _require_trustor_has_role_in_project(self, trust, clean_roles): + def _require_trustor_has_role_in_project(self, trust): user_roles = self._get_user_role(trust) - for trust_role in clean_roles: + for trust_role in trust['roles']: matching_roles = [x for x in user_roles if x == trust_role['id']] if not matching_roles: