U
    EZhu                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
 d dlmZmZmZmZ d dlmZmZ d dlmZ G dd dZG d	d
 d
Zdd Zdd Zd%ddZd&ddZd'ddZd(ddZG dd dZdd Zd)ddZdd  Zd*d!d"Z d#d$ Z!dS )+    N)create_request_objectprepare_request_dict)OrderedDict)ParamValidationErrorUnknownClientMethodErrorUnknownSignatureVersionError UnsupportedSignatureVersionError)	ArnParserdatetime2timestamp)fix_s3_hostc                   @   sz   e Zd ZdZdddZedd Zedd Zed	d
 ZdddZ	dddZ
dd Zdd ZdddZeZdddZdS )RequestSignera0  
    An object to sign requests before they go out over the wire using
    one of the authentication mechanisms defined in ``auth.py``. This
    class fires two events scoped to a service and operation name:

    * choose-signer: Allows overriding the auth signer name.
    * before-sign: Allows mutating the request before signing.

    Together these events allow for customization of the request
    signing pipeline, including overrides, request path manipulation,
    and disabling signing per operation.


    :type service_id: botocore.model.ServiceId
    :param service_id: The service id for the service, e.g. ``S3``

    :type region_name: string
    :param region_name: Name of the service region, e.g. ``us-east-1``

    :type signing_name: string
    :param signing_name: Service signing name. This is usually the
                         same as the service name, but can differ. E.g.
                         ``emr`` vs. ``elasticmapreduce``.

    :type signature_version: string
    :param signature_version: Signature name like ``v4``.

    :type credentials: :py:class:`~botocore.credentials.Credentials`
    :param credentials: User credentials with which to sign requests.

    :type event_emitter: :py:class:`~botocore.hooks.BaseEventHooks`
    :param event_emitter: Extension mechanism to fire events.
    Nc                 C   s4   || _ || _|| _|| _|| _|| _t|| _d S N)	_region_name_signing_name_signature_version_credentials_auth_token_service_idweakrefproxy_event_emitter)selfZ
service_idregion_namesigning_namesignature_versioncredentialsZevent_emitterZ
auth_token r   W/home/aprabhat/apps/x.techxrdev.in/venv/lib/python3.8/site-packages/botocore/signers.py__init__E   s    
zRequestSigner.__init__c                 C   s   | j S r   )r   r   r   r   r   r   Y   s    zRequestSigner.region_namec                 C   s   | j S r   )r   r   r   r   r   r   ]   s    zRequestSigner.signature_versionc                 C   s   | j S r   )r   r   r   r   r   r   a   s    zRequestSigner.signing_namec                 K   s   |  ||S r   )sign)r   operation_namerequestkwargsr   r   r   handlere   s    zRequestSigner.handlerstandardc              
   C   s\  |}|dkr| j }|dkr | j}| |||j}| jjd| j  d| ||| j || |d |tj	krX|||d}	|dk	r||	d< |j
di }
|s|

dr|
d |	d	< |

d
r|
d
 |	d
< |

dr|
d |	d< |

ddk	r| |	|
d |
d  z| jf |	}W n> tk
rL } z|dkr8t|dn|W 5 d}~X Y nX || dS )a<  Sign a request before it goes out over the wire.

        :type operation_name: string
        :param operation_name: The name of the current operation, e.g.
                               ``ListBuckets``.
        :type request: AWSRequest
        :param request: The request object to be sent over the wire.

        :type region_name: str
        :param region_name: The region to sign the request for.

        :type signing_type: str
        :param signing_type: The type of signing to perform. This can be one of
            three possible values:

            * 'standard'     - This should be used for most requests.
            * 'presign-url'  - This should be used when pre-signing a request.
            * 'presign-post' - This should be used when pre-signing an S3 post.

        :type expires_in: int
        :param expires_in: The number of seconds the presigned url is valid
            for. This parameter is only valid for signing type 'presign-url'.

        :type signing_name: str
        :param signing_name: The name to use for the service when signing.
        Nzbefore-sign..)r"   r   r   r   request_signerr!   )r   r   r   expiressigningregionr   r   request_credentialsidentity_cache	cache_keyr%   r   )r   r   _choose_signercontextr   emitr   	hyphenizebotocoreUNSIGNEDget_resolve_identity_cacheget_auth_instancer   r   Zadd_auth)r   r!   r"   r   signing_type
expires_inr   Zexplicit_region_namer   r#   Zsigning_contextauther   r   r   r    l   sd    #  



