Allow fetching user_id/project_id from auth

This would ideally not be required however when building certain URLs
the current user_id is needed. And when communicating with certain
services we need to have access to the current project id. It seems
better to allow plugins to give up the information if they have it than
do various hacks to try and get it from them.

Change-Id: Ib61b0628702806268be623a9987a922a60b04165
Closes-Bug: #1364724
This commit is contained in:
Jamie Lennox
2014-09-03 12:51:26 +10:00
parent 53a82232ff
commit 4cc1631665
7 changed files with 81 additions and 2 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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):

View File

@@ -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))

View File

@@ -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())

View File

@@ -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())