U
    ~fh).                     @  s  d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZmZ ddlZddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZ dd	lmZm Z  dd
l!m"Z" e	rddl#m$Z$ ddl%m&Z& dZ'ddddddZ(eG dd dZ)dddddddZ*dS )z$MONGODB-OIDC Authentication helpers.    )annotationsN)	dataclassfield)TYPE_CHECKINGAnyMappingMutableMappingOptionalUnion)Binary)	remaining)	CALLBACK_VERSIONHUMAN_CALLBACK_TIMEOUT_SECONDS MACHINE_CALLBACK_TIMEOUT_SECONDSTIME_BETWEEN_CALLS_SECONDSOIDCCallbackOIDCCallbackContextOIDCCallbackResultOIDCIdPInfo_OIDCProperties)ConfigurationErrorOperationFailure)_AUTHENTICATION_FAILURE_CODE)AsyncConnection)MongoCredentialFr   ztuple[str, int]_OIDCAuthenticator)credentialsaddressreturnc                 C  s   | j jr| j jS | j}| j}|jsd}|j}|D ]:}||d krFd}q0|dr0|d |dd  r0d}q0|std|d  d| t	||d| j _| j jS )	NFr   Tz*.   zRefusing to connect to z(, which is not in authOIDCAllowedHosts: )username
properties)
cachedatar    Zmechanism_propertiesenvironmentallowed_hosts
startswithendswithr   r   )r   r   principal_namer!   foundr%   patt r+   B/tmp/pip-unpacked-wheel-36gvocj8/pymongo/asynchronous/auth_oidc.py_get_authenticator/   s$     r-   c                   @  s^  e Zd ZU ded< ded< eddZded< eddZded	< eddZd
ed< eddZded< ee	j
dZded< eddZded< dddddZdddddZddddZdddd d!Zdddd"d#Zddd$d%Zdd&dd'd(d)Zd*d+d,d-d.Zdd/dd0d1Zdddd2d3d4Zdddd5d6Zdd&d7d8d9Zddd&d:d;d<ZdS )=r   strr    r   r!   N)defaultzOptional[str]refresh_tokenaccess_tokenzOptional[OIDCIdPInfo]idp_infor   inttoken_gen_id)default_factoryzthreading.Locklockfloatlast_call_timer   Optional[Mapping[str, Any]])connr   c                   s2   |  | | jjr"| |I dH S | |I dH S )z(Handle a reauthenticate from the server.N)_invalidater!   callback_authenticate_machine_authenticate_human)selfr:   r+   r+   r,   reauthenticateW   s    
z!_OIDCAuthenticator.reauthenticatec                   sX   |j }|r0| r0|j}|r0|d r0| j|_|S | jjrH| |I dH S | |I dH S )z'Handle an initial authenticate request.doneN)	Zauth_ctxZspeculate_succeededZspeculative_authenticater4   oidc_token_gen_idr!   r<   r=   r>   )r?   r:   ctxrespr+   r+   r,   authenticate`   s    z_OIDCAuthenticator.authenticatez"Optional[MutableMapping[str, Any]])r   c                 C  s   | j s
dS | d| j iS )z-Get the appropriate speculative auth command.Njwt)r1   _get_start_command)r?   r+   r+   r,   get_spec_auth_cmdr   s    z$_OIDCAuthenticator.get_spec_auth_cmdzMapping[str, Any]c              
     sp   | j r`z| |I d H W S  tk
r^ } z(| |rL| |I d H  W Y S  W 5 d }~X Y nX | |I d H S N)r1   _sasl_start_jwtr   _is_auth_errorr=   )r?   r:   er+   r+   r,   r=   x   s    
z(_OIDCAuthenticator._authenticate_machinec              
     s   | j r`z| |I d H W S  tk
r^ } z(| |rL| |I d H  W Y S  W 5 d }~X Y nX | jrz| |I d H W S  tk
r } z.| |rd | _| |I d H  W Y S  W 5 d }~X Y nX | d }| ||I d H }| ||I d H S rI   )	r1   rJ   r   rK   r>   r0   rG   _run_command_sasl_continue_jwt)r?   r:   rL   cmd
start_respr+   r+   r,   r>      s$    


