Remove v2.0 functionality

This change removes v2.0 functionality from
keystonemiddleware, as well as associated tests.

Partial-Bug: #1845539
Partial-Bug: #1777177

Change-Id: If47e90085d8a59c52fb23876dc329cd4f0b05ef0
This commit is contained in:
Gage Hugo 2019-07-08 10:35:05 -05:00
parent 19f2791082
commit a6a3edb80e
4 changed files with 24 additions and 340 deletions

View File

@ -13,7 +13,6 @@
from keystoneauth1 import discover
from keystoneauth1 import exceptions as ksa_exceptions
from keystoneauth1 import plugin
from keystoneclient.v2_0 import client as v2_client
from keystoneclient.v3 import client as v3_client
from six.moves import urllib
@ -37,25 +36,6 @@ class _RequestStrategy(object):
pass
class _V2RequestStrategy(_RequestStrategy):
AUTH_VERSION = (2, 0)
def __init__(self, adap, **kwargs):
super(_V2RequestStrategy, self).__init__(adap, **kwargs)
self._client = v2_client.Client(session=adap)
def verify_token(self, token, allow_expired=False):
# NOTE(jamielennox): allow_expired is ignored on V2
auth_ref = self._client.tokens.validate_access_info(token)
if not auth_ref:
msg = _('Failed to fetch token data from identity server')
raise ksm_exceptions.InvalidToken(msg)
return {'access': auth_ref}
class _V3RequestStrategy(_RequestStrategy):
AUTH_VERSION = (3, 0)
@ -81,7 +61,7 @@ class _V3RequestStrategy(_RequestStrategy):
return {'token': auth_ref}
_REQUEST_STRATEGIES = [_V3RequestStrategy, _V2RequestStrategy]
_REQUEST_STRATEGIES = [_V3RequestStrategy]
class IdentityServer(object):
@ -137,13 +117,12 @@ class IdentityServer(object):
def _get_strategy_class(self):
if self._requested_auth_version:
# A specific version was requested.
if discover.version_match(_V3RequestStrategy.AUTH_VERSION,
self._requested_auth_version):
return _V3RequestStrategy
# The version isn't v3 so we don't know what to do. Just assume V2.
return _V2RequestStrategy
if not discover.version_match(_V3RequestStrategy.AUTH_VERSION,
self._requested_auth_interface):
self._LOG.info('A version other than v3 was requested: %s',
self._requested_auth_interface)
# Return v3, even if the request is unknown
return _V3RequestStrategy
# Specific version was not requested then we fall through to
# discovering available versions from the server

View File

