diff options
author | Adam Young <ayoung@redhat.com> | 2014-07-11 20:20:50 -0500 |
---|---|---|
committer | ayoung <ayoung@redhat.com> | 2014-09-23 13:47:35 +0000 |
commit | a82d4a69219036781a276da4523bbbc242d7a50f (patch) | |
tree | 96412425ecc5a95fa222cb2e1756dc473f023a69 | |
parent | 79d1eec35aad874a7c08ff22c39260884a5524ba (diff) | |
download | python-keystoneclient-a82d4a69219036781a276da4523bbbc242d7a50f.tar.gz |
Enumerate Projects with Unscoped Tokens
Creating a client with a session using an Unscoped tokens now sets auth
info in client. This Auth Info is necessary in order to enumerate
projects. This is the standard login path for Horizon.
Change-Id: I688a27cd0e7c98e7cf899ac65bb593a85171813f
-rw-r--r-- | keystoneclient/base.py | 30 | ||||
-rw-r--r-- | keystoneclient/tests/auth/test_identity_v3.py | 55 | ||||
-rw-r--r-- | keystoneclient/v3/projects.py | 1 |
3 files changed, 75 insertions, 11 deletions
diff --git a/keystoneclient/base.py b/keystoneclient/base.py index f94c16b..a0618f9 100644 --- a/keystoneclient/base.py +++ b/keystoneclient/base.py @@ -25,6 +25,7 @@ import functools import six from six.moves import urllib +from keystoneclient import auth from keystoneclient import exceptions from keystoneclient.openstack.common.apiclient import base @@ -337,19 +338,26 @@ class CrudManager(Manager): return self._head(self.build_url(dict_args_in_out=kwargs)) @filter_kwargs - def list(self, **kwargs): + def list(self, fallback_to_auth=False, **kwargs): url = self.build_url(dict_args_in_out=kwargs) - if kwargs: - query = '?%s' % urllib.parse.urlencode(kwargs) - else: - query = '' - return self._list( - '%(url)s%(query)s' % { - 'url': url, - 'query': query, - }, - self.collection_key) + try: + if kwargs: + query = '?%s' % urllib.parse.urlencode(kwargs) + else: + query = '' + url_query = '%(url)s%(query)s' % {'url': url, 'query': query} + return self._list( + url_query, + self.collection_key) + except exceptions.EmptyCatalog: + if fallback_to_auth: + return self._list( + url_query, + self.collection_key, + endpoint_filter={'interface': auth.AUTH_INTERFACE}) + else: + raise @filter_kwargs def put(self, **kwargs): diff --git a/keystoneclient/tests/auth/test_identity_v3.py b/keystoneclient/tests/auth/test_identity_v3.py index ecdc38a..bce4fa7 100644 --- a/keystoneclient/tests/auth/test_identity_v3.py +++ b/keystoneclient/tests/auth/test_identity_v3.py @@ -15,7 +15,9 @@ import uuid from keystoneclient import access from keystoneclient.auth.identity import v3 +from keystoneclient import client from keystoneclient import exceptions +from keystoneclient import fixture from keystoneclient import session from keystoneclient.tests import utils @@ -110,6 +112,11 @@ class V3IdentityPlugin(utils.TestCase): def setUp(self): super(V3IdentityPlugin, self).setUp() + + V3_URL = "%sv3" % self.TEST_URL + self.TEST_DISCOVERY_RESPONSE = { + 'versions': {'values': [fixture.V3Discovery(V3_URL)]}} + self.TEST_RESPONSE_DICT = { "token": { "methods": [ @@ -138,6 +145,31 @@ class V3IdentityPlugin(utils.TestCase): "catalog": self.TEST_SERVICE_CATALOG }, } + self.TEST_PROJECTS_RESPONSE = { + "projects": [ + { + "domain_id": "1789d1", + "enabled": "True", + "id": "263fd9", + "links": { + "self": "https://identity:5000/v3/projects/263fd9" + }, + "name": "Dev Group A" + }, + { + "domain_id": "1789d1", + "enabled": "True", + "id": "e56ad3", + "links": { + "self": "https://identity:5000/v3/projects/e56ad3" + }, + "name": "Dev Group B" + } + ], + "links": { + "self": "https://identity:5000/v3/projects", + } + } def stub_auth(self, subject_token=None, **kwargs): if not subject_token: @@ -165,6 +197,29 @@ class V3IdentityPlugin(utils.TestCase): self.assertRequestHeaderEqual('Accept', 'application/json') self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN) + def test_authenticate_with_username_password_unscoped(self): + del self.TEST_RESPONSE_DICT['token']['catalog'] + del self.TEST_RESPONSE_DICT['token']['project'] + + self.stub_auth(json=self.TEST_RESPONSE_DICT) + self.stub_url(method="GET", json=self.TEST_DISCOVERY_RESPONSE) + test_user_id = self.TEST_RESPONSE_DICT['token']['user']['id'] + self.stub_url(method="GET", + json=self.TEST_PROJECTS_RESPONSE, + parts=['users', test_user_id, 'projects']) + + a = v3.Password(self.TEST_URL, + username=self.TEST_USER, + password=self.TEST_PASS) + s = session.Session(auth=a) + cs = client.Client(session=s, auth_url=self.TEST_URL) + + # As a sanity check on the auth_ref, make sure client has the + # proper user id, that it fetches the right project response + self.assertEqual(test_user_id, a.auth_ref.user_id) + t = cs.projects.list(user=a.auth_ref.user_id) + self.assertEqual(2, len(t)) + def test_authenticate_with_username_password_domain_scoped(self): self.stub_auth(json=self.TEST_RESPONSE_DICT) a = v3.Password(self.TEST_URL, username=self.TEST_USER, diff --git a/keystoneclient/v3/projects.py b/keystoneclient/v3/projects.py index ffc9f32..2fcd249 100644 --- a/keystoneclient/v3/projects.py +++ b/keystoneclient/v3/projects.py @@ -76,6 +76,7 @@ class ProjectManager(base.CrudManager): return super(ProjectManager, self).list( base_url=base_url, domain_id=base.getid(domain), + fallback_to_auth=True, **kwargs) def get(self, project): |