
    KiQ                        d Z ddlZddlmZmZ ddlmZmZ ddlm	Z	 ddl
Z
ddlZddlmZmZ ddlmZmZmZmZ ddlmZmZ  G d	 d
e      Zdedeegee   f   fdZ G d de      Z G d de      Z G d de      Z G d de      Zy)a  
OAuth client credential extensions for MCP.

Provides OAuth providers for machine-to-machine authentication flows:
- ClientCredentialsOAuthProvider: For client_credentials with client_id + client_secret
- PrivateKeyJWTOAuthProvider: For client_credentials with private_key_jwt authentication
  (typically using a pre-built JWT from workload identity federation)
- RFC7523OAuthClientProvider: For jwt-bearer grant (RFC 7523 Section 2.1)
    N)	AwaitableCallable)AnyLiteral)uuid4)	BaseModelField)OAuthClientProviderOAuthFlowErrorOAuthTokenErrorTokenStorage)OAuthClientInformationFullOAuthClientMetadatac                        e Zd ZdZ	 	 ddededededed   d	edz  d
df fdZddZd
e	j                  fdZd
e	j                  fdZ xZS )ClientCredentialsOAuthProvidera  OAuth provider for client_credentials grant with client_id + client_secret.

    This provider sets client_info directly, bypassing dynamic client registration.
    Use this when you already have client credentials (client_id and client_secret).

    Example:
        ```python
        provider = ClientCredentialsOAuthProvider(
            server_url="https://api.example.com",
            storage=my_token_storage,
            client_id="my-client-id",
            client_secret="my-client-secret",
        )
        ```
    N
server_urlstorage	client_idclient_secrettoken_endpoint_auth_method)client_secret_basicclient_secret_postscopesreturnc                 |    t        ddg||      }t        | 	  |||ddd       t        d||dg||      | _        y)a  Initialize client_credentials OAuth provider.

        Args:
            server_url: The MCP server URL.
            storage: Token storage implementation.
            client_id: The OAuth client ID.
            client_secret: The OAuth client secret.
            token_endpoint_auth_method: Authentication method for token endpoint.
                Either "client_secret_basic" (default) or "client_secret_post".
            scopes: Optional space-separated list of scopes to request.
        Nclient_credentialsredirect_urisgrant_typesr   scope     r@)r   r   r   r   r   r    )r   super__init__r   _fixed_client_info)	selfr   r   r   r   r   r   client_metadata	__class__s	           y/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/mcp/client/auth/extensions/client_credentials.pyr#   z'ClientCredentialsOAuthProvider.__init__)   sY    * .-.'A	
 	_gtT5Q"<'-.'A#
    c                    K   | j                   j                  j                          d{   | j                   _        | j                  | j                   _        d| _        y7 6wz6Load stored tokens and set pre-configured client_info.NTcontextr   
get_tokenscurrent_tokensr$   client_info_initializedr%   s    r(   _initializez*ClientCredentialsOAuthProvider._initializeO   H     ,0LL,@,@,K,K,M&M##'#:#:   'N   (A#A!7A#c                 >   K   | j                          d{   S 7 w)z)Perform client_credentials authorization.N"_exchange_token_client_credentialsr2   s    r(   _perform_authorizationz5ClientCredentialsOAuthProvider._perform_authorizationU        <<>>>>   c                   K   ddi}ddi}| j                   j                  ||      \  }}| j                   j                  | j                   j                        r| j                   j	                         |d<   | j                   j
                  j                  r#| j                   j
                  j                  |d<   | j                         }t        j                  d|||      S w)	z:Build token exchange request for client_credentials grant.
grant_typer   Content-Type!application/x-www-form-urlencodedresourcer    POSTdataheaders)
r-   prepare_token_authshould_include_resource_paramprotocol_versionget_resource_urlr&   r    _get_token_endpointhttpxRequestr%   
token_datarD   	token_urls       r(   r8   zAClientCredentialsOAuthProvider._exchange_token_client_credentialsY   s      .&

 $23V"W #ll==j'R
G<<55dll6S6ST%)\\%B%B%DJz"<<''--"&,,">">"D"DJw,,.	}}VYZQQs   C C")r   Nr   N)__name__
__module____qualname____doc__strr   r   r#   r3   rJ   rK   r9   r8   __classcell__r'   s   @r(   r   r      s    , \q!$
$
 $
 	$

 $
 %,,W$X$
 d
