diff --git a/keystoneclient/auth/base.py b/keystoneclient/auth/base.py index 4c743d950..ecbcf9635 100644 --- a/keystoneclient/auth/base.py +++ b/keystoneclient/auth/base.py @@ -108,6 +108,36 @@ class BaseAuthPlugin(object): """ return False + def get_user_id(self, session, **kwargs): + """Return a unique user identifier of the plugin. + + Wherever possible the user id should be inferred from the token however + there are certain URLs and other places that require access to the + currently authenticated user id. + + :param session: A session object so the plugin can make HTTP calls. + :type session: keystoneclient.session.Session + + :returns: A user identifier or None if one is not available. + :rtype: str + """ + return None + + def get_project_id(self, session, **kwargs): + """Return the project id that we are authenticated to. + + Wherever possible the project id should be inferred from the token + however there are certain URLs and other places that require access to + the currently authenticated project id. + + :param session: A session object so the plugin can make HTTP calls. + :type session: keystoneclient.session.Session + + :returns: A project identifier or None if one is not available. + :rtype: str + """ + return None + @classmethod def get_options(cls): """Return the list of parameters associated with the auth plugin. diff --git a/keystoneclient/auth/identity/base.py b/keystoneclient/auth/identity/base.py index 94b071219..610039a4d 100644 --- a/keystoneclient/auth/identity/base.py +++ b/keystoneclient/auth/identity/base.py @@ -236,6 +236,12 @@ class BaseIdentityPlugin(base.BaseAuthPlugin): return url + def get_user_id(self, session, **kwargs): + return self.get_access(session).user_id + + def get_project_id(self, session, **kwargs): + return self.get_access(session).project_id + @utils.positional() def get_discovery(self, session, url, authenticated=None): """Return the discovery object for a URL. diff --git a/keystoneclient/httpclient.py b/keystoneclient/httpclient.py index 458745f61..84b314e98 100644 --- a/keystoneclient/httpclient.py +++ b/keystoneclient/httpclient.py @@ -362,6 +362,12 @@ class HTTPClient(baseclient.Client, base.BaseAuthPlugin): else: return self.management_url + def get_user_id(self, session, **kwargs): + return self.auth_ref.user_id + + def get_project_id(self, session, **kwargs): + return self.auth_ref.project_id + @auth_token.setter def auth_token(self, value): """Override the auth_token. diff --git a/keystoneclient/tests/auth/test_identity_common.py b/keystoneclient/tests/auth/test_identity_common.py index 4a0cf5729..0b62159af 100644 --- a/keystoneclient/tests/auth/test_identity_common.py +++ b/keystoneclient/tests/auth/test_identity_common.py @@ -65,6 +65,13 @@ class CommonIdentityTests(object): def stub_auth_data(self, **kwargs): token = self.get_auth_data(**kwargs) + self.user_id = token.user_id + + try: + self.project_id = token.project_id + except AttributeError: + self.project_id = token.tenant_id + self.stub_auth(json=token) @abc.abstractproperty @@ -221,6 +228,13 @@ class CommonIdentityTests(object): self.assertIsNone(a.auth_ref) self.assertFalse(a.invalidate()) + def test_get_auth_properties(self): + a = self.create_auth_plugin() + s = session.Session() + + self.assertEqual(self.user_id, a.get_user_id(s)) + self.assertEqual(self.project_id, a.get_project_id(s)) + class V3(CommonIdentityTests, utils.TestCase): diff --git a/keystoneclient/tests/auth/test_token_endpoint.py b/keystoneclient/tests/auth/test_token_endpoint.py index a9028e374..a53c1b814 100644 --- a/keystoneclient/tests/auth/test_token_endpoint.py +++ b/keystoneclient/tests/auth/test_token_endpoint.py @@ -53,3 +53,11 @@ class TokenEndpointTest(utils.TestCase): self.assertIn('token', opt_names) self.assertIn('endpoint', opt_names) + + def test_token_endpoint_user_id(self): + a = token_endpoint.Token(self.TEST_URL, self.TEST_TOKEN) + s = session.Session() + + # we can't know this information about this sort of plugin + self.assertIsNone(a.get_user_id(s)) + self.assertIsNone(a.get_project_id(s)) diff --git a/keystoneclient/tests/v2_0/test_client.py b/keystoneclient/tests/v2_0/test_client.py index 5fbedf460..d09f326e6 100644 --- a/keystoneclient/tests/v2_0/test_client.py +++ b/keystoneclient/tests/v2_0/test_client.py @@ -27,7 +27,8 @@ from keystoneclient.v2_0 import client class KeystoneClientTest(utils.TestCase): def test_unscoped_init(self): - self.stub_auth(json=client_fixtures.unscoped_token()) + token = client_fixtures.unscoped_token() + self.stub_auth(json=token) c = client.Client(username='exampleuser', password='password', @@ -38,9 +39,12 @@ class KeystoneClientTest(utils.TestCase): self.assertFalse(c.auth_ref.project_scoped) self.assertIsNone(c.auth_ref.trust_id) self.assertFalse(c.auth_ref.trust_scoped) + self.assertIsNone(c.get_project_id(session=None)) + self.assertEqual(token.user_id, c.get_user_id(session=None)) def test_scoped_init(self): - self.stub_auth(json=client_fixtures.project_scoped_token()) + token = client_fixtures.project_scoped_token() + self.stub_auth(json=token) c = client.Client(username='exampleuser', password='password', @@ -53,6 +57,9 @@ class KeystoneClientTest(utils.TestCase): self.assertIsNone(c.auth_ref.trust_id) self.assertFalse(c.auth_ref.trust_scoped) + self.assertEqual(token.tenant_id, c.get_project_id(session=None)) + self.assertEqual(token.user_id, c.get_user_id(session=None)) + def test_auth_ref_load(self): self.stub_auth(json=client_fixtures.project_scoped_token()) diff --git a/keystoneclient/tests/v3/test_client.py b/keystoneclient/tests/v3/test_client.py index bf450321d..e1a85424d 100644 --- a/keystoneclient/tests/v3/test_client.py +++ b/keystoneclient/tests/v3/test_client.py @@ -40,6 +40,10 @@ class KeystoneClientTest(utils.TestCase): 'c4da488862bd435c9e6c0275a0d0e49a') self.assertFalse(c.has_service_catalog()) + self.assertEqual('c4da488862bd435c9e6c0275a0d0e49a', + c.get_user_id(session=None)) + self.assertIsNone(c.get_project_id(session=None)) + def test_domain_scoped_init(self): self.stub_auth(json=client_fixtures.domain_scoped_token()) @@ -70,6 +74,10 @@ class KeystoneClientTest(utils.TestCase): 'c4da488862bd435c9e6c0275a0d0e49a') self.assertEqual(c.auth_tenant_id, '225da22d3ce34b15877ea70b2a575f58') + self.assertEqual('c4da488862bd435c9e6c0275a0d0e49a', + c.get_user_id(session=None)) + self.assertEqual('225da22d3ce34b15877ea70b2a575f58', + c.get_project_id(session=None)) def test_auth_ref_load(self): self.stub_auth(json=client_fixtures.project_scoped_token())