Ë
    ïñþi%/  ã            
       óD  — 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 j0                  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-y))é    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                   j                  d«      }|sy|› d�}t        j                  ||«      }|r$|j	                  d«      xs |j	                  d«      S y)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        úU/root/aria/mcps/aria-brain/venv/lib/python3.12/site-packages/mcp/client/auth/utils.pyÚextract_field_from_www_authr!      sa   € ð ×&Ñ&×*Ñ*Ð+=Ó>€OÙØð �Ð5Ð6€GÜ�I‰I�g˜Ó/€Eáà�{‰{˜1‹~Ò/ §¡¨Q£Ð/àó    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Ð9r"   c                 ó>   — | r| j                   dk7  ry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Øä& xÐ1DÓEÐEr"   Úwww_auth_urlÚ
server_urlc                 ó@  — g }| r|j                  | «       t        |«      }|j                  › d|j                  › �}|j                  r9|j                  dk7  r*t        |d|j                  › �«      }|j                  |«       t        |d«      }|j                  |«       |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Ø—-‘-�  F§M¡M ?Ð3€Hð ‡{‚{�v—{‘{ cÒ)Ü  Ð-RÐSY×S^ÑS^ÐR_Ð+`ÓaˆØ�‰�NÔ#ô ˜XÐ'NÓO€NØ‡K�K�Ôà€Kr"   Úwww_authenticate_scopeÚprotected_resource_metadataÚauthorization_server_metadatac                 ó°   — | �| S |�'|j                   �dj                  |j                   «      S |�'|j                   �dj                  |j                   «      S y)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   se   € ð Ð)à%Ð%Ø	$Ð	0Ð5P×5aÑ5aÐ5mà�x‰xÐ3×DÑDÓEÐEØ	&Ð	2Ð7T×7eÑ7eÐ7qØ�x‰xÐ5×FÑFÓGÐGð r"   Úauth_server_urlc                 ó¦  — | s(t        |«      }|j                  › d|j                  › d�gS g }t        | «      }|j                  › d|j                  › �}|j                  r¼|j                  dk7  r­d|j                  j	                  d«      › �}|j                  t        ||«      «       d|j                  j	                  d«      › �}|j                  t        ||«      «       |j                  j	                  d«      › d�}|j                  t        ||«      «       |S |j                  t        |d«      «       |j                  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   �   s6  € ñ ô ˜*Ó%ˆØ—=‘=�/  V§]¡] OÐ3ZÐ[Ð\Ð\à€DÜ�oÓ&€FØ—-‘-�  F§M¡M ?Ð3€Hð ‡{‚{�v—{‘{ cÒ)Ø>¸v¿{¹{×?QÑ?QÐRUÓ?VÐ>WÐXˆ
Ø�‰”G˜H jÓ1Ô2ð 8¸¿¹×8JÑ8JÈ3Ó8OÐ7PÐQˆ	Ø�‰”G˜H iÓ0Ô1ð —{‘{×)Ñ)¨#Ó.Ð/Ð/PÐQˆ	Ø�‰”G˜H iÓ0Ô1Øˆð 	‡K�K”˜Ð"KÓLÔMð 	‡K�K”˜Ð"EÓFÔGà€Kr"   c              ƒ   ó¬   K  — | j                   dk(  r0	 | j                  «       ƒ d{  –—† }t        j                  |«      }|S y7 Œ# t        $ r Y yw xY w­w)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   ­   s\   è ø€ ð ×Ñ˜sÒ"ð	Ø$ŸN™NÓ,×,ˆGÜ0×DÑDÀWÓMˆHØˆOð ð -ùô ò 	áð	üs8   ‚A“A ¦A§A ÁAÁA Á	AÁAÁAÁAc              ƒ   óî   K  — | j                   dk(  r2	 | j                  «       ƒ d {  –—† }t        j                  |«      }d|fS | j                   dk  s| j                   dk\  ryy7 Œ=# t        $ r Y yw xY w­w)NrI   T)TNi�  iô  )FN)r)   rJ   r   rK   r   )r   rL   Úasms      r    Úhandle_auth_metadata_responserQ   Æ   s}   è ø€ Ø×Ñ˜sÒ"ð	Ø$ŸN™NÓ,×,ˆGÜ×3Ñ3°GÓ<ˆCØ˜�9Ðð 
×	Ñ	 Ò	# x×';Ñ';¸sÒ'BØØð -ùô ò 	Ùð	üs8   ‚A5“A& ¦A$§A& Á!A5Á$A& Á&	A2Á/A5Á1A2Á2A5Úurlc                 ó2   — t        d| t        t        i¬«      S )NÚGET)r   )r   r   r   )rR   s    r    Úcreate_oauth_metadata_requestrU   Ó   s   € Ü�5˜#Ô(<Ô>UÐ'VÔWÐWr"   Úauth_server_metadataÚclient_metadataÚauth_base_urlc                 ó¬   — | r"| j                   rt        | j                   «      }nt        |d«      }|j                  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   ×   sa   € ñ
 Ð 4× JÒ JÜÐ3×IÑIÓJÑä" =°+Ó>Ðà'×2Ñ2¸DÀvÐ\`Ð2ÓaÐä�6Ð+Ð2CÈnÐ^pÐMqÔrÐrr"   c              ƒ   óF  K  — | j                   dvr=| j                  «       ƒ d{  –—†  t        d| j                   › d| j                  › �«      ‚	 | j                  «       ƒ d{  –—† }t	        j
                  |«      }|S 7 ŒY7 Œ# t        $ r}t        d|› �«      ‚d}~ww xY w­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©   è ø€ à×Ñ :Ñ-Ø�n‰nÓ×ÐÜ$Ð'<¸X×=QÑ=QÐ<RÐRSÐT\×TaÑTaÐSbÐ%cÓdÐdðLØ Ÿ™Ó(×(ˆÜ0×DÑDÀWÓMˆØÐð 	øð )ùô
 ò LÜ$Ð'FÀqÀcÐ%JÓKÐKûðLüsE   ‚"B!¤A>¥)B!ÁB Á"B Á#B Á=B!Â B Â	BÂBÂBÂB!c                 ó|   — | sy	 t        | «      }|j                  dk(  xr |j                  dvS # t        $ r Y yw xY w)zøValidate 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   ö   sG   € ñ ØðÜ˜#“ˆØ�}‰} Ñ'ÒH¨F¯K©K¸yÐ,HÐHøÜò Ùðús   …)/ ¯	;º;Úoauth_metadataÚclient_metadata_urlc                 ó*   — |sy| sy| 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!   € ñ" ØáØà×?Ñ?À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  — 	 | j                  «       ƒ d{  –—† }t        j                  |«      }|S 7 Œ# t        $ r}t	        d|› �«      ‚d}~ww xY w­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}   ;  sY   è ø€ ð >Ø Ÿ™Ó(×(ˆÜ#×7Ñ7¸Ó@ˆØÐð )ùô ò >ÜÐ 8¸¸Ð<Ó=Ð=ûð>üs0   ‚A„5 —3˜5 ²A³5 µ	A¾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�      s7  ðÛ Û 	ß *ç #ß ,ç CÝ ;÷õ õ .à	ˆ×	Ñ	˜8Ó	$€ð¨(ð Àð ÈÈdÉ
ó ð,:¨(ð :°s¸T±zó :ð
F°hð 
FÀ3ÈÁ:ó 
Fð#À3ÈÁ:ð #Ð[^ð #ÐcgÐhkÑcló #ðR ;?ñØ $™Jðà!:¸TÑ!Aðð $1°4Ñ#7ðð 	ˆ4�Zó	ð0)ÈcÐTXÉjð )Ðfið )ÐnrÐsvÑnwó )ðXØðà Ñ%óð2
°(ð 
¸uÀTÈ=Ð[_ÑK_ÐE_Ñ?`ó 
ðX sð X¨wó XðsØ'¨$Ñ.ðsØATðsØehðsàósðL°ð LÐ>Xó Lð  c¨D¡jð °Tó ð(HØ! DÑ(ðHà˜t™ðHð 
óHð6 DHñØðØ-1°&©\¸DÑ-@ðàóð.>Øð>àô>r"   