$
 
$
L!?emm ?R%-- Rr)   r   tokenr   c                 ,     dt         dt         f fd}|S )a  Create an assertion provider that returns a static JWT token.

    Use this when you have a pre-built JWT (e.g., from workload identity federation)
    that doesn't need the audience parameter.

    Example:
        ```python
        provider = PrivateKeyJWTOAuthProvider(
            server_url="https://api.example.com",
            storage=my_token_storage,
            client_id="my-client-id",
            assertion_provider=static_assertion_provider(my_prebuilt_jwt),
        )
        ```

    Args:
        token: The pre-built JWT assertion string.

    Returns:
        An async callback suitable for use as an assertion_provider.
    audiencer   c                    K   S wN )rY   rW   s    r(   providerz+static_assertion_provider.<locals>.provider   s     s   rT   )rW   r]   s   ` r(   static_assertion_providerr_   n   s    .   Or)   c                       e Zd ZU dZ ed      Zeed<    ed      Zeed<    ed      Z	eed<    ed	d
      Z
eed<    edd      Zeed<    edd      Zeeef   dz  ed<   deegee   f   fdZy)SignedJWTParametersa  Parameters for creating SDK-signed JWT assertions.

    Use `create_assertion_provider()` to create an assertion provider callback
    for use with `PrivateKeyJWTOAuthProvider`.

    Example:
        ```python
        jwt_params = SignedJWTParameters(
            issuer="my-client-id",
            subject="my-client-id",
            signing_key=private_key_pem,
        )
        provider = PrivateKeyJWTOAuthProvider(
            server_url="https://api.example.com",
            storage=my_token_storage,
            client_id="my-client-id",
            assertion_provider=jwt_params.create_assertion_provider(),
        )
        ```
    z0Issuer for JWT assertions (typically client_id).)descriptionissuerz<Subject identifier for JWT assertions (typically client_id).subjectz)Private key for JWT signing (PEM format).signing_keyRS256%Algorithm for signing JWT assertions.defaultrb   signing_algorithm,  %Lifetime of generated JWT in seconds.lifetime_secondsNzAdditional claims.additional_claimsr   c                 ,     dt         dt         f fd}|S )zCreate an assertion provider callback for use with PrivateKeyJWTOAuthProvider.

        Returns:
            An async callback that takes the audience (authorization server issuer URL)
            and returns a signed JWT assertion.
        rY   r   c           	      b  K   t        t        j                               }j                  j                  | |j                  z   |t        t                     d}j                  r|j                  j                         t        j                  |j                  j                        S w)Nisssubaudexpiatjti	algorithm)inttimerc   rd   rm   rT   r   rn   updatejwtencodere   rj   )rY   nowclaimsr%   s      r(   r]   z?SignedJWTParameters.create_assertion_provider.<locals>.provider   s     diik"C{{||T22257|&F %%d445::fd&6&6$BXBXYYs   B,B/r^   )r%   r]   s   ` r(   create_assertion_providerz-SignedJWTParameters.create_assertion_provider   s     	ZS 	ZS 	Z r)   )rP   rQ   rR   rS   r	   rc   rT   __annotations__rd   re   rj   rm   rz   rn   dictr   r   r   r   r\   r)   r(   ra   ra      s    * $VWFCW%cdGSd)TUKU"7@ghsh!#;bccc/4TOc/dtCH~,d8SE9S>4I+J r)   ra   c                        e Zd ZdZ	 ddedededeegee   f   dedz  ddf fd	Zdd
