git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@408 830e0280-6d2a-0410-9c65-932aecc39d9d
Michal Ludvig authored on 2010/05/20 19:30:49... | ... |
@@ -1084,19 +1084,37 @@ def cmd_setacl(args): |
1084 | 1084 |
def _update_acl(uri, seq_label = ""): |
1085 | 1085 |
acl = s3.get_acl(uri) |
1086 | 1086 |
debug(u"acl: %s - %r" % (uri, acl.grantees)) |
1087 |
- if cfg.acl_public: |
|
1087 |
+ if cfg.acl_public == True: |
|
1088 | 1088 |
if acl.isAnonRead(): |
1089 | 1089 |
info(u"%s: already Public, skipping %s" % (uri, seq_label)) |
1090 |
- return |
|
1091 |
- acl.grantAnonRead() |
|
1092 |
- else: |
|
1090 |
+ if not cfg.acl_grants and not cfg.acl_revokes: |
|
1091 |
+ return; |
|
1092 |
+ else: |
|
1093 |
+ acl.grantAnonRead() |
|
1094 |
+ elif cfg.acl_public == False: # we explicitely check for False, because it could be None |
|
1093 | 1095 |
if not acl.isAnonRead(): |
1094 | 1096 |
info(u"%s: already Private, skipping %s" % (uri, seq_label)) |
1095 |
- return |
|
1096 |
- acl.revokeAnonRead() |
|
1097 |
+ if not cfg.acl_grants and not cfg.acl_revokes: |
|
1098 |
+ return; |
|
1099 |
+ else: |
|
1100 |
+ acl.revokeAnonRead() |
|
1101 |
+ |
|
1102 |
+ # update acl with arguments |
|
1103 |
+ # grant first and revoke later, because revoke has priority |
|
1104 |
+ if cfg.acl_grants: |
|
1105 |
+ for grant in cfg.acl_grants: |
|
1106 |
+ acl.grant( **grant ); |
|
1107 |
+ |
|
1108 |
+ if cfg.acl_revokes: |
|
1109 |
+ for revoke in cfg.acl_revokes: |
|
1110 |
+ acl.revoke( **revoke ); |
|
1111 |
+ |
|
1097 | 1112 |
retsponse = s3.set_acl(uri, acl) |
1098 | 1113 |
if retsponse['status'] == 200: |
1099 |
- output(u"%s: ACL set to %s %s" % (uri, set_to_acl, seq_label)) |
|
1114 |
+ if cfg.acl_public == True or cfg.acl_public == False: |
|
1115 |
+ output(u"%s: ACL set to %s %s" % (uri, set_to_acl, seq_label)) |
|
1116 |
+ else: |
|
1117 |
+ output(u"ACL updated") |
|
1100 | 1118 |
|
1101 | 1119 |
s3 = S3(cfg) |
1102 | 1120 |
|
... | ... |
@@ -1108,7 +1126,10 @@ def cmd_setacl(args): |
1108 | 1108 |
for arg in old_args: |
1109 | 1109 |
uri = S3Uri(arg) |
1110 | 1110 |
if not uri.has_object(): |
1111 |
- info("Setting bucket-level ACL for %s to %s" % (uri.uri(), set_to_acl)) |
|
1111 |
+ if cfg.acl_public != None: |
|
1112 |
+ info("Setting bucket-level ACL for %s to %s" % (uri.uri(), set_to_acl)) |
|
1113 |
+ else: |
|
1114 |
+ info("Setting bucket-level ACL for %s" % (uri.uri())) |
|
1112 | 1115 |
if not cfg.dry_run: |
1113 | 1116 |
_update_acl(uri) |
1114 | 1117 |
else: |
... | ... |
@@ -1538,6 +1559,10 @@ def main(): |
1538 | 1538 |
optparser.add_option("-r", "--recursive", dest="recursive", action="store_true", help="Recursive upload, download or removal.") |
1539 | 1539 |
optparser.add_option("-P", "--acl-public", dest="acl_public", action="store_true", help="Store objects with ACL allowing read for anyone.") |
1540 | 1540 |
optparser.add_option( "--acl-private", dest="acl_public", action="store_false", help="Store objects with default ACL allowing access for you only.") |
1541 |
+ |
|
1542 |
+ optparser.add_option( "--acl-grant", dest="acl_grants", 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") |
|
1543 |
+ optparser.add_option( "--acl-revoke", dest="acl_revokes", 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") |
|
1544 |
+ |
|
1541 | 1545 |
optparser.add_option( "--delete-removed", dest="delete_removed", action="store_true", help="Delete remote objects with no corresponding local file [sync]") |
1542 | 1546 |
optparser.add_option( "--no-delete-removed", dest="delete_removed", action="store_false", help="Don't delete remote objects.") |
1543 | 1547 |
optparser.add_option("-p", "--preserve", dest="preserve_attrs", action="store_true", help="Preserve filesystem attributes (mode, ownership, timestamps). Default for [sync] command.") |
... | ... |
@@ -1647,6 +1672,30 @@ def main(): |
1647 | 1647 |
debug(u"Updating Config.Config extra_headers[%s] -> %s" % (key.strip(), val.strip())) |
1648 | 1648 |
cfg.extra_headers[key.strip()] = val.strip() |
1649 | 1649 |
|
1650 |
+ |
|
1651 |
+ permission_re = "(?P<PERMISSION>read(_acp)?|write(_acp)?|full_control|all)" |
|
1652 |
+ |
|
1653 |
+ if options.acl_grants: |
|
1654 |
+ r_acl_grant = re.compile( "^%s:(?P<NAME>.+)$" % permission_re, re.IGNORECASE) |
|
1655 |
+ for grant in options.acl_grants: |
|
1656 |
+ is_data = r_acl_grant.match( grant ) |
|
1657 |
+ if is_data: |
|
1658 |
+ data = is_data.groupdict() |
|
1659 |
+ cfg.acl_grants.append( {'name': data['NAME'].lower(), 'permission': data["PERMISSION"].upper()} ) |
|
1660 |
+ else: |
|
1661 |
+ warning( u"skipped invalid --acl-grant option: [%s]" % grant) |
|
1662 |
+ |
|
1663 |
+ if options.acl_revokes: |
|
1664 |
+ r_acl_revoke = re.compile( "^%s:(?P<NAME>[a-f0-9]+)$" % permission_re, re.IGNORECASE) |
|
1665 |
+ for revoke in options.acl_revokes: |
|
1666 |
+ is_data = r_acl_revoke.match( revoke ) |
|
1667 |
+ if is_data: |
|
1668 |
+ data = is_data.groupdict() |
|
1669 |
+ cfg.acl_revokes.append( {'name': data['NAME'].lower(), 'permission': data["PERMISSION"].upper()} ) |
|
1670 |
+ else: |
|
1671 |
+ warning( u"skipped invalid --acl-revoke option: [%s]" % revoke) |
|
1672 |
+ |
|
1673 |
+ |
|
1650 | 1674 |
## Update Config with other parameters |
1651 | 1675 |
for option in cfg.option_list(): |
1652 | 1676 |
try: |
... | ... |
@@ -1659,6 +1708,7 @@ def main(): |
1659 | 1659 |
|
1660 | 1660 |
## Special handling for tri-state options (True, False, None) |
1661 | 1661 |
cfg.update_option("enable", options.enable) |
1662 |
+ cfg.update_option("acl_public", options.acl_public) |
|
1662 | 1663 |
|
1663 | 1664 |
## CloudFront's cf_enable and Config's enable share the same --enable switch |
1664 | 1665 |
options.cf_enable = options.enable |