a
    o½Df¶£  ã                   @   s¨  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 d dlZd dlmZ d dl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mZm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%m&Z&m'Z' d	dl(m)Z) d	dl*m+Z+m,Z, e -e.¡Z/dZ0dZ1dd„ Z2dd„ Z3dd„ Z4dd„ Z5G dd„ dej6jeƒZ7G dd„ de7ƒZ8G dd„ de8ƒZ9G dd „ d e8ƒZ:G d!d"„ d"e7ƒZ;G d#d$„ d$e7ƒZ<G d%d&„ d&e7ƒZ=G d'd(„ d(e7ƒZ>G d)d*„ d*e7ƒZ?G d+d,„ d,e7ƒZ@G d-d.„ d.e7ƒZAG d/d0„ d0e7ƒZBG d1d2„ d2eƒZCG d3d4„ d4ej6jƒZDG d5d6„ d6eƒZEG d7d8„ d8eEƒZFe=e?e@e<e8eBe;e>eAe9e:d9œZGe!d:ƒD ]ZHeH I¡ eGeHjJ< qteKeG L¡ ƒejM Nd;¡d< _NdS )=é    N)Úurlsafe_b64encode)Úpartial)ÚAuthProvider)ÚOAuth2Mixin)Ú	HTTPErrorÚHTTPRequest)r   ÚRequestHandlerÚdecode_signed_value)ÚWebSocketHandleré   )Úconfig)Úentry_points_for)ÚBASIC_LOGIN_TEMPLATEÚCDN_DISTÚERROR_TEMPLATEÚLOGOUT_TEMPLATEÚ_env)Ústate)Úbase64url_encodeÚdecode_tokenzpanel-oauth-statezpanel-oauth-codec                 C   s^   zt  | jd¡}W n  ty2   t  | jd¡}Y n0 t dd|¡}t dd|¡}t |¡}|S )z°
    Decodes the JSON-format response body

    Arguments
    ---------
    response: tornado.httpclient.HTTPResponse

    Returns
    -------
    Decoded response content
    Úasciiúutf-8ú"ú')ÚcodecsÚdecodeÚbodyÚ	ExceptionÚreÚsubÚjsonÚloads)Úresponser   © r#   úW/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/panel/auth.pyÚdecode_response_body&   s    
r%   c                 C   s    |   ||   d|› dg¡¡d S )zH
    Extracts a request argument from a urllib.parse.parse_qs dict.
    z/?Nr   )Úget)ÚargsÚkeyr#   r#   r$   Úextract_urlparam=   s    r)   c                 C   s    t  | ¡}t | d¡¡ d¡S )zCSerialize OAuth state to a base64 string after passing through JSONÚutf8r   )r    ÚdumpsÚbase64r   Úencoder   )r   Ú
json_stater#   r#   r$   Ú_serialize_stateD   s    
r/   c                 C   s€   t | tƒr|  d¡} zt | ¡ d¡}W n" tyJ   t d| ¡ i  Y S 0 zt	 
|¡W S  tyz   t d|¡ i  Y S 0 dS )z9Deserialize OAuth state as serialized in _serialize_stater   r*   zFailed to b64-decode state: %rzFailed to json-decode state: %rN)Ú
isinstanceÚstrr-   r,   Úurlsafe_b64decoder   Ú
ValueErrorÚlogÚerrorr    r!   )Z	b64_stater.   r#   r#   r$   Ú_deserialize_stateJ   s    


r6   c                   @   sª   e Zd ZdddœZg d¢ZddiZdZdZeZ	dZ
ed	d
„ ƒZd$dd„Zd%dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd&dd„Zd'd d!„Zd"d#„ ZdS )(ÚOAuthLoginHandlerúapplication/jsonúTornado OAuth©ÚAcceptz
User-Agent)ÚopenidÚemailÚprofileZoffline_accessÚ
grant_typeÚauthorization_codeNú/loginc                 C   s>   dt jv rt jd S dtjvr$| jS dd„ tjd  d¡D ƒS )NÚscopeZPANEL_OAUTH_SCOPEc                 S   s   g | ]}|‘qS r#   r#   )Ú.0rB   r#   r#   r$   Ú
<listcomp>u   ó    z,OAuthLoginHandler._SCOPE.<locals>.<listcomp>ú,)r   Úoauth_extra_paramsÚosÚenvironÚ_DEFAULT_SCOPESÚsplit©Úselfr#   r#   r$   Ú_SCOPEo   s
    


zOAuthLoginHandler._SCOPEc           	      Ã   sª   |r(| j ||||dI dH \}}}}|S |||dd|idœ}dtjv rXtjd |d d< | jdurl| j|d< dtjv r„tjd |d< t d	t| ƒj¡ | jf i |¤Ž dS )
aÓ  
        Fetches the authenticated user

        Arguments
        ---------
        redirect_uri: (str)
          The OAuth redirect URI
        client_id: (str)
          The OAuth client ID
        state: (str)
          The unguessable random string to protect against
          cross-site request forgery attacks
        client_secret: (str, optional)
          The client secret
        code: (str, optional)
          The response code from the server
        )Úclient_secretÚcodeNrP   r   )Úredirect_uriÚ	client_idrO   Úresponse_typeÚextra_paramsZaudiencerT   rB   z%s making authorize request)	Ú_fetch_access_tokenr   rG   rN   r4   ÚdebugÚtypeÚ__name__Zauthorize_redirect)	rM   rQ   rR   r   rO   rP   ÚuserÚ_Úparamsr#   r#   r$   Úget_authenticated_userw   s.    üÿû	



