o
    is.                     @  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rId d	lmZ g d
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                   @  s6   e Zd ZdZdZdZdddZdd	d
Z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.
    Frequestr   return)typing.Generator[Request, Response, None]c                 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   E/home/kim/smarthome/.venv/lib/python3.10/site-packages/httpx/_auth.py	auth_flow&   s   
zAuth.auth_flowc                 c  s^    | j r|  | |}t|}	 |V }| jr|  z||}W n
 ty-   Y dS w q)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.
        TN)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_flow(typing.AsyncGenerator[Request, Response]c                 C sj   | j r| I dH  | |}t|}	 |V }| jr"| I dH  z||}W n
 ty3   Y dS w q)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r   r   r   r   )r   r   r   r#   )	__name__
__module____qualname____doc__r   r   r   r"   r$   r   r   r   r   r      s    

r   c                   @  s$   e Zd ZdZdddZ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.
    func#typing.Callable[[Request], Request]r   Nonec                 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)   r0   r   r   r   r   r   r*   q   s    
r*   c                   @  s.   e Zd ZdZdddZdddZ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.
    usernamestr | bytespasswordr   r-   c                 C  s   |  ||| _d S r.   )_build_auth_header_auth_headerr   r1   r3   r   r   r   r0      s   zBasicAuth.__init__r   r   r   c                 c  s    | j |jd< |V  d S )NAuthorization)r5   headersr   r   r   r   r      s   
zBasicAuth.auth_flowstrc                 C  ,   d t|t|f}t| }d| S N   :zBasic joinr
   r   decoder   r1   r3   Zuserpasstokenr   r   r   r4         
zBasicAuth._build_auth_headerNr1   r2   r3   r2   r   r-   r%   r1   r2   r3   r2   r   r9   r&   r'   r(   r)   r0   r   r4   r   r   r   r   r   ~   s
    

r   c                   @  s0   e Zd ZdZddddZdddZdddZdS )r   zT
    Use a 'netrc' file to lookup basic auth credentials based on the url host.
    Nfile
str | Noner   r-   c                 C  s   dd l }| || _d S )Nr   )netrc_netrc_info)r   rF   rH   r   r   r   r0      s   zNetRCAuth.__init__r   r   r   c                 c  sR    | j |jj}|d u s|d s|V  d S | j|d |d d|jd< |V  d S )N   r   )r1   r3   r7   )rI   authenticatorsurlhostr4   r8   )r   r   Z	auth_infor   r   r   r      s   

zNetRCAuth.auth_flowr1   r2   r3   r9   c                 C  r:   r;   r=   r@   r   r   r   r4      rB   zNetRCAuth._build_auth_headerr.   )rF   rG   r   r-   r%   rD   rE   r   r   r   r   r      s
    
r   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
Z
d*ddZd+ddZd,ddZd-ddZd.d"d#Zd/d&d'Zd(S )0r   )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_FUNCTIONr1   r2   r3   r   r-   c                 C  s$   t || _t || _d | _d| _d S )Nr   )r
   	_username	_password_last_challenge_nonce_countr6   r   r   r   r0      s   


zDigestAuth.__init__r   r   r   c                 c  s    | j r| || j |jd< |V }|jdksd|jvrd S |jdD ]}| dr. nq#d S | |||| _ d| _| || j |jd< |j	rRt
|j	j|d |V  d S )Nr7   i  zwww-authenticatezdigest r   r   )rS   r4   r8   status_codeZget_listlower
startswith_parse_challengerT   cookiesr   Zset_cookie_header)r   r   r!   auth_headerr   r   r   r      s*   


zDigestAuth.auth_flowr!   r	   r[   r9   _DigestAuthChallengec              
   C  s   | d\}}}| dksJ i }t|D ]}| dd\}	}
t|
||	< qz4|d  }|d  }|dd}d	|v rF|d	  nd
}d|v rR|d  nd
}t|||||dW S  t	yr } z	d}t
||d|d
}~ww )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	algorithmrN   opaqueNqop)r`   ra   rb   rc   rd   z(Malformed Digest WWW-Authenticate headerrU   )	partitionrW   r   stripsplitr   encodegetr\   KeyErrorr   )r   r   r!   r[   scheme_fieldsZheader_dictfieldkeyvaluer`   ra   rb   rc   rd   excmessager   r   r   rY      s(   
zDigestAuth._parse_challenge	challengec                   sH  | j |j   d fdd}d| j|j| jf}|jj}d|j	
 |f}||}d| j }| | j|j}	|  jd7  _||}
|j d	rW|d|
|j|	f}
| j|j|d
}|d u rj|
|j|g}n	|
|j||	||g}| j|j|j||d||j
 d}|jr|j|d< |rd|d< ||d< |	|d< d| | S )Ndatabytesr   c                   s    |    S r.   )	hexdigestrh   )rt   Z	hash_funcr   r   r^     s   z-DigestAuth._build_auth_header.<locals>.digestr<   s   %08xr   z-sessrU   )r1   r`   ra   urir!   rb   rc      authrd   nccnoncezDigest )rt   ru   r   ru   )rP   rb   upperr>   rQ   r`   rR   rL   raw_pathmethodrh   rT   _get_client_noncera   rW   endswith_resolve_qoprd   rc   _get_header_value)r   r   rs   r^   A1pathA2HA2Znc_valuer{   HA1rd   Zdigest_dataZformat_argsr   rw   r   r4      s<   

zDigestAuth._build_auth_headernonce_countintra   ru   c                 C  sL   t | }||7 }|t  7 }|td7 }t| d d  S )N      )	r9   rh   timectimeosurandomhashlibsha1rv   )r   r   ra   sr   r   r   r   /  s
   zDigestAuth._get_client_nonceheader_fieldsdict[str, bytes]c           
      C  sb   d}d}d}d}t | D ] \}\}}|dkr|d7 }||vr"|n|}	||	|t|7 }q|S )N)rb   rd   rz   z{}="{}"z{}={} r   z, )	enumerateitemsformatr   )
r   r   ZNON_QUOTED_FIELDSZQUOTED_TEMPLATEZNON_QUOTED_TEMPLATEheader_valueirn   rp   templater   r   r   r   7  s   zDigestAuth._get_header_valuerd   bytes | Nonec                 C  sN   |d u rd S t d|}d|v rdS |dgkrtdd|d}t||d)Ns   , ?ry   s   auth-intz.Digest auth-int support is not yet implementedzUnexpected qop value "z" in digest authrU   )rerg   NotImplementedErrorr   )r   rd   r   Zqopsrr   r   r   r   r   I  s   
zDigestAuth._resolve_qopNrC   r%   )r   r   r!   r	   r[   r9   r   r\   )r   r   rs   r\   r   r9   )r   r   ra   ru   r   ru   )r   r   r   r9   )rd   r   r   r   r   r   )r&   r'   r(   r   md5r   sha256sha512rP   __annotations__r0   r   rY   r4   r   r   r   r   r   r   r   r      s"   
 




0
r   c                   @  s6   e Zd ZU ded< ded< ded< ded< ded< d	S )
r\   ru   r`   ra   r9   rb   r   rc   rd   N)r&   r'   r(   r   r   r   r   r   r\   W  s   
 r\   )
__future__r   r   r   r   r   typingbase64r   urllib.requestr   _exceptionsr   Z_modelsr   r   r	   Z_utilsr
   r   r   TYPE_CHECKINGr   __all__r   r*   r   r   r   
NamedTupler\   r   r   r   r   <module>   s*    [ )