@ -590,7 +590,7 @@ class CommonAuthTokenMiddlewareTest(object):
return self.middleware._token_cache.get(token)
def test_memcache_set_invalid_uuid(self):
invalid_uri = "%s/v2.0/tokens/invalid-token" % BASE_URI
invalid_uri = "%s/v3/tokens/invalid-token" % BASE_URI
self.requests_mock.get(invalid_uri, status_code=404)
token = 'invalid-token'
@ -601,7 +601,7 @@ class CommonAuthTokenMiddlewareTest(object):
def test_memcache_hit_invalid_token(self):
token = 'invalid-token'
invalid_uri = '%s/v2.0/tokens/invalid-token' % BASE_URI
invalid_uri = '%s/v3/tokens/invalid-token' % BASE_URI
self.requests_mock.get(invalid_uri, status_code=404)
# Call once to cache token's invalid state; verify it cached as such
@ -1016,169 +1016,6 @@ def request_timeout_response(request, context):
"Request to https://host/token/path timed out")
class v2AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
CommonAuthTokenMiddlewareTest,
testresources.ResourcedTestCase):
"""v2 token specific tests.
There are some differences between how the auth-token middleware handles
v2 and v3 tokens over and above the token formats, namely:
- A v3 keystone server will auto scope a token to a user's default project
if no scope is specified. A v2 server assumes that the auth-token
middleware will do that.
- A v2 keystone server may issue a token without a catalog, even with a
tenant
The tests below were originally part of the generic AuthTokenMiddlewareTest
class, but now, since they really are v2 specific, they are included here.
"""
resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)]
def setUp(self):
super(v2AuthTokenMiddlewareTest, self).setUp()
self.token_dict = {
'uuid_token_default': self.examples.UUID_TOKEN_DEFAULT,
'uuid_token_unscoped': self.examples.UUID_TOKEN_UNSCOPED,
'uuid_token_bind': self.examples.UUID_TOKEN_BIND,
'uuid_token_unknown_bind': self.examples.UUID_TOKEN_UNKNOWN_BIND,
'uuid_service_token_default':
self.examples.UUID_SERVICE_TOKEN_DEFAULT,
}
self.requests_mock.get(BASE_URI,
json=VERSION_LIST_v2,
status_code=300)
self.requests_mock.post('%s/v2.0/tokens' % BASE_URI,
text=FAKE_ADMIN_TOKEN)
for token in (self.examples.UUID_TOKEN_DEFAULT,
self.examples.UUID_TOKEN_UNSCOPED,
self.examples.UUID_TOKEN_BIND,
self.examples.UUID_TOKEN_UNKNOWN_BIND,
self.examples.UUID_TOKEN_NO_SERVICE_CATALOG,
self.examples.UUID_SERVICE_TOKEN_DEFAULT,):
url = "%s/v2.0/tokens/%s" % (BASE_URI, token)
text = self.examples.JSON_TOKEN_RESPONSES[token]
self.requests_mock.get(url, text=text)
url = '%s/v2.0/tokens/%s' % (BASE_URI, ERROR_TOKEN)
self.requests_mock.get(url, text=network_error_response)
url = '%s/v2.0/tokens/%s' % (BASE_URI, TIMEOUT_TOKEN)
self.requests_mock.get(url, text=request_timeout_response)
self.set_middleware()
def assert_unscoped_default_tenant_auto_scopes(self, token):
"""Unscoped v2 requests with a default tenant should ``auto-scope``.
The implied scope is the user's tenant ID.
"""
resp = self.call_middleware(headers={'X-Auth-Token': token})
self.assertEqual(FakeApp.SUCCESS, resp.body)
self.assertIn('keystone.token_info', resp.request.environ)
def assert_valid_last_url(self, token_id):
self.assertLastPath("/v2.0/tokens/%s" % token_id)
def test_default_tenant_uuid_token(self):
self.assert_unscoped_default_tenant_auto_scopes(
self.examples.UUID_TOKEN_DEFAULT)
def assert_unscoped_token_receives_401(self, token):
"""Unscoped requests with no default tenant ID should be rejected."""
resp = self.call_middleware(headers={'X-Auth-Token': token},
expected_status=401)
self.assertEqual('Keystone uri="https://keystone.example.com:1234"',
resp.headers['WWW-Authenticate'])
def test_request_prevent_service_catalog_injection(self):
token = self.examples.UUID_TOKEN_NO_SERVICE_CATALOG
resp = self.call_middleware(headers={'X-Service-Catalog': '[]',
'X-Auth-Token': token})
self.assertFalse(resp.request.headers.get('X-Service-Catalog'))
self.assertEqual(FakeApp.SUCCESS, resp.body)
def test_user_plugin_token_properties(self):
token = self.examples.UUID_TOKEN_DEFAULT
token_data = self.examples.TOKEN_RESPONSES[token]
service = self.examples.UUID_SERVICE_TOKEN_DEFAULT
resp = self.call_middleware(headers={'X-Service-Catalog': '[]',
'X-Auth-Token': token,
'X-Service-Token': service})
self.assertEqual(FakeApp.SUCCESS, resp.body)
token_auth = resp.request.environ['keystone.token_auth']
self.assertTrue(token_auth.has_user_token)
self.assertTrue(token_auth.has_service_token)
self.assertEqual(token_data.user_id, token_auth.user.user_id)
self.assertEqual(token_data.tenant_id, token_auth.user.project_id)
self.assertThat(token_auth.user.role_names, matchers.HasLength(2))
self.assertIn('role1', token_auth.user.role_names)
self.assertIn('role2', token_auth.user.role_names)
self.assertIsNone(token_auth.user.trust_id)
self.assertIsNone(token_auth.user.user_domain_id)
self.assertIsNone(token_auth.user.project_domain_id)
self.assertThat(token_auth.service.role_names, matchers.HasLength(2))
self.assertIn('service', token_auth.service.role_names)
self.assertIn('service_role2', token_auth.service.role_names)
self.assertIsNone(token_auth.service.trust_id)
class CrossVersionAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
testresources.ResourcedTestCase):
resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)]
def test_valid_uuid_request_forced_to_2_0(self):
"""Test forcing auth_token to use lower api version.
By installing the v3 http hander, auth_token will be get
a version list that looks like a v3 server - from which it
would normally chose v3.0 as the auth version. However, here
we specify v2.0 in the configuration - which should force
auth_token to use that version instead.
"""
conf = {
'auth_version': 'v2.0'
}
self.requests_mock.get(BASE_URI,
json=VERSION_LIST_v3,
status_code=300)
self.requests_mock.post('%s/v2.0/tokens' % BASE_URI,
text=FAKE_ADMIN_TOKEN)
token = self.examples.UUID_TOKEN_DEFAULT
url = "%s/v2.0/tokens/%s" % (BASE_URI, token)
text = self.examples.JSON_TOKEN_RESPONSES[token]
self.requests_mock.get(url, text=text)
self.set_middleware(conf=conf)
# This tests will only work is auth_token has chosen to use the
# lower, v2, api version
self.call_middleware(headers={'X-Auth-Token': token})
self.assertEqual(url, self.requests_mock.last_request.url)
class v3AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
CommonAuthTokenMiddlewareTest,
testresources.ResourcedTestCase):
@ -1190,19 +1027,7 @@ class v3AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
This is done by configuring the AuthTokenMiddlewareTest class via
its Setup(), passing in v3 style data that will then be used by
the tests themselves. This approach has been used to ensure we
really are running the same tests for both v2 and v3 tokens.
There a few additional specific test for v3 only:
- We allow an unscoped token to be validated (as unscoped), where
as for v2 tokens, the auth_token middleware is expected to try and
auto-scope it (and fail if there is no default tenant)
- Domain scoped tokens
Since we don't specify an auth version for auth_token to use, by
definition we are thefore implicitely testing that it will use
the highest available auth version, i.e. v3.0
the tests themselves.
"""
@ -1537,7 +1362,7 @@ class DelayedAuthTests(BaseAuthTokenMiddlewareTest):
body = uuid.uuid4().hex
www_authenticate_uri = 'http://local.test'
conf = {'delay_auth_decision': 'True',
'auth_version': 'v3.0',
'auth_version': 'v3',
'www_authenticate_uri': www_authenticate_uri}
middleware = self.create_simple_middleware(status='401 Unauthorized',
@ -1841,59 +1666,6 @@ class CommonCompositeAuthTests(object):
bind_level='required')
class v2CompositeAuthTests(BaseAuthTokenMiddlewareTest,
CommonCompositeAuthTests,
testresources.ResourcedTestCase):
"""Test auth_token middleware with v2 token based composite auth.
Execute the Composite auth class tests, but with the
auth_token middleware configured to expect v2 tokens back from
a keystone server.
"""
resources = [('examples', client_fixtures.EXAMPLES_RESOURCE)]
def setUp(self):
super(v2CompositeAuthTests, self).setUp(
expected_env=EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE,
fake_app=CompositeFakeApp)
uuid_token_default = self.examples.UUID_TOKEN_DEFAULT
uuid_service_token_default = self.examples.UUID_SERVICE_TOKEN_DEFAULT
uuid_token_bind = self.examples.UUID_TOKEN_BIND
uuid_service_token_bind = self.examples.UUID_SERVICE_TOKEN_BIND
self.token_dict = {
'uuid_token_default': uuid_token_default,
'uuid_service_token_default': uuid_service_token_default,
'uuid_token_bind': uuid_token_bind,
'uuid_service_token_bind': uuid_service_token_bind,
}
self.requests_mock.get(BASE_URI,
json=VERSION_LIST_v2,
status_code=300)
self.requests_mock.post('%s/v2.0/tokens' % BASE_URI,
text=FAKE_ADMIN_TOKEN)
for token in (self.examples.UUID_TOKEN_DEFAULT,
self.examples.UUID_SERVICE_TOKEN_DEFAULT,
self.examples.UUID_TOKEN_BIND,
self.examples.UUID_SERVICE_TOKEN_BIND):
text = self.examples.JSON_TOKEN_RESPONSES[token]
self.requests_mock.get('%s/v2.0/tokens/%s' % (BASE_URI, token),
text=text)
for invalid_uri in ("%s/v2.0/tokens/invalid-token" % BASE_URI,
"%s/v2.0/tokens/invalid-service-token" % BASE_URI):
self.requests_mock.get(invalid_uri, text='', status_code=404)
self.token_expected_env = dict(EXPECTED_V2_DEFAULT_ENV_RESPONSE)
self.service_token_expected_env = dict(
EXPECTED_V2_DEFAULT_SERVICE_ENV_RESPONSE)
self.set_middleware()
class v3CompositeAuthTests(BaseAuthTokenMiddlewareTest,
CommonCompositeAuthTests,
testresources.ResourcedTestCase):
@ -1908,7 +1680,7 @@ class v3CompositeAuthTests(BaseAuthTokenMiddlewareTest,
def setUp(self):
super(v3CompositeAuthTests, self).setUp(
auth_version='v3.0',
auth_version='v3',
fake_app=v3CompositeFakeApp)
uuid_token_default = self.examples.v3_UUID_TOKEN_DEFAULT
@ -1979,7 +1751,7 @@ class OtherTests(BaseAuthTokenMiddlewareTest):
self.call_middleware(headers={'X-Auth-Token': uuid.uuid4().hex},
expected_status=503)
self.assertIn('versions [v3.0, v2.0]', self.logger.output)
self.assertIn('versions [v3.0]', self.logger.output)
def _assert_auth_version(self, conf_version, identity_server_version):
self.set_middleware(conf={'auth_version': conf_version})
@ -1988,8 +1760,6 @@ class OtherTests(BaseAuthTokenMiddlewareTest):
identity_server.auth_version)
def test_micro_version(self):
self._assert_auth_version('v2', (2, 0))
self._assert_auth_version('v2.0', (2, 0))
self._assert_auth_version('v3', (3, 0))
self._assert_auth_version('v3.0', (3, 0))
self._assert_auth_version('v3.1', (3, 0))
@ -2003,14 +1773,10 @@ class OtherTests(BaseAuthTokenMiddlewareTest):
self.requests_mock.get(BASE_URI, json=VERSION_LIST_v3, status_code=300)
self._assert_auth_version(None, (3, 0))
# VERSION_LIST_v2 contains only v2 version elements
self.requests_mock.get(BASE_URI, json=VERSION_LIST_v2, status_code=300)
self._assert_auth_version(None, (2, 0))
def test_unsupported_auth_version(self):
# If the requested version isn't supported we will use v2
self._assert_auth_version('v1', (2, 0))
self._assert_auth_version('v10', (2, 0))
# If the requested version isn't supported we will use v3
self._assert_auth_version('v1', (3, 0))
self._assert_auth_version('v10', (3, 0))
class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest):
@ -2020,9 +1786,7 @@ class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest):
KEYSTONE_BASE_URL = 'http://keystone.url/prefix'
CRUD_URL = 'http://crud.url/prefix'
# NOTE(jamielennox): use the /v2.0 prefix here because this is what's most
# likely to be in the service catalog and we should be able to ignore it.
KEYSTONE_URL = KEYSTONE_BASE_URL + '/v2.0'
KEYSTONE_URL = KEYSTONE_BASE_URL + '/v3'
def setUp(self):
super(AuthProtocolLoadingTests, self).setUp()

View File

@ -80,72 +80,6 @@ class BaseUserPluginTests(object):
self.assertTokenDataEqual(service_id, service, plugin.service)
class V2UserPluginTests(BaseUserPluginTests, base.BaseAuthTokenTestCase):
def setUp(self):
super(V2UserPluginTests, self).setUp()
self.service_token = fixture.V2Token()
self.service_token.set_scope()
s = self.service_token.add_service('identity', name='keystone')
s.add_endpoint(public=BASE_URI,
admin=BASE_URI,
internal=BASE_URI)
self.configure_middleware(auth_type='v2password',
auth_url='%s/v2.0/' % AUTH_URL,
user_id=self.service_token.user_id,
password=uuid.uuid4().hex,
tenant_id=self.service_token.tenant_id)
auth_discovery = fixture.DiscoveryList(href=AUTH_URL, v3=False)
self.requests_mock.get(AUTH_URL, json=auth_discovery)
base_discovery = fixture.DiscoveryList(href=BASE_URI, v3=False)
self.requests_mock.get(BASE_URI, json=base_discovery)
url = '%s/v2.0/tokens' % AUTH_URL
self.requests_mock.post(url, json=self.service_token)
def get_role_names(self, token):
return [x['name'] for x in token['access']['user'].get('roles', [])]
def get_token(self, service=False):
token = fixture.V2Token()
token.set_scope()
token.add_role()
if service:
token.add_role('service')
request_headers = {'X-Auth-Token': self.service_token.token_id}
url = '%s/v2.0/tokens/%s' % (BASE_URI, token.token_id)
self.requests_mock.get(url,
request_headers=request_headers,
json=token)
return token.token_id, token
def assertTokenDataEqual(self, token_id, token, token_data):
super(V2UserPluginTests, self).assertTokenDataEqual(token_id,
token,
token_data)
self.assertEqual(token.tenant_id, token_data.project_id)
self.assertIsNone(token_data.user_domain_id)
self.assertIsNone(token_data.project_domain_id)
def test_trust_scope(self):
token_id, token = self.get_token()
token.set_trust()
plugin = self.get_plugin(token_id)
self.assertEqual(token.trust_id, plugin.user.trust_id)
self.assertEqual(token.trustee_user_id, plugin.user.trustee_user_id)
self.assertIsNone(plugin.user.trustor_user_id)
class V3UserPluginTests(BaseUserPluginTests, base.BaseAuthTokenTestCase):
def setUp(self):

View File

@ -0,0 +1,7 @@
---
upgrade:
- |
[`bug 1845539 <https://bugs.launchpad.net/keystone/+bug/1845539>`_]
[`bug 1777177 <https://bugs.launchpad.net/keystone/+bug/1777177>`_]
keystonemiddleware no longer supports the keystone v2.0 api, all
associated functionality has been removed.