z(OAuthLoginHandler.get_authenticated_userc              
   Ã   s:  t  dt| ƒj¡ d|i| j¥}|r,||d< | jrBd | j¡|d< |rN||d< |rhd}	||d< d|d	< nd
}	|rz||d< n |rŽ|j||d n|  ¡ |d< |  	¡ }
t
| jdt |¡| jd}z|
 |¡I dH }W nH ty } z.t  dt| ƒj¡ | j|jdd W Y d}~n
d}~0 0 |jr0t|ƒ }sLt  dt| ƒj¡ |  |¡ d|vr‚|rrt  dt| ƒj¡ dS | j||dd | d¡}|ršt|ƒ}|d | d¡ }}|	rÀd|||fS | d¡ }rz|  ||||¡}W n tyø   Y n 0 t  dt| ƒj¡ ||||fS t| jƒ}| jr¬| jrN| j}| j |d ¡|d< nd | j|d ¡}t  dt| ƒj¡ z |
j||dI dH }t|ƒ}W n tyª   d}Y n0 |st  dt| ƒj¡ zt|d ƒ}W n6 ty
   t  d t| ƒj¡ | j||dd Y n0 t  d!t| ƒj¡ |  ||||¡}||||fS )"aµ  
        Fetches the access token.

        Arguments
        ---------
        client_id:
          The client ID
        redirect_uri:
          The redirect URI
        code:
          The response code from the server
        client_secret:
          The client secret
        refresh_token:
          A token used for refreshing the access_token
        username:
          A username
        password:
          A password
        z%s making access token request.rR   rQ   ú rB   rP   TÚrefresh_tokenr?   FrO   )ÚusernameÚpasswordÚcode_verifierÚPOST)Úmethodr   ÚheadersNz%s access token request failed.é‘  )Ústatusz6%s token endpoint did not return a valid access token.Úaccess_tokenz2%s token endpoint did not reissue an access token.)NNNÚ
expires_inÚid_tokenz3%s successfully obtained access_token and id_token.ÚAuthorizationz{}{}z%s requesting OpenID userinfo.)rd   z¾%s could not fetch user information, the token endpoint did not return an id_token and no OpenID user info endpoint was provided. Attempting to code access_token to resolve user information.z!%s could not decode access_token.z3%s successfully obtained access_token and userinfo.)r4   rV   rW   rX   Ú_EXTRA_TOKEN_PARAMSrN   ÚjoinÚupdateÚget_code_cookieZget_auth_http_clientr   Ú_OAUTH_ACCESS_TOKEN_URLÚurlparseÚ	urlencodeÚ_API_BASE_HEADERSÚfetchÚHTTPClientErrorÚ_raise_errorr"   r   r%   r&   ÚintÚ_on_authr   ÚdictÚ_OAUTH_USER_URLÚ_access_token_headerÚformatr   r   )rM   rR   rQ   rO   rP   r^   r_   r`   r[   Z
refreshingÚhttpÚreqr"   Úer   rh   rg   ri   rY   Zuser_headersZuser_urlZuser_responser#   r#   r$   rU   ¥   s¢    ÿþ

ü&



ÿ

üz%OAuthLoginHandler._fetch_access_tokenc                 C   s8   | j du r2| jttjdpd dd¡| _ |  t¡ | j S )z[Get OAuth state from cookies
        To be compared with the value in redirect URL
        N©Zmax_age_daysrE   r*   Úreplace)Ú_state_cookieÚget_secure_cookieÚSTATE_COOKIE_NAMEr   Úoauth_expiryr   Úclear_cookierL   r#   r#   r$   Úget_state_cookie!  s    
