Hi there,
I don't think s3cmd lets you set public-read-write on buckets. Probably for
a good reason, it is generally not a good idea :)
I have attached a quick patch against the latest s3cmd HEAD that should let
you do this. I tested it quickly, so use at your own risk :)
If you set the acl back to --acl-private, it will remove anonymous read as
well as write.
Hope that helps.
neil
On Wed, Dec 4, 2013 at 2:31 AM, Gavin Huang <[email protected]> wrote:
> Hi, all
> I'm wondering is there any way to make a bucket in Riak-CS "public-write"?
> i tried to call s3cmd:
> s3cmd setacl --acl-public s3://test-bucket/
>
> but it only make bucket's read public:
> s3cmd info s3://test-bucket
>
> Location: any
> ACL: foobar: FULL_CONTROL
> ACL: *anon*: READ
> URL: http://test-bucket.s3.amazonaws.com/
>
>
> Thanks.
> Gavin
>
> _______________________________________________
> riak-users mailing list
> [email protected]
> http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com
>
>
diff --git a/S3/ACL.py b/S3/ACL.py
index 2408d06..8c03321 100644
--- a/S3/ACL.py
+++ b/S3/ACL.py
@@ -34,6 +34,9 @@ class Grantee(object):
def isAnonRead(self):
return self.isAllUsers() and (self.permission == "READ" or self.permission == "FULL_CONTROL")
+ def isAnonWrite(self):
+ return self.isAllUsers() and (self.permission == "WRITE" or self.permission == "FULL_CONTROL")
+
def getElement(self):
el = ET.Element("Grant")
grantee = ET.SubElement(el, "Grantee", {
@@ -54,6 +57,14 @@ class GranteeAnonRead(Grantee):
self.name = Grantee.ALL_USERS_URI
self.permission = "READ"
+class GranteeAnonWrite(Grantee):
+ def __init__(self):
+ Grantee.__init__(self)
+ self.xsi_type = "Group"
+ self.tag = "URI"
+ self.name = Grantee.ALL_USERS_URI
+ self.permission = "WRITE"
+
class GranteeLogDelivery(Grantee):
def __init__(self, permission):
"""
@@ -119,13 +130,26 @@ class ACL(object):
return True
return False
+ def isAnonWrite(self):
+ for grantee in self.grantees:
+ if grantee.isAnonWrite():
+ return True
+ return False
+
def grantAnonRead(self):
if not self.isAnonRead():
self.appendGrantee(GranteeAnonRead())
+ def grantAnonWrite(self):
+ if not self.isAnonWrite():
+ self.appendGrantee(GranteeAnonWrite())
+
def revokeAnonRead(self):
self.grantees = [g for g in self.grantees if not g.isAnonRead()]
+ def revokeAnonWrite(self):
+ self.grantees = [g for g in self.grantees if not g.isAnonWrite()]
+
def appendGrantee(self, grantee):
self.grantees.append(grantee)
diff --git a/S3/Config.py b/S3/Config.py
index c8dc99a..f9b3732 100644
--- a/S3/Config.py
+++ b/S3/Config.py
@@ -44,6 +44,7 @@ class Config(object):
skip_existing = False
recursive = False
acl_public = None
+ acl_public_read_write = None
acl_grants = []
acl_revokes = []
proxy_host = ""
diff --git a/S3/S3.py b/S3/S3.py
index 74e359e..b93443e 100644
--- a/S3/S3.py
+++ b/S3/S3.py
@@ -287,6 +287,8 @@ class S3(object):
check_bucket_name(bucket, dns_strict = False)
if self.config.acl_public:
headers["x-amz-acl"] = "public-read"
+ if self.config.acl_public_read_write:
+ headers["x-amz-acl"] = "public-read-write"
request = self.create_request("BUCKET_CREATE", bucket = bucket, headers = headers)
response = self.send_request(request, body)
return response
@@ -427,6 +429,8 @@ class S3(object):
## Other Amazon S3 attributes
if self.config.acl_public:
headers["x-amz-acl"] = "public-read"
+ if self.config.acl_public_read_write:
+ headers["x-amz-acl"] = "public-read-write"
if self.config.reduced_redundancy:
headers["x-amz-storage-class"] = "REDUCED_REDUNDANCY"
@@ -499,6 +503,8 @@ class S3(object):
headers['x-amz-metadata-directive'] = "COPY"
if self.config.acl_public:
headers["x-amz-acl"] = "public-read"
+ if self.config.acl_public_read_write:
+ headers["x-amz-acl"] = "public-read-write"
if self.config.reduced_redundancy:
headers["x-amz-storage-class"] = "REDUCED_REDUNDANCY"
# if extra_headers:
diff --git a/s3cmd b/s3cmd
index 2e58604..26609c5 100755
--- a/s3cmd
+++ b/s3cmd
@@ -345,7 +345,7 @@ def cmd_object_put(args):
output(u"File '%s' stored as '%s' (%d bytes in %0.1f seconds, %0.2f %sB/s) %s" %
(unicodise(full_name_orig), uri_final, response["size"], response["elapsed"],
speed_fmt[0], speed_fmt[1], seq_label))
- if Config().acl_public:
+ if Config().acl_public or Config().acl_public_read_write:
output(u"Public URL of the object is: %s" %
(uri_final.public_url()))
if Config().encrypt and full_name != full_name_orig:
@@ -588,7 +588,7 @@ def subcmd_cp_mv(args, process_fce, action_str, message):
try:
response = process_fce(src_uri, dst_uri, extra_headers)
output(message % { "src" : src_uri, "dst" : dst_uri })
- if Config().acl_public:
+ if Config().acl_public or Config().acl_public_read_write:
info(u"Public URL is: %s" % dst_uri.public_url())
except S3Error, e:
if cfg.ignore_failed_copy and e.code == "NoSuchKey":
@@ -1810,7 +1810,24 @@ def update_acl(s3, uri, seq_label=""):
else:
acl.revokeAnonRead()
something_changed = True
+ if not acl.isAnonWrite():
+ info(u"%s: already Private, skipping %s" % (uri, seq_label))
+ else:
+ acl.revokeAnonWrite()
+ something_changed = True
+ elif cfg.acl_public_read_write == True:
+ if acl.isAnonRead():
+ info(u"%s: already Public Read, skipping %s" % (uri, seq_label))
+ else:
+ acl.grantAnonRead()
+ something_changed = True
+ if acl.isAnonWrite():
+ info(u"%s: already Public Write, skipping %s" % (uri, seq_label))
+ else:
+ acl.grantAnonWrite()
+ something_changed = True
+
# update acl with arguments
# grant first and revoke later, because revoke has priority
if cfg.acl_grants:
@@ -1915,6 +1932,7 @@ def main():
optparser.add_option( "--no-check-md5", dest="check_md5", action="store_false", help="Do not check MD5 sums when comparing files for [sync]. Only size will be compared. May significantly speed up transfer but may also miss some changed files.")
optparser.add_option("-P", "--acl-public", dest="acl_public", action="store_true", help="Store objects with ACL allowing read for anyone.")
optparser.add_option( "--acl-private", dest="acl_public", action="store_false", help="Store objects with default ACL allowing access for you only.")
+ optparser.add_option( "--acl-public-read-write", dest="acl_public_read_write", action="store_true", help="Store objects with ACL allowing read/write for anyone.")
optparser.add_option( "--acl-grant", dest="acl_grants", type="s3acl", action="append", metavar="PERMISSION:EMAIL or USER_CANONICAL_ID", help="Grant stated permission to a given amazon user. Permission is one of: read, write, read_acp, write_acp, full_control, all")
optparser.add_option( "--acl-revoke", dest="acl_revokes", type="s3acl", action="append", metavar="PERMISSION:USER_CANONICAL_ID", help="Revoke stated permission for a given amazon user. Permission is one of: read, write, read_acp, wr ite_acp, full_control, all")
@@ -2098,6 +2116,7 @@ def main():
## Special handling for tri-state options (True, False, None)
cfg.update_option("enable", options.enable)
cfg.update_option("acl_public", options.acl_public)
+ cfg.update_option("acl_public_read_write", options.acl_public_read_write)
## Check multipart chunk constraints
if cfg.multipart_chunk_size_mb < MultiPartUpload.MIN_CHUNK_SIZE_MB:
_______________________________________________
riak-users mailing list
[email protected]
http://lists.basho.com/mailman/listinfo/riak-users_lists.basho.com