
    #_                     f   S r SSKJr  SSKJr  SSKJr  SSKJr  SSKrSSKJr  SSK	J
r
  SS	K	Jr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJ r   SSKJ!r!  SSK"J#r$  SSK%J&r&  SSK'J(r(  SSK)J*r*  SSK+J,r,  SSK+J-r-  Sr.S r/S!r0S"r1S#r2S$r3\.\/Ri                  S%5      -   \0Ri                  S%5      -   S&-   r5S'S%Rm                  \1\2\3/5      -   r7\" \5\75      r8\" \/\15      r9\" \.\25      r:\" \0\35      r;S( r<S,S) jr= " S* S+\5      r>g)-z:Implementation of acl command for cloud storage providers.    )absolute_import)print_function)division)unicode_literalsN)encoding)metrics)gcs_json_api)AccessDeniedException)BadRequestException)PreconditionException)Preconditions)ServiceException)Command)SetAclExceptionHandler)SetAclFuncWrapper)CommandArgument)ApiSelector)CommandException)CreateHelpText)StorageUrlFromString)UrlsAreForSingleProvider))RaiseErrorIfUrlsAreMixOfBucketsAndObjects)storage_v1_messages)
acl_helper)NO_MAX)Retry)GcloudStorageFlag)GcloudStorageMapzG
  gsutil acl set [-f] [-r] [-a] (<file-path>|<predefined-acl>) url...
z
  gsutil acl get url
aK  
  gsutil acl ch [-f] [-r] <grant>... url...

  where each <grant> is one of the following forms:

    -u <id>|<email>:<permission>
    -g <id>|<email>|<domain>|All|AllAuth:<permission>
    -p (viewers|editors|owners)-<project number>:<permission>
    -d <id>|<email>|<domain>|All|AllAuth|(viewers|editors|owners)-<project number>
z
<B>GET</B>
  The ``acl get`` command gets the ACL text for a bucket or object, which you
  can save and edit for the acl set command.
aU	  
<B>SET</B>
  The ``acl set`` command allows you to set an Access Control List on one or
  more buckets and objects. As part of the command, you must specify either a
  predefined ACL or the path to a file that contains ACL text. The simplest way
  to use the ``acl set`` command is to specify one of the predefined ACLs,
  e.g.,:

    gsutil acl set private gs://example-bucket/example-object

  If you want to make an object or bucket publicly readable or writable, it is
  recommended to use ``acl ch``, to avoid accidentally removing OWNER
  permissions. See the ``acl ch`` section for details.

  See `Predefined ACLs
  <https://cloud.google.com/storage/docs/access-control/lists#predefined-acl>`_
  for a list of predefined ACLs.

  If you want to define more fine-grained control over your data, you can
  retrieve an ACL using the ``acl get`` command, save the output to a file, edit
  the file, and then use the ``acl set`` command to set that ACL on the buckets
  and/or objects. For example:

    gsutil acl get gs://bucket/file.txt > acl.txt

  Make changes to acl.txt such as adding an additional grant, then:

    gsutil acl set acl.txt gs://cats/file.txt

  Note that you can set an ACL on multiple buckets or objects at once. For
  example, to set ACLs on all .jpg files found in a bucket:

    gsutil acl set acl.txt gs://bucket/**.jpg

  If you have a large number of ACLs to update you might want to use the
  gsutil -m option, to perform a parallel (multi-threaded/multi-processing)
  update:

    gsutil -m acl set acl.txt gs://bucket/**.jpg

  Note that multi-threading/multi-processing is only done when the named URLs
  refer to objects, which happens either if you name specific objects or
  if you enumerate objects by using an object wildcard or specifying
  the acl -r flag.


<B>SET OPTIONS</B>
  The "set" sub-command has the following options

  -R, -r      Performs "acl set" request recursively, to all objects under
              the specified URL.

  -a          Performs "acl set" request on all object versions.

  -f          Normally gsutil stops at the first error. The -f option causes
              it to continue when it encounters errors. If some of the ACLs
              couldn't be set, gsutil's exit status will be non-zero even if
              this flag is set. This option is implicitly set when running
              "gsutil -m acl...".
a  
<B>CH</B>
  The "acl ch" (or "acl change") command updates access control lists, similar
  in spirit to the Linux chmod command. You can specify multiple access grant
  additions and deletions in a single command run; all changes will be made
  atomically to each object in turn. For example, if the command requests
  deleting one grant and adding a different grant, the ACLs being updated will
  never be left in an intermediate state where one grant has been deleted but
  the second grant not yet added. Each change specifies a user or group grant
  to add or delete, and for grant additions, one of R, W, O (for the
  permission to be granted). A more formal description is provided in a later
  section; below we provide examples.