ÿþ
z"OAuthLoginHandler.get_state_cookiec                 C   s   | j t|tjdd d S ©NT)Úexpires_daysÚhttponly)Úset_secure_cookierƒ   r   r„   )rM   r   r#   r#   r$   Úset_state_cookie,  s    
ÿz"OAuthLoginHandler.set_state_cookiec                 C   s   | j j | jd¡}|  d|¡ }}|rx| dt d¡¡}t |¡}|jddd|j 	d¡ d 
¡ }||krxt d||¡ tt ¡ j|pˆddœƒS )NÚ Únextú\ú/)ÚschemeÚnetlocÚpathzIgnoring next_url %r, using %r)Zstate_idÚnext_url)ÚrequestÚurir€   Ú_login_endpointÚget_argumentrp   ÚquoteÚ_replacer’   ÚlstripÚgeturlr4   Úwarningr/   ÚuuidÚuuid4Úhex)rM   Zroot_urlr“   Zoriginal_next_urlZurlinfor#   r#   r$   Ú	get_state1  s    
ÿ
ÿÿzOAuthLoginHandler.get_statec                 C   sP   t  ¡ jt  ¡ j t  ¡ j }t | d¡¡ ¡ }t|ƒ d¡ 	dd¡}||fS )Nr   ú=rŒ   )
r   rž   rŸ   ÚhashlibÚsha256r-   Údigestr   r   r€   )rM   ra   Zhashed_code_verifierÚcode_challenger#   r#   r$   Úget_codeE  s    zOAuthLoginHandler.get_codec                 C   s*   | j ttjdpd dd¡}|  t¡ |S )Nr   rE   r*   r€   )r‚   ÚCODE_COOKIE_NAMEr   r„   r   r…   ©rM   rP   r#   r#   r$   rn   K  s    
z!OAuthLoginHandler.get_code_cookiec                 C   s   | j t|tjdd d S r‡   )rŠ   r§   r   r„   r¨   r#   r#   r$   Úset_code_cookieP  s    
ÿz!OAuthLoginHandler.set_code_cookiec                 Ã   sº  t  dt| ƒj¡ tjr tj}nd | jj| jj	¡}|tj
dœ}|  di ¡}|rlt |¡}dd„ | ¡ D ƒ}|  dt|dƒ¡}|  dt|dƒ¡}|  d	t|d	ƒ¡}|d uræ|  d
t|d
ƒ¡}|sÄ|}t  dt| ƒj|¡ td||d‚|  ¡ }|r†||krt  d||¡ tdddd‚t|ƒ}	| tj||dœ¡ | jf i |¤ŽI d H }
|
d u r`tddƒ‚t  dt| ƒj¡ |  |	 dd¡¡ n0|  ¡  |d< }	|  |	¡ | jf i |¤ŽI d H  d S )Nz%s received login requestz	{0}://{1})rQ   rR   r   c                 S   s    i | ]\}}|  d ¡d |“qS )ú?éÿÿÿÿ)rK   )rC   ÚargÚvaluer#   r#   r$   Ú
<dictcomp>g  rE   z)OAuthLoginHandler.get.<locals>.<dictcomp>rP   r   r5   Úerror_descriptionz2%s failed to authenticate with following error: %sre   ©ÚreasonúOAuth state mismatch: %s != %sz=OAuth state mismatch. Please restart the authentication flow.zstate mismatch)rO   rP   r   é“  zPermissions unknown.ú'%s authorized user, redirecting to app.r“   r   )r4   rV   rW   rX   r   Úoauth_redirect_urir{   r”   ÚprotocolÚhostÚ	oauth_keyr—   rp   Úparse_qsÚitemsr)   r5   r   r†   rœ   r6   rm   Úoauth_secretr\   Úredirectr&   r    r‹   )rM   rQ   r[   Únext_argrP   Ú	url_stater5   Ú	error_msgÚcookie_stater   rY   r#   r#   r$   r&   U  s^    þþ

ÿ
þ
ý


zOAuthLoginHandler.getc           	      C   sP  t |tƒrt|ƒ}n|}tt |¡ƒ}tjp0| j}||v rD|| }nt	 
dt| ƒj|¡ tddƒ‚|  d¡ | jd|tjd tjr¾tj | d¡¡}tj | d¡¡}|r¾tj | d¡¡}| jd|tjd | jd	|tjd |rtj tjj¡ ¡ }| jd
tt|| ƒƒtjd |r2| jd|tjd |tjv rLtj |d ¡ |S )Nz-%s token payload did not contain expected %r.re   z,OAuth token payload missing user informationÚis_guestrY   ©rˆ   r   rg   ri   r„   r^   )r0   r1   r   r   r    r+   r   Zoauth_jwt_userÚ	_USER_KEYr4   r5   rW   rX   r   r…   rŠ   r„   r   Ú
encryptionÚencryptr-   ÚdtÚdatetimeÚnowÚtimezoneÚutcÚ	timestamprv   Ú_oauth_user_overridesÚpop)	rM   ri   rg   r^   rh   ÚdecodedZuser_keyrY   Únow_tsr#   r#   r$   rw   “  s8    



ÿ

zOAuthLoginHandler._on_authé  c                 C   sœ   z|pt |ƒ}W n tjjy*   |}Y n0 | jj dd¡}|jr`t |› d|j› d|› ¡ nt 	|› d|› d¡ t
|| dt|ƒ¡| dd	¡d
‚d S )NÚLoginHandlerrŒ   z OAuth provider returned a z error. The full response was: zN OAuth provider failed to fully authenticate returning the following response:Ú.r¯   r5   zUnknown errorr°   )r%   r    ÚdecoderÚJSONDecodeErrorÚ	__class__rX   r€   r5   r4   rœ   r   r&   r1   )rM   r"   r   rf   Úproviderr#   r#   r$   ru   ²  s"    
ÿ

þ

