
    )`i%/              
       Z   d dl Z d dlZd dlmZmZ d dlmZmZ d dlm	Z	m
Z
 d dlmZmZ d dlmZ d dlmZmZmZmZmZ d dlmZ  e j        e          Zd	ed
ededz  fdZd	ededz  fdZd	ededz  fdZdedz  dedee         fdZ 	 d(dedz  dedz  dedz  dedz  fdZ!dedz  dedee         fdZ"d	ededz  fdZ#d	ede$e%edz  f         fdZ&dedefdZ'dedz  dededefdZ(d	edefd Z)dedz  de%fd!Z*d"edz  d#edz  de%fd$Z+	 d(d#ed%ee	         dz  defd&Z,d	edefd'Z-dS ))    N)urljoinurlparse)RequestResponse)AnyUrlValidationError)OAuthRegistrationErrorOAuthTokenError)MCP_PROTOCOL_VERSION)OAuthClientInformationFullOAuthClientMetadataOAuthMetadata
OAuthTokenProtectedResourceMetadata)LATEST_PROTOCOL_VERSIONresponse
field_namereturnc                     | j                             d          }|sdS | d}t          j        ||          }|r*|                    d          p|                    d          S dS )z
    Extract field from WWW-Authenticate header.

    Returns:
        Field value if found in WWW-Authenticate header, None otherwise
    zWWW-AuthenticateNz=(?:"([^"]+)"|([^\s,]+))      )headersgetresearchgroup)r   r   www_auth_headerpatternmatchs        i/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/mcp/client/auth/utils.pyextract_field_from_www_authr!      su     &**+=>>O t 666GIg//E 0{{1~~/Q/4    c                 "    t          | d          S )z
    Extract scope parameter from WWW-Authenticate header as per RFC6750.

    Returns:
        Scope string if found in WWW-Authenticate header, None otherwise
    scope)r!   r   s    r    extract_scope_from_www_authr&   ,   s     'x999r"   c                 @    | r| j         dk    rdS t          | d          S )z
    Extract protected resource metadata URL from WWW-Authenticate header as per RFC9728.

    Returns:
        Resource metadata URL if found in WWW-Authenticate header, None otherwise
    i  Nresource_metadata)status_coder!   r%   s    r    'extract_resource_metadata_from_www_authr*   6   s/      x+s22t&x1DEEEr"   www_auth_url
server_urlc                 @   g }| r|                     |            t          |          }|j         d|j         }|j        r8|j        dk    r-t          |d|j                   }|                     |           t          |d          }|                     |           |S )a;  
    Build ordered list of URLs to try for protected resource metadata discovery.

    Per SEP-985, the client MUST:
    1. Try resource_metadata from WWW-Authenticate header (if present)
    2. Fall back to path-based well-known URI: /.well-known/oauth-protected-resource/{path}
    3. Fall back to root-based well-known URI: /.well-known/oauth-protected-resource

    Args:
        www_auth_url: optional resource_metadata url extracted from the WWW-Authenticate header
        server_url: server url

    Returns:
        Ordered list of URLs to try for discovery
    :///z%/.well-known/oauth-protected-resource)appendr   schemenetlocpathr   )r+   r,   urlsparsedbase_urlpath_based_urlroot_based_urls          r    0build_protected_resource_metadata_discovery_urlsr9   C   s      D  "L!!! j!!F-33FM33H { $v{c)) +`SYS^+`+`aaN### X'NOONKKKr"   www_authenticate_scopeprotected_resource_metadataauthorization_server_metadatac                     | | S |!|j         d                    |j                   S |!|j         d                    |j                   S dS )zLSelect scopes as outlined in the 'Scope Selection Strategy' in the MCP spec.N )scopes_supportedjoin)r:   r;   r<   s      r    get_client_metadata_scopesrA   i   sa     )%%	$	05P5a5mxx3DEEE	&	27T7e7qxx5FGGG tr"   auth_server_urlc                    | s"t          |          }|j         d|j         dgS g }t          |           }|j         d|j         }|j        r|j        dk    rd|j                            d           }|                    t          ||                     d|j                            d           }|                    t          ||                     |j                            d           d}|                    t          ||                     |S |                    t          |d                     |                    t          |d                     |S )a  
    Generate ordered list of (url, type) tuples for discovery attempts.

    Args:
        auth_server_url: URL for the OAuth Authorization Metadata URL if found, otherwise None
        server_url: URL for the MCP server, used as a fallback if auth_server_url is None
    r.   z'/.well-known/oauth-authorization-serverr/   z!/.well-known/openid-configuration)r   r1   r2   r3   rstripr0   r   )rB   r,   r5   r4   r6   
