S3: Bucket policy

This commit is contained in:
Simon-Pierre Gingras 2015-07-23 17:33:52 -04:00
parent 3a81982cce
commit dc0557205d
3 changed files with 72 additions and 0 deletions

View File

@ -184,6 +184,7 @@ class FakeBucket(object):
self.multiparts = {} self.multiparts = {}
self.versioning_status = None self.versioning_status = None
self.rules = [] self.rules = []
self.policy = None
@property @property
def location(self): def location(self):
@ -269,6 +270,12 @@ class S3Backend(BaseBackend):
return itertools.chain(*(l for _, l in bucket.keys.iterlists())) return itertools.chain(*(l for _, l in bucket.keys.iterlists()))
def get_bucket_policy(self, bucket_name):
return self.get_bucket(bucket_name).policy
def set_bucket_policy(self, bucket_name, policy):
self.get_bucket(bucket_name).policy = policy
def set_bucket_lifecycle(self, bucket_name, rules): def set_bucket_lifecycle(self, bucket_name, rules):
bucket = self.get_bucket(bucket_name) bucket = self.get_bucket(bucket_name)
bucket.set_lifecycle(rules) bucket.set_lifecycle(rules)

View File

@ -103,6 +103,12 @@ class ResponseObject(_TemplateEnvironmentMixin):
versioning = self.backend.get_bucket_versioning(bucket_name) versioning = self.backend.get_bucket_versioning(bucket_name)
template = self.response_template(S3_BUCKET_GET_VERSIONING) template = self.response_template(S3_BUCKET_GET_VERSIONING)
return 200, headers, template.render(status=versioning) return 200, headers, template.render(status=versioning)
elif 'policy' in querystring:
policy = self.backend.get_bucket_policy(bucket_name)
if not policy:
template = self.response_template(S3_NO_POLICY)
return 404, headers, template.render(bucket_name=bucket_name)
return 200, headers, policy
elif 'versions' in querystring: elif 'versions' in querystring:
delimiter = querystring.get('delimiter', [None])[0] delimiter = querystring.get('delimiter', [None])[0]
encoding_type = querystring.get('encoding-type', [None])[0] encoding_type = querystring.get('encoding-type', [None])[0]
@ -167,6 +173,9 @@ class ResponseObject(_TemplateEnvironmentMixin):
rules = [rules] rules = [rules]
self.backend.set_bucket_lifecycle(bucket_name, rules) self.backend.set_bucket_lifecycle(bucket_name, rules)
return "" return ""
elif 'policy' in querystring:
self.backend.set_bucket_policy(bucket_name, body)
return 'True'
else: else:
try: try:
new_bucket = self.backend.create_bucket(bucket_name, region_name) new_bucket = self.backend.create_bucket(bucket_name, region_name)
@ -706,3 +715,13 @@ S3_ALL_MULTIPARTS = """<?xml version="1.0" encoding="UTF-8"?>
{% endfor %} {% endfor %}
</ListMultipartUploadsResult> </ListMultipartUploadsResult>
""" """
S3_NO_POLICY = """<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>NoSuchBucketPolicy</Code>
<Message>The bucket policy does not exist</Message>
<BucketName>{{ bucket_name }}</BucketName>
<RequestId>0D68A23BB2E2215B</RequestId>
<HostId>9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg=</HostId>
</Error>
"""

View File

@ -6,6 +6,7 @@ from six.moves.urllib.error import HTTPError
from functools import wraps from functools import wraps
from io import BytesIO from io import BytesIO
import json
import boto import boto
from boto.exception import S3CreateError, S3ResponseError from boto.exception import S3CreateError, S3ResponseError
from boto.s3.connection import S3Connection from boto.s3.connection import S3Connection
@ -823,3 +824,48 @@ def test_ranged_get():
key.get_contents_as_string(headers={'Range': 'bytes=-700'}).should.equal(rep * 10) key.get_contents_as_string(headers={'Range': 'bytes=-700'}).should.equal(rep * 10)
key.size.should.equal(100) key.size.should.equal(100)
@mock_s3
def test_policy():
conn = boto.connect_s3()
bucket_name = 'mybucket'
bucket = conn.create_bucket(bucket_name)
policy = json.dumps({
"Version": "2012-10-17",
"Id": "PutObjPolicy",
"Statement": [
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::{bucket_name}/*".format(bucket_name=bucket_name),
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}
]
})
with assert_raises(S3ResponseError) as err:
bucket.get_policy()
ex = err.exception
ex.box_usage.should.be.none
ex.error_code.should.equal('NoSuchBucketPolicy')
ex.message.should.equal('The bucket policy does not exist')
ex.reason.should.equal('Not Found')
ex.resource.should.be.none
ex.status.should.equal(404)
ex.body.should.contain(bucket_name)
ex.request_id.should_not.be.none
bucket.set_policy(policy).should.be.true
bucket = conn.get_bucket(bucket_name)
bucket.get_policy().decode('utf-8').should.equal(policy)