o
    RDi"B                     @  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Zd dl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 ddlmZmZmZmZmZ ddlmZmZ dd	lmZ d
dl m!Z! d
dl"m#Z# errddl$m%Z% e&e'Z(dZ)dddZ*G dd de#Z+dS )    )annotationsN)TYPE_CHECKINGAny   )parse_qsurlparseurlsplitOAUTH_TYPE_AUTHORIZATION_CODE)ER_INVALID_VALUEER_OAUTH_CALLBACK_ERRORER_OAUTH_SERVER_TIMEOUTER_OAUTH_STATE_CHANGEDER_UNABLE_TO_OPEN_BROWSER)ErrorProgrammingError)
TokenCache   )AuthHttpServer)AuthByOAuthBase)SnowflakeConnectioni @  urlstrreturndict[str, list[str]]c                 C  s   t t| j}|S Nr   r   query)r   parsed r   \/var/www/Datamplify/venv/lib/python3.10/site-packages/snowflake/connector/auth/oauth_code.py_get_query_params(   s   r!   c                      s   e Zd ZdZdZ							d^d_ fddZd`dd Zdad*d+Zdbd/d0Zdcd6d7Z	ddd9d:Z
ded;d<Zedfd>d?Zedgd@dAZdhdBdCZdidFdGZdjdIdJZdkdLdMZdldOdPZdmdQdRZedndSdTZdodVdWZdpdYdZZedqd\d]Z  ZS )rAuthByOauthCodez&Authenticates user by OAuth code flow.LOCAL_APPLICATIONTNFapplicationr   	client_idclient_secretauthentication_urltoken_request_urlredirect_uriscopehostpkce_enabledbooltoken_cacheTokenCache | Nonerefresh_token_enabledexternal_browser_timeout
int | None enable_single_use_refresh_tokens
connectionSnowflakeConnection | Noneuri
str | Noner   Nonec              	     s   |  |||\}}| ||||||\}}t jd	|||||
|d| || _d | _|| _|| _|| _t	
d| _tdddd | jD  d| _|	| _|	rVtd d | _|| _|| _d S )
N)r%   r&   r(   r*   r.   r0   +   zchose oauth state: %s c                 s  s    | ]}d V  qdS )*Nr   ).0_r   r   r    	<genexpr>b   s    z+AuthByOauthCode.__init__.<locals>.<genexpr>httpzoauth pkce is going to be usedr   )_validate_oauth_code_uris*_validate_client_credentials_with_defaultssuper__init___application_origin_authentication_url_redirect_uri_urisecretstoken_urlsafe_stateloggerdebugjoin	_protocol_pkce_enabled	_verifier_external_browser_timeout!_enable_single_use_refresh_tokens)selfr$   r%   r&   r'   r(   r)   r*   r+   r,   r.   r0   r1   r3   r4   r6   kwargs	__class__r   r    rC   4   sF   		

zAuthByOauthCode.__init__c                 C  s   t S r   r	   )rT   r   r   r    _get_oauth_type_idk   s   z"AuthByOauthCode._get_oauth_type_idconnr   authenticatorservice_nameaccountuserrU   r   (str | None, str | None)c          	      K  s^   t d t| j| jp| jd}| ||}| |||W  d   S 1 s(w   Y  dS )z!Web Browser based Authentication.z1authenticating with OAuth authorization code flow)r)   r6   N)rL   rM   r   rG   rH   _do_authorization_request_do_token_request)	rT   rY   rZ   r[   r\   r]   rU   callback_servercoder   r   r    _request_tokensn   s   

$zAuthByOauthCode._request_tokensdata	list[str]#tuple[str, str] | tuple[None, None]c                 C  s   d }d }d }|D ]}| dr|}q| dr|}q| dr!|}q|r3|r3|r3|dd  dkr5dS |dd  d|ddd   fS )NzAccess-Control-Request-Method:zAccess-Control-Request-Headers:zOrigin::r   POSTNN)
startswithsplitstriprN   )rT   rd   request_lineheader_lineorigin_lineliner   r   r    _check_post_requested   s,   


z%AuthByOauthCode._check_post_requestedsocket_clientsocket.sockethostnameportintc           	      C  s   |D ]	}| dr nqdS | |\}}|du s|du rdS | |||s(dS || _ddtdt dd| d	d
| j ddg}|d	|
d dS )z'Allows JS Ajax access to this endpoint.zOPTIONS FNHTTP/1.1 200 OKzDate: {}z%a, %d %b %Y %H:%M:%S GMTz'Access-Control-Allow-Methods: POST, GETzAccess-Control-Allow-Headers: zAccess-Control-Max-Age: 86400Access-Control-Allow-Origin: r:   
utf-8T)rj   rq   _validate_originrE   formattimestrftimegmtimesendallrN   encode)	rT   rd   rr   rt   ru   rp   requested_headersrequested_origincontentr   r   r    _process_options   s0   

z AuthByOauthCode._process_optionsr   c                 C  s^   t |}|jd}|d }t|dkr|d n| jdkrdnd}|j| jko.||ko.||kS )Nrg   r   r   httpsi  P   )r   netlocrk   lenrO   scheme)rT   r   rt   ru   retr   host_gotport_gotr   r   r    r{      s   $z AuthByOauthCode._validate_originc                 C  s   |  |sd S ddg}| jr%td| ji}|d| j  |d nd| j d}|dt|  |d	 || |d
	|
d d S )Nrw   zContent-Type: text/htmlconsentrx   zVary: Accept-Encoding, Originz
<!DOCTYPE html><html><head><meta charset="UTF-8"/>
<link rel="icon" href="data:,">
<title>OAuth Response for Snowflake</title></head>
<body>
Your identity was confirmed and propagated to Snowflake zR.
You can close this window now and go back where you started from.
</body></html>zContent-Length: r:   ry   rz   )_is_request_getrE   jsondumpsconsent_cache_id_tokenappendrD   r   r   rN   r   )rT   rd   rr   responsemsgr   r   r    _send_response   s    


zAuthByOauthCode._send_responser   c                 C  s   dt t| jv S )Nrb   r   )r   r   r   r    	_has_code   s   zAuthByOauthCode._has_codec                 C  s   t dd | D S )z!Whether an HTTP request is a GET.c                 s  s    | ]}| d V  qdS )zGET N)rj   )r<   rp   r   r   r    r>      s    z2AuthByOauthCode._is_request_get.<locals>.<genexpr>)any)rd   r   r   r    r      s   zAuthByOauthCode._is_request_getc                 C  s   d| j || jd}| jr| j|d< | jr6td| _tt	
| jd dd}||d< d|d	< tj|}| j d
| }|S )Nrb   )response_typer%   r)   stater*   r9   rz   =code_challengeS256code_challenge_method?)
_client_idrK   _scoperP   rI   rJ   rQ   base64urlsafe_b64encodehashlibsha256r   digestdecoderstripurllibparse	urlencoderF   )rT   r)   params	challenge
url_paramsr   r   r   r     _construct_authorization_request   s(   
z0AuthByOauthCode._construct_authorization_requestra   r   c                 C  s   |  |j}td td t|r| ||n| ||\}}|s0| j	|t
ddd d S || jkrP| j	|tddd tddt| dt|  d S |S )	Nz'step 1: going to open authorization URLzInitiating login request with your identity provider. A browser window should have opened for you to complete the login. If you can't see it, check existing browser windows, or your OS settings. Press CTRL+C to abort and try again...z[Unable to open a browser in this environment and OAuth URL contained no authorization code.rb   messagerY   r   z#State changed during OAuth process.z%received oauth code: %s and state: %sr;   )r   r)   rL   rM   print
webbrowseropen_receive_authorization_callback%_ask_authorization_callback_from_user_handle_failurer   rK   r   r   )rT   ra   r4   authorization_requestrb   r   r   r   r    r_     sF   
	



z)AuthByOauthCode._do_authorization_requestrb   c                 C  sP   t d d||jd}| jrd|d< | jr"| jd usJ | j|d< | ||S )Nz1step 2: received OAuth callback, requesting tokenauthorization_code)
grant_typerb   r)   truer3   code_verifier)rL   rM   r)   rS   rP   rQ   _get_request_token_response)rT   rb   ra   r4   fieldsr   r   r    r`   9  s   

z!AuthByOauthCode._do_token_requesthttp_serverc                 C  s   t d |j| jd\}}|d u r| j|tddd dS z(z| |||j|js0| 	|| |
tj W n	 ty@   Y nw W |  n|  w | |d jdd	d
 |S )Nz.trying to receive authorization redirected uri)timeoutzhUnable to receive the OAuth message within a given timeout. Please check the redirect URI and try again.r   r   ri   r   r   )maxsplitr   )rL   rM   receive_blockrR   r   r   r   rt   ru   r   shutdownsocket	SHUT_RDWROSErrorclose'_parse_authorization_redirected_requestrk   )rT   r   r4   rd   socket_connectionr   r   r    r   L  s6   

