o
    i=                     @   s   d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ eeZG dd deZG dd deZdS )a  OIDC Proxy Provider for FastMCP.

This provider acts as a transparent proxy to an upstream OIDC compliant Authorization
Server. It leverages the OAuthProxy class to handle Dynamic Client Registration and
forwarding of all OAuth flows.

This implementation is based on:
    OpenID Connect Discovery 1.0 - https://openid.net/specs/openid-connect-discovery-1_0.html
    OAuth 2.0 Authorization Server Metadata - https://datatracker.ietf.org/doc/html/rfc8414
    )SequenceN)AsyncKeyValue)
AnyHttpUrl	BaseModelmodel_validator)Self)TokenVerifier)
OAuthProxy)JWTVerifier)
get_loggerc                	   @   s  e Zd ZU dZdZeed< dZee	B dB ed< dZ
ee	B dB ed< dZee	B dB ed< dZee	B dB ed< dZee	B dB ed	< dZee	B dB ed
< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZee	 dB ed< dZ ee	 dB ed< dZ!ee	 dB ed< dZ"ee	 dB ed< dZ#ee	 dB ed< dZ$ee	B dB ed< dZ%ee	 dB ed < dZ&ee	 dB ed!< dZ'edB ed"< dZ(edB ed#< dZ)edB ed$< dZ*edB ed%< dZ+ee	B dB ed&< dZ,ee	B dB ed'< dZ-ee	B dB ed(< dZ.ee	 dB ed)< dZ/ee	 dB ed*< dZ0ee	B dB ed+< dZ1ee	 dB ed,< dZ2ee	 dB ed-< dZ3ee	 dB ed.< dZ4e	dB ed/< e5d0d1d2e6fd3d4Z7e8d5ededB d6e9dB d2e6fd7d8Z:dS )9OIDCConfigurationzOIDC Configuration.

    See:
        https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
        https://datatracker.ietf.org/doc/html/rfc8414#section-2
    TstrictNissuerauthorization_endpointtoken_endpointuserinfo_endpointjwks_uriregistration_endpointscopes_supportedresponse_types_supportedresponse_modes_supportedgrant_types_supportedacr_values_supportedsubject_types_supported%id_token_signing_alg_values_supported(id_token_encryption_alg_values_supported(id_token_encryption_enc_values_supported%userinfo_signing_alg_values_supported(userinfo_encryption_alg_values_supported(userinfo_encryption_enc_values_supported+request_object_signing_alg_values_supported.request_object_encryption_alg_values_supported.request_object_encryption_enc_values_supported%token_endpoint_auth_methods_supported0token_endpoint_auth_signing_alg_values_supporteddisplay_values_supportedclaim_types_supportedclaims_supportedservice_documentationclaims_locales_supportedui_locales_supportedclaims_parameter_supportedrequest_parameter_supportedrequest_uri_parameter_supported require_request_uri_registrationop_policy_uri
op_tos_urirevocation_endpoint*revocation_endpoint_auth_methods_supported5revocation_endpoint_auth_signing_alg_values_supportedintrospection_endpoint-introspection_endpoint_auth_methods_supported8introspection_endpoint_auth_signing_alg_values_supported code_challenge_methods_supportedsigned_metadataafter)modereturnc                    sj    j s S ddtdtddf fdd}|dd	 |d
d	 |dd	 |dd	 |d |d |d  S )zEnforce strict rules.Fattris_urlr;   Nc              
      s   t  | d }|sd|  }t| t||rt|trd S zt| W d S  tyA } zd|  }t| t||d }~ww )Nz)Missing required configuration metadata: z(Invalid URL for configuration metadata: )getattrloggererror
ValueError
isinstancer   	Exception)r<   r=   valuemessageeself d/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/fastmcp/server/auth/oidc_proxy.pyenforcer   s   




z2OIDCConfiguration._enforce_strict.<locals>.enforcer   Tr   r   r   r   r   r   )F)r   strbool)rH   rK   rI   rG   rJ   _enforce_strictl   s   



z!OIDCConfiguration._enforce_strict
config_urltimeout_secondsc                C   sx   i }|dur
||d< z!t jt|fi |}|  | }|dur&||d< | |W S  ty;   td|   w )zGet the OIDC configuration for the specified config URL.

        Args:
            config_url: The OIDC config URL
            strict: The strict flag for the configuration
            timeout_seconds: HTTP request timeout in seconds
        Ntimeoutr   z1Unable to get OIDC configuration for config url: )	httpxgetrL   raise_for_statusjsonmodel_validaterC   r?   	exception)clsrO   r   rP   
get_kwargsresponseconfig_datarI   rI   rJ   get_oidc_configuration   s    z(OIDCConfiguration.get_oidc_configuration);__name__
__module____qualname____doc__r   rM   __annotations__r   r   rL   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r   r   rN   classmethodintr\   rI   rI   rI   rJ   r      sv   
  r   c                %       s:  e Zd ZU dZeed< dddddddddddddddeeB dedB ded	ed
