
    6                        S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSK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rSrSrSrSrSr S r!S r"S r#SS jr$SS jr%S r&g)z#Utilities for the sign-url command.    )absolute_import)division)unicode_literalsN)apis_internal)iam_util)errors)log)requests)	transport)
console_io)
transports)files)timesz
RSA-SHA256zGOOG4-RSA-SHA256zUNSIGNED-PAYLOADclient_emailprivate_keyc
                    [         R                  R                  USS9n
[        R                  " [        R
                  S9nUR                  S5      u    pSU0nUR                  U5        SR                  [        UR                  5       5       VVs/ s H&  u  nnSR                  UR                  5       U5      PM(     snn5      nSR                  [        UR                  5       5      5      nS	R                  UR                  S
5      UR                  5       S9nUR                  S5      n[        U S-   U-   UU[!        U5      S.nUR                  U5        SR                  [        UR                  5       5       VVs/ s H5  u  nnSR                  U[         R                  R#                  U5      5      PM7     snn5      nSR                  UU
UUU[$        /5      n[&        R(                  " SU-   5        [*        R,                  " UR/                  S5      5      R1                  5       nSR                  [        UUU/5      n[&        R(                  " SU-   5        U(       a  [3        UU5      O[5        U UU	5      n[6        R8                  " U5      R                  5       R;                  S5      nSR                  UU
UUS9$ s  snnf s  snnf )a  Gets a signed URL for a GCS XML API request.

https://cloud.google.com/storage/docs/access-control/signed-urls

Args:
  client_id (str): Email of the service account that makes the request.
  duration (int): Amount of time (seconds) that the URL is valid for.
  headers (dict[str, str]): User-inputted headers for the request.
  host (str): The endpoint URL for the request. This should include a scheme,
    e.g. "https://"
  key (crypto.PKey): Key for the service account specified by client_id.
  verb (str): HTTP verb associated with the request.
  parameters (dict[str, str]): User-inputted parameters for the request.
  path (str): Of the form `/bucket-name/object-name`. Specifies the resource
    that is targeted by the request.
  region (str): The region of the target resource instance.
  delegates (list[str]|None): The list of service accounts in a delegation
    chain specified in --impersonate-service-account.

Returns:
  A URL (str) used to make the specified request.
z/~)safe)tzinfoz://host z{}:{}
;z%{date}/{region}/storage/goog4_requestz%Y%m%d)dateregionz%Y%m%dT%H%M%SZ/)zx-goog-algorithmzx-goog-credentialzx-goog-datezx-goog-signedheaderszx-goog-expires&z{}={}
zCanonical request string:
utf-8zString to sign:
z8{host}{path}?x-goog-signature={signature}&{query_string})r   path	signaturequery_string)urllibparsequoter   NowUTC
rpartitionupdatejoinsorteditemsformatlowerkeysstrftime_SIGNING_ALGORITHMstr
quote_plus_UNSIGNED_PAYLOADr	   debughashlibsha256encode	hexdigest_sign_with_key_sign_with_iambase64	b16encodedecode)	client_iddurationheadersr   keyverb
parametersr   r   	delegatesencoded_pathsigning_time_host_without_schemeheaders_to_signkvcanonical_headers_stringcanonical_signed_headers_stringcanonical_scopecanonical_timequery_params_to_signcanonical_query_stringcanonical_request_stringcanonical_request_hashstring_to_signraw_signaturer   s                               7lib/googlecloudsdk/command_lib/storage/sign_url_util.pyget_signed_urlrV   2   s   D ##Dt#4,%)),,"ooe4!Q01/!WW _22455da 

1779a
(5 %(HHVO4H4H4J-K$L!;BB  *\\^ C /
  (()9:. -$s?_<#=H j)88 1779::da ..FLL33A6
7: "YY
%(  ))),DDE">>%%g.IK 
 99	 . )).01 
 S.))^Y?  }-335<<WE)
D	L	L)	 
M 
 }.s   -K
?<K
c                    [         R                  " [        R                  SS9n[        R
                  " SSUS9nUR                  nUR                  R                  UR                  [        R                  " U 5      UR                  [        US5      U=(       d    /  Vs/ s H  n[        R                  " U5      PM     snS9S95      nUR                  $ s  snf )	a\  Generates a signature using the IAM sign-blob method.

Args:
  account_email (str): Email of the service account to sign as.
  string_to_sign (str): String to sign.
  delegates (list[str]|None): The list of service accounts in a delegation
    chain specified in --impersonate-service-account.

Returns:
  A raw signature for the specified string.
F)response_encodingallow_account_impersonationiamcredentialsv1)http_clientr   )payloadrC   )namesignBlobRequest)r   GetApitoolsTransportr   ENCODINGr   _GetClientInstanceMESSAGES_MODULEprojects_serviceAccountsSignBlob4IamcredentialsProjectsServiceAccountsSignBlobRequestr   EmailToAccountResourceNameSignBlobRequestbytes
signedBlob)account_emailrS   rC   r\   clientmessagesdelegateresponses           rU   r9   r9      s    , //!**+ +++& ##(,,55CC22=A"22NG4 #,/r/"1h 55h?"1 3  D 	( 
		s    Cc                 X    SSK Jn  UR                  XR                  S5      [        5      $ )zGenerates a signature using OpenSSL.crypto.

Args:
  key (crypto.PKey): Key for the signing service account.
  string_to_sign (str): String to sign.

Returns:
    A raw signature for the specified string.