<B>CH EXAMPLES</B>
  Examples for "ch" sub-command:

  Grant anyone on the internet READ access to the object example-object:

    gsutil acl ch -u allUsers:R gs://example-bucket/example-object

  NOTE: By default, publicly readable objects are served with a Cache-Control
  header allowing such objects to be cached for 3600 seconds. If you need to
  ensure that updates become visible immediately, you should set a
  Cache-Control header of "Cache-Control:private, max-age=0, no-transform" on
  such objects. For help doing this, see "gsutil help setmeta".

  Grant the user john.doe@example.com READ access to all objects
  in example-bucket that begin with folder/:

    gsutil acl ch -r -u john.doe@example.com:R gs://example-bucket/folder/

  Grant the group admins@example.com OWNER access to all jpg files in
  example-bucket:

    gsutil acl ch -g admins@example.com:O gs://example-bucket/**.jpg

  Grant the owners of project example-project WRITE access to the bucket
  example-bucket:

    gsutil acl ch -p owners-example-project:W gs://example-bucket

  NOTE: You can replace 'owners' with 'viewers' or 'editors' to grant access
  to a project's viewers/editors respectively.

  Remove access to the bucket example-bucket for the viewers of project number
  12345:

    gsutil acl ch -d viewers-12345 gs://example-bucket

  NOTE: You cannot remove the project owners group from ACLs of gs:// buckets in
  the given project. Attempts to do so will appear to succeed, but the service
  will add the project owners group into the new set of ACLs before applying it.

  Note that removing a project requires you to reference the project by
  its number (which you can see with the acl get command) as opposed to its
  project ID string.

  Grant the service account foo@developer.gserviceaccount.com WRITE access to
  the bucket example-bucket:

    gsutil acl ch -u foo@developer.gserviceaccount.com:W gs://example-bucket

  Grant all users from the `G Suite
  <https://www.google.com/work/apps/business/>`_ domain my-domain.org READ
  access to the bucket gcs.my-domain.org:

    gsutil acl ch -g my-domain.org:R gs://gcs.my-domain.org

  Remove any current access by john.doe@example.com from the bucket
  example-bucket:

    gsutil acl ch -d john.doe@example.com gs://example-bucket

  If you have a large number of objects to update, enabling multi-threading
  with the gsutil -m flag can significantly improve performance. The
  following command adds OWNER for admin@example.org using
  multi-threading:

    gsutil -m acl ch -r -u admin@example.org:O gs://example-bucket

  Grant READ access to everyone from my-domain.org and to all authenticated
  users, and grant OWNER to admin@mydomain.org, for the buckets
  my-bucket and my-other-bucket, with multi-threading enabled:

    gsutil -m acl ch -r -g my-domain.org:R -g AllAuth:R \
      -u admin@mydomain.org:O gs://my-bucket/ gs://my-other-bucket

<B>CH ROLES</B>
  You may specify the following roles with either their shorthand or
  their full name:

    R: READ
    W: WRITE
    O: OWNER

  For more information on these roles and the access they grant, see the
  permissions section of the `Access Control Lists page
  <https://cloud.google.com/storage/docs/access-control/lists#permissions>`_.

<B>CH ENTITIES</B>
  There are four different entity types: Users, Groups, All Authenticated Users,
  and All Users.

  Users are added with -u and a plain ID or email address, as in
  "-u john-doe@gmail.com:r". Note: Service Accounts are considered to be users.

  Groups are like users, but specified with the -g flag, as in
  "-g power-users@example.com:O". Groups may also be specified as a full
  domain, as in "-g my-company.com:r".

  allAuthenticatedUsers and allUsers are specified directly, as
  in "-g allUsers:R" or "-g allAuthenticatedUsers:O". These are case
  insensitive, and may be shortened to "all" and "allauth", respectively.

  Removing roles is specified with the -d flag and an ID, email
  address, domain, or one of allUsers or allAuthenticatedUsers.

  Many entities' roles can be specified on the same command line, allowing
  bundled changes to be executed in a single run. This will reduce the number of
  requests made to the server.

<B>CH OPTIONS</B>
  The "ch" sub-command has the following options

  -d          Remove all roles associated with the matching entity.

  -f          Normally gsutil stops at the first error. The -f option causes
              it to continue when it encounters errors. With this option the
              gsutil exit status will be 0 even if some ACLs couldn't be
              changed.

  -g          Add or modify a group entity's role.

  -p          Add or modify a project viewers/editors/owners role.

  -R, -r      Performs acl ch request recursively, to all objects under the
              specified URL.

  -u          Add or modify a user entity's role.