ýzOAuthLoginHandler._raise_errorc              	   K   sŠ   |d \}}}|   ¡  |  dd¡ t|tƒr<|j|j }}n,| jj dd¡}t	 
|› d|› ¡ d\}}|  | jjtjdd	||d
¡ d S )NÚexc_infoúContent-Typez	text/htmlrÑ   rŒ   z. OAuth provider encountered unexpected error: )z500: Internal Server Errorz&Server encountered unexpected problem.zPanel: Authentication ErrorzAuthentication Error)Únpm_cdnÚtitleZ
error_typer5   r¿   )Zclear_all_cookiesZ
set_headerr0   r   r±   Úlog_messagerÕ   rX   r€   r4   r5   ÚwriteÚ_error_templateÚrenderr   rÙ   )rM   Ústatus_codeÚkwargsrZ   r~   r5   r¿   rÖ   r#   r#   r$   Úwrite_errorÅ  s&    
ÿÿ
ûzOAuthLoginHandler.write_error)NN)NNNNNN)NN)NrÐ   )rX   Ú
__module__Ú__qualname__rr   rJ   rk   rz   r   r   rÝ   r–   ÚpropertyrN   r\   rU   r†   r‹   r    r¦   rn   r©   r&   rw   ru   rá   r#   r#   r#   r$   r7   Z   s6   þÿ
 ÿ
/  þ
|>

r7   c                   @   sH   e Zd ZdZddiZedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	dS )ÚGenericLoginHandlerú	Bearer {}r?   r@   c                 C   s   t j dtj d¡¡S )NZ	TOKEN_URLZPANEL_OAUTH_TOKEN_URL©r   rG   r&   rH   rI   rL   r#   r#   r$   ro   æ  s    z+GenericLoginHandler._OAUTH_ACCESS_TOKEN_URLc                 C   s   t j dtj d¡¡S )NZAUTHORIZE_URLZPANEL_OAUTH_AUTHORIZE_URLrç   rL   r#   r#   r$   Ú_OAUTH_AUTHORIZE_URLê  s    z(GenericLoginHandler._OAUTH_AUTHORIZE_URLc                 C   s   t j dtj d¡¡S )NZUSER_URLZPANEL_OAUTH_USER_URLrç   rL   r#   r#   r$   ry   î  s    z#GenericLoginHandler._OAUTH_USER_URLc                 C   s   t j dtj dd¡¡S )NZUSER_KEYZPANEL_USER_KEYr=   rç   rL   r#   r#   r$   rÃ   ò  s    zGenericLoginHandler._USER_KEYN)
rX   râ   rã   rz   rk   rä   ro   rè   ry   rÃ   r#   r#   r#   r$   rå   Þ  s   ÿ


