diff --git a/keystone/models/token_model.py b/keystone/models/token_model.py index 3280f8f4e..6893b37f0 100644 --- a/keystone/models/token_model.py +++ b/keystone/models/token_model.py @@ -250,6 +250,13 @@ class KeystoneToken(dict): else: return self.get('trust', {}).get('trustor_user_id') + @property + def trust_impersonation(self): + if self.version is V3: + return self.get('OS-TRUST:trust', {}).get('impersonation') + else: + return self.get('trust', {}).get('impersonation') + @property def oauth_scoped(self): return 'OS-OAUTH1' in self diff --git a/keystone/tests/test_auth.py b/keystone/tests/test_auth.py index 92704c0b4..81b2c7192 100644 --- a/keystone/tests/test_auth.py +++ b/keystone/tests/test_auth.py @@ -1092,6 +1092,35 @@ class AuthWithTrust(AuthTest): new_trust['id'])['trust'] self.assertEqual(3, trust['remaining_uses']) + def test_v2_trust_token_contains_trustor_user_id_and_impersonation(self): + new_trust = self.create_trust(self.sample_data, self.trustor['name']) + auth_response = self.fetch_v2_token_from_trust(new_trust) + + self.assertEqual(new_trust['trustee_user_id'], + auth_response['access']['trust']['trustee_user_id']) + self.assertEqual(new_trust['trustor_user_id'], + auth_response['access']['trust']['trustor_user_id']) + self.assertEqual(new_trust['impersonation'], + auth_response['access']['trust']['impersonation']) + self.assertEqual(new_trust['id'], + auth_response['access']['trust']['id']) + + validate_response = self.controller.validate_token( + context=dict(is_admin=True, query_string={}), + token_id=auth_response['access']['token']['id']) + self.assertEqual( + new_trust['trustee_user_id'], + validate_response['access']['trust']['trustee_user_id']) + self.assertEqual( + new_trust['trustor_user_id'], + validate_response['access']['trust']['trustor_user_id']) + self.assertEqual( + new_trust['impersonation'], + validate_response['access']['trust']['impersonation']) + self.assertEqual( + new_trust['id'], + validate_response['access']['trust']['id']) + class TokenExpirationTest(AuthTest): diff --git a/keystone/tests/test_token_provider.py b/keystone/tests/test_token_provider.py index 0362f971a..15f190458 100644 --- a/keystone/tests/test_token_provider.py +++ b/keystone/tests/test_token_provider.py @@ -34,7 +34,9 @@ SAMPLE_V2_TOKEN = { "access": { "trust": { "id": "abc123", - "trustee_user_id": "123456" + "trustee_user_id": "123456", + "trustor_user_id": "333333", + "impersonation": False }, "serviceCatalog": [ { @@ -341,7 +343,9 @@ SAMPLE_V2_TOKEN_WITH_EMBEDED_VERSION = { "access": { "trust": { "id": "abc123", - "trustee_user_id": "123456" + "trustee_user_id": "123456", + "trustor_user_id": "333333", + "impersonation": False }, "serviceCatalog": [ { diff --git a/keystone/tests/unit/token/test_token_model.py b/keystone/tests/unit/token/test_token_model.py index 6f7b909c2..46c778dd9 100644 --- a/keystone/tests/unit/token/test_token_model.py +++ b/keystone/tests/unit/token/test_token_model.py @@ -180,7 +180,12 @@ class TestKeystoneTokenModel(core.TestCase): token_data.project_domain_name) self.assertEqual(self.v2_sample_token['access']['trust']['id'], token_data.trust_id) - self.assertIsNone(token_data.trustor_user_id) + self.assertEqual( + self.v2_sample_token['access']['trust']['trustor_user_id'], + token_data.trustor_user_id) + self.assertEqual( + self.v2_sample_token['access']['trust']['impersonation'], + token_data.trust_impersonation) self.assertEqual( self.v2_sample_token['access']['trust']['trustee_user_id'], token_data.trustee_user_id) diff --git a/keystone/token/providers/common.py b/keystone/token/providers/common.py index d474f25ea..3e8d35384 100644 --- a/keystone/token/providers/common.py +++ b/keystone/token/providers/common.py @@ -34,7 +34,8 @@ CONF = config.CONF class V2TokenDataHelper(object): """Creates V2 token data.""" @classmethod - def format_token(cls, token_ref, roles_ref=None, catalog_ref=None): + def format_token(cls, token_ref, roles_ref=None, catalog_ref=None, + trust_ref=None): audit_info = None user_ref = token_ref['user'] metadata_ref = token_ref['metadata'] @@ -84,10 +85,14 @@ class V2TokenDataHelper(object): o['access']['metadata'] = {'is_admin': 0} if 'roles' in metadata_ref: o['access']['metadata']['roles'] = metadata_ref['roles'] - if CONF.trust.enabled and 'trust_id' in metadata_ref: + if CONF.trust.enabled and trust_ref: o['access']['trust'] = {'trustee_user_id': - metadata_ref['trustee_user_id'], - 'id': metadata_ref['trust_id'] + trust_ref['trustee_user_id'], + 'id': trust_ref['id'], + 'trustor_user_id': + trust_ref['trustor_user_id'], + 'impersonation': + trust_ref['impersonation'] } return o @@ -401,8 +406,13 @@ class BaseProvider(provider.Provider): def issue_v2_token(self, token_ref, roles_ref=None, catalog_ref=None): + metadata_ref = token_ref['metadata'] + trust_ref = None + if CONF.trust.enabled and metadata_ref and 'trust_id' in metadata_ref: + trust_ref = self.trust_api.get_trust(metadata_ref['trust_id']) + token_data = self.v2_token_data_helper.format_token( - token_ref, roles_ref, catalog_ref) + token_ref, roles_ref, catalog_ref, trust_ref) token_id = self._get_token_id(token_data) token_data['access']['token']['id'] = token_id return token_id, token_data @@ -551,8 +561,14 @@ class BaseProvider(provider.Provider): token_ref['user']['id'], token_ref['tenant']['id'], metadata_ref) + + trust_ref = None + if CONF.trust.enabled and 'trust_id' in metadata_ref: + trust_ref = self.trust_api.get_trust( + metadata_ref['trust_id']) + token_data = self.v2_token_data_helper.format_token( - token_ref, roles_ref, catalog_ref) + token_ref, roles_ref, catalog_ref, trust_ref) return token_data except exception.ValidationError as e: LOG.exception(_('Failed to validate token'))