Repro bug 1845530: versioned discovery is authed

This recreates the referenced bug, demonstrating that requests for
versioned discovery endpoints (/v2, /v2.1) are being piped through
authentication.

Change-Id: Iaef1229f542e4e824c6c5c73335bc601bed08c04
Related-Bug: #1845530
This commit is contained in:
Eric Fried 2019-09-26 15:10:26 -05:00 committed by melanie witt
parent 7520676b28
commit 49a9f45644
3 changed files with 76 additions and 33 deletions

View File

@ -874,7 +874,7 @@ class OSAPIFixture(fixtures.Fixture):
def __init__(self, api_version='v2',
project_id='6f70656e737461636b20342065766572',
use_project_id_in_urls=False):
use_project_id_in_urls=False, stub_keystone=True):
"""Constructor
:param api_version: the API version that we're interested in
@ -883,11 +883,14 @@ class OSAPIFixture(fixtures.Fixture):
:param project_id: the project id to use on the API.
:param use_project_id_in_urls: If True, act like the "endpoint" in the
"service catalog" has the legacy format including the project_id.
:param stub_keystone: If True, stub keystonemiddleware and
NovaKeystoneContext to simulate (but not perform) real auth.
"""
super(OSAPIFixture, self).__init__()
self.api_version = api_version
self.project_id = project_id
self.use_project_id_in_urls = use_project_id_in_urls
self.stub_keystone = stub_keystone
def setUp(self):
super(OSAPIFixture, self).setUp()
@ -903,22 +906,8 @@ class OSAPIFixture(fixtures.Fixture):
}
self.useFixture(ConfPatcher(**conf_overrides))
# Stub out authentication middleware
# TODO(efried): Use keystonemiddleware.fixtures.AuthTokenFixture
self.useFixture(fixtures.MockPatch(
'keystonemiddleware.auth_token.filter_factory',
return_value=lambda _app: _app))
# Stub out context middleware
def fake_ctx(env, **kwargs):
user_id = env['HTTP_X_AUTH_USER']
project_id = env['HTTP_X_AUTH_PROJECT_ID']
is_admin = user_id == 'admin'
return context.RequestContext(
user_id, project_id, is_admin=is_admin, **kwargs)
self.useFixture(fixtures.MonkeyPatch(
'nova.api.auth.NovaKeystoneContext._create_context', fake_ctx))
if self.stub_keystone:
self._stub_keystone()
# Turn off manipulation of socket_options in TCPKeepAliveAdapter
# to keep wsgi-intercept happy. Replace it with the method
@ -950,6 +939,24 @@ class OSAPIFixture(fixtures.Fixture):
# the fixture.
self.app = app
def _stub_keystone(self):
# Stub out authentication middleware
# TODO(efried): Use keystonemiddleware.fixtures.AuthTokenFixture
self.useFixture(fixtures.MockPatch(
'keystonemiddleware.auth_token.filter_factory',
return_value=lambda _app: _app))
# Stub out context middleware
def fake_ctx(env, **kwargs):
user_id = env['HTTP_X_AUTH_USER']
project_id = env['HTTP_X_AUTH_PROJECT_ID']
is_admin = user_id == 'admin'
return context.RequestContext(
user_id, project_id, is_admin=is_admin, **kwargs)
self.useFixture(fixtures.MonkeyPatch(
'nova.api.auth.NovaKeystoneContext._create_context', fake_ctx))
class OSMetadataServer(fixtures.Fixture):
"""Create an OS Metadata API server as a fixture.

View File

@ -12,33 +12,64 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import ddt
import fixtures
import webob
from nova.api.openstack import api_version_request as avr
from nova.tests.functional.api_sample_tests import api_sample_base
@ddt.ddt
class VersionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
"""Validate that proper version documents can be fetched without auth."""
# Here we want to avoid stubbing keystone middleware. That will cause
# "real" keystone middleware to run (and fail) if it's in the pipeline.
# (The point of this test is to prove we do version discovery through
# pipelines that *don't* authenticate.)
STUB_KEYSTONE = False
sample_dir = 'versions'
_use_project_id = False
# NOTE(gmann): Setting empty scenario for 'version' API testing
# as those does not send request on particular endpoint and running
# its tests alone is enough.
scenarios = []
max_api_version = avr.max_api_version().get_string()
max_api_version = {'max_api_version': avr.max_api_version().get_string()}
def test_versions_get(self):
response = self._do_get('', strip_version=True)
self._verify_response('versions-get-resp',
{'max_api_version': self.max_api_version},
def setUp(self):
super(VersionsSampleJsonTest, self).setUp()
# Version documents are supposed to be available without auth, so make
# the auth middleware "fail" authentication.
self.useFixture(fixtures.MockPatch(
# [api]auth_strategy is set to noauth2 by the ConfFixture
'nova.api.openstack.auth.NoAuthMiddlewareBase.base_call',
return_value=webob.Response(status=401)))
def _get(self, url):
return self._do_get(
url,
# Since we're explicitly getting discovery endpoints, strip the
# automatic /v2[.1] added by the fixture.
strip_version=True)
@ddt.data('', '/')
def test_versions_get_base(self, url):
response = self._get(url)
self._verify_response('versions-get-resp', self.max_api_version,
response, 200, update_links=False)
def test_versions_get_v2(self):
response = self._do_get('/v2', strip_version=True)
self._verify_response('v2-version-get-resp', {},
response, 200, update_links=False)
def test_versions_get_v21(self):
response = self._do_get('/v2.1', strip_version=True)
self._verify_response('v21-version-get-resp',
{'max_api_version': self.max_api_version},
response, 200, update_links=False)
@ddt.data(('/v2', 'v2-version-get-resp', {}),
('/v2/', 'v2-version-get-resp', {}),
('/v2.1', 'v21-version-get-resp', max_api_version),
('/v2.1/', 'v21-version-get-resp', max_api_version))
@ddt.unpack
def test_versions_get_versioned(self, url, tplname, subs):
response = self._get(url)
# TODO(efried): This is bug 1845530 whereby we try to authenticate at
# the versioned discovery endpoint.
self.assertEqual(401, response.status_code)
# TODO(efried): Uncomment when bug 1845530 is resolved
# self._verify_response(tplname, subs, response, 200,
# update_links=False)

View File

@ -362,6 +362,10 @@ class _IntegratedTestBase(test.TestCase, InstanceHelperMixin):
# This indicates whether to include the project ID in the URL for API
# requests through OSAPIFixture. Overridden by subclasses.
_use_project_id = False
# Override this in subclasses to avoid stubbing keystonemiddleware and
# NovaKeystoneContext, thus making those middlewares behave as they would
# in real life (i.e. try to do real authentication).
STUB_KEYSTONE = True
def setUp(self):
super(_IntegratedTestBase, self).setUp()
@ -398,7 +402,8 @@ class _IntegratedTestBase(test.TestCase, InstanceHelperMixin):
self.api_fixture = self.useFixture(
nova_fixtures.OSAPIFixture(
api_version=self.api_major_version,
use_project_id_in_urls=self._use_project_id))
use_project_id_in_urls=self._use_project_id,
stub_keystone=self.STUB_KEYSTONE))
# if the class needs to run as admin, make the api endpoint
# the admin, otherwise it's safer to run as non admin user.