From 95799b99bc5a31f112b1b493a628a877ee652219 Mon Sep 17 00:00:00 2001 From: acsbendi Date: Tue, 16 Jul 2019 16:27:50 +0200 Subject: [PATCH] Fixed incorrect authentication error handling in S3. --- moto/s3/responses.py | 109 ++++++++++++------------------------------- 1 file changed, 30 insertions(+), 79 deletions(-) diff --git a/moto/s3/responses.py b/moto/s3/responses.py index a052e4cfb..e868b24be 100644 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import re import six -from werkzeug.exceptions import HTTPException from moto.core.utils import str_to_rfc_1123_datetime from six.moves.urllib.parse import parse_qs, urlparse, unquote @@ -119,13 +118,10 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): def should_autoescape(self): return True - def all_buckets(self, headers): - try: - self.data["Action"] = "ListAllMyBuckets" - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + def all_buckets(self): + self.data["Action"] = "ListAllMyBuckets" + self._authenticate_s3_action() + # No bucket specified. Listing all buckets all_buckets = self.backend.get_all_buckets() template = self.response_template(S3_ALL_BUCKETS) @@ -219,7 +215,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): bucket_name = self.parse_bucket_name_from_url(request, full_url) if not bucket_name: # If no bucket specified, list all buckets - return self.all_buckets(headers) + return self.all_buckets() self.data["BucketName"] = bucket_name @@ -236,15 +232,15 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): body = u'{0}'.format(body).encode('utf-8') if method == 'HEAD': - return self._bucket_response_head(bucket_name, headers) + return self._bucket_response_head(bucket_name) elif method == 'GET': - return self._bucket_response_get(bucket_name, querystring, headers) + return self._bucket_response_get(bucket_name, querystring) elif method == 'PUT': - return self._bucket_response_put(request, body, region_name, bucket_name, querystring, headers) + return self._bucket_response_put(request, body, region_name, bucket_name, querystring) elif method == 'DELETE': - return self._bucket_response_delete(body, bucket_name, querystring, headers) + return self._bucket_response_delete(body, bucket_name, querystring) elif method == 'POST': - return self._bucket_response_post(request, body, bucket_name, headers) + return self._bucket_response_post(request, body, bucket_name) else: raise NotImplementedError( "Method {0} has not been impelemented in the S3 backend yet".format(method)) @@ -255,7 +251,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): querystring = parse_qs(parsed_url.query, keep_blank_values=True) return querystring - def _bucket_response_head(self, bucket_name, headers): + def _bucket_response_head(self, bucket_name): try: self.backend.get_bucket(bucket_name) except MissingBucket: @@ -266,14 +262,9 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): return 404, {}, "" return 200, {}, "" - def _bucket_response_get(self, bucket_name, querystring, headers): + def _bucket_response_get(self, bucket_name, querystring): self._set_action("BUCKET", "GET", querystring) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() if 'uploads' in querystring: for unsup in ('delimiter', 'max-uploads'): @@ -502,17 +493,12 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): next_continuation_token = None return result_keys, is_truncated, next_continuation_token - def _bucket_response_put(self, request, body, region_name, bucket_name, querystring, headers): + def _bucket_response_put(self, request, body, region_name, bucket_name, querystring): if not request.headers.get('Content-Length'): return 411, {}, "Content-Length required" self._set_action("BUCKET", "PUT", querystring) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() if 'versioning' in querystring: ver = re.search('([A-Za-z]+)', body.decode()) @@ -612,14 +598,9 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): template = self.response_template(S3_BUCKET_CREATE_RESPONSE) return 200, {}, template.render(bucket=new_bucket) - def _bucket_response_delete(self, body, bucket_name, querystring, headers): + def _bucket_response_delete(self, body, bucket_name, querystring): self._set_action("BUCKET", "DELETE", querystring) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() if 'policy' in querystring: self.backend.delete_bucket_policy(bucket_name, body) @@ -647,7 +628,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): S3_DELETE_BUCKET_WITH_ITEMS_ERROR) return 409, {}, template.render(bucket=removed_bucket) - def _bucket_response_post(self, request, body, bucket_name, headers): + def _bucket_response_post(self, request, body, bucket_name): if not request.headers.get('Content-Length'): return 411, {}, "Content-Length required" @@ -655,22 +636,12 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): if self.is_delete_keys(request, path, bucket_name): self.data["Action"] = "DeleteObject" + self._authenticate_s3_action() - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) - - return self._bucket_response_delete_keys(request, body, bucket_name, headers) + return self._bucket_response_delete_keys(request, body, bucket_name) self.data["Action"] = "PutObject" - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() # POST to bucket-url should create file from form if hasattr(request, 'form'): @@ -707,7 +678,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): path = request.full_path if hasattr(request, 'full_path') else path_url(request.url) return path - def _bucket_response_delete_keys(self, request, body, bucket_name, headers): + def _bucket_response_delete_keys(self, request, body, bucket_name): template = self.response_template(S3_DELETE_KEYS_RESPONSE) keys = minidom.parseString(body).getElementsByTagName('Key') @@ -813,21 +784,16 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): elif method == 'HEAD': return self._key_response_head(bucket_name, query, key_name, headers=request.headers) elif method == 'DELETE': - return self._key_response_delete(bucket_name, query, key_name, headers) + return self._key_response_delete(bucket_name, query, key_name) elif method == 'POST': - return self._key_response_post(request, body, bucket_name, query, key_name, headers) + return self._key_response_post(request, body, bucket_name, query, key_name) else: raise NotImplementedError( "Method {0} has not been implemented in the S3 backend yet".format(method)) def _key_response_get(self, bucket_name, query, key_name, headers): self._set_action("KEY", "GET", query) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() response_headers = {} if query.get('uploadId'): @@ -864,12 +830,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): def _key_response_put(self, request, body, bucket_name, query, key_name, headers): self._set_action("KEY", "PUT", query) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() response_headers = {} if query.get('uploadId') and query.get('partNumber'): @@ -1237,14 +1198,9 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): config = parsed_xml['AccelerateConfiguration'] return config['Status'] - def _key_response_delete(self, bucket_name, query, key_name, headers): + def _key_response_delete(self, bucket_name, query, key_name): self._set_action("KEY", "DELETE", query) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() if query.get('uploadId'): upload_id = query['uploadId'][0] @@ -1265,14 +1221,9 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin): raise InvalidPartOrder() yield (pn, p.getElementsByTagName('ETag')[0].firstChild.wholeText) - def _key_response_post(self, request, body, bucket_name, query, key_name, headers): + def _key_response_post(self, request, body, bucket_name, query, key_name): self._set_action("KEY", "POST", query) - - try: - self._authenticate_s3_action() - except HTTPException as http_error: - response = http_error.code, headers, http_error.description - return self._send_response(response) + self._authenticate_s3_action() if body == b'' and 'uploads' in query: metadata = metadata_from_headers(request.headers)