Z	de
j                  fdZdeeef   ddfdZde
j                  fdZ xZS )PrivateKeyJWTOAuthProvideraq  OAuth provider for client_credentials grant with private_key_jwt authentication.

    Uses RFC 7523 Section 2.2 for client authentication via JWT assertion.

    The JWT assertion's audience MUST be the authorization server's issuer identifier
    (per RFC 7523bis security updates). The `assertion_provider` callback receives
    this audience value and must return a JWT with that audience.

    **Option 1: Pre-built JWT via Workload Identity Federation**

    In production scenarios, the JWT assertion is typically obtained from a workload
    identity provider (e.g., GCP, AWS IAM, Azure AD):

        ```python
        async def get_workload_identity_token(audience: str) -> str:
            # Fetch JWT from your identity provider
            # The JWT's audience must match the provided audience parameter
            return await fetch_token_from_identity_provider(audience=audience)

        provider = PrivateKeyJWTOAuthProvider(
            server_url="https://api.example.com",
            storage=my_token_storage,
            client_id="my-client-id",
            assertion_provider=get_workload_identity_token,
        )
        ```

    **Option 2: Static pre-built JWT**

    If you have a static JWT that doesn't need the audience parameter:

        ```python
        provider = PrivateKeyJWTOAuthProvider(
            server_url="https://api.example.com",
            storage=my_token_storage,
            client_id="my-client-id",
            assertion_provider=static_assertion_provider(my_prebuilt_jwt),
        )
        ```

    **Option 3: SDK-signed JWT (for testing/simple setups)**

    For testing or simple deployments, use `SignedJWTParameters.create_assertion_provider()`:

        ```python
        jwt_params = SignedJWTParameters(
            issuer="my-client-id",
            subject="my-client-id",
            signing_key=private_key_pem,
        )
        provider = PrivateKeyJWTOAuthProvider(
            server_url="https://api.example.com",
            storage=my_token_storage,
            client_id="my-client-id",
            assertion_provider=jwt_params.create_assertion_provider(),
        )
        ```
    Nr   r   r   assertion_providerr   r   c                     t        ddgd|      }t        | 	  |||ddd       || _        t	        d|dgd|      | _        y)a  Initialize private_key_jwt OAuth provider.

        Args:
            server_url: The MCP server URL.
            storage: Token storage implementation.
            client_id: The OAuth client ID.
            assertion_provider: Async callback that takes the audience (authorization
                server's issuer identifier) and returns a JWT assertion. Use
                `SignedJWTParameters.create_assertion_provider()` for SDK-signed JWTs,
                `static_assertion_provider()` for pre-built JWTs, or provide your own
                callback for workload identity federation.
            scopes: Optional space-separated list of scopes to request.
        Nr   private_key_jwtr   r!   )r   r   r   r   r    )r   r"   r#   _assertion_providerr   r$   )r%   r   r   r   r   r   r&   r'   s          r(   r#   z#PrivateKeyJWTOAuthProvider.__init__   s^    , .-.'8	
 	_gtT5Q#5 "<-.'8#
r)   c                    K   | j                   j                  j                          d{   | j                   _        | j                  | j                   _        d| _        y7 6wr+   r,   r2   s    r(   r3   z&PrivateKeyJWTOAuthProvider._initialize%  r4   r5   c                 >   K   | j                          d{   S 7 w)z>Perform client_credentials authorization with private_key_jwt.Nr7   r2   s    r(   r9   z1PrivateKeyJWTOAuthProvider._perform_authorization+  r:   r;   rM   c                   K   | j                   j                  st        d      t        | j                   j                  j                        }| j                  |       d{   }||d<   d|d<   y7 w)IAdd JWT assertion for client authentication to token endpoint parameters./Missing OAuth metadata for private_key_jwt flowNclient_assertion6urn:ietf:params:oauth:client-assertion-type:jwt-bearerclient_assertion_type)r-   oauth_metadatar   rT   rc   r   )r%   rM   rY   	assertions       r(   _add_client_authentication_jwtz9PrivateKeyJWTOAuthProvider._add_client_authentication_jwt/  sk     ||** !RSS t||2299:228<<	 *3
%&.f
*+	 =s   AA3!A1"A3c                   K   ddi}ddi}| j                  |       d{    | j                  j                  | j                  j                        r| j                  j	                         |d<   | j                  j
                  j                  r#| j                  j
                  j                  |d<   | j                         }t        j                  d	|||
      S 7 w)zOBuild token exchange request for client_credentials grant with private_key_jwt.r=   r   r>   r?   rM   Nr@   r    rA   rB   )