zRequestSigner.signc                 C   s   ||d< ||d< d S )Nr,   r-   r   )r   r#   cacher-   r   r   r   r6      s    z%RequestSigner._resolve_identity_cachec                 C   s   ddd}| |d}| dp$| j}| di }| d| j}| d| j}	|tjk	rj||sj||7 }| jjd	| j	
  d
| ||	||d\}
}|dk	r|}|tjk	r||s||7 }|S )ai  
        Allow setting the signature version via the choose-signer event.
        A value of `botocore.UNSIGNED` means no signing will be performed.

        :param operation_name: The operation to sign.
        :param signing_type: The type of signing that the signer is to be used
            for.
        :return: The signature version to sign with.
        z-presign-postz-query)presign-postpresign-url Z	auth_typer)   r   r*   zchoose-signer.r&   )r   r   r   r0   N)r5   r   r   r   r3   r4   endswithr   Zemit_until_responser   r2   )r   r!   r8   r0   Zsigning_type_suffix_mapsuffixr   r)   r   r   r$   responser   r   r   r/      s8    
zRequestSigner._choose_signerc                 K   s   |dkr| j }tjj|}|dkr.t|d|jdkr\d}| jdk	rP| j }||}|S |pd| j	}	t
|dddkr|d }
|d }|
|}	|d= d}|	dk	r|	 }||d< |jr| jdkrtj ||d< ||d	< |f |}|S )
a  
        Get an auth instance which can be used to sign a request
        using the given signature version.

        :type signing_name: string
        :param signing_name: Service signing name. This is usually the
                             same as the service name, but can differ. E.g.
                             ``emr`` vs. ``elasticmapreduce``.

        :type region_name: string
        :param region_name: Name of the service region, e.g. ``us-east-1``

        :type signature_version: string
        :param signature_version: Signature name like ``v4``.

        :rtype: :py:class:`~botocore.auth.BaseSigner`
        :return: Auth instance to sign a request.
        Nr.   TZREQUIRES_IDENTITY_CACHEr,   r-   r   r   service_name)r   r3   r:   ZAUTH_TYPE_MAPSr5   r   ZREQUIRES_TOKENr   Zget_frozen_tokenr   getattrZget_credentialsZget_frozen_credentialsZREQUIRES_REGIONr   
exceptionsZNoRegionError)r   r   r   r   r+   r#   clsZfrozen_tokenr:   r   r<   keyZfrozen_credentialsr   r   r   r7      s<    







zRequestSigner.get_auth_instance  c                 C   s*   t |}| |||d|| |  |jS )a  Generates a presigned url

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type operation_name: str
        :param operation_name: The operation being signed.

        :type expires_in: int
        :param expires_in: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

        :type region_name: string
        :param region_name: The region name to sign the presigned url.

        :type signing_name: str
        :param signing_name: The name to use for the service when signing.

        :returns: The presigned url
        r>   )r   r    prepareurl)r   request_dictr!   r9   r   r   r"   r   r   r   generate_presigned_url@  s    	z$RequestSigner.generate_presigned_url)N)NN)Nr%   NN)NN)rH   NN)__name__
__module____qualname____doc__r   propertyr   r   r   r$   r    r6   r/   r7   Zget_authrL   r   r   r   r   r   "   s2   * 




    
\4  
B   r   c                   @   s<   e Zd ZdZdd ZdddZdd Zdd	d
Zdd ZdS )CloudFrontSignera  A signer to create a signed CloudFront URL.

    First you create a cloudfront signer based on a normalized RSA signer::

        import rsa
        def rsa_signer(message):
            private_key = open('private_key.pem', 'r').read()
            return rsa.sign(
                message,
                rsa.PrivateKey.load_pkcs1(private_key.encode('utf8')),
                'SHA-1')  # CloudFront requires SHA-1 hash
        cf_signer = CloudFrontSigner(key_id, rsa_signer)

    To sign with a canned policy::

        signed_url = cf_signer.generate_signed_url(
            url, date_less_than=datetime(2015, 12, 1))

    To sign with a custom policy::

        signed_url = cf_signer.generate_signed_url(url, policy=my_policy)
    c                 C   s   || _ || _dS )a  Create a CloudFrontSigner.

        :type key_id: str
        :param key_id: The CloudFront Key Pair ID

        :type rsa_signer: callable
        :param rsa_signer: An RSA signer.
               Its only input parameter will be the message to be signed,
               and its output will be the signed content as a binary string.
               The hash algorithm needed by CloudFront is SHA-1.
        N)key_id