rå   c                   @   s$   e Zd ZddiZdd„ Zdd„ ZdS )ÚPasswordLoginHandlerr?   r`   c                 C   s`   z|   d¡}W n ty$   d}Y n0 |   dd ¡}|rB|  d|¡ | jj|td}|  |¡ d S ©Nr5   rŒ   r   r“   )ÚerrormessageÚ	PANEL_CDN©r—   r   Ú
set_cookieÚ_login_templaterÞ   r   rÜ   ©rM   rë   r“   Úhtmlr#   r#   r$   r&   ý  s    
þzPasswordLoginHandler.getc                 Ã   sz   |   dd¡}|   dd¡}tjr&tj}n| jj› d| jj› | j› }| jtj|||dI d H \}}}}|sld S |  	d¡ d S )Nr_   rŒ   r`   ú://)rR   rQ   r_   r`   r   )
r—   r   rµ   r”   r¶   r·   r–   rU   r¸   r¼   )rM   r_   r`   rQ   rY   rZ   r#   r#   r$   Úpost  s    üzPasswordLoginHandler.postN)rX   râ   rã   rk   r&   ró   r#   r#   r#   r$   ré   ÷  s   ÿré   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚCodeChallengeLoginHandlerc                 Ã   sÚ   |   dd¡}|   dd¡}tjr&tj}n| jj› d| jj› | j› }|rJ|sX|  |¡ d S |  ¡ }||kr€t	 
d||¡ tddƒ‚t|ƒ}| j|tj||dI d H }|d u r²td	ƒ‚t	 d
t| ƒj¡ |  | dd¡¡ d S )NrP   rŒ   r   rò   r²   rÐ   zOAuth state mismatch)rP   r³   r´   r“   r   )r—   r   rµ   r”   r¶   r·   r–   Ú_authorize_redirectr†   r4   rœ   r   r6   r\   r¸   rV   rW   rX   r¼   r&   )rM   rP   r¾   rQ   rÀ   r   rY   r#   r#   r$   r&      s$    

zCodeChallengeLoginHandler.getc              	   C   sl   |   ¡ }|  |¡ |  ¡ \}}|  |¡ tjdd | j¡|d|d|dœ}t 	|¡}|  
| j› d|› ¡ d S )NrP   r]   ÚqueryZS256)rR   rS   rB   r   Zresponse_moder¥   Zcode_challenge_methodrQ   rª   )r    r‹   r¦   r©   r   r¸   rl   rN   rp   rq   r¼   rè   )rM   rQ   r   ra   r¥   r[   Zquery_paramsr#   r#   r$   rõ   8  s    


ø

z-CodeChallengeLoginHandler._authorize_redirectN)rX   râ   rã   r&   rõ   r#   r#   r#   r$   rô     s   rô   c                   @   s$   e Zd ZdZdZdZdZdZdZdS )ÚGithubLoginHandlerz»GitHub OAuth2 Authentication
    To authenticate with GitHub, first register your application at
    https://github.com/settings/applications/new to get the client ID and
    secret.
    z+https://github.com/login/oauth/access_tokenz(https://github.com/login/oauth/authorizezhttps://api.github.com/userztoken {}ÚloginN)	rX   râ   rã   Ú__doc__ro   rè   ry   rz   rÃ   r#   r#   r#   r$   r÷   L  s   r÷   c                   @   s$   e Zd ZddiZdZdZdZdZdS )ÚBitbucketLoginHandlerr;   r8   z.https://bitbucket.org/site/oauth2/access_tokenz+https://bitbucket.org/site/oauth2/authorizez0https://api.bitbucket.org/2.0/user?access_token=r_   N)rX   râ   rã   rr   ro   rè   ry   rÃ   r#   r#   r#   r$   rú   \  s   ÿrú   c                   @   sD   e Zd ZdZdZdZdZdZedd„ ƒZ	edd	„ ƒZ
ed
d„ ƒZdS )ÚAuth0Handlerræ   z!https://{0}.auth0.com/oauth/tokenzhttps://{0}.auth0.com/authorizezhttps://{0}.auth0.com/userinfor=   c                 C   s   t j dd¡}| j |¡S ©NZ	subdomainZexample©r   rG   r&   Ú_OAUTH_ACCESS_TOKEN_URL_r{   ©rM   Úurlr#   r#   r$   ro   s  s    z$Auth0Handler._OAUTH_ACCESS_TOKEN_URLc                 C   s   t j dd¡}| j |¡S rü   ©r   rG   r&   Ú_OAUTH_AUTHORIZE_URL_r{   rÿ   r#   r#   r$   rè   x  s    z!Auth0Handler._OAUTH_AUTHORIZE_URLc                 C   s   t j dd¡}| j |¡S rü   ©r   rG   r&   Ú_OAUTH_USER_URL_r{   rÿ   r#   r#   r$   ry   }  s    zAuth0Handler._OAUTH_USER_URLN)rX   râ   rã   rz   rþ   r  r  rÃ   rä   ro   rè   ry   r#   r#   r#   r$   rû   i  s   

rû   c                   @   sT   e Zd ZddiZddiZdZdZdZdZd	Z	e
d
d„ ƒZe
dd„ ƒZe
dd„ ƒZdS )ÚGitLabLoginHandlerr;   r8   r?   r@   zhttps://{0}/oauth/tokenzhttps://{0}/oauth/authorizezhttps://{0}/api/v4/userræ   r_   c                 C   s   t j dd¡}| j |¡S ©Nr   z
gitlab.comrý   rÿ   r#   r#   r$   ro   –  s    z*GitLabLoginHandler._OAUTH_ACCESS_TOKEN_URLc                 C   s   t j dd¡}| j |¡S r  r  rÿ   r#   r#   r$   rè   ›  s    z'GitLabLoginHandler._OAUTH_AUTHORIZE_URLc                 C   s   t j dd¡}| j |¡S r  r  rÿ   r#   r#   r$   ry      s    z"GitLabLoginHandler._OAUTH_USER_URLN)rX   râ   rã   rr   rk   rþ   r  r  rz   rÃ   rä   ro   rè   ry   r#   r#   r#   r$   r  „  s   ÿÿ

r  c                   @   sJ   e Zd ZdddœZdZdZdZdZedd	„ ƒZ	ed
d„ ƒZ
edd„ ƒZdS )ÚAzureAdLoginHandlerr8   r9   r:   z7https://login.microsoftonline.com/{tenant}/oauth2/tokenz;https://login.microsoftonline.com/{tenant}/oauth2/authorizerŒ   Zunique_namec                 C   s&   t j dtj dd¡¡}| jj|dS ©NZAAD_TENANT_IDÚtenantÚcommon)r	  ©rH   rI   r&   r   rG   rþ   r{   ©rM   r	  r#   r#   r$   ro   ³  s    z+AzureAdLoginHandler._OAUTH_ACCESS_TOKEN_URLc                 C   s&   t j dtj dd¡¡}| jj|dS r  ©rH   rI   r&   r   rG   r  r{   r  r#   r#   r$   rè   ¸  s    z(AzureAdLoginHandler._OAUTH_AUTHORIZE_URLc                 C   s   | j jf i tj¤ŽS ©N©r  r{   r   rG   rL   r#   r#   r$   ry   ½  s    z#AzureAdLoginHandler._OAUTH_USER_URLN©rX   râ   rã   rr   rþ   r  r  rÃ   rä   ro   rè   ry   r#   r#   r#   r$   r  ¦  s   þ

r  c                   @   sJ   e Zd ZdddœZdZdZdZdZedd	„ ƒZ	ed
d„ ƒZ
edd„ ƒZdS )ÚAzureAdV2LoginHandlerr8   r9   r:   z<https://login.microsoftonline.com/{tenant}/oauth2/v2.0/tokenz@https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorizerŒ   r=   c                 C   s&   t j dtj dd¡¡}| jj|dS r  r  r  r#   r#   r$   ro   Ï  s    z-AzureAdV2LoginHandler._OAUTH_ACCESS_TOKEN_URLc                 C   s&   t j dtj dd¡¡}| jj|dS r  r  r  r#   r#   r$   rè   Ô  s    z*AzureAdV2LoginHandler._OAUTH_AUTHORIZE_URLc                 C   s   | j jf i tj¤ŽS r  r  rL   r#   r#   r$   ry   Ù  s    z%AzureAdV2LoginHandler._OAUTH_USER_URLNr  r#   r#   r#   r$   r  Â  s   þ

r  c                   @   sZ   e Zd ZdZdddœZdZdZdZdZd	Z	d
Z
dZedd„ ƒZedd„ ƒZedd„ ƒZdS )ÚOktaLoginHandlerzˆOkta OAuth2 Authentication

    To authenticate with Okta you first need to set up and configure
    in the Okta developer console.
    r@   zcode,token,id_token)r?   rS   zhttps://{0}/oauth2/{1}/v1/tokenzhttps://{0}/oauth2/v1/tokenz#https://{0}/oauth2/{1}/v1/authorizezhttps://{0}/oauth2/v1/authorizez0https://{0}/oauth2/{1}/v1/userinfo?access_token=z,https://{0}/oauth2/v1/userinfo?access_token=r=   c                 C   s>   t j dd¡}t j dd¡}|r.| j ||¡S | j |¡S d S ©Nr   zokta.comÚserverÚdefault)r   rG   r&   rþ   r{   Ú_OAUTH_ACCESS_TOKEN_URL__©rM   r   r  r#   r#   r$   ro   ó  s
    z(OktaLoginHandler._OAUTH_ACCESS_TOKEN_URLc                 C   s>   t j dd¡}t j dd¡}|r.| j ||¡S | j |¡S d S r  )r   rG   r&   r  r{   Ú_OAUTH_AUTHORIZE_URL__r  r#   r#   r$   rè   ü  s
    z%OktaLoginHandler._OAUTH_AUTHORIZE_URLc                 C   s@   t j dd¡}t j dd¡}|r.| j ||¡S | j ||¡S d S r  )r   rG   r&   r  r{   Ú_OAUTH_USER_URL__r  r#   r#   r$   ry     s
    z OktaLoginHandler._OAUTH_USER_URLN)rX   râ   rã   rù   rk   rþ   r  r  r  r  r  rÃ   rä   ro   rè   ry   r#   r#   r#   r$   r  Þ  s"   þ

r  c                   @   s(   e Zd ZddiZg d¢ZdZdZdZdS )ÚGoogleLoginHandlerrØ   z0application/x-www-form-urlencoded; charset=utf-8)r<   r=   r>   z,https://accounts.google.com/o/oauth2/v2/authz*https://accounts.google.com/o/oauth2/tokenr=   N)rX   râ   rã   rr   rJ   rè   ro   rÃ   r#   r#   r#   r$   r    s   ÿr  c                   @   s0   e Zd ZeZdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚBasicLoginHandlerc                 C   s`   z|   d¡}W n ty$   d}Y n0 |   dd ¡}|rB|  d|¡ | jj|td}|  |¡ d S rê   rí   rð   r#   r#   r$   r&     s    
þzBasicLoginHandler.getc                 C   s®   dt j | ji ¡v r&t j| j d }ntj}t|tƒr|tj	 
|¡r|t|dd}t | ¡ ¡}W d   ƒ n1 sr0    Y  t|tƒrž||vr’dS ||| kS ||krªdS dS )NÚ
basic_authr   )ÚencodingFT)r   Z_server_configr&   Úapplicationr   r  r0   r1   rH   r’   ÚisfileÚopenr    r!   Úreadrx   )rM   r_   r`   Z	auth_infoZ	auth_filer#   r#   r$   Ú	_validate-  s    ,
zBasicLoginHandler._validatec                 C   sp   |   dd¡}|   dd¡}|  ||¡}|rJ|  |¡ |  dd¡}|  |¡ n"dtj d¡ }|  | jj	| ¡ d S )Nr_   rŒ   r`   r“   r   z?error=zInvalid username or password!)
r—   r"  Úset_current_userZ
get_cookier¼   ÚtornadoÚescapeZ
url_escaper”   r•   )rM   r_   r`   Úauthr“   r¿   r#   r#   r$   ró   =  s    
zBasicLoginHandler.postc                 C   sx   |s|   d¡ |   d¡ d S |   d¡ | jd|tjd tt d|i¡ƒ}tjrbtj 	| 
d¡¡}| jd|tjd d S )NrÁ   rY   rÂ   r   ri   )r…   rŠ   r   r„   r   r    r+   r   rÄ   rÅ   r-   )rM   rY   ri   r#   r#   r$   r#  I  s    


z"BasicLoginHandler.set_current_userN)	rX   râ   rã   r   rï   r&   r"  ró   r#  r#   r#   r#   r$   r    s
   r  c                   @   s   e Zd ZdZeZdd„ ZdS )ÚLogoutHandlerrA   c                 C   s\   |   d¡ |   d¡ |   d¡ |   d¡ |   d¡ |   t¡ | jjt| jd}|  |¡ d S )NrY   ri   rg   r^   r„   )rì   ZLOGIN_ENDPOINT)r…   rƒ   Ú_logout_templaterÞ   r   r–   rÜ   )rM   rñ   r#   r#   r$   r&   \  s    





þzLogoutHandler.getN)rX   râ   rã   r–   r   r(  r&   r#   r#   r#   r$   r'  V  s   r'  c                       sn   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zed	d
„ ƒZedd„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZ‡  ZS )ÚBasicAuthProviderzF
    An AuthProvider which serves a simple login and logout page.
    Nc                    s  |d u rt | _n8t|ƒ }t | ¡ ¡| _W d   ƒ n1 s>0    Y  |d u rXt| _n8t|ƒ }t | ¡ ¡| _W d   ƒ n1 s†0    Y  |d u r t| _	n8t|ƒ }t | ¡ ¡| _	W d   ƒ n1 sÎ0    Y  |pÞd| _
|pèd| _|pòg | _t | j¡ tƒ  ¡  d S )NrA   z/logout)r   rÝ   r   r   Zfrom_stringr!  r   r(  r   rï   r–   Ú_logout_endpointÚ_guest_endpointsr   Zon_session_destroyedÚ_remove_userÚsuperÚ__init__)rM   Zlogin_endpointZlogout_endpointZlogin_templateZlogout_templateÚerror_templateZguest_endpointsÚf©rÕ   r#   r$   r.  o  s"    
.
.
.


zBasicAuthProvider.__init__c                 C   s|   |j j d¡}|j j d¡}|r&d}n&|rHttjd|ƒ}|rL| d¡}nd }|sTd S tj|  d8  < tj| sxtj|= d S ©NrÁ   rY   Úguestr   r   )	r”   Úcookiesr&   r	   r   Úcookie_secretr   r   Ú_active_users©rM   Zsession_contextZguest_cookieZuser_cookierY   r#   r#   r$   r,  Š  s     ÿ
zBasicAuthProvider._remove_userc                 C   s6   t jr|| jksd|v sdS | dd¡| jv r2dS dS )Nz?code=Tz/wsrŒ   F)r   Zoauth_optionalr–   r€   r+  )rM   r•   r#   r#   r$   Ú_allow_guest  s    zBasicAuthProvider._allow_guestc                    s   ‡ fdd„}|S )Nc                    s~   | j dtjd}|r | d¡}n:ˆ  | jj¡rZd}d| jjd< t| t	ƒsZ| j
ddtjd |rzt| t	ƒrztj|  d7  < |S )	NrY   r   r   r3  Ú1rÁ   rÂ   r   )r‚   r   r„   r   r8  r”   r•   r4  r0   r
   rî   r   r6  )Zrequest_handlerrY   rL   r#   r$   Úget_user¤  s    
z,BasicAuthProvider.get_user.<locals>.get_userr#   ©rM   r:  r#   rL   r$   r:  ¢  s    zBasicAuthProvider.get_userc                 C   s   | j S r  )r–   rL   r#   r#   r$   Ú	login_url³  s    zBasicAuthProvider.login_urlc                 C   s   | j t_ | jt_tS r  )r–   r  rï   rL   r#   r#   r$   Úlogin_handler·  s    zBasicAuthProvider.login_handlerc                 C   s   | j S r  )r*  rL   r#   r#   r$   Ú
logout_url½  s    zBasicAuthProvider.logout_urlc                 C   s   | j r| j t_ | jt_tS r  )r(  r'  r–   rL   r#   r#   r$   Úlogout_handlerÁ  s    z BasicAuthProvider.logout_handler)NNNNNN)rX   râ   rã   rù   r.  r,  r8  rä   r:  r<  r=  r>  r?  Ú__classcell__r#   r#   r1  r$   r)  j  s"      ý



r)  c                       s\   e Zd ZdZedd„ ƒZe‡ fdd„ƒZedd„ ƒZdd	„ Zd
d„ Z	dd„ Z
dd„ Z‡  ZS )ÚOAuthProviderz~
    An AuthProvider using specific OAuth implementation selected via
    the global config.oauth_provider configuration.
    c                 C   s   d S r  r#   rL   r#   r#   r$   r:  Ï  s    zOAuthProvider.get_userc                    s   ‡‡ fdd„}|S )Nc                 “   s  t tˆƒ | ¡}tjr|d u r"|S tj tjj	¡ 
¡ }d }|tjv r„tj| s`t d¡I d H  qDtj| }|d }|d r°|d }n,| jdtjd}|s¦t d¡ d S t |¡}|d u rzt|ƒ}|d }W n@ ty   | jdtjd}|d u r
t d¡ | Y S Y n0 |tjv r,tj| d	 }n@| jd	tjd}	|	rht |	¡}ˆ |d ||| j| j¡ nd }||kr„t d
¡ |S |r¾zt|ƒ}
|
d |k r¦d }W n ty¼   Y n0 |d u rÞt dtˆƒj¡ d S t dtˆƒj¡ ˆ ||| j| j¡I d H  |S )Nçš™™™™™¹?rg   Úexpiryr   z:No access token available, forcing user to reauthenticate.Úexpr„   zCaccess_token is not a valid JWT token. Expiry cannot be determined.r^   z1Fully authenticated and access_token still valid.z[%s access_token is expired and refresh_token not available, forcing user to reauthenticate.ú%s refreshing token)r-  rA  r:  r   Zoauth_refresh_tokensrÆ   rÇ   rÈ   rÉ   rÊ   rË   r   rÌ   ÚasyncioÚsleepr‚   r„   r4   rV   Z_decrypt_cookier   r   Ú_schedule_refreshr  r”   rW   rX   Ú_refresh_access_token)ÚhandlerrY   rÏ   rC  Ú
user_staterg   Zaccess_cookieZaccess_jsonr^   Zrefresh_cookieZrefresh_json)rÕ   rM   r#   r$   r:  Õ  sb    