z/AuthByOauthCode._receive_authorization_callbackr   c                 C  sP   t d td|  td}| ||\}}|s$| j|tddd ||fS )Nz1requesting authorization redirected url from userzWe were unable to open a browser window for you, please open the URL manually then paste the URL you are redirected to into the terminal:
z0Enter the URL the OAuth flow redirected you to: zLUnable to open a browser in this environment and OAuth URL contained no coder   r   )rL   rM   r   inputr   r   r   )rT   r   r4   received_redirected_requestrb   r   r   r   r    r   m  s*   

z5AuthByOauthCode._ask_authorization_callback_from_userc              	   C  sz   t t|j}d|v r+| j|td|d d  dd|v r#d|d d  nd dd	 |d
d gd |dd gd fS )NerrorzOauth callback returned an r   z errorerror_descriptionz: .r   r   rb   r   )r   r   r   r   r   get)rT   r   rY   r   r   r   r    r     s   .$z7AuthByOauthCode._parse_authorization_redirected_requestc                 C  s    | dks|| v o|dkp||v S Nr:   r   )r'   r(   r+   r   r   r    _is_snowflake_as_idp  s   z$AuthByOauthCode._is_snowflake_as_idpauthorization_urlc                 C  s0   |dks|d u o|dkp|d u o| j |||S r   )rW   r   )rT   r%   r&   r   r(   r+   r   r   r    (_eligible_for_default_client_credentials  s   	z8AuthByOauthCode._eligible_for_default_client_credentialstuple[str, str] | Nonec                 C  s8   |  |||||r| jj| jjfS | ||| ||fS r   )r   rW   %_LOCAL_APPLICATION_CLIENT_CREDENTIALS$_validate_client_credentials_present)rT   r%   r&   r   r(   r+   r4   r   r   r    rA     s   	
z:AuthByOauthCode._validate_client_credentials_with_defaultstuple[str, str]c                 C  sZ   | r|  dst|d tdtd |r)| ds)| ds)t|d tdtd | |fS )Nzhttps://z>OAuth supports only authorization urls that use 'https' scheme)r   errnozhttp://z@OAuth supports only authorization urls that use 'http(s)' scheme)rj   r   errorhandler_wrapperr   r   )r   r)   r4   r   r   r    r@     s.   		z)AuthByOauthCode._validate_oauth_code_uris)TNFNFNN) r$   r   r%   r   r&   r   r'   r   r(   r   r)   r   r*   r   r+   r   r,   r-   r.   r/   r0   r-   r1   r2   r3   r-   r4   r5   r6   r7   r   r8   )r   r   )rY   r   rZ   r   r[   r7   r\   r   r]   r   rU   r   r   r^   )rd   re   r   rf   )
rd   re   rr   rs   rt   r   ru   rv   r   r-   )r   r   rt   r   ru   rv   r   r-   )rd   re   rr   rs   r   r8   )r   r   r   r-   )rd   re   r   r-   )r)   r   r   r   )ra   r   r4   r   r   r7   )rb   r   ra   r   r4   r   r   r^   )r   r   r4   r   r   r^   )r   r   r4   r   r   r^   )r   r   rY   r   r   r^   )r'   r   r(   r   r+   r   r   r-   )r%   r   r&   r   r   r   r(   r   r+   r   r   r-   )r%   r   r&   r   r   r   r(   r   r+   r   r4   r   r   r   )r   r   r)   r   r4   r   r   r   )__name__
__module____qualname____doc__r   rC   rX   rc   rq   r   r{   r   staticmethodr   r   r   r_   r`   r   r   r   r   r   rA   r@   __classcell__r   r   rV   r    r"   /   sB    
7



!



3

!
 

r"   )r   r   r   r   ),
__future__r   r   r   r   loggingrI   r   r}   urllib.parser   r   typingr   r   compatr   r   r   	constantsr
   	errorcoder   r   r   r   r   errorsr   r   r.   r   _http_serverr   _oauth_baser   r:   r   	getLoggerr   rL   BUF_SIZEr!   r"   r   r   r   r    <module>   s0   

