
    kKj#                        d Z ddlmZ ddlmZ ddlZddlmZmZ ddl	m
Z
 ddlmZ ddlmZmZ dd	lmZ dd
lmZ  ee      Z G d ded      Z G d de      Zy)a  PropelAuth authentication provider for FastMCP.

Example:
    ```python
    from fastmcp import FastMCP
    from fastmcp.server.auth.providers.propelauth import PropelAuthProvider

    auth = PropelAuthProvider(
        auth_url="https://auth.yourdomain.com",
        introspection_client_id="your-client-id",
        introspection_client_secret="your-client-secret",
        base_url="https://your-fastmcp-server.com",
        required_scopes=["read:user_data"],
    )

    mcp = FastMCP("My App", auth=auth)
    ```
    )annotations)	TypedDictN)
AnyHttpUrl	SecretStr)JSONResponse)Route)AccessTokenRemoteAuthProviderIntrospectionTokenVerifier)
get_loggerc                  6    e Zd ZU ded<   ded<   ded<   ded<   y)	%PropelAuthTokenIntrospectionOverridesinttimeout_secondsz
int | Nonecache_ttl_secondsmax_cache_sizezhttpx.AsyncClient | Nonehttp_clientN)__name__
__module____qualname____annotations__     y/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/fastmcp/server/auth/providers/propelauth.pyr   r   $   s    !!))r   r   F)totalc                       e Zd ZdZddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZ	 d		 	 	 d
 fdZd fdZ	 	 	 	 	 	 	 	 	 	 	 	 ddZ xZS )PropelAuthProvideram  PropelAuth resource server provider using OAuth 2.1 token introspection.

    This provider validates access tokens via PropelAuth's introspection endpoint
    and forwards authorization server metadata for OAuth discovery.

    Setup:
        1. Enable MCP authentication in the PropelAuth Dashboard
        2. Configure scopes on the MCP page
        3. Select which redirect URIs to enable by picking which clients you support
        4. Generate introspection credentials (Client ID + Client Secret)

    For detailed setup instructions, see:
    https://docs.propelauth.com/mcp-authentication/overview

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.auth.providers.propelauth import PropelAuthProvider

        auth = PropelAuthProvider(
            auth_url="https://auth.yourdomain.com",
            introspection_client_id="your-client-id",
            introspection_client_secret="your-client-secret",
            base_url="https://your-fastmcp-server.com",
            required_scopes=["read:user_data"],
        )

        mcp = FastMCP("My App", auth=auth)
        ```
    N)required_scopesscopes_supportedresource_nameresource_documentationresourcetoken_introspection_overridesc       
        $   t        |      j                  d      }| d}t        | d      }|	d| _        t        j                  d       nt        |	      | _        | j                  |||||
      }|| _        t        | %  ||g||||       y)aL  Initialize PropelAuth provider.

        Args:
            auth_url: Your PropelAuth Auth URL (from the Backend Integration page)
            introspection_client_id: Introspection Client ID from the PropelAuth Dashboard
            introspection_client_secret: Introspection Client Secret from the PropelAuth Dashboard
            base_url: Public URL of this FastMCP server
            required_scopes: Optional list of scopes that must be present in tokens
            scopes_supported: Optional list of scopes to advertise in OAuth metadata.
                If None, uses required_scopes. Use this when the scopes clients should
                request differ from the scopes enforced on tokens.
            resource_name: Optional name for the protected resource metadata.
            resource_documentation: Optional documentation URL for the protected resource.
            resource: Optional resource URI (RFC 8707) identifying this MCP server.
                Use this when multiple MCP servers share the same PropelAuth
                authorization server (e.g. ``resource="https://api.example.com/mcp"``),
                so only tokens intended for this MCP server are accepted.
            token_introspection_overrides: Optional overrides for the underlying
                IntrospectionTokenVerifier (timeout, caching, http_client)
        /z/oauth/2.1/introspectz
/oauth/2.1NzFPropelAuthProvider: no resource configured, audience checking disabled)introspection_url	client_idclient_secretr   introspection_overrides)token_verifierauthorization_serversbase_urlr    r!   r"   )
strrstripr   	_resourceloggerdebug_create_token_verifier_normalized_auth_urlsuper__init__)selfauth_urlintrospection_client_idintrospection_client_secretr-   r   r    r!   r"   r#   r$   normalized_auth_urlr'   authorization_server_urlr+   	__class__s                  r   r6   zPropelAuthProvider.__init__K   s    H "(m2237233HI#-1D0EZ.P#Q !DNLLX !]DN44/-5+$A 5 
 %8!)#;"<-'#9 	 	
r   c                n     t            |      } fd}|j                  t        d|dg             |S )a  Get routes for this provider.

        Includes the standard routes from the RemoteAuthProvider (protected resource metadata routes (RFC 9728)),
        and creates an authorization server metadata route that forwards to PropelAuth's route

        Args:
            mcp_path: The path where the MCP endpoint is mounted (e.g., "/mcp")
                This is used to advertise the resource URL in metadata.
        c                  K   	 t        j                         4 d{   }|j                  j                   d       d{   }|j	                          |j                         }t        |      cddd      d{    S 7 f7 B7 	# 1 d{  7  sw Y   yxY w# t        $ r}t        dd| dd      cY d}~S d}~ww xY ww)z6Forward PropelAuth OAuth authorization server metadataNz1/.well-known/oauth-authorization-server/oauth/2.1server_errorz%Failed to fetch PropelAuth metadata: )errorerror_descriptioni  )status_code)httpxAsyncClientgetr4   raise_for_statusjsonr   	Exception)requestclientresponsemetadataer7   s        r   #oauth_authorization_server_metadatazJPropelAuthProvider.get_routes.<locals>.oauth_authorization_server_metadata   s      ,,..&%+ZZ4455fg&  H --/'}}H'1 /..  /...  #!//TUVTW-X !$ s   CB BB "B
B.B
2B >B?B CB B
B 
BBBB CB 	C(C :C;C CCz'/.well-known/oauth-authorization-serverGET)endpointmethods)r5   
get_routesappendr   )r7   mcp_pathroutesrO   r=   s   `   r   rS   zPropelAuthProvider.get_routes   sA     #H-	& 	9<	
 r   c                   K   t         |   |       d{   }|| j                  |S |j                  j	                  d      }|| j                  k7  r"t
        j                  d|| j                         y|S 7 bw)zIVerify token and check the ``aud`` claim against the configured resource.Naudz@PropelAuthProvider: token audience %r does not match resource %s)r5   verify_tokenr0   claimsrF   r1   r2   )r7   tokenresultrX   r=   s       r   rY   zPropelAuthProvider.verify_token   st     w+E22>T^^3Mmm&$.. LLR
  3s   A;A9A#A;c                    i }|0d|v r|d   |d<   d|v r|d   |d<   d|v r|d   |d<   d|v r|d   |d<   t        d||||d|S )Nr   r   r   r   )r'   r(   r)   r   r   r   )r7   r'   r(   r)   r   r*   safe_overridess          r   r3   z)PropelAuthProvider._create_token_verifier   s     AC". $;;4K%501 #&==6M'723  #::3J$4/0  770G0V}-) 
/'+	

 
 	
r   )r8   AnyHttpUrl | strr9   r.   r:   str | SecretStrr-   r_   r   list[str] | Noner    ra   r!   
str | Noner"   zAnyHttpUrl | Noner#   zAnyHttpUrl | str | Noner$   ,PropelAuthTokenIntrospectionOverrides | None)N)rU   rb   returnzlist[Route])r[   r.   rd   zAccessToken | None)r'   r.   r(   r.   r)   r`   r   ra   r*   rc   rd   r   )	r   r   r   __doc__r6   rS   rY   r3   __classcell__)r=   s   @r   r   r   +   s    L -1-1$(48,0 @
 #@
 "%	@

 &5@
 #@
 *@
 +@
 "@
 !2@
 *@
 9@
H  $** 
*X" 
 
  
 '	 

 * 
 "N 
 
$ 
r   r   )re   
__future__r   typingr   rD   pydanticr   r   starlette.responsesr   starlette.routingr   fastmcp.server.authr	   r
   +fastmcp.server.auth.providers.introspectionr   fastmcp.utilities.loggingr   r   r1   r   r   r   r   r   <module>ro      sN   & #   * , # ? R 0	H	*IU *
+ 
r   