z.OAuthProvider.get_user_async.<locals>.get_userr#   r;  r1  rL   r$   Úget_user_asyncÓ  s    >zOAuthProvider.get_user_asyncc                 C   s,   t tj }| jr| j|_| j|_| j|_|S r  )ÚAUTH_PROVIDERSr   Zoauth_providerrÝ   rï   r–   )rM   rJ  r#   r#   r$   r=    s    
zOAuthProvider.login_handlerc                 C   sŽ   |j j d¡}|j j d¡}|r&d}n&|rHttjd|ƒ}|rL| d¡}nd }|sTd S tj|  d8  < tj| sŠtj|= |tj	v rŠtj	|= d S r2  )
r”   r4  r&   r	   r   r5  r   r   r6  rÌ   r7  r#   r#   r$   r,    s$    ÿ

zOAuthProvider._remove_userc                 C   sÚ   t j |¡sd S tj tjj¡ ¡ }|| d }t	 
dt| ƒj|¡ tj ¡ tj|d }t| j||||ƒ}	|dkr‚t  |	¡ d S |› d}
z6zt  |
¡ W n ty®   Y n0 W t j|
|	|d nt j|
|	|d 0 d S )Né
   z)%s scheduling token refresh in %d seconds)Úsecondsr   z-refresh-access-tokens)Úat)r   r6  r&   rÆ   rÇ   rÈ   rÉ   rÊ   rË   r4   rV   rW   rX   Ú	timedeltar   Ú_scheduled_refreshÚexecuteZcancel_taskÚKeyErrorZschedule_task)rM   Z	expiry_tsrY   r^   r  r”   rÏ   Zexpiry_secondsZexpiry_dateZ