z&_OIDCAuthenticator._authenticate_humanc           
   
   C  sH  | j }|jd k	}|r"| jd kr"d S |jr.|j}|jr:|j}| j}|rH|S |d krX|sXd S |sB|d k	rB| j | j}||kr|W  5 Q R  S t | j }|tk rt	t|  t | _|rt
}| jd k	stntt pt}t|t| j| j| j jd}||}	t|	tstd|	j| _|	j| _|  jd7  _W 5 Q R X | jS )N)Ztimeout_secondsversionr0   r2   r    z2Callback result must be of type OIDCCallbackResultr   )r!   Zhuman_callbackr2   r<   r1   r6   timer8   r   sleepr   AssertionErrorr3   r   r   r   r   r0   r    fetch
isinstancer   
ValueErrorr4   )
r?   r!   Zis_humancb
prev_token	new_tokendeltatimeoutcontextrD   r+   r+   r,   _get_access_token   sP    


z$_OIDCAuthenticator._get_access_tokenzMutableMapping[str, Any])r:   rO   r   c              
     sV   z|j d|ddI d H W S  tk
rP } z| |r>| |  W 5 d }~X Y nX d S )Nz	$externalT)Z	no_reauth)commandr   rK   r;   )r?   r:   rO   rL   r+   r+   r,   rM      s    

z_OIDCAuthenticator._run_command	Exceptionbool)errr   c                 C  s   t |tsdS |jtkS )NF)rV   r   coder   )r?   rb   r+   r+   r,   rK      s    
z!_OIDCAuthenticator._is_auth_errorNonec                 C  s*   |j pd}|d k	r || jk r d S d | _d S )Nr   )rB   r4   r1   )r?   r:   r4   r+   r+   r,   r;      s    
z_OIDCAuthenticator._invalidate)r:   rP   r   c                   s`   d | _ d | _t|d }d|kr.tf || _|  }| j|_| 	d|i|}| 
||I d H S )NpayloadZissuerrF   )r1   r0   bsondecoder   r2   r^   r4   rB   _get_continue_commandrM   )r?   r:   rP   Zstart_payloadr1   rO   r+   r+   r,   rN      s    z%_OIDCAuthenticator._sasl_continue_jwtc                   s0   |   }| j|_| d|i}| ||I d H S )NrF   )r^   r4   rB   rG   rM   )r?   r:   r1   rO   r+   r+   r,   rJ     s    z"_OIDCAuthenticator._sasl_start_jwt)re   r   c                 C  s:   |d kr | j }|rd|i}ni }tt|}dd|dS )Nnr   zMONGODB-OIDC)Z	saslStartZ	mechanismre   )r    r   rf   encode)r?   re   r(   bin_payloadr+   r+   r,   rG   	  s    
z%_OIDCAuthenticator._get_start_command)re   rP   r   c                 C  s   t t|}d||d dS )Nr   conversationId)ZsaslContinuere   rl   )r   rf   rj   )r?   re   rP   rk   r+   r+   r,   rh     s
    z(_OIDCAuthenticator._get_continue_command)__name__
__module____qualname____annotations__r   r0   r1   r2   r4   	threadingLockr6   r8   r@   rE   rH   r=   r>   r^   rM   rK   r;   rN   rJ   rG   rh   r+   r+   r+   r,   r   L   s*   
	!8

r   ra   r9   )r   r:   r@   r   c                   s4   t | |j}|r ||I dH S ||I dH S dS )z Authenticate using MONGODB-OIDC.N)r-   r   r@   rE   )r   r:   r@   Zauthenticatorr+   r+   r,   _authenticate_oidc  s    rs   )+__doc__
__future__r   rq   rR   Zdataclassesr   r   typingr   r   r   r   r	   r
   rf   Zbson.binaryr   Zpymongo._csotr   Zpymongo.auth_oidc_sharedr   r   r   r   r   r   r   r   r   Zpymongo.errorsr   r   Zpymongo.helpers_sharedr   Zpymongo.asynchronous.poolr   Zpymongo.auth_sharedr   Z_IS_SYNCr-   r   rs   r+   r+   r+   r,   <module>   s(    , R