rsa_signer)r   rS   rT   r   r   r   r     s    zCloudFrontSigner.__init__Nc           	      C   s   |dk	o|dk	}|dko|dk}|s(|r4d}t ||dk	rH| ||}t|tr\|d}|dk	rzdtt| g}nd| |d g}| 	|}|
d| |d d| j g | ||S )a  Creates a signed CloudFront URL based on given parameters.

        :type url: str
        :param url: The URL of the protected object

        :type date_less_than: datetime
        :param date_less_than: The URL will expire after that date and time

        :type policy: str
        :param policy: The custom policy, possibly built by self.build_policy()

        :rtype: str
        :return: The signed URL.
        Nz=Need to provide either date_less_than or policy, but not bothutf8zExpires=zPolicy=z
Signature=zKey-Pair-Id=)
ValueErrorbuild_policy
isinstancestrencodeintr
   _url_b64encodedecoderT   extendrS   
_build_url)	r   rJ   date_less_thanpolicyZboth_args_suppliedZneither_arg_suppliedr;   params	signaturer   r   r   rL     s&    



z'CloudFrontSigner.generate_presigned_urlc                 C   s"   d|krdnd}|| d | S )N?&)join)r   base_urlZextra_params	separatorr   r   r   r_     s    zCloudFrontSigner._build_urlc           	      C   s   t t|}tdd|ii}|r<d|kr0|d7 }d|i|d< |rXt t|}d|i|d< d|fd	|fg}d
t|gi}tj|ddS )a0  A helper to build policy.

        :type resource: str
        :param resource: The URL or the stream filename of the protected object

        :type date_less_than: datetime
        :param date_less_than: The URL will expire after the time has passed

        :type date_greater_than: datetime
        :param date_greater_than: The URL will not be valid until this time

        :type ip_address: str
        :param ip_address: Use 'x.x.x.x' for an IP, or 'x.x.x.x/x' for a subnet

        :rtype: str
        :return: The policy in a compact string.
        ZDateLessThanzAWS:EpochTime/z/32zAWS:SourceIpZ	IpAddressZDateGreaterThanResource	ConditionZ	Statement),:)
