summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openstack_auth/plugin/base.py38
-rw-r--r--openstack_auth/tests/tests.py63
2 files changed, 83 insertions, 18 deletions
diff --git a/openstack_auth/plugin/base.py b/openstack_auth/plugin/base.py
index 5172329..4b520b4 100644
--- a/openstack_auth/plugin/base.py
+++ b/openstack_auth/plugin/base.py
@@ -98,6 +98,18 @@ class BasePlugin(object):
msg = _('Unable to retrieve authorized projects.')
raise exceptions.KeystoneAuthException(msg)
+ def list_domains(self, session, auth_plugin, auth_ref=None):
+ try:
+ if self.keystone_version >= 3:
+ client = v3_client.Client(session=session, auth=auth_plugin)
+ return client.auth.domains()
+ else:
+ return []
+ except (keystone_exceptions.ClientException,
+ keystone_exceptions.AuthorizationFailure):
+ msg = _('Unable to retrieve authorized domains.')
+ raise exceptions.KeystoneAuthException(msg)
+
def get_access_info(self, keystone_auth):
"""Get the access info from an unscoped auth
@@ -190,22 +202,36 @@ class BasePlugin(object):
session = utils.get_session()
auth_url = unscoped_auth.auth_url
- if not domain_name or utils.get_keystone_version() < 3:
+ if utils.get_keystone_version() < 3:
return None, None
+ if domain_name:
+ domains = [domain_name]
+ else:
+ domains = self.list_domains(session,
+ unscoped_auth,
+ unscoped_auth_ref)
+ domains = [domain.name for domain in domains if domain.enabled]
# domain support can require domain scoped tokens to perform
# identity operations depending on the policy files being used
# for keystone.
domain_auth = None
domain_auth_ref = None
- try:
+ for domain_name in domains:
token = unscoped_auth_ref.auth_token
domain_auth = utils.get_token_auth_plugin(
auth_url,
token,
domain_name=domain_name)
- domain_auth_ref = domain_auth.get_access(session)
- except (keystone_exceptions.ClientException,
- keystone_exceptions.AuthorizationFailure):
- LOG.debug('Error getting domain scoped token.', exc_info=True)
+ try:
+ domain_auth_ref = domain_auth.get_access(session)
+ except (keystone_exceptions.ClientException,
+ keystone_exceptions.AuthorizationFailure):
+ pass
+ else:
+ if len(domains) > 1:
+ LOG.info("More than one valid domain found for user %s,"
+ " scoping to %s" %
+ (unscoped_auth_ref.user_id, domain_name))
+ break
return domain_auth, domain_auth_ref
diff --git a/openstack_auth/tests/tests.py b/openstack_auth/tests/tests.py
index 45adf2e..4790f73 100644
--- a/openstack_auth/tests/tests.py
+++ b/openstack_auth/tests/tests.py
@@ -108,25 +108,45 @@ class OpenStackAuthFederatedTestsMixin(object):
client.federation.projects = self.mox.CreateMockAnything()
client.federation.projects.list().AndReturn(projects)
+ def _mock_unscoped_list_domains(self, client, domains):
+ client.auth = self.mox.CreateMockAnything()
+ client.auth.domains().AndReturn(domains)
+
def _mock_unscoped_token_client(self, unscoped, auth_url=None,
- client=True):
+ client=True, plugin=None):
if not auth_url:
auth_url = settings.OPENSTACK_KEYSTONE_URL
- plugin = self._create_token_auth(
- None,
- token=unscoped.auth_token,
- url=auth_url)
- plugin.get_access(mox.IsA(session.Session)).AndReturn(unscoped)
+ if unscoped and not plugin:
+ plugin = self._create_token_auth(
+ None,
+ token=unscoped.auth_token,
+ url=auth_url)
+ plugin.get_access(mox.IsA(session.Session)).AndReturn(unscoped)
plugin.auth_url = auth_url
if client:
return self.ks_client_module.Client(
session=mox.IsA(session.Session),
auth=plugin)
- def _mock_federated_client_list_projects(self, unscoped, projects):
- client = self._mock_unscoped_token_client(unscoped)
+ def _mock_plugin(self, unscoped, auth_url=None):
+ if not auth_url:
+ auth_url = settings.OPENSTACK_KEYSTONE_URL
+ plugin = self._create_token_auth(
+ None,
+ token=unscoped.auth_token,
+ url=auth_url)
+ plugin.get_access(mox.IsA(session.Session)).AndReturn(unscoped)
+ plugin.auth_url = settings.OPENSTACK_KEYSTONE_URL
+ return plugin
+
+ def _mock_federated_client_list_projects(self, unscoped_auth, projects):
+ client = self._mock_unscoped_token_client(None, plugin=unscoped_auth)
self._mock_unscoped_federated_list_projects(client, projects)
+ def _mock_federated_client_list_domains(self, unscoped_auth, domains):
+ client = self._mock_unscoped_token_client(None, plugin=unscoped_auth)
+ self._mock_unscoped_list_domains(client, domains)
+
class OpenStackAuthTestsV2(OpenStackAuthTestsMixin, test.TestCase):
@@ -885,6 +905,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
self.data = data_v3.generate_test_data(service_providers=True)
self.sp_data = data_v3.generate_test_data(endpoint='http://sp2')
projects = [self.data.project_one, self.data.project_two]
+ domains = []
user = self.data.user
unscoped = self.data.unscoped_access_info
form_data = self.get_form_data(user)
@@ -925,7 +946,13 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
# mock authenticate for service provider
sp_projects = [self.sp_data.project_one, self.sp_data.project_two]
sp_unscoped = self.sp_data.federated_unscoped_access_info
- client = self._mock_unscoped_token_client(sp_unscoped, plugin.auth_url)
+ sp_unscoped_auth = self._mock_plugin(sp_unscoped,
+ auth_url=plugin.auth_url)
+ client = self._mock_unscoped_token_client(None, plugin.auth_url,
+ plugin=sp_unscoped_auth)
+ self._mock_unscoped_list_domains(client, domains)
+ client = self._mock_unscoped_token_client(None, plugin.auth_url,
+ plugin=sp_unscoped_auth)
self._mock_unscoped_federated_list_projects(client, sp_projects)
self._mock_scoped_client_for_tenant(sp_unscoped,
self.sp_data.project_one.id,
@@ -961,6 +988,7 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
self.data = data_v3.generate_test_data(service_providers=True)
keystone_provider = 'localkeystone'
projects = [self.data.project_one, self.data.project_two]
+ domains = []
user = self.data.user
unscoped = self.data.unscoped_access_info
form_data = self.get_form_data(user)
@@ -971,7 +999,12 @@ class OpenStackAuthTestsV3(OpenStackAuthTestsMixin,
self._mock_unscoped_token_client(unscoped,
auth_url=auth_url,
client=False)
- client = self._mock_unscoped_token_client(unscoped, auth_url)
+ unscoped_auth = self._mock_plugin(unscoped)
+ client = self._mock_unscoped_token_client(None, auth_url=auth_url,
+ plugin=unscoped_auth)
+ self._mock_unscoped_list_domains(client, domains)
+ client = self._mock_unscoped_token_client(None, auth_url=auth_url,
+ plugin=unscoped_auth)
self._mock_unscoped_list_projects(client, user, projects)
self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id)
@@ -1154,11 +1187,14 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin,
def test_websso_login(self):
projects = [self.data.project_one, self.data.project_two]
+ domains = []
unscoped = self.data.federated_unscoped_access_info
token = unscoped.auth_token
+ unscoped_auth = self._mock_plugin(unscoped)
form_data = {'token': token}
- self._mock_federated_client_list_projects(unscoped, projects)
+ self._mock_federated_client_list_domains(unscoped_auth, domains)
+ self._mock_federated_client_list_projects(unscoped_auth, projects)
self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id)
self.mox.ReplayAll()
@@ -1173,11 +1209,14 @@ class OpenStackAuthTestsWebSSO(OpenStackAuthTestsMixin,
settings.OPENSTACK_KEYSTONE_URL = 'http://auth.openstack.org:5000/v3'
projects = [self.data.project_one, self.data.project_two]
+ domains = []
unscoped = self.data.federated_unscoped_access_info
token = unscoped.auth_token
+ unscoped_auth = self._mock_plugin(unscoped)
form_data = {'token': token}
- self._mock_federated_client_list_projects(unscoped, projects)
+ self._mock_federated_client_list_domains(unscoped_auth, domains)
+ self._mock_federated_client_list_projects(unscoped_auth, projects)
self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id)
self.mox.ReplayAll()