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

Reply via email to