separators)r[   r
   r   jsondumps)	r   resourcer`   Zdate_greater_than
ip_addressZmoment	conditionZordered_payloadZcustom_policyr   r   r   rW     s    zCloudFrontSigner.build_policyc                 C   s"   t |ddddddS )N   +   -   =   _   /   ~)base64	b64encodereplace)r   datar   r   r   r\     s    
   zCloudFrontSigner._url_b64encode)NN)NN)	rM   rN   rO   rP   r   rL   r_   rW   r\   r   r   r   r   rR   k  s   
&   
*rR   c                 K   s   t | d< d S )Ngenerate_db_auth_token)r~   Zclass_attributesr#   r   r   r   add_generate_db_auth_token  s    r   c                 K   s   t | d< t| d< d S )NZgenerate_db_connect_auth_tokenZ$generate_db_connect_admin_auth_token)#dsql_generate_db_connect_auth_token)dsql_generate_db_connect_admin_auth_tokenr   r   r   r   'add_dsql_generate_db_auth_token_methods  s    r   c                 C   st   |}|dkr| j j}d|d}ddi |dd}d}| | d	| }	t||	 | jjd||d
dd}
|
t|d S )a  Generates an auth token used to connect to a db with IAM credentials.

    :type DBHostname: str
    :param DBHostname: The hostname of the database to connect to.

    :type Port: int
    :param Port: The port number the database is listening on.

    :type DBUsername: str
    :param DBUsername: The username to log in as.

    :type Region: str
    :param Region: The region the database is in. If None, the client
        region will be used.

    :return: A presigned url which can be used as an auth token.
    Nconnect)ActionZDBUserri   r?   GETZurl_pathZquery_stringheadersbodymethodhttps://rm     zrds-dbr!   rK   r   r9   r   )metar   r   _request_signerrL   len)r   Z
DBHostnameZPortZ
DBUsernameRegionr*   rb   rK   schemeendpoint_urlpresigned_urlr   r   r   r~     s.    
r~   r   c           
      C   s   d}||kr(t d| dd| d|dkr8| jj}ddi d	|id
d}d}| | }t|| | jj||||dd}	|	t|d S )a&  Generate a DSQL database token for an arbitrary action.

    :type Hostname: str
    :param Hostname: The DSQL endpoint host name.

    :type Action: str
    :param Action: Action to perform on the cluster (DbConnectAdmin or DbConnect).

    :type Region: str
    :param Region: The AWS region where the DSQL Cluster is hosted. If None, the client region will be used.

    :type ExpiresIn: int
    :param ExpiresIn: The token expiry duration in seconds (default is 900 seconds).

    :return: A presigned url which can be used as an auth token.
    )	DbConnectDbConnectAdminz	Received z! for action but expected one of: z, )reportNri   r?   r   r   r   r   Zdsqlr   )r   rf   r   r   r   r   rL   r   )
r   Hostnamer   r   	ExpiresInZpossible_actionsrK   r   r   r   r   r   r   _dsql_generate_db_auth_token4  s4     	
r   c                 C   s   t | |d||S )a  Generate a DSQL database token for the "DbConnect" action.

    :type Hostname: str
    :param Hostname: The DSQL endpoint host name.

    :type Region: str
    :param Region: The AWS region where the DSQL Cluster is hosted. If None, the client region will be used.

    :type ExpiresIn: int
    :param ExpiresIn: The token expiry duration in seconds (default is 900 seconds).

    :return: A presigned url which can be used as an auth token.
    r   r   r   r   r   r   r   r   r   r   g  s        r   c                 C   s   t | |d||S )a  Generate a DSQL database token for the "DbConnectAdmin" action.

    :type Hostname: str
    :param Hostname: The DSQL endpoint host name.

    :type Region: str
    :param Region: The AWS region where the DSQL Cluster is hosted. If None, the client region will be used.

    :type ExpiresIn: int
    :param ExpiresIn: The token expiry duration in seconds (default is 900 seconds).

    :return: A presigned url which can be used as an auth token.
    r   r   r   r   r   r   r   |  s        r   c                   @   s   e Zd Zdd ZdddZdS )S3PostPresignerc                 C   s
   || _ d S r   )r   )r   r'   r   r   r   r     s    zS3PostPresigner.__init__NrH   c                 C   s   |dkri }|dkrg }i }t j  }|t j|d }|tjj|d< g |d< |D ]}	|d |	 qTt|}
||
j	d< ||
j	d< | j
d|
|d |
j|d	S )
a  Generates the url and the form fields used for a presigned s3 post

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type fields: dict
        :param fields: A dictionary of prefilled form fields to build on top
            of.

        :type conditions: list
        :param conditions: A list of conditions to include in the policy. Each
            element can be either a list or a structure. For example:

            .. code:: python

                [
                    {"acl": "public-read"},
                    {"bucket": "amzn-s3-demo-bucket"},
                    ["starts-with", "$key", "mykey"]
                ]

        :type expires_in: int
        :param expires_in: The number of seconds the presigned post is valid
            for.

        :type region_name: string
        :param region_name: The region name to sign the presigned post to.

        :rtype: dict
        :returns: A dictionary with two elements: ``url`` and ``fields``.
            Url is the url to post to. Fields is a dictionary filled with
            the form fields and respective values to use when submitting the
            post. For example:

            .. code:: python

                {
                    'url': 'https://amzn-s3-demo-bucket.s3.amazonaws.com',
                    'fields': {
                        'acl': 'public-read',
                        'key': 'mykey',
                        'signature': 'mysignature',
                        'policy': 'mybase64 encoded policy'
                    }
                }
        N)secondsZ
expiration
conditionszs3-presign-post-fieldszs3-presign-post-policyZ	PutObjectr=   )rJ   fields)datetimeutcnow	timedeltastrftimer3   r:   ZISO8601appendr   r0   r   r    rJ   )r   rK   r   r   r9   r   ra   Zdatetime_nowZexpire_daters   r"   r   r   r   generate_presigned_post  s*    7


   z'S3PostPresigner.generate_presigned_post)NNrH   N)rM   rN   rO   r   r   r   r   r   r   r     s       r   c                 K   s   t | d< d S )NrL   )rL   r   r   r   r   add_generate_presigned_url  s    r   rH   c                 C   s   |}|}|dkri }|}|}dt | d}	| j}
z| j| }W n tk
r\   t|dY nX | jj|}| j|||	d}t	
|dd}| j|||	| d\}}}| j||||	|d	d
}|dk	r||d< |
j|||dS )ax  Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
        ``ClientMethod``.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned url is valid
        for. By default it expires in an hour (3600 seconds)

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
        default, the http method is whatever is used in the method's model.

    :returns: The presigned url
    NTZis_presign_requestZuse_global_endpoint)method_name
api_paramsoperation_modelr0   Bucketr?   Zignore_signing_regionFr   r   r   r0   r   Zset_user_agent_headerr   )rK   r9   r!   )_should_use_global_endpointr   Z_PY_TO_OP_NAMEKeyErrorr   r   service_modelr   _emit_api_paramsr	   is_arnr5   _resolve_endpoint_ruleset_convert_to_request_dictrL   )r   ZClientMethodZParamsr   Z
HttpMethodZclient_methodrb   r9   Zhttp_methodr0   r'   r!   r   bucket_is_arnr   additional_headers
propertiesrK   r   r   r   rL     s\    
rL   c                 K   s   t | d< d S )Nr   )r   r   r   r   r   add_generate_presigned_post>  s    r   c                 C   s  |}|}|}|}	|}
|dkr"i }n|  }|	dkr6g }	dt| d}t| j}| jjd}| jd|i||d}t	|
dd}| j|||| d\}}}| j|||||d	d
}|	d|i |dr|	dd|dtd  g n|	d|i ||d< |j|||	|
dS )aw
  Builds the url and the form fields used for a presigned s3 post

    :type Bucket: string
    :param Bucket: The name of the bucket to presign the post to. Note that
        bucket related conditions should not be included in the
        ``conditions`` parameter.

    :type Key: string
    :param Key: Key name, optionally add ${filename} to the end to
        attach the submitted filename. Note that key related conditions and
        fields are filled out for you and should not be included in the
        ``Fields`` or ``Conditions`` parameter.

    :type Fields: dict
    :param Fields: A dictionary of prefilled form fields to build on top
        of. Elements that may be included are acl, Cache-Control,
        Content-Type, Content-Disposition, Content-Encoding, Expires,
        success_action_redirect, redirect, success_action_status,
        and x-amz-meta-.

        Note that if a particular element is included in the fields
        dictionary it will not be automatically added to the conditions
        list. You must specify a condition for the element as well.

    :type Conditions: list
    :param Conditions: A list of conditions to include in the policy. Each
        element can be either a list or a structure. For example:

        .. code:: python

            [
                {"acl": "public-read"},
                ["content-length-range", 2, 5],
                ["starts-with", "$success_action_redirect", ""]
            ]

        Conditions that are included may pertain to acl,
        content-length-range, Cache-Control, Content-Type,
        Content-Disposition, Content-Encoding, Expires,
        success_action_redirect, redirect, success_action_status,
        and/or x-amz-meta-.

        Note that if you include a condition, you must specify
        a valid value in the fields dictionary as well. A value will
        not be added automatically to the fields dictionary based on the
        conditions.

    :type ExpiresIn: int
    :param ExpiresIn: The number of seconds the presigned post
        is valid for.

    :rtype: dict
    :returns: A dictionary with two elements: ``url`` and ``fields``.
        Url is the url to post to. Fields is a dictionary filled with
        the form fields and respective values to use when submitting the
        post. For example:

        .. code:: python

            {
                'url': 'https://amzn-s3-demo-bucket.s3.amazonaws.com',
                'fields': {
                    'acl': 'public-read',
                    'key': 'mykey',
                    'signature': 'mysignature',
                    'policy': 'mybase64 encoded policy'
                }
            }
    NTr   ZCreateBucketr   r   r?   r   Fr   bucketz${filename}zstarts-withz$keyrG   )rK   r   r   r9   )copyr   r   r   r   r   r   r   r	   r   r5   r   r   r   r@   r   r   )r   r   KeyZFieldsZ
Conditionsr   r   rG   r   r   r9   r0   Zpost_presignerr   rb   r   r   r   r   rK   r   r   r   r   B  sd    H


 r   c                 C   sd   | j jdkrdS | j jj}|r`|ddr.dS |ddkrN| j jjdkrNdS |ddkr`dS d	S )
NZawsFZuse_dualstack_endpointZus_east_1_regional_endpointZregionalz	us-east-1Zaddressing_styleZvirtualT)r   	partitionconfigZs3r5   r   )clientZ	s3_configr   r   r   r     s    
r   )N)Nr   )Nr   )Nr   )NrH   N)NNrH   )"rz   r   ro   r   r3   Zbotocore.authZbotocore.awsrequestr   r   Zbotocore.compatr   Zbotocore.exceptionsr   r   r   r   Zbotocore.utilsr	   r
   r   r   rR   r   r   r~   r   r   r   r   r   rL   r   r   r   r   r   r   r   <module>   sP     K 	
7   
4   
   
Z     
O     
 