U
    B“úgs.  ã                   @  s  d dl m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 d dl	m
Z
 ddlmZ ddlmZmZmZ ddlmZmZmZ ejr’d d	lmZ d
dddgZG dd
„ d
ƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZdS )é    )ÚannotationsN)Ú	b64encode)Úparse_http_listé   )ÚProtocolError)ÚCookiesÚRequestÚResponse)Úto_bytesÚto_strÚunquote)Ú_HashÚAuthÚ	BasicAuthÚ
DigestAuthÚ	NetRCAuthc                   @  sH   e Zd ZdZdZdZdddœdd„Zdddœdd	„Zdd
dœdd„ZdS )r   aô  
    Base class for all authentication schemes.

    To implement a custom authentication scheme, subclass `Auth` and override
    the `.auth_flow()` method.

    If the authentication scheme does I/O such as disk access or network calls, or uses
    synchronization primitives such as locks, you should override `.sync_auth_flow()`
    and/or `.async_auth_flow()` instead of `.auth_flow()` to provide specialized
    implementations that will be used by `Client` and `AsyncClient` respectively.
    Fr   ú)typing.Generator[Request, Response, None]©ÚrequestÚreturnc                 c  s
   |V  dS )a  
        Execute the authentication flow.

        To dispatch a request, `yield` it:

        ```
        yield request
        ```

        The client will `.send()` the response back into the flow generator. You can
        access it like so:

        ```
        response = yield request
        ```

        A `return` (or reaching the end of the generator) will result in the
        client returning the last response obtained from the server.

        You can dispatch as many requests as is necessary.
        N© ©Úselfr   r   r   ú//tmp/pip-unpacked-wheel-z2jyfz_s/httpx/_auth.pyÚ	auth_flow&   s    zAuth.auth_flowc                 c  sb   | j r| ¡  |  |¡}t|ƒ}|V }| jr4| ¡  z| |¡}W q  tk
rZ   Y q^Y q X q dS )zè
        Execute the authentication flow synchronously.

        By default, this defers to `.auth_flow()`. You should override this method
        when the authentication scheme does I/O and/or uses concurrency primitives.
        N)Úrequires_request_bodyÚreadr   ÚnextÚrequires_response_bodyÚsendÚStopIteration©r   r   ZflowÚresponser   r   r   Úsync_auth_flow>   s    	
zAuth.sync_auth_flowz(typing.AsyncGenerator[Request, Response]c                 C sn   | j r| ¡ I dH  |  |¡}t|ƒ}|V }| jr@| ¡ I dH  z| |¡}W q& tk
rf   Y qjY q&X q&dS )zé
        Execute the authentication flow asynchronously.

        By default, this defers to `.auth_flow()`. You should override this method
        when the authentication scheme does I/O and/or uses concurrency primitives.
        N)r   Zareadr   r   r   r   r    r!   r   r   r   Úasync_auth_flowW   s    	
zAuth.async_auth_flowN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r#   r$   r   r   r   r   r      s   c                   @  s0   e Zd ZdZdddœdd„Zddd	œd
d„ZdS )ÚFunctionAuthz‘
    Allows the 'auth' argument to be passed as a simple callable function,
    that takes the request, and returns a new, modified request.
    z#typing.Callable[[Request], Request]ÚNone)Úfuncr   c                 C  s
   || _ d S ©N©Z_func)r   r+   r   r   r   Ú__init__w   s    zFunctionAuth.__init__r   r   r   c                 c  s   |   |¡V  d S r,   r-   r   r   r   r   r   z   s    zFunctionAuth.auth_flowN)r%   r&   r'   r(   r.   r   r   r   r   r   r)   q   s   r)   c                   @  sD   e Zd ZdZddddœdd„Zddd	œd
