def get_plugin(self, service_provider=None, auth_url=None, plugins=[], **kwargs): """Authenticate using keystone to keystone federation. This plugin uses other v3 plugins to authenticate a user to a identity provider in order to authenticate the user to a service provider :param service_provider: service provider ID :param auth_url: Keystone auth url :param plugins: list of openstack_auth plugins to check :returns Keystone2Keystone keystone auth plugin """ # service_provider being None prevents infinite recursion if utils.get_keystone_version() < 3 or not service_provider: return None keystone_idp_id = getattr(settings, 'KEYSTONE_PROVIDER_IDP_ID', 'localkeystone') if service_provider == keystone_idp_id: return None for plugin in plugins: unscoped_idp_auth = plugin.get_plugin(plugins=plugins, auth_url=auth_url, **kwargs) if unscoped_idp_auth: break else: LOG.debug('Could not find base authentication backend for ' 'K2K plugin with the provided credentials.') return None idp_exception = None scoped_idp_auth = None unscoped_auth_ref = base.BasePlugin.get_access_info( self, unscoped_idp_auth) try: scoped_idp_auth, __ = self.get_project_scoped_auth( unscoped_idp_auth, unscoped_auth_ref) except exceptions.KeystoneAuthException as idp_excp: idp_exception = idp_excp if not scoped_idp_auth or idp_exception: msg = 'Identity provider authentication Failed.' raise exceptions.KeystoneAuthException(msg) session = utils.get_session() if scoped_idp_auth.get_sp_auth_url(session, service_provider) is None: msg = _('Could not find service provider ID on Keystone.') raise exceptions.KeystoneAuthException(msg) unscoped_auth = v3_auth.Keystone2Keystone( base_plugin=scoped_idp_auth, service_provider=service_provider) return unscoped_auth
def test_switch_keystone_provider_remote(self): auth_url = settings.OPENSTACK_KEYSTONE_URL target_provider = 'k2kserviceprovider' 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) # mock authenticate self._mock_unscoped_and_domain_list_projects(user, projects) self._mock_scoped_client_for_tenant(unscoped, self.data.project_one.id) # mock switch plugin = v3_auth.Token(auth_url=auth_url, token=unscoped.auth_token, project_id=None, reauthenticate=False) plugin.get_access(mox.IsA(session.Session)).AndReturn( self.data.unscoped_access_info) plugin.auth_url = auth_url client = self.ks_client_module.Client(session=mox.IsA(session.Session), auth=plugin) self._mock_unscoped_list_projects(client, user, projects) plugin = self._create_token_auth( self.data.project_one.id, token=self.data.unscoped_access_info.auth_token, url=settings.OPENSTACK_KEYSTONE_URL) plugin.get_access(mox.IsA(session.Session)).AndReturn( settings.OPENSTACK_KEYSTONE_URL) plugin.get_sp_auth_url( mox.IsA(session.Session), target_provider ).AndReturn('https://k2kserviceprovider/sp_url') plugin = v3_auth.Keystone2Keystone(base_plugin=plugin, service_provider=target_provider) plugin.get_access(mox.IsA(session.Session)). \ AndReturn(self.sp_data.unscoped_access_info) plugin.auth_url = 'http://service_provider_endp:5000/v3' # 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 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, url=plugin.auth_url, token=sp_unscoped.auth_token) self.mox.ReplayAll() # Log in url = reverse('login') response = self.client.get(url) self.assertEqual(response.status_code, 200) response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) # Switch url = reverse('switch_keystone_provider', args=[target_provider]) form_data['keystone_provider'] = target_provider response = self.client.get(url, form_data, follow=True) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) # Assert keystone provider has changed self.assertEqual(self.client.session['keystone_provider_id'], target_provider) # These should not change self.assertEqual(self.client.session['k2k_base_unscoped_token'], unscoped.auth_token) self.assertEqual(self.client.session['k2k_auth_url'], auth_url)
def get_plugin(self, **kwargs): kwargs.setdefault('base_plugin', self._get_base_plugin()) kwargs.setdefault('service_provider', self.SP_ID) return v3.Keystone2Keystone(**kwargs)
def test_switch_keystone_provider_remote_fail(self): target_provider = 'k2kserviceprovider' 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] user = self.data.user form_data = self.get_form_data(user) plugin = v3_auth.Password( auth_url=settings.OPENSTACK_KEYSTONE_URL, password=self.data.user.password, username=self.data.user.name, user_domain_name=DEFAULT_DOMAIN, unscoped=True) plugin.get_access(mox.IsA(session.Session)). \ AndReturn(self.data.unscoped_access_info) plugin.auth_url = settings.OPENSTACK_KEYSTONE_URL client = self.ks_client_module.Client( session=mox.IsA(session.Session), auth=plugin) plugin = v3_auth.Token( auth_url=settings.OPENSTACK_KEYSTONE_URL, token=self.data.unscoped_access_info.auth_token, domain_name=DEFAULT_DOMAIN, reauthenticate=False) plugin.get_access(mox.IsA(session.Session)).AndReturn( self.data.domain_scoped_access_info) client.projects = self.mox.CreateMockAnything() client.projects.list(user=user.id).AndReturn(projects) plugin = v3_auth.Token( auth_url=settings.OPENSTACK_KEYSTONE_URL, token=self.data.unscoped_access_info.auth_token, project_id=self.data.project_one.id, reauthenticate=False) self.scoped_token_auth = plugin plugin.get_access(mox.IsA(session.Session)).AndReturn( self.data.unscoped_access_info) self.ks_client_module.Client( session=mox.IsA(session.Session), auth=plugin) # mock switch plugin = v3_auth.Token( auth_url=settings.OPENSTACK_KEYSTONE_URL, token=self.data.unscoped_access_info.auth_token, project_id=None, reauthenticate=False) plugin.get_access(mox.IsA(session.Session)).AndReturn( self.data.unscoped_access_info) plugin.auth_url = settings.OPENSTACK_KEYSTONE_URL client = self.ks_client_module.Client(session=mox.IsA(session.Session), auth=plugin) client.projects = self.mox.CreateMockAnything() client.projects.list(user=user.id).AndReturn(projects) plugin = v3_auth.Token( auth_url=settings.OPENSTACK_KEYSTONE_URL, token=self.data.unscoped_access_info.auth_token, project_id=self.data.project_one.id, reauthenticate=False) plugin.get_access(mox.IsA(session.Session)).AndReturn( settings.OPENSTACK_KEYSTONE_URL) plugin.get_sp_auth_url( mox.IsA(session.Session), target_provider ).AndReturn('https://k2kserviceprovider/sp_url') # let the K2K plugin fail when logging in plugin = v3_auth.Keystone2Keystone( base_plugin=plugin, service_provider=target_provider) plugin.get_access(mox.IsA(session.Session)).AndRaise( keystone_exceptions.AuthorizationFailure) self.mox.ReplayAll() # Log in url = reverse('login') response = self.client.get(url) self.assertEqual(response.status_code, 200) response = self.client.post(url, form_data) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) # Switch url = reverse('switch_keystone_provider', args=[target_provider]) form_data['keystone_provider'] = target_provider response = self.client.get(url, form_data, follow=True) self.assertRedirects(response, settings.LOGIN_REDIRECT_URL) # Assert that provider has not changed because of failure self.assertEqual(self.client.session['keystone_provider_id'], 'localkeystone') # These should never change self.assertEqual(self.client.session['k2k_base_unscoped_token'], self.data.unscoped_access_info.auth_token) self.assertEqual(self.client.session['k2k_auth_url'], settings.OPENSTACK_KEYSTONE_URL)