S3: Bucket policy
This commit is contained in:
parent
3a81982cce
commit
dc0557205d
@ -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)
|
||||||
|
@ -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>
|
||||||
|
"""
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user