diff --git a/keystoneclient/access.py b/keystoneclient/access.py index 53cb0ffd7..e54e9868a 100644 --- a/keystoneclient/access.py +++ b/keystoneclient/access.py @@ -391,11 +391,11 @@ def domain_scoped(self): @property def trust_id(self): - return None + return self.get('trust', {}).get('id') @property def trust_scoped(self): - return False + return 'trust' in self @property def project_id(self): diff --git a/keystoneclient/tests/utils.py b/keystoneclient/tests/utils.py index 24e8bed41..620ec6bb3 100644 --- a/keystoneclient/tests/utils.py +++ b/keystoneclient/tests/utils.py @@ -30,6 +30,7 @@ class TestCase(testtools.TestCase): TEST_TENANT_ID = '1' TEST_TENANT_NAME = 'aTenant' TEST_TOKEN = 'aToken' + TEST_TRUST_ID = 'aTrust' TEST_USER = 'test' TEST_ROOT_URL = 'http://127.0.0.1:5000/' diff --git a/keystoneclient/tests/v2_0/test_auth.py b/keystoneclient/tests/v2_0/test_auth.py index f25ff9fa7..94333ea56 100644 --- a/keystoneclient/tests/v2_0/test_auth.py +++ b/keystoneclient/tests/v2_0/test_auth.py @@ -173,6 +173,24 @@ def test_authenticate_success_token_scoped(self): self.TEST_RESPONSE_DICT["access"]["token"]["id"]) self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY) + @httpretty.activate + def test_authenticate_success_token_scoped_trust(self): + del self.TEST_REQUEST_BODY['auth']['passwordCredentials'] + self.TEST_REQUEST_BODY['auth']['token'] = {'id': self.TEST_TOKEN} + self.TEST_REQUEST_BODY['auth']['trust_id'] = self.TEST_TRUST_ID + response = self.TEST_RESPONSE_DICT.copy() + response['access']['trust'] = {"trustee_user_id": self.TEST_USER, + "id": self.TEST_TRUST_ID} + self.stub_auth(json=response) + + cs = client.Client(token=self.TEST_TOKEN, + tenant_id=self.TEST_TENANT_ID, + trust_id=self.TEST_TRUST_ID, + auth_url=self.TEST_URL) + self.assertTrue(cs.auth_ref.trust_scoped) + self.assertEqual(cs.auth_ref.trust_id, self.TEST_TRUST_ID) + self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY) + @httpretty.activate def test_authenticate_success_token_unscoped(self): del self.TEST_REQUEST_BODY['auth']['passwordCredentials'] diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 22c6199a5..217c098bd 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -142,6 +142,7 @@ def get_raw_token_from_identity_service(self, auth_url, username=None, password=None, tenant_name=None, tenant_id=None, token=None, project_name=None, project_id=None, + trust_id=None, **kwargs): """Authenticate against the v2 Identity API. @@ -157,6 +158,7 @@ def get_raw_token_from_identity_service(self, auth_url, username=None, tenant_id=project_id or tenant_id, tenant_name=project_name or tenant_name, password=password, + trust_id=trust_id, token=token) except (exceptions.AuthorizationFailure, exceptions.Unauthorized): _logger.debug("Authorization Failed.") @@ -166,11 +168,13 @@ def get_raw_token_from_identity_service(self, auth_url, username=None, "%s" % e) def _base_authN(self, auth_url, username=None, password=None, - tenant_name=None, tenant_id=None, token=None): + tenant_name=None, tenant_id=None, trust_id=None, + token=None): """Takes a username, password, and optionally a tenant_id or tenant_name to get an authentication token from keystone. May also take a token and a tenant_id to re-scope a token - to a tenant. + to a tenant, or a token, tenant_id and trust_id and re-scope + the token to the trust """ headers = {} if auth_url is None: @@ -188,5 +192,7 @@ def _base_authN(self, auth_url, username=None, password=None, params['auth']['tenantId'] = tenant_id elif tenant_name: params['auth']['tenantName'] = tenant_name + if trust_id: + params['auth']['trust_id'] = trust_id resp, body = self.request(url, 'POST', body=params, headers=headers) return resp, body