From a6a3edb80ead7fa1c4587d40461bd68e3f501fe7 Mon Sep 17 00:00:00 2001 From: Gage Hugo Date: Mon, 8 Jul 2019 10:35:05 -0500 Subject: [PATCH] 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 --- keystonemiddleware/auth_token/_identity.py | 35 +-- .../auth_token/test_auth_token_middleware.py | 256 +----------------- .../unit/auth_token/test_user_auth_plugin.py | 66 ----- ...removed-as-of-ussuri-4e1ea485ba8801c9.yaml | 7 + 4 files changed, 24 insertions(+), 340 deletions(-) create mode 100644 releasenotes/notes/removed-as-of-ussuri-4e1ea485ba8801c9.yaml diff --git a/keystonemiddleware/auth_token/_identity.py b/keystonemiddleware/auth_token/_identity.py index 49bdf9a6..53d3819e 100644 --- a/keystonemiddleware/auth_token/_identity.py +++ b/keystonemiddleware/auth_token/_identity.py @@ -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 diff --git a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py index a09d269d..8d7785e9 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py +++ b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py @@ -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() diff --git a/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py b/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py index 87499930..554b2c30 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py +++ b/keystonemiddleware/tests/unit/auth_token/test_user_auth_plugin.py @@ -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): diff --git a/releasenotes/notes/removed-as-of-ussuri-4e1ea485ba8801c9.yaml b/releasenotes/notes/removed-as-of-ussuri-4e1ea485ba8801c9.yaml new file mode 100644 index 00000000..1dafbfb8 --- /dev/null +++ b/releasenotes/notes/removed-as-of-ussuri-4e1ea485ba8801c9.yaml @@ -0,0 +1,7 @@ +--- +upgrade: + - | + [`bug 1845539 `_] + [`bug 1777177 `_] + keystonemiddleware no longer supports the keystone v2.0 api, all + associated functionality has been removed.