
    ;g                        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mZ d dlZd dlm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/m0Z0  ejb                  e2      Z3dZ4dZ5d Z6d Z7d Z8d Z9 G d dejt                  j>                  e      Z; G d de;      Z< G d de<      Z= G d de<      Z> G d d e;      Z? G d! d"e;      Z@ G d# d$e;      ZA G d% d&e;      ZB G d' d(e;      ZC G d) d*e;      ZD G d+ d,e;      ZE G d- d.e;      ZF G d/ d0e      ZG G d1 d2ejt                  j>                        ZH G d3 d4e      ZI G d5 d6eI      ZJ G d7 d8eG      ZKeAeCeDe@e<eFe?eBeEe=e>eKd9ZL e%d:      D ]  ZMeMj                         eLeMj                  <   !  ePeLj                               e#j                  j                  d;      d<   _S        y)=    N)urlsafe_b64encode)partial)ClassVar)AuthProvider)get_token_payload)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                 Z   	 t        j                  | j                  d      }t	        j
                  dd|      }t	        j
                  dd|      }t	        j
                  dd|      }t        j                  |      }|S # t        $ r# t        j                  | j                  d      }Y w xY w)z
    Decodes the JSON-format response body

    Parameters
    ----------
    response: tornado.httpclient.HTTPResponse

    Returns
    -------
    Decoded response content
    asciiutf-8'z\"")codecsdecodebody	Exceptionresubjsonloads)responser    s     *lib/python3.12/site-packages/panel/auth.pydecode_response_bodyr(   (   s    5}}X]]G4 66$t$D66#tT"D66#sD!D::dDK  5}}X]]G45s    A> >)B*)B*c                 T    | j                  || j                  d| dg            d   S )zH
    Extracts a request argument from a urllib.parse.parse_qs dict.
    z/?Nr   )get)argskeys     r'   extract_urlparamr-   @   s-     88CBse*tf56q99    c                     t        j                  |       }t        j                  |j	                  d            j                  d      S )zCSerialize OAuth state to a base64 string after passing through JSONutf8r   )r$   dumpsbase64r   encoder   )r   
json_states     r'   _serialize_stater5   G   s7    E"J##J$5$5f$=>EEgNNr.   c                 V   t        | t              r| j                  d      } 	 t        j                  |       j                  d      }	 t        j                  |      S # t        $ r t        j                  d|        i cY S w xY w# t        $ r t        j                  d|       i cY S w xY w)z9Deserialize OAuth state as serialized in _serialize_stater   r0   zFailed to b64-decode state: %rzFailed to json-decode state: %r)
isinstancestrr3   r2   urlsafe_b64decoder   
ValueErrorlogerrorr$   r%   )	b64_stater4   s     r'   _deserialize_stater>   M   s    )S!$$W-	--i8??G
zz*%%	  		2I>	
  		3Z@	s#   $A B !B B!B('B(c                       e Zd ZU dddZg dZddiZdZeedz     e	d<   dZ
eedz     e	d	<   eZd
Zee   e	d<   ed        Z	 ddZ	 	 ddZd Zd Zd Zd Zd Zd Zd Zedd       ZddZd Zy)OAuthLoginHandlerapplication/jsonTornado OAuthAcceptz
User-Agent)openidemailprofileoffline_access
grant_typeauthorization_codeN_access_token_header_state_cookie/login_login_endpointc                     dt         j                  v rt         j                  d   S dt        j                  vr| j                  S t        j                  d   j                  d      D cg c]  }| c}S c c}w )NscopePANEL_OAUTH_SCOPE,)r   oauth_extra_paramsosenviron_DEFAULT_SCOPESsplit)selfrP   s     r'   _SCOPEzOAuthLoginHandler._SCOPEr   sh    f///,,W55 

