From ea66a717657c6d55f91be4ac7062a337c88023d9 Mon Sep 17 00:00:00 2001 From: Jack Danger Date: Fri, 22 Sep 2017 10:42:13 -0700 Subject: [PATCH 1/3] supporting signed urls for private keys --- moto/s3/responses.py | 6 ++++-- tests/test_s3/test_s3.py | 14 +++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/moto/s3/responses.py b/moto/s3/responses.py index 86d5dbdef..781af2e48 100755 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -548,8 +548,10 @@ class ResponseObject(_TemplateEnvironmentMixin): # header. if 'Authorization' not in request.headers: key = self.backend.get_key(bucket_name, key_name) - if key and not key.acl.public_read: - return 403, {}, "" + signed_url = 'Signature=' in request.url + if key: + if not key.acl.public_read and not signed_url: + return 403, {}, "" if hasattr(request, 'body'): # Boto diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py index 8ce56bd01..67ef17bc6 100644 --- a/tests/test_s3/test_s3.py +++ b/tests/test_s3/test_s3.py @@ -875,15 +875,19 @@ def test_s3_object_in_public_bucket(): s3_anonymous = boto3.resource('s3') s3_anonymous.meta.client.meta.events.register('choose-signer.s3.*', disable_signing) - contents = s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get()['Body'].read() - contents.should.equal(b'ABCD') + # contents = s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get()['Body'].read() + # contents.should.equal(b'ABCD') bucket.put_object(ACL='private', Body=b'ABCD', Key='file.txt') - with assert_raises(ClientError) as exc: - s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get() - exc.exception.response['Error']['Code'].should.equal('403') + # with assert_raises(ClientError) as exc: + # s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get() + # exc.exception.response['Error']['Code'].should.equal('403') + params = {'Bucket': 'test-bucket','Key': 'file.txt'} + presigned_url = boto3.client('s3').generate_presigned_url('get_object', params, ExpiresIn=900) + response = requests.get(presigned_url) + assert response.status_code == 200 @mock_s3 def test_s3_object_in_private_bucket(): From 390fe8513748bab74a4f6c3e556048f9abef000b Mon Sep 17 00:00:00 2001 From: Jack Danger Date: Fri, 22 Sep 2017 10:44:55 -0700 Subject: [PATCH 2/3] supporting httpretty requests --- moto/s3/responses.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/moto/s3/responses.py b/moto/s3/responses.py index 781af2e48..d340d16e4 100755 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -547,8 +547,12 @@ class ResponseObject(_TemplateEnvironmentMixin): # ACL and checking for the mere presence of an Authorization # header. if 'Authorization' not in request.headers: + if hasattr(request, 'url'): + signed_url = 'Signature=' in request.url + elif hasattr(request, 'requestline'): + signed_url = 'Signature=' in request.path key = self.backend.get_key(bucket_name, key_name) - signed_url = 'Signature=' in request.url + if key: if not key.acl.public_read and not signed_url: return 403, {}, "" From eeda0cd28edc472a73443fb6cdf00354760bc6ef Mon Sep 17 00:00:00 2001 From: Jack Danger Date: Fri, 22 Sep 2017 10:57:06 -0700 Subject: [PATCH 3/3] re-enabling tests --- tests/test_s3/test_s3.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py index 67ef17bc6..cb40edb33 100644 --- a/tests/test_s3/test_s3.py +++ b/tests/test_s3/test_s3.py @@ -875,14 +875,14 @@ def test_s3_object_in_public_bucket(): s3_anonymous = boto3.resource('s3') s3_anonymous.meta.client.meta.events.register('choose-signer.s3.*', disable_signing) - # contents = s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get()['Body'].read() - # contents.should.equal(b'ABCD') + contents = s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get()['Body'].read() + contents.should.equal(b'ABCD') bucket.put_object(ACL='private', Body=b'ABCD', Key='file.txt') - # with assert_raises(ClientError) as exc: - # s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get() - # exc.exception.response['Error']['Code'].should.equal('403') + with assert_raises(ClientError) as exc: + s3_anonymous.Object(key='file.txt', bucket_name='test-bucket').get() + exc.exception.response['Error']['Code'].should.equal('403') params = {'Bucket': 'test-bucket','Key': 'file.txt'} presigned_url = boto3.client('s3').generate_presigned_url('get_object', params, ExpiresIn=900)