edB de	dB de
dB dedB dee dB deeB deeB dB dedB dee dB dedB deeB dB dedB deddf$ fddZdededB de	dB defddZddddddedB d
edB dee dB de	dB de
f
ddZ  ZS )	OIDCProxya  OAuth provider that wraps OAuthProxy to provide configuration via an OIDC configuration URL.

    This provider makes it easier to add OAuth protection for any upstream provider
    that is OIDC compliant.

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.auth.oidc_proxy import OIDCProxy

        # Simple OIDC based protection
        auth = OIDCProxy(
            config_url="https://oidc.config.url",
            client_id="your-oidc-client-id",
            client_secret="your-oidc-client-secret",
            base_url="https://your.server.url",
        )

        mcp = FastMCP("My Protected Server", auth=auth)
        ```
    oidc_configNT)r   audiencerP   token_verifier	algorithmrequired_scopes
issuer_urlredirect_pathallowed_client_redirect_urisclient_storagejwt_signing_keytoken_endpoint_auth_methodrequire_authorization_consentrO   r   	client_idclient_secretrf   rP   rg   rh   ri   base_urlrj   rk   rl   rm   rn   ro   rp   r;   c                   sN  |st d|st d|st d|
st d|dur,|dur$t d|	dur,t dt|tr5t|}| |||| _| jjrE| jjsRt	d| j  t d	| jj
r\t| jj
nd}|du rk| j|||	|d
}t| jjt| jj|||||
|p}|
| jj|||||d}|r||d< |rd|i}||d< ||d< t jdi | dS )a  Initialize the OIDC proxy provider.

        Args:
            config_url: URL of upstream configuration
            strict: Optional strict flag for the configuration
            client_id: Client ID registered with upstream server
            client_secret: Client secret for upstream server
            audience: Audience for upstream server
            timeout_seconds: HTTP request timeout in seconds
            token_verifier: Optional custom token verifier (e.g., IntrospectionTokenVerifier for opaque tokens).
                If not provided, a JWTVerifier will be created using the OIDC configuration.
                Cannot be used with algorithm or required_scopes parameters (configure these on your verifier instead).
            algorithm: Token verifier algorithm (only used if token_verifier is not provided)
            required_scopes: Required scopes for token validation (only used if token_verifier is not provided)
            base_url: Public URL where OAuth endpoints will be accessible (includes any mount path)
            issuer_url: Issuer URL for OAuth metadata (defaults to base_url). Use root-level URL
                to avoid 404s during discovery when mounting under a path.
            redirect_path: Redirect path configured in upstream OAuth app (defaults to "/auth/callback")
            allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients.
                Patterns support wildcards (e.g., "http://localhost:*", "https://*.example.com/*").
                If None (default), only localhost redirect URIs are allowed.
                If empty list, all redirect URIs are allowed (not recommended for production).
                These are for MCP clients performing loopback redirects, NOT for the upstream OAuth app.
            client_storage: Storage backend for OAuth state (client registrations, encrypted tokens).
                If None, a DiskStore will be created in the data directory (derived from `platformdirs`). The
                disk store will be encrypted using a key derived from the JWT Signing Key.
            jwt_signing_key: Secret for signing FastMCP JWT tokens (any string or bytes). If bytes are provided,
                they will be used as is. If a string is provided, it will be derived into a 32-byte key. If not
                provided, the upstream client secret will be used to derive a 32-byte key using PBKDF2.
            token_endpoint_auth_method: Token endpoint authentication method for upstream server.
                Common values: "client_secret_basic", "client_secret_post", "none".
                If None, authlib will use its default (typically "client_secret_basic").
            require_authorization_consent: Whether to require user consent before authorizing clients (default True).
                When True, users see a consent screen before being redirected to the upstream IdP.
                When False, authorization proceeds directly without user confirmation.
                SECURITY WARNING: Only disable for local development or testing environments.
        zMissing required config URLzMissing required client idzMissing required client secretzMissing required base URLNzzCannot specify 'algorithm' when providing a custom token_verifier. Configure the algorithm on your token verifier instead.zCannot specify 'required_scopes' when providing a custom token_verifier. Configure required scopes on your token verifier instead.zInvalid OIDC Configuration: zMissing required OIDC endpointsrh   rf   ri   rP   )upstream_authorization_endpointupstream_token_endpointupstream_client_idupstream_client_secretupstream_revocation_endpointrg   rs   rj   service_documentation_urlrl   rm   rn   ro   rp   rk   rf   extra_authorize_paramsextra_token_paramsrI   )rA   rB   rL   r   r\   re   r   r   r?   debugr1   get_token_verifierr(   super__init__)rH   rO   r   rq   rr   rf   rP   rg   rh   ri   rs   rj   rk   rl   rm   rn   ro   rp   r1   init_kwargsextra_params	__class__rI   rJ   r      s~   B

zOIDCProxy.__init__c                 C   s   t j|||dS )a  Gets the OIDC configuration for the specified configuration URL.

        Args:
            config_url: The OIDC configuration URL
            strict: The strict flag for the configuration
            timeout_seconds: HTTP request timeout in seconds
        )r   rP   )r   r\   )rH   rO   r   rP   rI   rI   rJ   r\   Y  s   z OIDCProxy.get_oidc_configurationrt   c                C   s"   t t| jjt| jj|||dS )aX  Creates the token verifier for the specified OIDC configuration and arguments.

        Args:
            algorithm: Optional token verifier algorithm
            audience: Optional token verifier audience
            required_scopes: Optional token verifier required_scopes
            timeout_seconds: HTTP request timeout in seconds
        )r   r   rh   rf   ri   )r
   rL   re   r   r   )rH   rh   rf   ri   rP   rI   rI   rJ   r~   j  s   

zOIDCProxy.get_token_verifier)r]   r^   r_   r`   r   ra   r   rL   rM   rc   r   listr   bytesr   r\   r~   __classcell__rI   rI   r   rJ   rd      s   
 	




 

rd   )r`   collections.abcr   rR   key_value.aio.protocolsr   pydanticr   r   r   typing_extensionsr   fastmcp.server.authr   fastmcp.server.auth.oauth_proxyr	   !fastmcp.server.auth.providers.jwtr
   fastmcp.utilities.loggingr   r]   r?   r   rd   rI   rI   rI   rJ   <module>   s     