2'''#%::.A#B#H#H#MN#M%#MNNNs   (	A4c                   K   |r$| j                  ||||       d{   \  }}}}|S |||dd|id}dt        j                  v rt        j                  d   |d   d<   | j                  | j                  |d<   dt        j                  v rt        j                  d   |d<   t        j                  d	t        |       j                          | j                  d
i | y7 w)a  
        Fetches the authenticated user

        Parameters
        ----------
        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codeNr\   r   )redirect_uri	client_idr[   response_typeextra_paramsaudiencer`   rP   z%s making authorize request )	_fetch_access_tokenr   rS   rY   r;   debugtype__name__authorize_redirect)	rX   r]   r^   r   r[   r\   user_paramss	            r'   get_authenticated_userz(OAuthLoginHandler.get_authenticated_userz   s     & "&":":+	 #; # MD!Q K )%*#
 222171J1J:1VF>":.;;""kkF7Of///$77@F7O		/d1D1DE)&)1s   CCC Cc                   K   t         j                  dt        |       j                         d|i| j                  }|r||d<   | j
                  rdj                  | j
                        |d<   |r||d<   |rd}	||d<   d|d	<   nd
}	|r||d<   n)|r|j                  ||       n| j                         |d<   | j                         }
t        | j                  dt        j                  |      | j                        }	 |
j                  |       d{   }j&                  rt)        |      x}s:t         j                  dt        |       j                         | j#                  |       dvr@|r*t         j                  dt        |       j                         y| j#                  ||d       |j+                  d      }|rt-        |      }|d   |j+                  d      }}|	rd|||fS |j+                  d      x}rI	 t.        j1                  | ||||      }t         j                  dt        |       j                         ||||fS t5        | j                        }| j6                  r| j8                  r.| j6                  }| j8                  j;                  |d         |d<   ndj;                  | j6                  |d         }t         j                  dt        |       j                         	 |
j                  ||       d{   }t)        |      }|s8t         j                  dt        |       j                         	 t=        |d         }t         j                  d!t        |       j                         t.        j1                  | ||||      }||||fS 7 # t         $ rQ}t         j                  dt        |       j                         | j#                  |j$                  d       Y d}~d}~ww xY w# t2        $ r Y w xY w7 # t         $ r d}Y w xY w# t>        $ rA t         j                  d t        |       j                         | j#                  ||d       Y w xY ww)"a  
        Fetches the access token.

        Parameters
        ----------
        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.r^   r]    rP   r\   Trefresh_tokenrI   Fr[   )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.)rt   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.) r;   rd   re   rf   _EXTRA_TOKEN_PARAMSrY   joinupdateget_code_cookieget_auth_http_clientr
   _OAUTH_ACCESS_TOKEN_URLurlparse	urlencode_API_BASE_HEADERSfetchHTTPClientError_raise_errorr&   r    r(   r*   intr@   set_auth_cookiesr	   dict_OAUTH_USER_URLrK   formatr   r!   )rX   r^   r]   r[   r\   rn   ro   rp   rj   
refreshinghttpreqr&   er    ry   rw   rz   rh   user_headersuser_urluser_responses                         r'   rc   z%OAuthLoginHandler._fetch_access_token   s    0 			3T$Z5H5HI
&&
 %1F>";;!hht{{3F7O!F6NJ&3F?##2F< J&3F?#MM8hM?&*&:&:&<F?#((* ((##F+**	
	6!ZZ_,H
 }},@,J%JT%JIINPTUYPZPcPcdh'%		NPTUYPZPcPcd'hS9XXl+
ZJ&*>&:DHH_<Um}j@@,,X,E(99$,Xegqr 		OQUVZQ[QdQde\=*DDD223((//040I0I0P0P(1_- "==)=)=tN?STII6T
8K8KL &*jj<j&P P/> IIO T
##	>'^(<=
 			GdI\I\] 11$,P]_ij\=*<<A - 	6II7d9L9LMajj55	62  $ !Q"     >		=tDz?R?RS!!(D!=>s   C:Q#=N NN C&Q#=O1 CQ#)P ?P P +Q#;P 	AQ#N 	O.AO)#Q#)O..Q#1	O>:Q#=O>>Q#P PQ#PQ#AQ Q#Q  Q#c                     | j                   S| j                  t        t        j                        xs dj                  dd      | _         | j                  t               | j                   S )z[Get OAuth state from cookies
        To be compared with the value in redirect URL
        max_age_daysr.   r0   replace)rL   get_secure_cookieSTATE_COOKIE_NAMEr   oauth_expiryr   clear_cookierX   s    r'   get_state_cookiez"OAuthLoginHandler.get_state_cookie$  sa     %&&'8vGZGZ&[b_bfVY'  /0!!!r.   c                 R    | j                  t        |t        j                  d       y NTexpires_dayshttponly)set_secure_cookier   r   r   )rX   r   s     r'   set_state_cookiez"OAuthLoginHandler.set_state_cookie/  s%    u63F3FQU 	 	
r.   c                    | j                   j                  j                  | j                  d      }| j	                  d|      x}}|r|j                  dt        j                  d            }t        j
                  |      }|j                  ddd|j                  j                  d      z         j                         }||k7  rt        j                  d||       t        t        j                         j                   |xs dd      S )N next\/)schemenetlocpathzIgnoring next_url %r, using %r)state_idnext_url)requesturir   rN   get_argumentr   quote_replacer   lstripgeturlr;   warningr5   uuiduuid4hex)rX   root_urlr   original_next_urlurlinfos        r'   	get_statezOAuthLoginHandler.get_state4  s    <<##++D,@,@"E'+'8'8'JJ$''hnnT.BCH ''1G''"31D1DS1I+I ( fh  ,,46G  ))x3G
 	
r.   c                 z   t        j                         j                  t        j                         j                  z   t        j                         j                  z   }t        j                  |j                  d            j                         }t        |      j                  d      j                  dd      }||fS )Nr   =r   )
r   r   r   hashlibsha256r3   digestr   r   r   )rX   rq   hashed_code_verifiercode_challenges       r'   get_codezOAuthLoginHandler.get_codeH  s    

((4::<+;+;;djjl>N>NN&~~m.B.B7.KLSSU*+?@GGPXXY\^`an,,r.   c                     | j                  t        t        j                        xs dj	                  dd      }| j                  t               |S )Nr   r.   r0   r   )r   CODE_COOKIE_NAMEr   r   r   r   rX   r\   s     r'   r   z!OAuthLoginHandler.get_code_cookieN  sG    &&'7fFYFY&Za^aiijpr{|*+r.   c                 R    | j                  t        |t        j                  d       y r   )r   r   r   r   r   s     r'   set_code_cookiez!OAuthLoginHandler.set_code_cookieS  s$    d1D1Dt 	 	
r.   c                   K   t         j                  dt        |       j                         t        j
                  rt        j
                  }n/| j                  j                   d| j                  j                   }|t        j                  d}| j                  di       }|rJt        j                  |      }|j                         D ci c]  \  }}|j                  d      d   | }}}| j                  dt        |d            }| j                  dt        |d            }| j                  d	t        |d	            }|X| j                  d
t        |d
            }	|	s|}	t         j!                  dt        |       j                  |       t#        d|	|      | j%                         }
|r|
|k7  r%t         j'                  d|
|       t#        ddd      t)        |      }|j+                  t        j,                  ||d        | j.                  di | d {   }|t#        dd      t         j                  dt        |       j                         | j1                   |j2                  dd             y | j5                         x|d<   }| j7                  |        | j.                  di | d {    y c c}}w 7 7 w)Nz%s received login request://)r]   r^   r   ?r\   r   r<   error_descriptionz2%s failed to authenticate with following error: %sru   )reasonOAuth state mismatch: %s != %sz=OAuth state mismatch. Please restart the authentication flow.zstate mismatch)r[   r\   r     zPermissions unknown.'%s authorized user, redirecting to app.r   r   rb   )r;   rd   re   rf   r   oauth_redirect_urir   protocolhost	oauth_keyr   r   parse_qsitemsrW   r-   r<   r	   r   r   r>   r~   oauth_secretrk   redirectr*   r   r   )rX   r]   rj   next_argargvaluer\   	url_stater<   	error_msgcookie_stater   rh   s                r'   r*   zOAuthLoginHandler.getX  s    		-tDz/B/BC$$!44L"ll334C8I8I7JKL(",,
 $$VR0((2HDLNNDTUDTjc5		#r*E1DTHU  )9(F)KL%%g/?'/RS	 !!'+;Hg+NO))#%5h@S%TVI!	IIDT
##U C599 ,,.y(<lIV%dm}~~&y1E MM!'!4!4" 
 544>v>>D|%;<<II?dATATUMM)%))J45 '+nn&66F7Oe!!%(-$--7777U VB ? 8s2   C	KJ:*D0KK BK4K5KKc           	      (   |rt        |t              rt        |      }n |}t        t	        j
                  |            }t        j                  xs | j                  }||v r||   }n6t        j                  dt        |       j                  |       t        dd      | j                  d       | j                  d|t        j                   d       nd }t"        j$                  rt"        j$                  j'                  |j)                  d            }|r.t"        j$                  j'                  |j)                  d            }|r.t"        j$                  j'                  |j)                  d            }| j                  d	|t        j                   d       |r#| j                  d
|t        j                   d       |r}t*        j,                  j/                  t*        j0                  j2                        j5                         }| j                  dt        t7        ||z               t        j                   d       |r#| j                  d|t        j                   d       |r2|t"        j8                  v r t"        j8                  j;                  |d        |S )Nz-%s token payload did not contain expected %r.ru   z,OAuth token payload missing user informationis_guestrh   Tr   r   rw   rz   r   rn   )r7   r8   r   r   r$   r1   r   oauth_jwt_user	_USER_KEYr;   r<   re   rf   r	   r   r   r   r   
encryptionencryptr3   dtdatetimenowtimezoneutc	timestampr   _oauth_user_overridespop)	handlerrz   rw   rn   ry   decodeduser_keyrh   now_tss	            r'   r   z"OAuthLoginHandler.set_auth_cookies  s   (C(&x0"+DJJx,@A,,A0A0AH7"x(		Iw-00(<%STT  ,%%fdATAT_c%dD ++33L4G4G4PQL ++33HOOG4LM % 0 0 8 89M9Mg9V W!!.,VM`M`ko!p%%j(I\I\gk%l[[__R[[__5??AF%%nc#fz>Q:R6Sbhbubu  AE%  F%%o}SYSfSfqu%vDE777''++D$7r.   c                     	 |xs t        |      }| j                  j
                  j                  dd      }|j                  r(t        j                  | d|j                   d|        nt        j                  | d| d       t        |d      r.|j                  dt        |            }|j                  d	d
      }nt        |      }d}t        |||      # t        j                  j                  $ r |}Y w xY w)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*   r   r<   zUnknown errorzUnknown Error)log_messager   )r(   r$   decoderJSONDecodeError	__class__rf   r   r<   r;   r   hasattrr*   r8   r	   )rX   r&   r    rv   providerr   r   s          r'   r   zOAuthLoginHandler._raise_error  s   	9/9D >>**22>2F>>II
"=hnn=M N77;f> ? KK8* %I&# $ 4((#6D	BKXXg7Fh-K$F#
 	
# ||++ 	D	s   C C=<C=c           	         |d   \  }}}| j                          | j                  dd       t        |t              r|j                  |j
                  }}nE| j                  j                  j                  dd      }t        j                  | d|        d\  }}| j                  | j                  j                  t        j                  dd	||
             y )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title
error_typer<   r   )clear_all_cookies
set_headerr7   r	   r   r   r   rf   r   r;   r<   write_error_templaterenderr   r   )rX   status_codekwargsri   r   r<   r   r   s           r'   write_errorzOAuthLoginHandler.write_error  s    $1a 4a# xx9E~~..66~rJHII*  E9 	

4''..NN/- / 
 	r.   )NNNNNNNN)N  )rf   
__module____qualname__r   rV   r|   rK   r   r8   __annotations__rL   r   r  rN   propertyrY   rk   rc   r   r   r   r   r   r   r*   staticmethodr   r   r
  rb   r.   r'   r@   r@   ]   s     %%
 GO 	- 26(3:.5*.M8C$J'.$O%-OXc]-O O ?C,*^ FJ48z=x	"


(-


98v # #J
4r.   r@   c                   X    e Zd ZdZddiZed        Zed        Zed        Zed        Z	y)	GenericLoginHandler	Bearer {}rI   rJ   c                 |    t         j                  j                  dt        j                  j                  d            S )N	TOKEN_URLPANEL_OAUTH_TOKEN_URLr   rS   r*   rT   rU   r   s    r'   r   z+GenericLoginHandler._OAUTH_ACCESS_TOKEN_URL  s)    ((,,["**..I`:abbr.   c                 |    t         j                  j                  dt        j                  j                  d            S )NAUTHORIZE_URLPANEL_OAUTH_AUTHORIZE_URLr  r   s    r'   _OAUTH_AUTHORIZE_URLz(GenericLoginHandler._OAUTH_AUTHORIZE_URL  s)    ((,,_bjjnnMh>ijjr.   c                 |    t         j                  j                  dt        j                  j                  d            S )NUSER_URLPANEL_OAUTH_USER_URLr  r   s    r'   r   z#GenericLoginHandler._OAUTH_USER_URL  s)    ((,,ZH^9_``r.   c                 ~    t         j                  j                  dt        j                  j                  dd            S )NUSER_KEYPANEL_USER_KEYrF   r  r   s    r'   r   zGenericLoginHandler._USER_KEY   s,    ((,,ZHXZa9bccr.   N)
rf   r  r  rK   r|   r  r   r  r   r   rb   r.   r'   r  r    sp    & 	* c c k k a a d dr.   r  c                        e Zd ZddiZd Zd Zy)PasswordLoginHandlerrI   rp   c                     	 | j                  d      }| j                  dd       }|r| j                  d|       | j                  j	                  |t
              }| j                  |       y # t        $ r d}Y fw xY wNr<   r   r   r   )errormessage	PANEL_CDNr   r!   
set_cookie_login_templater  r   r  rX   r'  r   htmls       r'   r*   zPasswordLoginHandler.get      	,,W5L $$VT2OOJ1##**% + 
 	

4  	L	   A, ,A:9A:c                   K   | j                  dd      }| j                  dd      }t        j                  rt        j                  }n;| j                  j                   d| j                  j
                   | j                   }| j                  t        j                  |||       d {   \  }}}}|sy | j                  d       y 7 w)Nro   r   rp   r   )r^   r]   ro   rp   r   )
r   r   r   r   r   r   rN   rc   r   r   )rX   ro   rp   r]   rh   ri   s         r'   postzPasswordLoginHandler.post  s     $$Z4$$Z4$$!44L"ll334C8I8I7J4K_K_J`aL"66&&%	 7 
 
aA c
s   B'C
)C*C
N)rf   r  r  r|   r*   r1  rb   r.   r'   r$  r$    s     	jr.   r$  c                       e Zd Zd Zd Zy)CodeChallengeLoginHandlerc                   K   | j                  dd      }| j                  dd      }t        j                  rt        j                  }n;| j                  j                   d| j                  j
                   | j                   }|r|s| j                  |       y | j                         }||k7  r#t        j                  d||       t        dd      t        |      }| j                  |t        j                  ||       d {   }|t        d	      t        j                  d
t!        |       j"                         | j%                   |j&                  dd             y 7 ]w)Nr\   r   r   r   r   r  zOAuth state mismatch)r\   r   r   r   r   )r   r   r   r   r   r   rN   _authorize_redirectr   r;   r   r	   r>   rk   r   rd   re   rf   r   r*   )rX   r\   r   r]   r   r   rh   s          r'   r*   zCodeChallengeLoginHandler.get.  s/      ,%%gr2	$$!44L"ll334C8I8I7J4K_K_J`aL9$$\2,,.9$KK8,	RC!788"9-00v?O?OQZae0ff<C. 		;T$Z=P=PQieii
C01	 gs   D E"E AE"c           	      \   | j                         }| j                  |       | j                         \  }}| j                  |       t        j
                  ddj                  | j                        |d|d|d}t        j                  |      }| j                  | j                   d|        y )Nr\   rm   queryS256)r^   r_   rP   r   response_moder   code_challenge_methodr]   r   )r   r   r   r   r   r   r}   rY   r   r   r   r  )rX   r]   r   rq   r   rj   query_paramss          r'   r5  z-CodeChallengeLoginHandler._authorize_redirectF  s     e$(,%~]+))#XXdkk*$,%+(	
  ))&12231\NCDr.   N)rf   r  r  r*   r5  rb   r.   r'   r3  r3  ,  s    20Er.   r3  c                   $    e Zd ZdZdZdZdZdZdZy)GithubLoginHandlerzGitHub 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)	rf   r  r  __doc__r   r  r   rK   r   rb   r.   r'   r=  r=  Z  s&     LE3O%Ir.   r=  c                   $    e Zd ZddiZdZdZdZdZy)BitbucketLoginHandlerrD   rA   z.https://bitbucket.org/site/oauth2/access_tokenz+https://bitbucket.org/site/oauth2/authorizez0https://api.bitbucket.org/2.0/user?access_token=ro   N)rf   r  r  r   r   r  r   r   rb   r.   r'   rA  rA  j  s+     	$ OHHOIr.   rA  c                   P    e Zd ZdZdZdZdZdZed        Z	ed        Z
ed        Zy	)
Auth0Handlerr  z!https://{0}.auth0.com/oauth/tokenzhttps://{0}.auth0.com/authorizezhttps://{0}.auth0.com/userinforF   c                 x    t         j                  j                  dd      }| j                  j	                  |      S N	subdomainexampler   rS   r*   _OAUTH_ACCESS_TOKEN_URL_r   rX   urls     r'   r   z$Auth0Handler._OAUTH_ACCESS_TOKEN_URL  s1    ''++KC,,33C88r.   c                 x    t         j                  j                  dd      }| j                  j	                  |      S rE  r   rS   r*   _OAUTH_AUTHORIZE_URL_r   rJ  s     r'   r  z!Auth0Handler._OAUTH_AUTHORIZE_URL  s1    ''++KC))0055r.   c                 x    t         j                  j                  dd      }| j                  j	                  |      S rE  r   rS   r*   _OAUTH_USER_URL_r   rJ  s     r'   r   zAuth0Handler._OAUTH_USER_URL  s1    ''++KC$$++C00r.   N)rf   r  r  rK   rI  rN  rQ  r   r  r   r  r   rb   r.   r'   rC  rC  w  sY    &B=7I9 9 6 6 1 1r.   rC  c                   `    e Zd ZddiZddiZdZdZdZdZd	Z	e
d
        Ze
d        Ze
d        Zy)GitLabLoginHandlerrD   rA   rI   rJ   zhttps://{0}/oauth/tokenzhttps://{0}/oauth/authorizezhttps://{0}/api/v4/userr  ro   c                 x    t         j                  j                  dd      }| j                  j	                  |      S NrK  z
gitlab.comrH  rJ  s     r'   r   z*GitLabLoginHandler._OAUTH_ACCESS_TOKEN_URL  s1    ''++E<@,,33C88r.   c                 x    t         j                  j                  dd      }| j                  j	                  |      S rU  rM  rJ  s     r'   r  z'GitLabLoginHandler._OAUTH_AUTHORIZE_URL  s1    ''++E<@))0055r.   c                 x    t         j                  j                  dd      }| j                  j	                  |      S rU  rP  rJ  s     r'   r   z"GitLabLoginHandler._OAUTH_USER_URL  s1    ''++E<@$$++C00r.   N)rf   r  r  r   r|   rI  rN  rQ  rK   r   r  r   r  r   rb   r.   r'   rS  rS    s{     	$
 	*  990&I9 9 6 6 1 1r.   rS  c                   V    e Zd ZdddZdZdZdZdZed        Z	ed	        Z
ed
        Zy)AzureAdLoginHandlerrA   rB   rC   z7https://login.microsoftonline.com/{tenant}/oauth2/tokenz;https://login.microsoftonline.com/{tenant}/oauth2/authorizer   unique_namec                     t         j                  j                  dt        j                  j                  dd            }| j
                  j                  |      S NAAD_TENANT_IDtenantcommon)r^  rT   rU   r*   r   rS   rI  r   rX   r^  s     r'   r   z+AzureAdLoginHandler._OAUTH_ACCESS_TOKEN_URL  D    1J1J1N1NxYa1bc,,3363BBr.   c                     t         j                  j                  dt        j                  j                  dd            }| j
                  j                  |      S r\  rT   rU   r*   r   rS   rN  r   ra  s     r'   r  z(AzureAdLoginHandler._OAUTH_AUTHORIZE_URL  D    1J1J1N1NxYa1bc))000??r.   c                 V     | j                   j                  di t        j                  S Nrb   rQ  r   r   rS   r   s    r'   r   z#AzureAdLoginHandler._OAUTH_USER_URL  $    +t$$++Hf.G.GHHr.   Nrf   r  r  r   rI  rN  rQ  r   r  r   r  r   rb   r.   r'   rY  rY    sl     %%
  YYIC C @ @ I Ir.   rY  c                   V    e Zd ZdddZdZdZdZdZed        Z	ed	        Z
ed
        Zy)AzureAdV2LoginHandlerrA   rB   rC   z<https://login.microsoftonline.com/{tenant}/oauth2/v2.0/tokenz@https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorizer   rF   c                     t         j                  j                  dt        j                  j                  dd            }| j
                  j                  |      S r\  r`  ra  s     r'   r   z-AzureAdV2LoginHandler._OAUTH_ACCESS_TOKEN_URL  rb  r.   c                     t         j                  j                  dt        j                  j                  dd            }| j
                  j                  |      S r\  rd  ra  s     r'   r  z*AzureAdV2LoginHandler._OAUTH_AUTHORIZE_URL  re  r.   c                 V     | j                   j                  di t        j                  S rg  rh  r   s    r'   r   z%AzureAdV2LoginHandler._OAUTH_USER_URL  ri  r.   Nrj  rb   r.   r'   rl  rl    sl     %%
  ^^IC C @ @ I Ir.   rl  c                   f    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        Zed        Zed        Zy)OktaLoginHandlerzOkta OAuth2 Authentication

    To authenticate with Okta you first need to set up and configure
    in the Okta developer console.
    rJ   zcode,token,id_token)rI   r_   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=rF   c                     t         j                  j                  dd      }t         j                  j                  dd      }|r| j                  j	                  ||      S | j
                  j	                  |      S NrK  zokta.comserverdefault)r   rS   r*   rI  r   _OAUTH_ACCESS_TOKEN_URL__rX   rK  rt  s      r'   r   z(OktaLoginHandler._OAUTH_ACCESS_TOKEN_URL  se    ''++E:>**..xC0077VDD1188==r.   c                     t         j                  j                  dd      }t         j                  j                  dd      }|r| j                  j	                  ||      S | j
                  j	                  |      S rs  )r   rS   r*   rN  r   _OAUTH_AUTHORIZE_URL__rw  s      r'   r  z%OktaLoginHandler._OAUTH_AUTHORIZE_URL
  se    ''++E:>**..xC--44S&AA..55c::r.   c                     t         j                  j                  dd      }t         j                  j                  dd      }|r| j                  j	                  ||      S | j
                  j	                  ||      S rs  )r   rS   r*   rQ  r   _OAUTH_USER_URL__rw  s      r'   r   z OktaLoginHandler._OAUTH_USER_URL  sg    ''++E:>**..xC((//V<<))00f==r.   N)rf   r  r  r?  r|   rI  rv  rN  ry  rQ  r{  r   r  r   r  r   rb   r.   r'   rq  rq    s}     ..
  A =A>IFI> > ; ; > >r.   rq  c                   (    e Zd ZddiZg dZdZdZdZy)GoogleLoginHandlerr   z0application/x-www-form-urlencoded; charset=utf-8)rE   rF   rG   z,https://accounts.google.com/o/oauth2/v2/authz*https://accounts.google.com/o/oauth2/tokenrF   N)rf   r  r  r   rV   r  r   r   rb   r.   r'   r}  r}    s*     	J 5OIJIr.   r}  c                   (    e Zd ZeZd Zd Zd Zd Zy)BasicLoginHandlerc                     	 | j                  d      }| j                  dd       }|r| j                  d|       | j                  j	                  |t
              }| j                  |       y # t        $ r d}Y fw xY wr&  r)  r,  s       r'   r*   zBasicLoginHandler.get,  r.  r/  c                    dt         j                  j                  | j                  i       v r!t         j                  | j                     d   }nt        j
                  }t        |t              rXt        j                  j                  |      r9t        |d      5 }t        j                  |j                               }d d d        t        |t              r||vry|||   k(  S ||k(  ryy# 1 sw Y   -xY w)N
basic_authr   )encodingFT)r   _server_configr*   applicationr   r  r7   r8   rT   r   isfileopenr$   r%   readr   )rX   ro   rp   	auth_info	auth_files        r'   	_validatezBasicLoginHandler._validate;  s    5//33D4D4DbII,,T-=-=>|LI))Ii%"''..*Ci'2i JJy~~'78	 3i&y(y222" 32s   $C**C3c                 r   | j                  dd      }| j                  dd      }| j                  ||      }|r5| j                  |       | j                  dd      }| j	                  |       y dt
        j                  j                  d      z   }| j	                  | j                  j                  |z          y )Nro   r   rp   r   r   z?error=zInvalid username or password!)
r   r  set_current_user
get_cookier   tornadoescape
url_escaper   r   )rX   ro   rp   authr   r   s         r'   r1  zBasicLoginHandler.postK  s    $$Z4$$Z4~~h1!!(+z37HMM(#!GNN$=$=>]$^^IMM$,,**Y67r.   c                    |s#| j                  d       | j                  d       y | j                  d       | j                  d|t        j                  d       t	        t        j                  d|i            }t        j                  r.t        j                  j                  |j                  d            }| j                  d|t        j                  d       y )Nr   rh   Tr   r   rz   )r   r   r   r   r   r$   r1   r   r   r   r3   )rX   rh   rz   s      r'   r  z"BasicLoginHandler.set_current_userW  s    j)f%*%vt&:M:MX\]#DJJ~$>?''//0HIHz8&BUBU`der.   N)	rf   r  r  r   r+  r*   r  r1  r  rb   r.   r'   r  r  (  s    *O 
8
fr.   r  c                       e Zd ZdZeZd Zy)LogoutHandlerrM   c                 P   | j                  d       | j                  d       | j                  d       | j                  d       | j                  d       | j                  t               | j                  j                  t        | j
                        }| j                  |       y )Nrh   rz   rw   rn   r   )r(  LOGIN_ENDPOINT)r   r   _logout_templater  r   rN   r  )rX   r-  s     r'   r*   zLogoutHandler.getj  s    &!*%.)/*.)+,$$++// , 
 	

4r.   N)rf   r  r  rN   r   r  r*   rb   r.   r'   r  r  d  s    O&r.   r  c                        e Zd ZdZ	 	 	 d
 fd	Zd Zd Zed        Zed        Z	ed        Z
ed        Zed	        Z xZS )BasicAuthProviderzF
    An AuthProvider which serves a simple login and logout page.
    c                    |t         | _        n<t        |      5 }t        j                  |j                               | _        d d d        |t        | _        n<t        |      5 }t        j                  |j                               | _        d d d        |t        | _	        n<t        |      5 }t        j                  |j                               | _	        d d d        |xs d| _
        |xs d| _        |xs g | _        t        j                  | j                         t         | E          y # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   pxY w)NrM   z/logout)r   r  r  r   from_stringr  r   r  r   r+  rN   _logout_endpoint_guest_endpointsr   on_session_destroyed_remove_usersuper__init__)	rX   login_endpointlogout_endpointlogin_templatelogout_templateerror_templateguest_endpointsfr   s	           r'   r  zBasicAuthProvider.__init__}  s   
 !#1D n%'+'7'7'A$ &"$3D!o&!(,(8(8(B% '!#7D n%'+'7'7'A$ &-9 / <9 / 52""4#4#45# &%
 '&
 &%s#   )D/%)D;/)E/D8;EEc                    |j                   j                  j                  d      }|j                   j                  j                  d      }|rd}n3|r/t        t        j
                  d|      }|r|j                  d      }nd }|sy t        j                  |xx   dz  cc<   t        j                  |   st        j                  |= y y Nr   rh   guestr   r   )	r   cookiesr*   r   r   cookie_secretr   r   _active_usersrX   session_contextguest_cookieuser_cookierh   s        r'   r  zBasicAuthProvider._remove_user  s    &..66:::F%--5599&AD&$$fkD {{7+DD!Q&!""4(##D) )r.   c                     t         j                  r|| j                  k(  sd|v sy|j                  dd      | j                  v rdS dS )Nz?code=Tz/wsr   F)r   oauth_optionalrN   r   r  )rX   r   s     r'   _allow_guestzBasicAuthProvider._allow_guest  sE      #1E1E*EUX{{5"-1F1FFtQEQr.   c                       fd}|S )Nc                    | j                  dt        j                        }|r|j                  d      }nrj	                  | j
                  j                        rMd}d| j
                  j                  d<   t        | t              s"| j                  ddt        j                         |r+t        | t              rt        j                  |xx   dz  cc<   |S )	Nrh   r   r   r  1r   )r   r   )r   r   r   r   r  r   r   r  r7   r   r*  r   r  )request_handlerrh   rX   s     r'   get_userz,BasicAuthProvider.get_user.<locals>.get_user  s    "44V&J]J]4^D{{7+""?#:#:#>#>?>A''//
;!/3CD#..z3VM`M`.a
?4DE##D)Q.)Kr.   rb   )rX   r  s   ` r'   r  zBasicAuthProvider.get_user  s    	 r.   c                     | j                   S N)rN   r   s    r'   	login_urlzBasicAuthProvider.login_url  s    ###r.   c                 b    | j                   t        _         | j                  t        _        t        S r  )rN   r  r+  r   s    r'   login_handlerzBasicAuthProvider.login_handler  s&    ,0,@,@),0,@,@)  r.   c                     | j                   S r  )r  r   s    r'   
logout_urlzBasicAuthProvider.logout_url  s    $$$r.   c                 z    | j                   r| j                   t        _         | j                  t        _        t        S r  )r  r  rN   r   s    r'   logout_handlerz BasicAuthProvider.logout_handler  s-      -1-B-BM*(,(<(<%r.   r  )rf   r  r  r?  r  r  r  r  r  r  r  r  r  __classcell__r   s   @r'   r  r  x  s    
 48BF6*&R
    $ $ ! !
 % %  r.   r  c                   f     e Zd ZdZed        Ze fd       Zed        Zd Zd Z	d	dZ
d Z xZS )
OAuthProviderz~
    An AuthProvider using specific OAuth implementation selected via
    the global config.oauth_provider configuration.
    c                      y r  rb   r   s    r'   r  zOAuthProvider.get_user  s    r.   c                       fd}|S )Nc                 x  K   t         t          |       }t        j                  r||S t        | t              }|rd| j                  j                  v r| j                  j                  d   }|j                  d      \  }}t        |      }d|v rk|d   }t        j                  r.t        j                  j                  |      j                  d      }t        j                   |      }|t        j"                  |<   t$        j&                  j)                  t$        j*                  j,                        j/                         }d }	|t        j"                  v rgt        j"                  |   s1t1        j2                  d       d {    t        j"                  |   s1t        j"                  |   }
|
d   }|
d   rT|
d   }	nN| j5                  dt        j6                        }|st8        j;                  d	       y t        j<                  |      }	 t?        |      }|d
   }		 tC        |	      }	|	:| j5                  dt        j6                        }	|	t8        j;                  d       |S |t        j"                  v rt        j"                  |   d   }n;| j5                  dt        j6                        }|rt        j<                  |      }nd }|	|kD  rb|r`t8        j;                  d       |r)jE                  |	||| jF                  | j                         |	|z
  }tH        jK                  | d |||       |S |r	 t?        |      }|d
   |k  rd }|*t8        j;                  dtM              jN                         y t8        j;                  dtM              jN                         jQ                  ||| jF                  | j                  |       d {   \  }}}	|t        j"                  vry |	|z
  }tH        jK                  | d |||       |S 7 # t@        $ r Y w xY w# t@        $ r d }	Y w xY w# t@        $ r Y w xY w7 ow)NzSec-Websocket-Protocolz, 	user_datar   皙?rw   expiryr   z:No access token available, forcing user to reauthenticate.expr   zCaccess_token is not a valid JWT token. Expiry cannot be determined.rn   z+Fully authenticated and tokens still valid.z[%s access_token is expired and refresh_token not available, forcing user to reauthenticate.zFaccess_token has expired, %s using refresh_token to obtain new tokens.)
reschedule))r  r  r  r   oauth_refresh_tokensr7   r   r   rt   rW   r   r   r   decryptr   r$   r%   r   r   r   r   r   r   r   asynciosleepr   r   r;   rd   _decrypt_cookier   r!   float_schedule_refreshr  r@   r   re   rf   _scheduled_refresh)r   rh   is_wsprotocol_headerri   tokenpayloadr  r   r  
user_staterw   access_cookieaccess_jsonrn   refresh_cookiery   refresh_jsonr   rX   s                     r'   r  z.OAuthProvider.get_user_async.<locals>.get_user  s    6w?D..$, w(89E1W__5L5LL")//"9"9:R"S*0065+E2') ' 4I''$)$4$4$<$<Y$G$N$Nw$W	 $

9 5I8AE//5[[__R[[__5??AFFu22255d;!--,,,  55d;"88>
).9h''1F ' 9 9.W]WjWj 9 k$IIZ[$44]C*<8$U+
v ~ 22>PVPcPc2d>IIcdKu222 % ; ;D A/ R!(!:!:?Y_YlYl!:!m!$)$9$9.$IM$(M=		GH**64H[H[]d]l]lm#f_
!22T<
 #/#>L#E*V3(,
 $		wy}  C  zD  zM  zM  NII^`dei`j`s`st8<8O8OmW%8%8'//  9P 9 3/L- 5666&J..|]J K] -"    D ! 3s   E=P: PP:A1P:P P 'D	P:1P) BP:P8	<P:	PP:PP:P&"P:%P&&P:)	P52P:4P55P:rb   )rX   r  r   s   ` r'   get_user_asynczOAuthProvider.get_user_async  s    e	L r.   c                     t         t        j                     }| j                  r| j                  |_        | j                  |_        | j
                  |_        |S r  )AUTH_PROVIDERSr   oauth_providerr  r+  rN   )rX   r   s     r'   r  zOAuthProvider.login_handlerK  sJ     !6!67&*&:&:G#"&"6"6"&"6"6r.   c                    |j                   j                  j                  d      }|j                   j                  j                  d      }|rd}n3|r/t        t        j
                  d|      }|r|j                  d      }nd }|sy t        j                  |xx   dz  cc<   t        j                  |   sCt        j                  |= t        j                  j                  |      t        j                  |= y y y r  )
r   r  r*   r   r   r  r   r   r  r   r  s        r'   r  zOAuthProvider._remove_userT  s    &..66:::F%--5599&AD&$$fkD {{7+DD!Q&!""4(##D) **..t4@//5 A	 )r.   c                    t         j                  j                  |      sy t        j                  j                  t        j                  j                        j                         }||z
  dz
  }t        j                  j                         t        j                  |      z   }t        | j                  ||||      }	|dk  r?t        j                  dt        |       j                         t        j                   |	       y t        j                  dt        |       j                  |       | d}
	 t        j"                  |
       t        j&                  |
|	|       y # t$        $ r Y $w xY w# t        j&                  |
|	|       w xY w)N<   )secondsr   z6%s token expired unexpectedly, refreshing immediately.z)%s scheduling token refresh in %d secondsz-refresh-access-tokens)at)r   r  r*   r   r   r   r   r   r   	timedeltar   r  r;   rd   re   rf   executecancel_taskKeyErrorschedule_task)rX   	expiry_tsrh   rn   r  r   r   expiry_secondsexpiry_date
refresh_cbtasks              r'   r  zOAuthProvider._schedule_refreshk  s/   ""&&t,1;;="V+b0kkoo'",,~*NNT44dM;X_`
QIINPTUYPZPcPcdMM*%		=tDz?R?RTbc-.	Bd# j[A  		 j[As$   0E 	E*'E- )E**E- -Fc                   K   | j                  ||||       d {    |t        j                  vryt        j                  |   }|d   |d   }}|d   r|d   }nt        |      d   }|r| j	                  |||||       |||fS 7 iw)Nrx   rw   rn   r  r  )_refresh_access_tokenr   r   r   r  )	rX   rh   rn   r  r   r  r  rw   r  s	            r'   r  z OAuthProvider._scheduled_refresh  s     ((}k7SSSu222#006
&0&@*_B]mh)F!,/6F""64WU]F22 	Ts   BBA*Bc                   K   |t         j                  v rnt         j                  |   sEt         j                  |   s1t        j                  d       d {    t         j                  |   s1y t         j                  |   d   }t        j                  dt        |       j                         i t         j                  |<   | j                  ||      }|j                  t        j                  t        j                  |       d {   \  }}}}|rt        j                  dt        |       j                         t        j                  j                  t        j                   j"                        j%                         }	|||r|	|z   nd dt         j                  |<   y t        j                  dt        |       j                         t         j                  |= y 7 7 ֭w)	Nr  rn   z%s refreshing tokens)r  r   )r^   r[   rn   z&%s successfully refreshed access_token)rw   rn   r  z!%s failed to refresh access_token)r   r   r  r  r;   rd   re   rf   r  rc   r   r   r   r   r   r   r   r   r   )
rX   rh   rn   r  r   auth_handlerri   rw   ry   r   s
             r'   r  z#OAuthProvider._refresh_access_token  sz    5.....t455d;!--,,,  55d; % ; ;D A/ R		($t**=*=>,.##D)))k7)S;G;[;[&& --' <\ <
 6
2<

 II>T
@S@ST[[__R[[__5??AF ,!./9&+t1E''- II94:;N;NO++D1- -6
s,   AGGG,BGGCGG)T)rf   r  r  r?  r  r  r  r  r  r  r  r  r  r  s   @r'   r  r    s\    
   g gR  6.B(32r.   r  c                       e Zd ZdZd Zy)PAMLoginHandlerz:
    A LoginHandler that authenticates users via PAM.
    c                     	 dd l }	 |j	                  ||       y# t        $ r}t        j                  d       |d }~ww xY w# |j
                  $ r Y yw xY w)Nr   z`PAM authentication requires the pamela package. Please install it with e.g. 'pip install pamela'FT)pamelaImportErrorr;   r<   authenticatePAMError)rX   ro   rp   r  r   s        r'   r  zPAMLoginHandler._validate  sc    		(3   	IIr G		  		s!    A 	?:?AAN)rf   r  r  r?  r  rb   r.   r'   r  r    s    r.   r  )auth0azureazurev2	bitbucketgenericgooglegithubgitlaboktarp   	auth_codepamz
panel.authF_oauth_provider)Tr  r2   r   r   r   r   r$   loggingrT   r"   urllib.parseparser   r   r   	functoolsr   typingr   r  bokeh.server.auth_providerr   bokeh.util.tokenr   tornado.authr   tornado.httpclientr	   r   r
   tornado.webr   r   tornado.websocketr   r   entry_pointsr   io.resourcesr   r   r   r   r   io.stater   utilr   r   	getLoggerrf   r;   r   r   r(   r-   r5   r>   webr@   r  r$  r3  r=  rA  rC  rS  rY  rl  rq  r}  r  r  r  r  r  r  entry_pointloadnamelistkeysparamobjectsrb   r.   r'   <module>r$     s          	 	   $    3 . $ H F F .  *   0g!' % 0:O L22K L^d+ d2$. $N*E 3 *E\*  
- 
1$ 161* 1DI+ I8I- I8.>( .>b* 9f 9fxGKK.. (\ \~Q2% Q2h' *  $&"   $*  $L1K'2'7'7'9N;##$ 2 :>n>Q>Q>S9T  U - . 6r.   