U
    d,                     @  sB  U 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
 ddlmZmZmZ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 dd
lmZ erddlm Z  ddl!m"Z" eG dd dZ#dZ$dZ%dZ&dZ'i Z(de)d< ddddddZ*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)datetime	timedeltatimezone)	TYPE_CHECKINGAnyCallableDictListMappingMutableMappingOptionalTuple)Binary)SON)ConfigurationErrorOperationFailure)_REAUTHENTICATION_REQUIRED_CODE)MongoCredential)
Connectionc                   @  s.   e Zd ZU ded< ded< ded< ded< dS )	_OIDCPropertieszOptional[Callable[..., Dict]]request_token_callbackrefresh_token_callbackOptional[str]provider_namez	List[str]allowed_hostsN)__name__
__module____qualname____annotations__ r"   r"   5/tmp/pip-unpacked-wheel-oblwsawz/pymongo/auth_oidc.pyr   -   s   
r      i,  zDict[str, '_OIDCAuthenticator']_CACHEr   zTuple[str, int]_OIDCAuthenticator)credentialsaddressreturnc                 C  s  t tj}g }t D ]&\}}|jd k	r|j|k r|| q|D ]
}t|= qD| j}| j	}|j
}|j}	|jsd}
|j}|D ]:}||d krd}
q||dr||d |dd  r|d}
q||
std|d  d| | |d  |d  t| t|	 }t|t||d t| S )	NFr   Tz*.   zRefusing to connect to z(, which is not in authOIDCAllowedHosts: )username
properties)r   nowr   utcr%   itemscache_exp_utcappendr+   Zmechanism_propertiesr   r   r   r   
startswithendswithr   id
setdefaultr&   )r'   r(   now_utcZ	to_removekeyvalueprincipal_namer,   
request_cb
refresh_cbfoundr   patt	cache_keyr"   r"   r#   _get_authenticator?   s4     (r?   r   r)   c                   C  s   t tjttd S )Nminutes)r   r-   r   r.   r   CACHE_TIMEOUT_MINUTESr"   r"   r"   r#   _get_cache_expf   s    rD   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d
dZ	ded< eddZ
ded< eedZded< eejdZded< d-dddddZd.dddddZdd d!d"Zd#d$d%d&d'd(Zd/d#dd%d*d+d,ZdS )0r&   strr+   r   r,   N)defaultzOptional[Dict]idp_infoidp_respr   intreauth_gen_ididp_info_gen_idtoken_gen_idzOptional[datetime]token_exp_utc)default_factoryr   r0   zthreading.LocklockTboolr   )use_callbacksr)   c              
   C  s  | j }|j}|j}|sd }d }d}| jd k	rZttj}| j}td }|| 	 |krZd}t
}	|sj|sjd S |sX|d k	rX| jr| jd nd }
| j | jr| jd nd }||
kr|W  5 Q R  S | jo| jd}|pd}|	t|d}| jd ks|d kr|| j|| _n|d k	r$|| j|| _ttjttd }|| _|  jd	7  _W 5 Q R X | j}t|tsrtd
d|krtddddg}|D ] }||krtd| dq|d }d|krt|d }td }||krttj}|t|d }|| _|S )NF<   TZaccess_tokenrefresh_token )Ztimeout_secondsversionrS   rA   r*   z%OIDC callback returned invalid resultz,OIDC callback did not return an access_tokenZexpires_in_secondsZrefesh_tokenz%Unexpected field in callback result "")seconds)r,   r   r   rM   r   r-   r   r.   TOKEN_BUFFER_MINUTEStotal_secondsCALLBACK_TIMEOUT_SECONDSrH   rO   getCALLBACK_VERSIONrG   r   rC   r0   rL   
isinstancedict
ValueErrorrI   )selfrQ   r,   r:   r;   Zcurrent_valid_tokenr6   Zexp_utcZbuffer_secondstimeout
prev_token	new_tokenrS   contextr0   Ztoken_resultexpectedr7   tokenZ
expires_inr"   r"   r#   get_current_tokenw   sn    






z$_OIDCAuthenticator.get_current_tokenzOptional[SON[str, Any]]c           
   	   C  s  | j }|jdkrbtjd }t|}|  }W 5 Q R X d|i}tdddtt	
|fg}|S | j}| jd k	rttjttd | _| jd krt | _| jd kri }|r||d< tdddtt	
|fd	g}|S | |}|sd S tt	
d|i}	tddd|	fgS )
NZawsZAWS_WEB_IDENTITY_TOKEN_FILEjwt)Z	saslStartr*   )Z	mechanismzMONGODB-OIDCpayloadrA   n)ZautoAuthorizer*   )r,   r   osenvironopenreadstripr   r   bsonencoder+   rG   r   r-   r   r.   r   rC   r0   rD   rg   )
r`   rQ   r,   Zaws_identity_fileZfidrf   ri   cmdr9   bin_payloadr"   r"   r#   auth_start_cmd   sT    







z!_OIDCAuthenticator.auth_start_cmdNoner@   c                 C  s   d | _ d | _d | _d S )N)rG   rH   rM   )r`   r"   r"   r#   clear   s    z_OIDCAuthenticator.clearr   zMutableMapping[str, Any]Optional[Mapping[str, Any]])connrr   r)   c              
   C  s   z|j d|ddW S  tk
r~ } zN|   |jtkrldt|d krl| j| jkrV | j	|dd W Y S  W 5 d }~X Y nX d S )Nz	$externalT)Z	no_reauthrh   ri   reauthenticate)
commandr   rv   coder   rp   decoderK   rJ   authenticate)r`   rx   rr   excr"   r"   r#   run_command   s    
z_OIDCAuthenticator.run_commandF)rx   rz   r)   c                 C  s8  |r8t |dd }|| jkr8| j| _d | _| jjs8|   |j}d }|rV|	 rV|j
}n |  }|d k	sjt| ||}|d k	st|d r| j|_d S t|d }d|kr|| _|  jd7  _|d }|  }	| j|_ttd|	i}
tdd|fd|
fg}| ||}|d k	st|d s4|   td	|S )
Noidc_token_gen_iddoneri   Zissuerr*   ZconversationIdrh   )ZsaslContinuer*   z%SASL conversation failed to complete.)getattrrL   rK   rJ   rM   r,   r   rv   Zauth_ctxZspeculate_succeededZspeculative_authenticatert   AssertionErrorr   r   rp   r}   rG   rg   r   rq   r   r   )r`   rx   rz   Zprev_idctxrr   respZserver_respZconversation_idrf   rs   r"   r"   r#   r~     sL    

z_OIDCAuthenticator.authenticate)T)T)F)r   r   r    r!   r   rG   rH   rJ   rK   rL   rM   rD   r0   	threadingLockrO   rg   rt   rv   r   r~   r"   r"   r"   r#   r&   j   s    
J9 r   rP   rw   )r'   rx   rz   r)   c                 C  s   t | |j}|j||dS )z Authenticate using MONGODB-OIDC.ry   )r?   r(   r~   )r'   rx   rz   Zauthenticatorr"   r"   r#   _authenticate_oidc@  s    r   ).__doc__
__future__r   rk   r   Zdataclassesr   r   r   r   r   typingr   r	   r
   r   r   r   r   r   r   rp   Zbson.binaryr   Zbson.sonr   Zpymongo.errorsr   r   Zpymongo.helpersr   Zpymongo.authr   Zpymongo.poolr   r   rX   rZ   rC   r\   r%   r!   r?   rD   r&   r   r"   r"   r"   r#   <module>   s6   ,	' V