o
    .jM6                     @  sF  U d Z 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Zddl	m
Z
 ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ejrPddlmZ dZded< dZded< d'ddZG dd 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!eG d!d" d"Z"G d#d$ d$eZ#G d%d& d&e#eZ$dS )(z]
requests.auth
~~~~~~~~~~~~~

This module contains the authentication handlers for Requests.
    )annotationsN)	b64encode)	dataclassfield)urlparse   )iscoroutinefunction)extract_cookies_to_jar)parse_dict_header)PreparedRequestz!application/x-www-form-urlencodedstrCONTENT_TYPE_FORM_URLENCODEDzmultipart/form-dataCONTENT_TYPE_MULTI_PARTusernamestr | bytespasswordreturnc                 C  sJ   t | tr
| d} t |tr|d}dtd| |f   }|S )zReturns a Basic Auth string.utf-8zBasic    :)
isinstancer   encoder   joinstripdecode)r   r   authstr r   B/home/thesage/.local/lib/python3.10/site-packages/niquests/auth.py_basic_auth_str   s   



r   c                   @     e Zd ZdZdddZdS )	AsyncAuthBasezABase class that all asynchronous auth implementations derive fromrr   r   c                   s
   t dNzAuth hooks must be callable.NotImplementedErrorselfr    r   r   r   __call__0   s   zAsyncAuthBase.__call__Nr    r   r   r   __name__
__module____qualname____doc__r&   r   r   r   r   r   -       r   c                   @  r   )	AuthBasez@Base class that all synchronous auth implementations derive fromr    r   r   c                 C  s   t dr!   r"   r$   r   r   r   r&   7   s   zAuthBase.__call__Nr'   r(   r   r   r   r   r.   4   r-   r.   c                   @  s6   e Zd ZdZdddZddd	Zdd
dZdd ZdS )BearerTokenAuthz.Simple token injection in Authorization headertokenr   c                 C  s
   || _ d S N)r0   )r%   r0   r   r   r   __init__>      
zBearerTokenAuth.__init__r   boolc                 C  s   | j t|dd kS )Nr0   )r0   getattrr%   otherr   r   r   __eq__A   s   zBearerTokenAuth.__eq__c                 C  
   | |k S r1   r   r6   r   r   r   __ne__D   r3   zBearerTokenAuth.__ne__c                 C  sB   | j jddd}t|dkrd| j  |jd< |S | j |jd< |S )N r   )maxsplitzBearer Authorization)r0   splitlenheaders)r%   r    detect_token_typer   r   r   r&   G   s   zBearerTokenAuth.__call__N)r0   r   r   r4   r)   r*   r+   r,   r2   r8   r:   r&   r   r   r   r   r/   ;   s    


r/   c                   @  s6   e Zd ZdZdddZdd	d
ZdddZdd ZdS )HTTPBasicAuthz?Attaches HTTP Basic Authentication to the given Request object.r   r   r   c                 C  s   || _ || _d S r1   )r   r   r%   r   r   r   r   r   r2   U   s   
zHTTPBasicAuth.__init__r   r4   c                 C  (   t | jt|dd k| jt|dd kgS Nr   r   allr   r5   r   r6   r   r   r   r8   Y   
   zHTTPBasicAuth.__eq__c                 C  r9   r1   r   r6   r   r   r   r:   a   r3   zHTTPBasicAuth.__ne__c                 C     t | j| j|jd< |S )Nr=   r   r   r   r@   r$   r   r   r   r&   d      zHTTPBasicAuth.__call__N)r   r   r   r   rB   rC   r   r   r   r   rD   R   s    