r   r-   rF   rG   rH   r&   r    rI   rJ   rK   rL   s       r(   r8   z=PrivateKeyJWTOAuthProvider._exchange_token_client_credentials=  s      .&

 $23V"W 11Z1HHH<<55dll6S6ST%)\\%B%B%DJz"<<''--"&,,">">"D"DJw,,.	}}VYZQQ 	Is   CCB=Cr[   rO   )rP   rQ   rR   rS   rT   r   r   r   r#   r3   rJ   rK   r9   r   r   r   r8   rU   rV   s   @r(   r   r      s    9B "%
%
 %
 	%

 %cUIcN%:;%
 d
%
 
%
N!?emm ?g$sCx. gUY gR%-- Rr)   r   c                   N   e Zd ZU dZ edd      Zedz  ed<    edd      Zedz  ed<    edd      Z	edz  ed	<    edd
      Z
edz  ed<    edd      Zeeef   dz  ed<    edd      Zedz  ed<    edd      Zedz  ed<    edd      Zeed<   ddedz  defdZy)JWTParameterszJWT parameters.NzeJWT assertion for JWT authentication. Will be used instead of generating a new assertion if provided.rh   r   zIssuer for JWT assertions.rc   z&Subject identifier for JWT assertions.rd   zAudience for JWT assertions.rY   z%Additional claims for JWT assertions.r   rf   rg   jwt_signing_algorithmzPrivate key for JWT signing.jwt_signing_keyrk   rl   jwt_lifetime_secondswith_audience_fallbackr   c           	      `   | j                   | j                   }|S | j                  st        d      | j                  st        d      | j                  st        d      | j
                  r| j
                  n|}|st        d      t        t        j                               }| j                  | j                  ||| j                  z   |t        t                     d}|j                  | j                  xs i        t        j                  || j                  | j                  xs d      }|S )Nz(Missing signing key for JWT bearer grantz#Missing issuer for JWT bearer grantz$Missing subject for JWT bearer grantz%Missing audience for JWT bearer grantrq   rf   rx   )r   r   r   rc   rd   rY   rz   r{   r   rT   r   r|   r   r}   r~   r   )r%   r   r   rY   r   r   s         r(   to_assertionzJWTParameters.to_assertionc  s   >>%I: 7 ''$%OPP;;$%JKK<<$%KLL(,t}};QH$%LMMdiik"C{{||T66657|&F MM$+++,

$$44?I
 r)   r[   )rP   rQ   rR   rS   r	   r   rT   r   rc   rd   rY   r   r   r   r   r   r   rz   r   r\   r)   r(   r   r   R  s    !JIsTz  t9UVFC$JV:bcGS4Zc ;YZHcDjZ$)$Dk$lFDcNT!l(-gKr(s3:s"'B`"aOS4Za %c?f g#g 3:    r)   r   c                   2    e Zd ZdZ	 	 	 	 ddedededeeged   f   dz  deg ee	eedz  f      f   dz  de
d	edz  d
df fdZdddededeeef   dz  d
ej                   f fdZd
ej                   f fdZdeeef   fdZd
ej                   fdZ xZS )RFC7523OAuthClientProvidera  OAuth client provider for RFC 7523 jwt-bearer grant.

    .. deprecated::
        Use :class:`ClientCredentialsOAuthProvider` for client_credentials with
        client_id + client_secret, or :class:`PrivateKeyJWTOAuthProvider` for
        client_credentials with private_key_jwt authentication instead.

    This provider supports the jwt-bearer authorization grant (RFC 7523 Section 2.1)
    where the JWT itself is the authorization grant.
    Nr   r&   r   redirect_handlercallback_handlertimeoutjwt_parametersr   c                 t    dd l }|j                  dt        d       t        	|   ||||||       || _        y )Nr   zsRFC7523OAuthClientProvider is deprecated. Use ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider instead.   )
