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
This commit is contained in:
Adam Young
2014-07-11 20:20:50 -05:00
committed by ayoung
parent 79d1eec35a
commit a82d4a6921
3 changed files with 75 additions and 11 deletions

View File

@@ -25,6 +25,7 @@ import functools
import six import six
from six.moves import urllib from six.moves import urllib
from keystoneclient import auth
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient.openstack.common.apiclient import base 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)) return self._head(self.build_url(dict_args_in_out=kwargs))
@filter_kwargs @filter_kwargs
def list(self, **kwargs): def list(self, fallback_to_auth=False, **kwargs):
url = self.build_url(dict_args_in_out=kwargs) url = self.build_url(dict_args_in_out=kwargs)
if kwargs: try:
query = '?%s' % urllib.parse.urlencode(kwargs) if kwargs:
else: query = '?%s' % urllib.parse.urlencode(kwargs)
query = '' else:
return self._list( query = ''
'%(url)s%(query)s' % { url_query = '%(url)s%(query)s' % {'url': url, 'query': query}
'url': url, return self._list(
'query': query, url_query,
}, self.collection_key)
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 @filter_kwargs
def put(self, **kwargs): def put(self, **kwargs):

View File

@@ -15,7 +15,9 @@ import uuid
from keystoneclient import access from keystoneclient import access
from keystoneclient.auth.identity import v3 from keystoneclient.auth.identity import v3
from keystoneclient import client
from keystoneclient import exceptions from keystoneclient import exceptions
from keystoneclient import fixture
from keystoneclient import session from keystoneclient import session
from keystoneclient.tests import utils from keystoneclient.tests import utils
@@ -110,6 +112,11 @@ class V3IdentityPlugin(utils.TestCase):
def setUp(self): def setUp(self):
super(V3IdentityPlugin, self).setUp() super(V3IdentityPlugin, self).setUp()
V3_URL = "%sv3" % self.TEST_URL
self.TEST_DISCOVERY_RESPONSE = {
'versions': {'values': [fixture.V3Discovery(V3_URL)]}}
self.TEST_RESPONSE_DICT = { self.TEST_RESPONSE_DICT = {
"token": { "token": {
"methods": [ "methods": [
@@ -138,6 +145,31 @@ class V3IdentityPlugin(utils.TestCase):
"catalog": self.TEST_SERVICE_CATALOG "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): def stub_auth(self, subject_token=None, **kwargs):
if not subject_token: if not subject_token:
@@ -165,6 +197,29 @@ class V3IdentityPlugin(utils.TestCase):
self.assertRequestHeaderEqual('Accept', 'application/json') self.assertRequestHeaderEqual('Accept', 'application/json')
self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN) 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): def test_authenticate_with_username_password_domain_scoped(self):
self.stub_auth(json=self.TEST_RESPONSE_DICT) self.stub_auth(json=self.TEST_RESPONSE_DICT)
a = v3.Password(self.TEST_URL, username=self.TEST_USER, a = v3.Password(self.TEST_URL, username=self.TEST_USER,

View File

@@ -76,6 +76,7 @@ class ProjectManager(base.CrudManager):
return super(ProjectManager, self).list( return super(ProjectManager, self).list(
base_url=base_url, base_url=base_url,
domain_id=base.getid(domain), domain_id=base.getid(domain),
fallback_to_auth=True,
**kwargs) **kwargs)
def get(self, project): def get(self, project):