r   cryptor   )OpenSSLrr   signr6   _DIGEST)r@   rS   rr   s      rU   r8   r8      s#     	S//8'	BB    c                    SSK Jn  SSKJn  SSKJn   [        R                  " U 5      nU[           nUR                  UR                  U[           US9nXg4$ ! [         a    U(       d  [        R                  " S5      n[        U[         5      (       d  UR#                  S5      nUR%                  XS9u  pn
UR&                  R)                  U5      nU	R*                  R-                  UR.                  5      nUS   R0                  U4s $ f = f)	a  Loads signing information from a JSON or P12 private key.

JSON keys from GCP do not use a passphrase by default, so we follow gsutil in
not prompting the user for a password.

P12 keystores from GCP do use a default ('notasecret'), so we will prompt the
user if they do not provide a password.

Args:
  raw_data (str): Un-parsed JSON data from the key file or creds store.
  password_bytes (bytes): A password used to decrypt encrypted private keys.

Returns:
  A tuple (client_id: str, key: crypto.PKey), which can be used to sign URLs.
r   rq   )pkcs12)NameOID)
passphrasez+Keystore password (default: 'notasecret'): r   )password)rs   rr   ,cryptography.hazmat.primitives.serializationrx   cryptography.x509.oidry   jsonloadsJSON_CLIENT_ID_KEYload_privatekeyFILETYPE_PEMJSON_PRIVATE_KEY_KEY
ValueErrorr   PromptPassword
isinstanceri   r6   load_key_and_certificatesPKeyfrom_cryptography_keysubjectget_attributes_for_oidCOMMON_NAMEvalue)raw_datapassword_bytesrr   rx   ry   parsed_jsonr=   r@   r   certificaterF   s              rU   !get_signing_information_from_jsonr      s     A+ + **X&K./I

 
 ()! ! C
 >	 + "00
7n ne,,%,,W5n"("B"B #C #Ka ++33K@K##::7;N;NOIQ<{**'+s   AA B0D
Dc                     U(       a  UR                  S5      nOSn[        R                  " U 5       nUR                  5       nSSS5        [	        WU5      $ ! , (       d  f       N= f)a  Loads signing information from a JSON or P12 private key file.

Args:
  path (str): The location of the file.
  password (str|None): The password used to decrypt encrypted private keys.

Returns:
  A tuple (client_id: str, key: crypto.PKey), which can be used to sign URLs.
r   N)r6   r   BinaryFileReaderreadr   )r   r{   r   filer   s        rU   !get_signing_information_from_filer     sR     __W-NNd#tyy{H $ 
+8^	DD $#s   A
A%c	                    0 n	SU;   a  US   U	S'   [        U S0 UUSU	UUSS9
n
[        R                  " 5       nUR                  U
5      nUR                  S:X  a  US:X  a  gSU;   nU(       a  gUR
                  R                  5       (       a/  [        R                  " S	R                  UR
                  5      5      e[        R                  " S
R                  UR
                  5      5      eUR                  S:X  a0  [        R                  " SR                  XR
                  5      5        g UR                  5         g! [        R                  R                   a*  n[        R                  " SR                  U5      5      eSnAff = f)a.  Checks if provided credentials offer appropriate access to a resource.

Args:
  client_id (str): Email of the service account that makes the request.
  host (str): The endpoint URL for the request.
  key (crypto.PKey): Key for the service account specified by client_id.
  path (str): Of the form `/bucket-name/object-name`. Specifies the resource
    that is targeted by the request.
  region (str): The region of the target resource instance.
  requested_headers (dict[str, str]): Headers used in the user's request.
    These do not need to be passed into the HEAD request performed by this
    function, but they do need to be checked for this function to raise
    appropriate errors for different use cases (e.g. for resumable uploads).
  requested_http_verb (str): Method the user requested.
  requested_parameters (dict[str, str]): URL parameters the user requested.
  requested_resource (resource_reference.Resource): Resource the user
    requested to access.

Raises:
  errors.Error if the requested resource is not available for the requested
    operation.
userProject<   HEADN)
r=   r>   r?   r   r@   rA   rB   r   r   rC   i  PUTzx-goog-resumablezjBucket {} does not exist. Please create a bucket with that name before creating a signed URL to access it.zkObject {} does not exist. Please create an object with that name before creating a signed URL to access it.i  z{} does not have permissions on {}. Using this link will likely result in a 403 error until at least READ permissions are granted.zbExpected an HTTP response code of 200 while querying object readability, but received an error: {})rV   core_requests
GetSessionheadstatus_codestorage_url	is_bucketr   Errorr+   r	   warningraise_for_statusr
   
exceptions	HTTPError)r=   r   r@   r   r   requested_headersrequested_http_verbrequested_parametersrequested_resourcerB   urlsessionro   is_resumable_uploaderrors                  rU   probe_access_to_resourcer   )  s   B * ** 4] CJ}
	# $$&'\\#(S e#  -0AA%%//11LL88> ,,9  LL88> ,,9  s"KK	GGMv55H
!(( LL44:F5M s   +D< <F%E??F)N)'__doc__
__future__r   r   r   r:   r4   r~   urllib.parser!   googlecloudsdk.api_lib.utilr   googlecloudsdk.command_lib.iamr   "googlecloudsdk.command_lib.storager   googlecloudsdk.corer	   r
   r   r   googlecloudsdk.core.consoler   googlecloudsdk.core.credentialsr   googlecloudsdk.core.utilr   r   ru   r/   r2   r   r   rV   r9   r8   r   r   r    rv   rU   <module>r      s    * &  '     5 3 5 # 9 ) 2 6 * *  ' &  $ $ m`*ZC4+nE*brv   