a
    ϑ`_                     @   s   d dl mZ d dlmZmZ d dlZd dlZd dlZd dlZd dl	m
Z
mZmZ d dlmZ d dlZddlmZ edZe Zed	Zed
g dZG dd deZG dd dZdS )    )partial)
HTTPServerBaseHTTPRequestHandlerN)urlparseparse_qs	urlencode)
namedtuple   )
get_configZrepo_cli
verify_sslConfig)	client_idportauthorize_url	token_urlredirect_uriserverc                       sD   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Z  Z	S )RequestHandlerc                    s   || _ t j|i | d S N)configsuper__init__)selfr   argskwargs	__class__ ?lib/python3.9/site-packages/repo_cli/utils/local_auth_server.pyr      s    zRequestHandler.__init__c                 C   s~   d| j v r>t| jjd| jjd}dj| jj|d}| |S d| j v rntt	| j j
}|d d }| |S | dd	 d
S )a   The main handler for the auth server.

        To initiate the flow, we are openining the browser at http://localhost:PORT/get_token, which
        generates the redirect header to the OpenID Connect Provider/

        Once user is logged in on OpenID Connect provider, it's redirected back to the
        http://localhost:PORT/?code=CODE&.... location, query string contains the authorization
        code in `code` parameter.

        Next we need to exchange the code for a jwt token, calling the token endpoint.
        
/get_tokencode)r   Zresponse_typer   z{authorize_url}?{qs})r   qszcode=r   i  z	Not FoundN)pathr   r   r   r   formatr   redirectr   r   queryprocess_coderesponse)r   r!   Zredirect_urlr    r   r   r   do_GET   s    



zRequestHandler.do_GETc                 C   s   | j j}d|| j j| j jd}tj||td}| dd |jdkrf|	 d }|| j j
_td ntd|||j t  d	S )
aK   Exchanges the authorization code, send back by OpenID Connect provider for the token,
        calling the token endpoint with the proper client_id and redirect_uri.

        Args:
            code (str): authorization_code string

        Returns:
            None, stops the webserver by exiting and stopping the thread.
        Zauthorization_code)Z
grant_typer    r   r   Zverify   zToken receivedaccess_tokenzReceived access_tokenz$Accessed %s with %s and got error %sN)r   r   r   r   requestsZpostr   r'   Zstatus_codejsonr   r+   loggerinfoerrortextsysexit)r   r    r   datarr+   r   r   r   r&   =   s     


zRequestHandler.process_codec                 C   s"   |  d | d| |   d S )Ni.  ZLocation)send_responsesend_headerend_headers)r   locationr   r   r   r$   [   s    
zRequestHandler.redirectc                 C   s2   |  | | dd |   | j|  d S )NzContent-Typez	text/html)r6   r7   r8   Zwfilewriteencode)r   statusr4   r   r   r   r'   `   s    
zRequestHandler.responsec                 G   s   d S r   r   )r   r#   r   r   r   r   log_messagef   s    zRequestHandler.log_message)
__name__
__module____qualname__r   r(   r&   r$   r'   r=   __classcell__r   r   r   r   r      s   r   c                   @   sJ   e Zd ZdddZedd Zejdd Zdd Zd	d
 ZdddZ	dS )	WebServerNc                 C   sP   || _ tj|td }|d | _|d | _|d ur<|| _n
|  | _d | _	d S )Nr)   Zauthorization_endpointZtoken_endpoint)
r   r,   getr   r-   r   r   r   find_unused_port_access_token)r   r   Zopenid_configuration_urlr   Zopenid_confr   r   r   r   k   s    


zWebServer.__init__c                 C   s   | j S r   rE   )r   r   r   r   r+   v   s    zWebServer.access_tokenc                 C   s   |r
|| _ d S r   rF   )r   valuer   r   r   r+   z   s    c                 C   sX   d| j f}t| j | j| j| j| d| d}tt|}t||}t	j
|jd}d|_|S )N /)r   r   r   r   r   r   )targetT)r   r   r   r   r   localhost_urlr   r   r   	threadingThreadZserve_foreverdaemon)r   Zserver_addressr   Zhandlerr   threadr   r   r   start   s    


zWebServer.startc                 C   sJ   t  t jt j&}|d | d W  d   S 1 s<0    Y  dS )zN Returns an unused port number on localhost. Will be used for webserver port. )z	127.0.0.1r   r	   N)socketZAF_INETZSOCK_STREAMZbindZgetsockname)r   sr   r   r   rD      s    
zWebServer.find_unused_portr   c                 C   s   dj | j|dS )Nzhttp://localhost:{port}{path})r   r"   )r#   r   )r   r"   r   r   r   rK      s    zWebServer.localhost_url)N)r   )
r>   r?   r@   r   propertyr+   setterrP   rD   rK   r   r   r   r   rB   j   s   


rB   )	functoolsr   Zhttp.serverr   r   loggingr,   rQ   rL   urllib.parser   r   r   collectionsr   r2   r   r
   Z	getLoggerr.   Zdefault_configrC   r   r   r   rB   r   r   r   r   <module>   s$   

P