
    e                         d dl Z d dlZd dl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Z e j        d          Z edg d          Zd	Zd
Z G d de	          Z G d d          ZdS )    N)
namedtuple)partial)BaseHTTPRequestHandler
HTTPServer)parse_qs	urlencodeurlparserepo_cliConfig)	client_idportauthorize_url	token_urlredirect_uriserver
verify_ssla~  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Anaconda Server - Token received</title>
    <style>
        body { text-align: center; padding: 150px; }
        h1 { font-size: 50px; }
        body { font: 20px Helvetica, sans-serif; color: #333; }
        article { display: block; text-align: left; width: 650px; margin: 0 auto; }
        a { color: #dc8100; text-decoration: none; }
        a:hover { color: #333; text-decoration: none; }
    </style>
</head>
<body>
    <article>
        <h1>Token received</h1>
        <div>
            <p>We successfully received a token.<br>You can close the browser window and continue to use the CLI</p>
            <p>&mdash; Anaconda</p>
        </div>
    </article>
</body>
</html>
a  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Anaconda Server - Not Found</title>
    <style>
        body { text-align: center; padding: 150px; }
        h1 { font-size: 50px; }
        body { font: 20px Helvetica, sans-serif; color: #333; }
        article { display: block; text-align: left; width: 650px; margin: 0 auto; }
        a { color: #dc8100; text-decoration: none; }
        a:hover { color: #333; text-decoration: none; }
    </style>
</head>
<body>
    <article>
        <h1>404</h1>
        <div>
            <p>Not Found</p>
        </div>
    </article>
</body>
</html>
c                   <     e Zd Z fdZd Zd Zd Zd Zd Z xZ	S )RequestHandlerc                 H    || _          t                      j        |i | d S N)configsuper__init__)selfr   argskwargs	__class__s       @lib/python3.11/site-packages/repo_cli/utils/local_auth_server.pyr   zRequestHandler.__init__W   s,    $)&)))))    c                    d| j         v r]t          | j        j        d| j        j        d          }d                    | j        j        |          }|                     |          S d| j         v rIt          t          | j                   j
                  }|d         d         }|                     |          S |                     dt                     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   response_typer   z{authorize_url}?{qs})r   qszcode=r   i  N)pathr   r   r   r   formatr   redirectr   r	   queryprocess_coderesponseHTML_404_RESPONSE)r   r$   redirect_urlr"   s       r   do_GETzRequestHandler.do_GET[   s     49$$!%!6%+$(K$<  B 288"k7B 9  L ==...di(49--344Bf:a=D$$T***c,-----r   c                    | j         j        }d|| j         j        | j         j        d}t	          j        ||| j         j                  }|                     dt                     |j	        dk    rF|
                                d         }|| j         j        _        t                              d           n"t                              d|||j                   t#          j                     dS )	aJ  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.
        authorization_code)
grant_typer"   r   r   verify   access_tokenzReceived access_tokenz$Accessed %s with %s and got error %sN)r   r   r   r   requestspostr   r*   HTML_SUCCESS_RESPONSEstatus_codejsonr   r4   loggerinfoerrortextsysexit)r   r"   r   datarr4   s         r   r)   zRequestHandler.process_code{   s     K)	.. K4	
 
 M)T$+2HIIIc0111=C6688N3L.:DK+KK/0000LL6	4   	




r   c                     |                      d           |                     d|           |                                  d S )Ni.  Location)send_responsesend_headerend_headers)r   locations     r   r'   zRequestHandler.redirect   sD    3X...r   c                     |                      |           |                     dd           |                                  | j                            |                                           d S )NzContent-Typez	text/html)rD   rE   rF   wfilewriteencode)r   statusr@   s      r   r*   zRequestHandler.response   sb    6"""555
'''''r   c                     d S r    )r   r&   r   s      r   log_messagezRequestHandler.log_message   s    r   )
__name__
__module____qualname__r   r-   r)   r'   r*   rO   __classcell__)r   s   @r   r   r   V   s        * * * * *. . .@  <  
( ( (      r   r   c                   `    e Zd Zd	dZed             Zej        d             Zd Zd Zd
dZ	dS )	WebServerNc                    || _         || _        t          j        || j                                                  }|d         | _        |d         | _        ||| _        n|                                 | _        d | _	        d S )Nr1   authorization_endpointtoken_endpoint)
r   r   r5   getr9   r   r   r   find_unused_port_access_token)r   r   openid_configuration_urlr   r   openid_confs         r   r   zWebServer.__init__   s    "$l$T_
 
 

$&& 	 ))AB$%56DII--//DI!r   c                     | j         S r   r[   )r   s    r   r4   zWebServer.access_token   s    !!r   c                     |r	|| _         d S d S r   r_   )r   values     r   r4   zWebServer.access_token   s"     	'!&D	' 	'r   c           	      (   d| j         f}t          | j         | j        | j        | j        |                     d          | | j                  }t          t          |          }t          ||          }t          j        |j                  }d|_        |S )N /)r   r   r   r   r   r   r   )targetT)r   r   r   r   r   localhost_urlr   r   r   r   	threadingThreadserve_foreverdaemon)r   server_addressr   handlerr   threads         r   startzWebServer.start   s    din,n++C00
 
 
 .&11NG44!)=>>>r   c                     t          j         t           j        t           j                  5 }|                    d           |                                d         cddd           S # 1 swxY w Y   dS )zLReturns an unused port number on localhost. Will be used for webserver port.)z	127.0.0.1r      N)socketAF_INETSOCK_STREAMbindgetsockname)r   ss     r   rZ   zWebServer.find_unused_port   s    ]6>6+=>> 	&!FF#$$$==??1%	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&s   /A&&A*-A*r!   c                 :    d                     | j        |          S )Nzhttp://localhost:{port}{path})r   r%   )r&   r   )r   r%   s     r   rf   zWebServer.localhost_url   s    .554945PPPr   )NN)r!   )
rP   rQ   rR   r   propertyr4   setterrn   rZ   rf   rN   r   r   rU   rU      s        " " " " " " X" ' ' '  "& & &Q Q Q Q Q Qr   rU   )loggingrq   r>   rg   collectionsr   	functoolsr   http.serverr   r   urllib.parser   r   r	   r5   	getLoggerr:   r   r7   r+   r   rU   rN   r   r   <module>r      sF     



     " " " " " "       : : : : : : : : 6 6 6 6 6 6 6 6 6 6 		:	&	& 
  
 
 : :O O O O O+ O O Od1Q 1Q 1Q 1Q 1Q 1Q 1Q 1Q 1Q 1Qr   