refresh_cbZtaskr#   r#   r$   rH  3  s     

zOAuthProvider._schedule_refreshc                 Ã   sf   |   ||||¡I d H  tj| }|d |d  }}|d rD|d }nt|ƒd }|  |||||¡ d S )Nrg   r^   rC  rD  )rI  r   rÌ   r   rH  )rM   rY   r^   r  r”   rK  rg   rC  r#   r#   r$   rR  F  s    

z OAuthProvider._scheduled_refreshc           
      Ã   sÒ   |t jv rBt j| s4t j| s0t d¡I d H  qd S t j| d }t dt| ƒj¡ i t j|< | j||d}|j	t
jt
j|dI d H \}}}}|rÆtj tjj¡ ¡ }	|||r¶|	| nd dœt j|< nt j|= d S )NrB  r^   rE  )r  r”   )rR   rO   r^   )rg   r^   rC  )r   rÌ   rF  rG  r4   rV   rW   rX   r=  rU   r   r¸   r»   rÆ   rÇ   rÈ   rÉ   rÊ   rË   )
rM   rY   r^   r  r”   Zauth_handlerrZ   rg   rh   rÏ   r#   r#   r$   rI  P  s*    



ýýz#OAuthProvider._refresh_access_token)rX   râ   rã   rù   rä   r:  rL  r=  r,  rH  rR  rI  r@  r#   r#   r1  r$   rA  É  s   
A

rA  )Zauth0ZazureZazurev2Z	bitbucketZgenericZgoogleZgithubZgitlabZoktar`   Z	auth_codez
panel.authFZ_oauth_provider)OrF  r,   r   rÇ   rÆ   r¢   r    ÚloggingrH   r   Úurllib.parseÚparserp   r   r   Ú	functoolsr   r$  Zbokeh.server.auth_providerr   Ztornado.authr   Ztornado.httpclientr   rt   r   Ztornado.webr   r	   Ztornado.websocketr
   r   Zentry_pointsr   Zio.resourcesr   r   r   r   r   Zio.stater   Úutilr   r   Ú	getLoggerrX   r4   rƒ   r§   r%   r)   r/   r6   Zwebr7   rå   ré   rô   r÷   rú   rû   r  r  r  r  r  r  r'  r)  rA  rM  Úentry_pointÚloadÚnameÚlistÚkeysÚparamZobjectsr#   r#   r#   r$   Ú<module>   s‚   
   '."1<_ %õ