diff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py index d976783e5a..d796475c98 100644 --- a/swift/common/middleware/s3api/s3request.py +++ b/swift/common/middleware/s3api/s3request.py @@ -491,15 +491,6 @@ class S3Request(swob.Request): self.user_id = None self.slo_enabled = slo_enabled - # NOTE(andrey-mp): substitute authorization header for next modules - # in pipeline (s3token). it uses this and X-Auth-Token in specific - # format. - # (kota_): yeah, the reason we need this is s3token only supports - # v2 like header consists of AWS access:signature. Since the commit - # b626a3ca86e467fc7564eac236b9ee2efd49bdcc, the s3token is in swift3 - # repo so probably we need to change s3token to support v4 format. - self.headers['Authorization'] = 'AWS %s:%s' % ( - self.access_key, self.signature) # Avoids that swift.swob.Response replaces Location header value # by full URL when absolute path given. See swift.swob for more detail. self.environ['swift.leave_relative_location'] = True @@ -1460,7 +1451,6 @@ class S3AclRequest(S3Request): # Need to skip S3 authorization on subsequent requests to prevent # overwriting the account in PATH_INFO - del self.headers['Authorization'] del self.environ['s3api.auth_details'] def to_swift_req(self, method, container, obj, query=None, diff --git a/test/unit/common/middleware/s3api/__init__.py b/test/unit/common/middleware/s3api/__init__.py index c7d6e18663..e11d0fdc85 100644 --- a/test/unit/common/middleware/s3api/__init__.py +++ b/test/unit/common/middleware/s3api/__init__.py @@ -38,15 +38,14 @@ class FakeApp(object): E.g. '/v1/test:tester/bucket/object' will become '/v1/AUTH_test/bucket/object'. This method emulates the behavior. """ - _, authorization = env['HTTP_AUTHORIZATION'].split(' ') - tenant_user, sign = authorization.rsplit(':', 1) + tenant_user = env['s3api.auth_details']['access_key'] tenant, user = tenant_user.rsplit(':', 1) path = env['PATH_INFO'] env['PATH_INFO'] = path.replace(tenant_user, 'AUTH_' + tenant) def __call__(self, env, start_response): - if 'HTTP_AUTHORIZATION' in env: + if 's3api.auth_details' in env: self._update_s3_path_info(env) return self.swift(env, start_response) diff --git a/test/unit/common/middleware/s3api/helpers.py b/test/unit/common/middleware/s3api/helpers.py index f10b98e7fc..65795f4fa8 100644 --- a/test/unit/common/middleware/s3api/helpers.py +++ b/test/unit/common/middleware/s3api/helpers.py @@ -41,11 +41,10 @@ class FakeSwift(object): if 'swift.authorize_override' in env: return - if 'HTTP_AUTHORIZATION' not in env: + if 's3api.auth_details' not in env: return - _, authorization = env['HTTP_AUTHORIZATION'].split(' ') - tenant_user, sign = authorization.rsplit(':', 1) + tenant_user = env['s3api.auth_details']['access_key'] tenant, user = tenant_user.rsplit(':', 1) path = env['PATH_INFO'] diff --git a/test/unit/common/middleware/s3api/test_obj.py b/test/unit/common/middleware/s3api/test_obj.py index ef7bb839ca..00126ac23f 100644 --- a/test/unit/common/middleware/s3api/test_obj.py +++ b/test/unit/common/middleware/s3api/test_obj.py @@ -30,27 +30,6 @@ from swift.common.middleware.s3api.subresource import ACL, User, encode_acl, \ Owner, Grant from swift.common.middleware.s3api.etree import fromstring from swift.common.middleware.s3api.utils import mktime, S3Timestamp -from test.unit.common.middleware.s3api.helpers import FakeSwift - - -def _wrap_fake_auth_middleware(org_func): - def fake_fake_auth_middleware(self, env): - org_func(env) - - if 'swift.authorize_override' in env: - return - - if 'HTTP_AUTHORIZATION' not in env: - return - - _, authorization = env['HTTP_AUTHORIZATION'].split(' ') - tenant_user, sign = authorization.rsplit(':', 1) - tenant, user = tenant_user.rsplit(':', 1) - - env['HTTP_X_TENANT_NAME'] = tenant - env['HTTP_X_USER_NAME'] = user - - return fake_fake_auth_middleware class TestS3ApiObj(S3ApiTestCase): @@ -320,15 +299,20 @@ class TestS3ApiObj(S3ApiTestCase): @s3acl(s3acl_only=True) def test_object_GET_with_s3acl_and_keystone(self): # for passing keystone authentication root - fake_auth = self.swift._fake_auth_middleware - with patch.object(FakeSwift, '_fake_auth_middleware', - _wrap_fake_auth_middleware(fake_auth)): + orig_auth = self.swift._fake_auth_middleware + calls = [] + def wrapped_auth(env): + calls.append((env['REQUEST_METHOD'], 's3api.auth_details' in env)) + orig_auth(env) + + with patch.object(self.swift, '_fake_auth_middleware', wrapped_auth): self._test_object_GETorHEAD('GET') - _, _, headers = self.swift.calls_with_headers[-1] - self.assertNotIn('Authorization', headers) - _, _, headers = self.swift.calls_with_headers[0] - self.assertNotIn('Authorization', headers) + self.assertEqual(calls, [ + ('TEST', True), + ('HEAD', False), + ('GET', False), + ]) @s3acl def test_object_GET_Range(self): diff --git a/test/unit/common/middleware/s3api/test_s3api.py b/test/unit/common/middleware/s3api/test_s3api.py index 56afccb57a..cae193318e 100644 --- a/test/unit/common/middleware/s3api/test_s3api.py +++ b/test/unit/common/middleware/s3api/test_s3api.py @@ -267,8 +267,8 @@ class TestS3ApiMiddleware(S3ApiTestCase): req.content_type = 'text/plain' status, headers, body = self.call_s3api(req) self.assertEqual(status.split()[0], '200') - for _, _, headers in self.swift.calls_with_headers: - self.assertEqual(headers['Authorization'], 'AWS test:tester:X') + for _, path, headers in self.swift.calls_with_headers: + self.assertNotIn('Authorization', headers) def test_signed_urls_no_timestamp(self): expire = '2147483647' # 19 Jan 2038 03:14:07 @@ -281,7 +281,7 @@ class TestS3ApiMiddleware(S3ApiTestCase): # for signed_url access and it also doesn't check timestamp self.assertEqual(status.split()[0], '200') for _, _, headers in self.swift.calls_with_headers: - self.assertEqual(headers['Authorization'], 'AWS test:tester:X') + self.assertNotIn('Authorization', headers) def test_signed_urls_invalid_expire(self): expire = 'invalid' @@ -332,8 +332,8 @@ class TestS3ApiMiddleware(S3ApiTestCase): status, headers, body = self.call_s3api(req) self.assertEqual(status.split()[0], '200', body) for _, _, headers in self.swift.calls_with_headers: - self.assertEqual('AWS test:tester:X', headers['Authorization']) - self.assertIn('X-Auth-Token', headers) + self.assertNotIn('Authorization', headers) + self.assertIsNone(headers['X-Auth-Token']) def test_signed_urls_v4_bad_credential(self): def test(credential, message, extra=''): @@ -740,12 +740,14 @@ class TestS3ApiMiddleware(S3ApiTestCase): def test_signature_v4(self): environ = { 'REQUEST_METHOD': 'GET'} + authz_header = 'AWS4-HMAC-SHA256 ' + ', '.join([ + 'Credential=test:tester/%s/us-east-1/s3/aws4_request' % + self.get_v4_amz_date_header().split('T', 1)[0], + 'SignedHeaders=host;x-amz-date', + 'Signature=X', + ]) headers = { - 'Authorization': - 'AWS4-HMAC-SHA256 ' - 'Credential=test:tester/%s/us-east-1/s3/aws4_request, ' - 'SignedHeaders=host;x-amz-date,' - 'Signature=X' % self.get_v4_amz_date_header().split('T', 1)[0], + 'Authorization': authz_header, 'X-Amz-Date': self.get_v4_amz_date_header(), 'X-Amz-Content-SHA256': '0123456789'} req = Request.blank('/bucket/object', environ=environ, headers=headers) @@ -753,8 +755,8 @@ class TestS3ApiMiddleware(S3ApiTestCase): status, headers, body = self.call_s3api(req) self.assertEqual(status.split()[0], '200', body) for _, _, headers in self.swift.calls_with_headers: - self.assertEqual('AWS test:tester:X', headers['Authorization']) - self.assertIn('X-Auth-Token', headers) + self.assertEqual(authz_header, headers['Authorization']) + self.assertIsNone(headers['X-Auth-Token']) def test_signature_v4_no_date(self): environ = { diff --git a/test/unit/common/middleware/s3api/test_s3request.py b/test/unit/common/middleware/s3api/test_s3request.py index a9ea7fee69..51c0e5b589 100644 --- a/test/unit/common/middleware/s3api/test_s3request.py +++ b/test/unit/common/middleware/s3api/test_s3request.py @@ -246,8 +246,6 @@ class TestRequest(S3ApiTestCase): m_swift_resp.return_value = FakeSwiftResponse() s3_req = S3AclRequest(req.environ, MagicMock()) self.assertNotIn('s3api.auth_details', s3_req.environ) - self.assertNotIn('HTTP_AUTHORIZATION', s3_req.environ) - self.assertNotIn('Authorization', s3_req.headers) self.assertEqual(s3_req.token, 'token') def test_to_swift_req_Authorization_not_exist_in_swreq(self): @@ -265,8 +263,6 @@ class TestRequest(S3ApiTestCase): s3_req = S3AclRequest(req.environ, MagicMock()) sw_req = s3_req.to_swift_req(method, container, obj) self.assertNotIn('s3api.auth_details', sw_req.environ) - self.assertNotIn('HTTP_AUTHORIZATION', sw_req.environ) - self.assertNotIn('Authorization', sw_req.headers) self.assertEqual(sw_req.headers['X-Auth-Token'], 'token') def test_to_swift_req_subrequest_proxy_access_log(self):