rD   c                   @     e Zd ZdZdd ZdS )HTTPProxyAuthz=Attaches HTTP Proxy Authentication to a given Request object.c                 C  rK   )NzProxy-AuthorizationrL   r$   r   r   r   r&   l   rM   zHTTPProxyAuth.__call__Nr(   r   r   r   r   rO   i   s    rO   c                   @  s`   e Zd ZU dZdZded< dZded< dZd	ed
< ee	dZ
ded< dZded< dZded< dS )DigestAuthStatez/Container for digest auth state per task/threadFr4   init r   
last_noncer   intnonce_count)default_factoryztyping.Mapping[str, str | None]chalNz
int | Noneposnum_401_calls)r)   r*   r+   r,   rQ   __annotations__rS   rU   r   dictrW   rX   rY   r   r   r   r   rP   q   s   
 rP   c                   @  sd   e Zd ZdZdddZdd	d
Zd ddZdddZdd Zdd Z	dd Z
d!ddZd!ddZdS )"HTTPDigestAuthz@Attaches HTTP Digest Authentication to the given Request object.r   r   r   c                 C  s   || _ || _td| _d S )Ndigest_auth_state)r   r   contextvars
ContextVar_thread_localrE   r   r   r   r2      s   zHTTPDigestAuth.__init__r   Nonec                 C  s4   | j d }|d u s|js| j tdd d S d S )NT)rQ   )r`   getrQ   setrP   )r%   stater   r   r   init_per_thread_state   s   z$HTTPDigestAuth.init_per_thread_statemethodurl
str | Nonec                   s  | j d }|d usJ |jd }|jd }|jd}|jd}|jd}d  |d u r1d}	n| }	|	dks=|	dkrEd2dd}
|
 n,|	dkrQd2dd}| n |	dkr]d2dd}| n|	dkrid2dd}| ntd|	 d fdd} d u r}d S d }t|}|jpd}|jr|d|j 7 }| j d| d| j	 }| d| } |} |}||j
kr| jd7  _nd|_|jd}t|jd }|d usJ ||d 7 }|t d 7 }|td!7 }t| d d" }|	dkr | d| d| }|s||| d| }n"|d#ksd#|d$v r2| d| d| d%| }|||}nd S ||_
d&| j d'| d(| d)| d*| d+}|rU|d,| d+7 }|r`|d-| d+7 }|rk|d.| d+7 }|ry|d/| d0| d+7 }d1| S )3Nrealmnonceqop	algorithmopaqueMD5zMD5-SESSxr   r   r   c                 S  "   t | tr
| d} t|  S Nr   )r   r   r   hashlibmd5	hexdigestro   r   r   r   md5_utf8      

z4HTTPDigestAuth.build_digest_header.<locals>.md5_utf8SHAc                 S  rp   rq   )r   r   r   rr   sha1rt   ru   r   r   r   sha_utf8   rw   z4HTTPDigestAuth.build_digest_header.<locals>.sha_utf8zSHA-256c                 S  rp   rq   )r   r   r   rr   sha256rt   ru   r   r   r   sha256_utf8   rw   z7HTTPDigestAuth.build_digest_header.<locals>.sha256_utf8zSHA-512c                 S  rp   rq   )r   r   r   rr   sha512rt   ru   r   r   r   sha512_utf8   rw   z7HTTPDigestAuth.build_digest_header.<locals>.sha512_utf8'z$' hashing algorithm is not supportedc                   s    |  d| S )N:r   )sd	hash_utf8r   r   <lambda>   s    z4HTTPDigestAuth.build_digest_header.<locals>.<lambda>/?r   r   08xr         auth,z:auth:z
username="z
", realm="z
", nonce="z", uri="z", response=""z
, opaque="z, algorithm="z
, digest="z, qop="auth", nc=z
, cnonce="zDigest )ro   r   r   r   )r`   rb   rW   upper
ValueErrorr   pathqueryr   r   rS   rU   r   r   timectimeosurandomrr   ry   rt   r>   )r%   rf   rg   rd   ri   rj   rk   rl   rm   
_algorithmrv   rz   r|   r~   KDentdigp_parsedr   A1A2HA1HA2ncvaluer   cnoncerespdignoncebitbaser   r   r   build_digest_header   s   