stacklevel)warningswarnDeprecationWarningr"   r#   r   )
r%   r   r&   r   r   r   r   r   r   r'   s
            r(   r#   z#RFC7523OAuthClientProvider.__init__  sH     	5	 	 	
 	_g?OQacjk,r)   r   	auth_codecode_verifierrM   c                   K   |xs i }| j                   j                  j                  dk(  r| j                  |       t        |   |||       d{   S 7 w)z9Build token exchange request for authorization_code flow.r   r   N)r-   r&   r   r   r"   "_exchange_token_authorization_code)r%   r   r   rM   r'   s       r(   r   z=RFC7523OAuthClientProvider._exchange_token_authorization_code  s[       %2
<<''BBFWW//:/FW?	=eo?pppps   AAAAc                    K   d| j                   j                  j                  v r| j                          d{   }|S t        |           d{   S 7 7 w)zPerform the authorization flow.+urn:ietf:params:oauth:grant-type:jwt-bearerN)r-   r&   r   _exchange_token_jwt_bearerr"   r9   )r%   token_requestr'   s     r(   r9   z1RFC7523OAuthClientProvider._perform_authorization  sS     8DLL<X<X<d<dd"&"A"A"CCM  7999 D :s!   6AAAAAAc                L   | j                   st        d      | j                  j                  st        d      t	        | j                  j                  j
                        }| j                   j                  |      }||d<   d|d<   | j                  j                         |d<   y)	r   z/Missing JWT parameters for private_key_jwt flowr   r   r   r   r   rY   N)r   r   r-   r   rT   rc   r   rH   )r%   rM   rc   r   s       r(   r   z9RFC7523OAuthClientProvider._add_client_authentication_jwt  s    ""!"STT||**!"STT T\\00778''44F4S	 *3
%&.f
*+ "&!>!>!@
:r)   c                   K   | j                   j                  st        d      | j                  st        d      | j                   j                  st        d      t        | j                   j                  j                        }| j                  j                  |      }d|d}| j                   j                  | j                   j                        r| j                   j                         |d<   | j                   j                  j                  r#| j                   j                  j                  |d<   | j                         }t        j                   d	||d
di      S w)z2Build token exchange request for JWT bearer grant.zMissing client infozMissing JWT parameterszMissing OAuth metadatar   r   )r=   r   r@   r    rA   r>   r?   rB   )r-   r0   r   r   r   r   rT   rc   r   rF   rG   rH   r&   r    rI   rJ   rK   )r%   rc   r   rM   rN   s        r(   r   z5RFC7523OAuthClientProvider._exchange_token_jwt_bearer  s"    ||'' !677"" !9::||**!":;; T\\00778''44F4S	 H"


 <<55dll6S6ST%)\\%B%B%DJz"<<''--"&,,">">"D"DJw,,.	}}IJIl8m
 	
s   EE )NNr!   N)rP   rQ   rR   rS   rT   r   r   r   r   tuplefloatr   r#   r   r   rJ   rK   r   r9   r   r   rU   rV   s   @r(   r   r     s   	  EISW/3-- -- 	-
 #C5)D/#9:TA- #2ysC$J1G'H#HIDP- - &,- 
-, Z^qq-0qAEc3hRVAVq	q:emm :ADcN A&
%-- 
r)   r   )rS   r{   collections.abcr   r   typingr   r   uuidr   rJ   r}   pydanticr   r	   mcp.client.authr
   r   r   r   mcp.shared.authr   r   r   rT   r_   ra   r   r   r   r\   r)   r(   <module>r      s     /    
 % ^ ^ KSR%8 SRlS XseYs^6K-L :4) 4nMR!4 MR`1I 1ha
!4 a
r)   