d„Zddddœdd„ZdS )r   zy
    Allows the 'auth' argument to be passed as a (username, password) pair,
    and uses HTTP Basic authentication.
    ústr | bytesr*   ©ÚusernameÚpasswordr   c                 C  s   |   ||¡| _d S r,   )Ú_build_auth_headerÚ_auth_header©r   r1   r2   r   r   r   r.   „   s    zBasicAuth.__init__r   r   r   c                 c  s   | j |jd< |V  d S )NÚAuthorization)r4   Úheadersr   r   r   r   r   ‡   s    zBasicAuth.auth_flowÚstrc                 C  s,   d  t|ƒt|ƒf¡}t|ƒ ¡ }d|› S ©Nó   :zBasic ©Újoinr
   r   Údecode©r   r1   r2   ZuserpassÚtokenr   r   r   r3   ‹   s    zBasicAuth._build_auth_headerN©r%   r&   r'   r(   r.   r   r3   r   r   r   r   r   ~   s   c                   @  sD   e Zd ZdZddddœdd„Zdd	d
œdd„Zddddœdd„ZdS )r   zT
    Use a 'netrc' file to lookup basic auth credentials based on the url host.
    Nz
str | Noner*   )Úfiler   c                 C  s   dd l }|  |¡| _d S )Nr   )ÚnetrcÚ_netrc_info)r   rA   rB   r   r   r   r.   –   s    zNetRCAuth.__init__r   r   r   c                 c  sN   | j  |jj¡}|d ks |d s(|V  n"| j|d |d d|jd< |V  d S )Né   r   )r1   r2   r6   )rC   ÚauthenticatorsÚurlÚhostr3   r7   )r   r   Z	auth_infor   r   r   r      s     ÿzNetRCAuth.auth_flowr/   r8   r0   c                 C  s,   d  t|ƒt|ƒf¡}t|ƒ ¡ }d|› S r9   r;   r>   r   r   r   r3   ©   s    zNetRCAuth._build_auth_header)Nr@   r   r   r   r   r   ‘   s   c                	   @  s¸   e Zd ZU ejejejejejejejejdœZde	d< ddddœdd„Z
d	d
dœdd„Zd	ddddœdd„Zd	dddœdd„Zddddœdd„Zdddœdd„Zd d	d d!œd"d#„Zd$S )%r   )ÚMD5zMD5-SESSÚSHAzSHA-SESSzSHA-256zSHA-256-SESSzSHA-512zSHA-512-SESSz*dict[str, typing.Callable[[bytes], _Hash]]Ú_ALGORITHM_TO_HASH_FUNCTIONr/   r*   r0   c                 C  s$   t |ƒ| _t |ƒ| _d | _d| _d S )Nr   )r
   Ú	_usernameÚ	_passwordÚ_last_challengeÚ_nonce_countr5   r   r   r   r.   »   s    

zDigestAuth.__init__r   r   r   c                 c  s¬   | j r|  || j ¡|jd< |V }|jdks4d|jkr8d S |j d¡D ]}| ¡  d¡rD q`qDd S |  |||¡| _ d| _|  || j ¡|jd< |j	r¢t
|j	ƒj|d |V  d S )Nr6   i‘  zwww-authenticatezdigest r   ©r   )rM   r3   r7   Ústatus_codeZget_listÚlowerÚ
startswithÚ_parse_challengerN   Úcookiesr   Zset_cookie_header)r   r   r"   Úauth_headerr   r   r   r   Á   s*     ÿ
 ÿ
zDigestAuth.auth_flowr	   r8   Ú_DigestAuthChallenge)r   r"   rU   r   c              
   C  sô   |  d¡\}}}| ¡ dks t‚i }t|ƒD ]$}| ¡  dd¡\}	}
t|
ƒ||	< q,zh|d  ¡ }|d  ¡ }| dd¡}d	|krŒ|d	  ¡ nd
}d|kr¤|d  ¡ nd
}t	|||||dW S  t
k
rî } zd}t||d|‚W 5 d
}~X Y nX d
S )zÁ
        Returns a challenge from a Digest WWW-Authenticate header.
        These take the form of:
        `Digest realm="realm@host.com",qop="auth,auth-int",nonce="abc",opaque="xyz"`
        ú Údigestú=r   ÚrealmÚnonceÚ	algorithmrH   ÚopaqueNÚqop)rZ   r[   r\   r]   r^   z(Malformed Digest WWW-Authenticate headerrO   )Ú	partitionrQ   ÚAssertionErrorr   ÚstripÚsplitr   ÚencodeÚgetrV   ÚKeyErrorr   )r   r   r"   rU   ÚschemeÚ_ÚfieldsZheader_dictÚfieldÚkeyÚvaluerZ   r[   r\   r]   r^   ÚexcÚmessager   r   r   rS   à   s,        ÿzDigestAuth._parse_challenge)r   Ú	challenger   c                   sR  | j |j ¡  ‰ dddœ‡ fdd„}d | j|j| jf¡}|jj}d |j	 
¡ |f¡}||ƒ}d| j }|  | j|j¡}	|  jd7  _||ƒ}
|j ¡  d¡r´|d |
|j|	f¡ƒ}
| j|j|d	}|d krÚ|
|j|g}n|
|j||	||g}| j|j|j||d |¡ƒ|j 
¡ d
œ}|jr&|j|d< |rDd|d< ||d< |	|d< d|  |¡ S )NÚbytes)Údatar   c                   s   ˆ | ƒ  ¡  ¡ S r,   )Ú	hexdigestrc   )rp   ©Z	hash_funcr   r   rX     s    z-DigestAuth._build_auth_header.<locals>.digestr:   s   %08xr   z-sessrO   )r1   rZ   r[   Úurir"   r\   r]   ó   authr^   ÚncÚcnoncezDigest )rJ   r\   Úupperr<   rK   rZ   rL   rF   Úraw_pathÚmethodrc   rN   Ú_get_client_noncer[   rQ   ÚendswithÚ_resolve_qopr^   r]   Ú_get_header_value)r   r   rn   rX   ÚA1ÚpathÚA2ÚHA2Znc_valuerv   ÚHA1r^   Zdigest_dataZformat_argsr   rr   r   r3   ÿ   s<    
ú
zDigestAuth._build_auth_headerÚintro   )Únonce_countr[   r   c                 C  sL   t |ƒ ¡ }||7 }|t ¡  ¡ 7 }|t d¡7 }t |¡ ¡ d d…  ¡ S )Né   é   )	r8   rc   ÚtimeÚctimeÚosÚurandomÚhashlibÚsha1rq   )r   r„   r[   Úsr   r   r   rz   /  s
    zDigestAuth._get_client_noncezdict[str, bytes])Úheader_fieldsr   c           
      C  sb   d}d}d}d}t | ¡ ƒD ]@\}\}}|dkr8|d7 }||krD|n|}	||	 |t|ƒ¡7 }q|S )N)r\   r^   ru   z{}="{}"z{}={}Ú r   z, )Ú	enumerateÚitemsÚformatr   )
r   rŽ   ZNON_QUOTED_FIELDSZQUOTED_TEMPLATEZNON_QUOTED_TEMPLATEÚheader_valueÚiri   rk   Útemplater   r   r   r}   7  s    ÿýzDigestAuth._get_header_valueúbytes | None)r^   r   r   c                 C  sR   |d krd S t  d|¡}d|kr$dS |dgkr6tdƒ‚d|›d}t||d‚d S )Ns   , ?rt   s   auth-intz.Digest auth-int support is not yet implementedzUnexpected qop value "z" in digest authrO   )Úrerb   ÚNotImplementedErrorr   )r   r^   r   Zqopsrm   r   r   r   r|   I  s    
zDigestAuth._resolve_qopN)r%   r&   r'   r‹   Úmd5rŒ   Úsha256Úsha512rJ   Ú__annotations__r.   r   rS   r3   rz   r}   r|   r   r   r   r   r   ¯   s    
ø0c                   @  s6   e Zd ZU ded< ded< ded< ded< ded< d	S )
rV   ro   rZ   r[   r8   r\   r–   r]   r^   N)r%   r&   r'   rœ   r   r   r   r   rV   W  s
   
rV   )Ú
__future__r   r‹   r‰   r—   r‡   ÚtypingÚbase64r   Úurllib.requestr   Ú_exceptionsr   Z_modelsr   r   r	   Ú_utilsr
   r   r   ÚTYPE_CHECKINGr   Ú__all__r   r)   r   r   r   Ú
NamedTuplerV   r   r   r   r   Ú<module>   s(   [ )