oauth_path	oidc_paths          r    8build_oauth_authorization_server_metadata_discovery_urlsrG      su     ] *%%=[[V][[[\\Do&&F-33FM33H { v{c))Xv{?Q?QRU?V?VXX
GHj11222 R8J8J38O8OQQ	GHi00111 {))#..QQQ	GHi00111 	KK"KLLMMM 	KK"EFFGGGKr"   c                    K   | j         dk    rB	 |                                  d{V }t          j        |          }|S # t          $ r Y dS w xY wdS )z
    Handle protected resource metadata discovery response.

    Per SEP-985, supports fallback when discovery fails at one URL.

    Returns:
        True if metadata was successfully discovered, False if we should try next URL
       N)r)   areadr   model_validate_jsonr   )r   contentmetadatas      r    "handle_protected_resource_responserN      sz       s""	$NN,,,,,,,,G0DWMMHO 	 	 	44	
 ts   /? 
AAc                    K   | j         dk    rD	 |                                  d {V }t          j        |          }d|fS # t          $ r Y dS w xY w| j         dk     s| j         dk    rdS dS )NrI   T)TNi  i  )FN)r)   rJ   r   rK   r   )r   rL   asms      r    handle_auth_metadata_responserQ      s      s""	$NN,,,,,,,,G3G<<C9 	 	 	::				#	#x';s'B'B{:s   1A 
AAurlc                 >    t          d| t          t          i          S )NGET)r   )r   r   r   )rR   s    r    create_oauth_metadata_requestrU      s    5#(<>U'VWWWWr"   auth_server_metadataclient_metadataauth_base_urlc                     | r| j         rt          | j                   }nt          |d          }|                    ddd          }t	          d||ddi          S )	z9Build registration request or skip if already registered.z	/registerTjson)by_aliasmodeexclude_nonePOSTzContent-Typezapplication/json)rZ   r   )registration_endpointstrr   
model_dumpr   )rV   rW   rX   registration_urlregistration_datas        r    "create_client_registration_requestrd      sw    
  ? 4 J ?3IJJ"=+>>'22Dv\`2aa6+2Cn^pMqrrrrr"   c                 4  K   | j         dvr9|                                  d{V  t          d| j          d| j                   	 |                                  d{V }t	          j        |          }|S # t          $ r}t          d|           d}~ww xY w)zHandle registration response.)rI      NzRegistration failed: r>   zInvalid registration response: )r)   rJ   r	   textr   rK   r   )r   rL   client_infoes       r    handle_registration_responserj      s      :--nn$%cX=Q%c%cT\Ta%c%cdddL ((((((((0DWMM  L L L$%Jq%J%JKKKLs   /A6 6
B BBc                 t    | sdS 	 t          |           }|j        dk    o|j        dvS # t          $ r Y dS w xY w)zValidate that a URL is suitable for use as a client_id (CIMD).

    The URL must be HTTPS with a non-root pathname.

    Args:
        url: The URL to validate

    Returns:
        True if the URL is a valid HTTPS URL with a non-root pathname
    Fhttps) r/   )r   r1   r3   	Exception)rR   r5   s     r    is_valid_client_metadata_urlro      s\      u#}'HFKy,HH   uus   ") 
77oauth_metadataclient_metadata_urlc                 $    |sdS | sdS | j         du S )a  Determine if URL-based client ID (CIMD) should be used instead of DCR.

    URL-based client IDs should be used when:
    1. The server advertises client_id_metadata_document_supported=true
    2. The client has a valid client_metadata_url configured

    Args:
        oauth_metadata: OAuth authorization server metadata
        client_metadata_url: URL-based client ID (already validated)

    Returns:
        True if CIMD should be used, False if DCR should be used
    FT)%client_id_metadata_document_supported)rp   rq   s     r    should_use_client_metadata_urlrt   
  s,    "  u u?4GGr"   redirect_urisc                 &    t          | d|          S )a  Create client information using a URL-based client ID (CIMD).

    When using URL-based client IDs, the URL itself becomes the client_id
    and no client_secret is used (token_endpoint_auth_method="none").

    Args:
        client_metadata_url: The URL to use as the client_id
        redirect_uris: The redirect URIs from the client metadata (passed through for
            compatibility with OAuthClientInformationFull which inherits from OAuthClientMetadata)

    Returns:
        OAuthClientInformationFull with the URL as client_id
    none)	client_idtoken_endpoint_auth_methodru   )r   )rq   ru   s     r    $create_client_info_from_metadata_urlrz   $  s$      &%#)#   r"   c                    K   	 |                                   d{V }t          j        |          }|S # t          $ r}t	          d|           d}~ww xY w)av  Parse and validate token response with optional scope validation.

    Parses token response JSON. Callers should check response.status_code before calling.

    Args:
        response: HTTP response from token endpoint (status already checked by caller)

    Returns:
        Validated OAuthToken model

    Raises:
        OAuthTokenError: If response JSON is invalid
    NzInvalid token response: )rJ   r   rK   r   r
   )r   rL   token_responseri   s       r    handle_token_response_scopesr}   ;  sx       > ((((((((#7@@ > > ><<<===>s   /4 
AAA)N).loggingr   urllib.parser   r   httpxr   r   pydanticr   r   mcp.client.authr	   r
   mcp.client.streamable_httpr   mcp.shared.authr   r   r   r   r   	mcp.typesr   	getLogger__name__loggerr`   r!   r&   r*   listr9   rA   rG   rN   tupleboolrQ   rU   rd   rj   ro   rt   rz   r}    r"   r    <module>r      s    				 * * * * * * * * # # # # # # # # , , , , , , , , C C C C C C C C ; ; ; ; ; ;              . - - - - -		8	$	$(  d
    ,:( :sTz : : : :
Fh 
F3: 
F 
F 
F 
F#3: #[^ #cghkcl # # # #R ;? $J!:T!A $14#7 	4Z	   0)cTXj )fi )nrsvnw ) ) ) )X%   2
( 
uT=[_K_E_?` 
 
 
 
Xs Xw X X X Xs'$.sATsehss s s sL L>X L L L L cDj T    (H!D(HtH 
H H H H6 DH -1&\D-@   .>>> > > > > >r"   