&
z"HTTPDigestAuth.build_digest_headerc                 K  s,   | j d}|dusJ |jrd|_dS dS )z)Reset num_401_calls counter on redirects.Nr   )r`   rb   is_redirectrY   )r%   r    kwargsrd   r   r   r   handle_redirect   s
   
zHTTPDigestAuth.handle_redirectc                   s@  | j d}|dusJ d|j  krdk sn d|_|S |jdur+|jj|j |jdd}d|	 v r|jdk r| jd7  _t
jd	t
jd
}t|jd|dd|_|jI dH  | I dH  |j }t|j|j|j ||j | |j|j|jd< |jj|fi |I dH }|j| ||_|S d|_|S )z
        Takes the given response and tries digest-auth, if needed (async version).

        :rtype: requests.Response
        N    r   www-authenticaterR   digest   digest flagscountr=   r`   rb   status_coderY   rX   requestbodyseekr@   lowerrecompile
IGNORECASEr
   subrW   contentclosecopyr	   _cookiesrawprepare_cookiesr   rf   rg   
connectionsendhistoryappendr%   r    r   rd   s_authpatprep_rr   r   r   async_handle_401  s2   

zHTTPDigestAuth.async_handle_401c                 K  s,  | j d}|dusJ d|j  krdk sn d|_|S |jdur*|jj|j |jdd}d|	 v r|jdk r| jd7  _t
jd	t
jd
}t|jd|dd|_|j |  |j }t|j|j|j ||j | |j|j|jd< |jj|fi |}|j| ||_|S d|_|S )zo
        Takes the given response and tries digest-auth, if needed.

        :rtype: requests.Response
        Nr   r   r   r   rR   r   r   r   r   r   r=   r   r   r   r   r   
handle_4014  s0   

zHTTPDigestAuth.handle_401c                 C  s   |    | jd }|d usJ |jr| |j|j|jd< z|j	 |_
W n ty2   d |_
Y nw |d| j |d| j d|_|S Nr=   responser   )re   r`   rb   rS   r   rf   rg   r@   r   tellrX   AttributeErrorregister_hookr   r   rY   r%   r    rd   r   r   r   r&   a  s   
zHTTPDigestAuth.__call__r4   c                 C  rF   rG   rH   r6   r   r   r   r8   x  rJ   zHTTPDigestAuth.__eq__c                 C  r9   r1   r   r6   r   r   r   r:     r3   zHTTPDigestAuth.__ne__N)r   r   r   r   )r   ra   )rf   r   rg   r   r   rh   rB   )r)   r*   r+   r,   r2   re   r   r   r   r   r&   r8   r:   r   r   r   r   r\   }   s    



q	--
r\   c                   @  rN   )AsyncHTTPDigestAutha  Async version of HTTPDigestAuth for use with AsyncSession.

    Attaches HTTP Digest Authentication to the given Request object and handles
    401 responses asynchronously.

    Example usage::

        >>> import niquests
        >>> auth = niquests.auth.AsyncHTTPDigestAuth('user', 'pass')
        >>> async with niquests.AsyncSession() as session:
        ...     r = await session.get('https://httpbin.org/digest-auth/auth/user/pass', auth=auth)
        ...     print(r.status_code)
        200
    c                   s   |    | jd }|d usJ |jr| |j|j|jd< zt|j	j
r0|j	
 I d H |_n|j	
 |_W n tyC   d |_Y nw |d| j |d| j d|_|S r   )re   r`   rb   rS   r   rf   rg   r@   r   r   r   rX   r   r   r   r   rY   r   r   r   r   r&     s$   
zAsyncHTTPDigestAuth.__call__Nr(   r   r   r   r   r     s    r   )r   r   r   r   r   r   )%r,   
__future__r   r^   rr   r   r   r   typingbase64r   dataclassesr   r   urllib.parser   _compatr   cookiesr	   utilsr
   TYPE_CHECKINGmodelsr   r   rZ   r   r   r   r.   r/   rD   rO   rP   r\   r   r   r   r   r   <module>   s<    
  	