z

z+
  The acl command has three sub-commands:
c                 J    U R                   R                  SU5        SU l        g )NzEncountered a problem: %sF)loggererroreverything_set_okay)cls	exceptions     %platform/gsutil/gslib/commands/acl.py_ApplyExceptionHandlerr'   "  s    **.	:!#    c                 "    U R                  XS9  g )N)thread_state)ApplyAclChanges)r$   url_or_expansion_resultr*   s      r&   _ApplyAclChangesWrapperr-   '  s    -Ir(   c                     ^  \ rS rSrSr\R                  " S/ SQ\S\SSSS\	R                  \	R                  /\	R                  \R                  " 5       \R                  " 5       /\R                  " S5      /\R                  " 5       /S	.S
9r\R"                  " S/ SQSS\\\\S.S9rS rU 4S jrS rS rS rS r\" \SSS9SS j5       r\" \ SSS9S 5       r!S r"S r#Sr$U =r%$ )
AclCommandi+  z%Implementation of gsutil acl command.acl)getaclsetaclchacl   zafRrg:u:d:p:F   )setgetch)command_name_aliasesusage_synopsismin_argsmax_argssupported_sub_argsfile_url_okprovider_url_okurls_start_arggs_api_supportgs_default_apiargparse_arguments)r1   r2   chmodr3   command_helpz-Get, set, or change bucket and/or object ACLs)r7   r6   r8   )	help_namehelp_name_aliases	help_typehelp_one_line_summary	help_textsubcommand_help_textc                     U R                    Vs/ s H  n[        U5      PM     nnSnU R                   H  u  pEUS;   d  M  Sn  O   [        X#5        US   R	                  5       (       a  U(       d  ggs  snf )NF)-r-RTr   bucketsobjects)argsr   sub_optsr   IsBucket)selfurlobject_or_bucket_urlsrecurseflag_key_s         r&   _get_shim_command_group"AclCommand._get_shim_command_groupQ  ss    BF))L)31#6)LG	\	! ' ..CMQ((**7 Ms   A3c                   > U R                   R                  S5      nUS:X  a@  [        U R                   S   5      R                  5       (       a  SnOSn[	        SUSS/0 S9nGO~US	:X  a  U R                  5         U R                   R                  S5      n[        R                  R                  U5      (       a  S
U-   nO/U[        R                  ;   a  [        R                  U   nOUnSU-   nU R                  5       n[	        SUS/U/-   [        S5      [        S5      [        S5      [        S5      S.S9nOUS:X  a  U R                  5         [        R                  " U R                  5      U l        U R                  5       n[	        SUS/[        S5      [        S5      [        S5      [        S5      [        S5      [        S5      [        S5      [        S5      S.S9n[         TU ]E  W5      $ )Nr   r7   rP   rO   storagedescribez--format=multi(acl:format=json))gcloud_commandflag_mapr6   z--acl-file=z--predefined-acl=updatez--all-versionsz--continue-on-errorz--recursive)-a-frN   rM   r8   z--add-acl-grantz--remove-acl-grant)-g-p-u-drb   rc   rN   rM   )rQ   popr   IsObjectr   ParseSubOptsospathisfiler	   +FULL_PREDEFINED_ACL_XML_TO_JSON_TRANSLATIONrZ   r   r   translate_sub_opts_for_shimrR   superget_gcloud_storage_args)rT   sub_commandcommand_groupgcloud_storage_mapacl_file_or_predefined_aclacl_flagpredefined_acl	__class__s          r&   rq   "AclCommand.get_gcloud_storage_args_  s   ))--"Ke	diil	+	4	4	6	6!!+
]J
+< 68	9 
	
#'99==#3 	2	3	3 #==%DDF FF,.  6.&7224m+#]H=
J%&67%&;<%m4%m4	 
	
 <<T]]Kdm224m+#]H=%&78%&78%&78%&:;%&67%&;<%m4%m4	 7*+=>>r(   c                     U R                   (       d  U R                  5         U R                   S   R                  5       S:X  d  U R                  S:X  a  gg)Nr   r6   r2   r5   )rQ   $RaiseWrongNumberOfArgumentsExceptionlowercommand_alias_used)rT   s    r&   _CalculateUrlsStartArg!AclCommand._CalculateUrlsStartArg  sA    99
//1		!%4+B+Bh+Nr(   c                    SU l         U R                  (       aX  U R                   HH  u  pUS:X  a	  SU l        M  US:X  a	  SU l         M#  US:X  d  US:X  a	  SU l        M8  U R	                  5         MJ      U R                  [        [        5        U R                  (       d  [        S5      eg! [         a  nU R                  5         e SnAff = f)	z>Parses options and sets ACLs on the specified buckets/objects.Frb   Trc   rM   rN   N'ACLs for some objects could not be set.)continue_on_errorrR   all_versionsrecursion_requestedRaiseInvalidArgumentExceptionSetAclCommandHelperr   r   r
   _WarnServiceAccountsr#   r   )rT   ounused_aunused_es       r&   _SetAclAclCommand._SetAcl  s    "D}}+!9"$
$Y#'$
 $Y!t)%)$
"

,
,
. '
02HI ##FGG $ ! 
!s   2B) )
C	3CC	c                    SU l         / U l        SU l        U R                  (       Ga  U R                   GHo  u  pUS:X  a	  SU l        M  US:X  aY  SU;   a  [	        S5      eU R                  R                  [        R                  " U[        R                  R                  S95        Mt  US:X  aH  U R                  R                  [        R                  " U[        R                  R                  S95        M  US	:X  aI  U R                  R                  [        R                  " U[        R                  R                  S95        GM  US
:X  a2  U R                  R                  [        R                  " U5      5        GMI  US:X  d  US:X  a
  SU l        GM_  U R                  5         GMr     U R                  (       d  [	        S5      e[        U R                   5      (       a&  [#        U R                   S   5      R$                  S:w  a$  [	        SR'                  U R(                  5      5      eSU l        U R-                  [.        [0        U R                   / SQS9  U R*                  (       d  [	        S5      eg)zAParses options and changes ACLs on the specified buckets/objects.TFrc   rd   zgserviceaccount.comznService accounts are considered users, not groups; please use "gsutil acl ch -u" instead of "gsutil acl ch -g")
scope_typere   rf   rg   rM   rN   zFPlease specify at least one access change with the -g, -u, or -d flagsr   gsz2The "{0}" command can only be used with gs:// URLsr0   
generationmetageneration)object_fieldsr   N)parse_versionschangesr   rR   r   appendr   	AclChange
ChangeTypeGROUPPROJECTUSERAclDelr   r   r   rQ   r   schemeformatcommand_namer#   ApplyAclFuncr-   r'   )rT   r   as      r&   _ChAclAclCommand._ChAcl  s   DDL"D}}}--$!9#'$
 $Y"a'"CD D ,,

""11F1F1L1LMO$Y
,,

""11F1F1N1NOQ$Y
,,

""11F1F1K1KLN$Y
,,

j//2
3$Y!t)%)$
"

,
,
.+  . << < = = %TYY//TYYq\*11T9
>
E
E!" "  $D-,ii$K  M ##FGG $r(   c                 >    U R                  5         [        SU-  5      e)NzTFailed to set acl for %s. Please ensure you have OWNER-role access to this resource.)r   r   )rT   rU   s     r&   _RaiseForAccessDenied AclCommand._RaiseForAccessDenied  s,    
 ACFG H Hr(      )triestimeout_secsc           
      >   U(       a  UnOU R                   nUR                  nUR                  5       (       a4  UR                  UR                  UR
                  SS/S9nUR                  nOPUR                  5       (       a;  [        R                  " [        R                  UR                  5      nUR                  nW(       d  U R                  U5        U R                  XF5      S:X  a  U R                  R!                  SU5        g UR                  5       (       aP  [#        WR$                  S9n[        R&                  " US9n	UR)                  UR                  U	UUR
                  S	/S
9  Oq[#        WR*                  UR$                  S9n[        R                  " US9n
 UR-                  UR                  UR.                  U
UUR
                  UR*                  S	/S9  U R                  R!                  SU5        g! [0         a  nU R3                  XC5         SnAN=SnAff = f! [4         a  n[7        S[9        U5      -  5      eSnAf[:         a    U R                  U5         g[0         a0  nUR                  5       (       a  [7        [9        U5      5      eUeSnAff = f)zApplies the changes in self.changes to the provided URL.

Args:
  name_expansion_result: NameExpansionResult describing the target object.
  thread_state: If present, gsutil Cloud API instance to apply the changes.
r0   r   providerfieldsr   No changes to %sN)meta_gen_matchr0   id)preconditionsr   r   	gen_matchr   r   r   r   r   zUpdated ACL on %sz$Received bad request from server: %s)
gsutil_apiexpanded_storage_urlrS   	GetBucketbucket_namer   r0   ri   r   JsonToMessageapitools_messagesObjectexpanded_resultr   $_ApplyAclChangesAndReturnChangeCountr!   infor   r   BucketPatchBucketr   PatchObjectMetadataobject_namer   (_RefetchObjectMetadataAndApplyAclChangesr   r   strr
   )rT   name_expansion_resultr*   r   rU   bucketcurrent_acl
gcs_objectr   bucket_metadataobject_metadataes               r&   r+   AclCommand.ApplyAclChanges  s@    j??j

4
4C
||~~##COO-0ZZ,13C+D $ Ff JJk	))*;*B*B*?*O*OQjNNk
  %00BaG
kk)3/&	%V5J5JK+22{Cs.-:(+

'+f	 	 	. &
0E0E5?5N5NP+22{C	I

(
(),)87D25**47NN15 ) 8 kk*C0 % 	I 
7
7
H
H		I  NCc!fLMM  &
  %  	s1v&&gsU   BH" >G: H" :
HHH" HH" "
J,IJ#	J,+JJc           
         UR                  UR                  UR                  UR                  / SQS9nUR                  nU R                  X5      S:X  a  U R                  R                  SU5        g[        R                  " US9n[        UR                  UR                  S9nUR                  UR                  UR                  UUUR                  UR                  S/S	9  g)
z<Reattempts object ACL changes after a PreconditionException.r   r   r   r   Nr   r   r   r   )GetObjectMetadatar   r   r   r0   r   r!   r   r   r   r   r   r   r   )rT   rU   r   r   r   r   r   s          r&   r   3AclCommand._RefetchObjectMetadataAndApplyAclChanges3  s     --6	 . 8J
 ..K00BaG
kk)3/'..;?O!J,A,A1;1J1JLM""3??#&??#21>,/JJ.8.C.C+/& # 2r(   c                 n    SnU R                    H"  nX4R                  XSU R                  5      -  nM$     U$ )Nr   r0   )r   Executer!   )rT   storage_urlacl_messagemodification_countchanges        r&   r   /AclCommand._ApplyAclChangesAndReturnChangeCountL  s=    ,,NN;U+/;;8 8  r(   c                     U R                   R                  S5      nU R                  SS9  [        R                  " U R
                  S9  SU l        US:X  a4  [        R                  " U/S9  U R                  U R                   S   5        gUS:X  a&  [        R                  " U/S9  U R                  5         gUS	;   a&  [        R                  " U/S9  U R                  5         g[        S
U< SU R                  < S35      e)z(Command entry point for the acl command.r   T)
check_args)rR   Fr7   )subcommandsr6   )r8   r   zInvalid subcommand "z
" for the z  command.
See "gsutil help acl".)rQ   rh   rj   r   LogCommandParamsrR   def_aclGetAndPrintAclr   r   r   r   )rT   action_subcommands     r&   
RunCommandAclCommand.RunCommandS  s    		a(& dmm4DLE!,=+>?
$))A,'  
e	#,=+>?
lln  
.	.,=+>?
kkm 	 (94;L;LNO Or(   )r   r   r   r   r#   r   r   rR   N)&__name__
__module____qualname____firstlineno____doc__r   CreateCommandSpec	_SYNOPSISr   r   XMLJSONr   MakeFileURLOrCannedACLArgumentMakeZeroOrMoreCloudURLsArgumentMakeNCloudURLsArgumentcommand_specHelpSpec_DETAILED_HELP_TEXT_get_help_text_set_help_text_ch_help_text	help_specrZ   rq   r~   r   r   r   r   r   r+   r   r   r   r   __static_attributes____classcell__)rx   s   @r&   r/   r/   +  s4   - **8'!oo{'7'78 %% <<>==? "88;< @@BC	,* >K#):?xH*.H`H
 		3C 4CJ 		aa82 920 r(   r/   r   )?r   
__future__r   r   r   r   rk   apitools.base.pyr   gslibr   r	   gslib.cloud_apir
   r   r   r   r   gslib.commandr   r   r   gslib.command_argumentr   gslib.cs_api_mapr   gslib.exceptionr   gslib.help_providerr   gslib.storage_urlr   r   r   "gslib.third_party.storage_apitoolsr   r   gslib.utilsr   gslib.utils.constantsr   gslib.utils.retry_utilr   gslib.utils.shim_utilr   r   _SET_SYNOPSIS_GET_SYNOPSIS_CH_SYNOPSIS_GET_DESCRIPTION_SET_DESCRIPTION_CH_DESCRIPTIONlstripr   join_DESCRIPTIONr   r   r   r   r'   r-   r/    r(   r&   <module>r     s3   A & %  ' 	 %   1 / 1 ) , ! 0 + 2 ( , . 2 6 G W " ( ( 3 2	 ; zKZ ]11$77  &')/0	
ii!#3_EFG %Y= /?@/?@|_="
J r(   