o
    i\C                     @  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mZ ddlm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 ddlm Z m!Z! ee"Z#G dd deZ$G dd deZ%G dd deZ&G dd deZ'G dd deZ(dS )a7  WorkOS authentication providers for FastMCP.

This module provides two WorkOS authentication strategies:

1. WorkOSProvider - OAuth proxy for WorkOS Connect applications (non-DCR)
2. AuthKitProvider - DCR-compliant provider for WorkOS AuthKit

Choose based on your WorkOS setup and authentication requirements.
    )annotationsN)AsyncKeyValue)
AnyHttpUrl	SecretStrfield_validator)BaseSettingsSettingsConfigDict)JSONResponse)Route)AccessTokenRemoteAuthProviderTokenVerifier)
OAuthProxy)JWTVerifier)ENV_FILEparse_scopes)
get_logger)NotSetNotSetTc                   @  s   e Zd ZU dZededdZdZded< dZ	ded	< dZ
ded
< dZded< dZded< dZded< dZded< dZded< dZded< dZded< edddedd ZdS )WorkOSProviderSettingsz#Settings for WorkOS OAuth provider.FASTMCP_SERVER_AUTH_WORKOS_ignore
env_prefixenv_fileextraN
str | None	client_idzSecretStr | Noneclient_secretauthkit_domainzAnyHttpUrl | str | Nonebase_url
issuer_urlredirect_pathlist[str] | Nonerequired_scopesz
int | Nonetimeout_secondsallowed_client_redirect_urisjwt_signing_keybeforemodec                 C     t |S Nr   clsv r1   j/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/fastmcp/server/auth/providers/workos.py_parse_scopes3      z$WorkOSProviderSettings._parse_scopes)__name__
__module____qualname____doc__r   r   model_configr   __annotations__r   r    r!   r"   r#   r%   r&   r'   r(   r   classmethodr3   r1   r1   r1   r2   r      s(   
 
r   c                      s4   e Zd ZdZdddd fddZdddZ  ZS )WorkOSTokenVerifierzToken verifier for WorkOS OAuth tokens.

    WorkOS AuthKit tokens are opaque, so we verify them by calling
    the /oauth2/userinfo endpoint to check validity and get user info.
    N
   )r%   r&   r    strr%   r$   r&   intc                  s$   t  j|d |d| _|| _dS )zInitialize the WorkOS token verifier.

        Args:
            authkit_domain: WorkOS AuthKit domain (e.g., "https://your-app.authkit.app")
            required_scopes: Required OAuth scopes
            timeout_seconds: HTTP request timeout
        )r%   /N)super__init__rstripr    r&   )selfr    r%   r&   	__class__r1   r2   rB   @   s   
zWorkOSTokenVerifier.__init__tokenreturnAccessToken | Nonec                   sv  zt j| jd4 I dH n}|j| j dd| dddI dH }|jdkrAtd	|j|jdd  	 W d  I dH  W dS |	 }t
|t|d
d| jpRg d|d
|d|d|d|d|dddW  d  I dH  W S 1 I dH sw   Y  W dS  t jy } ztd| W Y d}~dS d}~w ty } ztd| W Y d}~dS d}~ww )z7Verify WorkOS OAuth token by calling userinfo endpoint.)timeoutNz/oauth2/userinfozBearer zFastMCP-WorkOS-OAuth)Authorizationz
User-Agent)headers   z)WorkOS token verification failed: %d - %ssubunknownemailemail_verifiedname
given_namefamily_name)rN   rP   rQ   rR   rS   rT   )rG   r   scopes
expires_atclaimsz!Failed to verify WorkOS token: %sz#WorkOS token verification error: %s)httpxAsyncClientr&   getr    status_codeloggerdebugtextjsonr   r>   r%   RequestError	Exception)rD   rG   clientresponse	user_dataer1   r1   r2   verify_tokenR   sR   

4$z WorkOSTokenVerifier.verify_token)r    r>   r%   r$   r&   r?   )rG   r>   rH   rI   )r5   r6   r7   r8   rB   rf   __classcell__r1   r1   rE   r2   r<   9   s    
r<   c                      s>   e Zd ZdZeeeeeeeeededdd fddZ  ZS )WorkOSProviderar  Complete WorkOS OAuth provider for FastMCP.

    This provider implements WorkOS AuthKit OAuth using the OAuth Proxy pattern.
    It provides OAuth2 authentication for users through WorkOS Connect applications.

    Features:
    - Transparent OAuth proxy to WorkOS AuthKit
    - Automatic token validation via userinfo endpoint
    - User information extraction from ID tokens
    - Support for standard OAuth scopes (openid, profile, email)

    Setup Requirements:
    1. Create a WorkOS Connect application in your dashboard
    2. Note your AuthKit domain (e.g., "https://your-app.authkit.app")
    3. Configure redirect URI as: http://localhost:8000/auth/callback
    4. Note your Client ID and Client Secret

    Example:
        ```python
        from fastmcp import FastMCP
        from fastmcp.server.auth.providers.workos import WorkOSProvider

        auth = WorkOSProvider(
            client_id="client_123",
            client_secret="sk_test_456",
            authkit_domain="https://your-app.authkit.app",
            base_url="http://localhost:8000"
        )

        mcp = FastMCP("My App", auth=auth)
        ```
    NT)r   r   r    r!   r"   r#   r%   r&   r'   client_storager(   require_authorization_consentr   str | NotSetTr   r    r!   AnyHttpUrl | str | NotSetTr"   r#   r%   list[str] | NotSetT | Noner&   int | NotSetTr'   list[str] | NotSetTri   AsyncKeyValue | Noner(   str | bytes | NotSetTrj   boolc                  s  t dd |||||||||	|d
 D }|jstd|js%td|js,td|j}|ds9d| }|d	}|j	pBd
}|j
pGg }|j}|jrS|j nd}t|||d}t j| d| d|j|||j|j|jpt|j||
|j|d td|j| dS )a  Initialize WorkOS OAuth provider.

        Args:
            client_id: WorkOS client ID
            client_secret: WorkOS client secret
            authkit_domain: Your WorkOS AuthKit domain (e.g., "https://your-app.authkit.app")
            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 WorkOS (defaults to "/auth/callback")
            required_scopes: Required OAuth scopes (no default)
            timeout_seconds: HTTP request timeout for WorkOS API calls
            allowed_client_redirect_uris: List of allowed redirect URI patterns for MCP clients.
                If None (default), all URIs are allowed. If empty list, no URIs are allowed.
            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.
            require_authorization_consent: Whether to require user consent before authorizing clients (default True).
                When True, users see a consent screen before being redirected to WorkOS.
                When False, authorization proceeds directly without user confirmation.
                SECURITY WARNING: Only disable for local development or testing environments.
        c                 S     i | ]\}}|t ur||qS r1   r   .0kr0   r1   r1   r2   
<dictcomp>   s
    z+WorkOSProvider.__init__.<locals>.<dictcomp>)
r   r   r    r!   r"   r#   r%   r&   r'   r(   zQclient_id is required - set via parameter or FASTMCP_SERVER_AUTH_WORKOS_CLIENT_IDzYclient_secret is required - set via parameter or FASTMCP_SERVER_AUTH_WORKOS_CLIENT_SECRETz[authkit_domain is required - set via parameter or FASTMCP_SERVER_AUTH_WORKOS_AUTHKIT_DOMAIN)zhttp://https://ry   r@   r=    )r    r%   r&   z/oauth2/authorizez/oauth2/token)upstream_authorization_endpointupstream_token_endpointupstream_client_idupstream_client_secrettoken_verifierr!   r#   r"   r'   ri   r(   rj   zFInitialized WorkOS OAuth provider for client %s with AuthKit domain %sN)r   model_validateitemsr   
ValueErrorr   r    
startswithrC   r&   r%   r'   get_secret_valuer<   rA   rB   r!   r#   r"   r(   r\   r]   )rD   r   r   r    r!   r"   r#   r%   r&   r'   ri   r(   rj   settingsauthkit_domain_strauthkit_domain_finaltimeout_seconds_finalscopes_final"allowed_client_redirect_uris_finalclient_secret_strr   rE   r1   r2   rB      s|   *




zWorkOSProvider.__init__)r   rk   r   rk   r    rk   r!   rl   r"   rl   r#   rk   r%   rm   r&   rn   r'   ro   ri   rp   r(   rq   rj   rr   )r5   r6   r7   r8   r   rB   rg   r1   r1   rE   r2   rh      s    $rh   c                   @  sP   e Zd ZU ededdZded< ded< dZded	< ed	d
de	dd Z
dS )AuthKitProviderSettings$FASTMCP_SERVER_AUTH_AUTHKITPROVIDER_r   r   r   r    r!   Nr$   r%   r)   r*   c                 C  r,   r-   r   r.   r1   r1   r2   r3   &  r4   z%AuthKitProviderSettings._parse_scopes)r5   r6   r7   r   r   r9   r:   r%   r   r;   r3   r1   r1   r1   r2   r     s   
 
r   c                      s@   e Zd ZdZeeeddd fddZ	dd fddZ  ZS )AuthKitProvideru  AuthKit metadata provider for DCR (Dynamic Client Registration).

    This provider implements AuthKit integration using metadata forwarding
    instead of OAuth proxying. This is the recommended approach for WorkOS DCR
    as it allows WorkOS to handle the OAuth flow directly while FastMCP acts
    as a resource server.

    IMPORTANT SETUP REQUIREMENTS:

    1. Enable Dynamic Client Registration in WorkOS Dashboard:
       - Go to Applications → Configuration
       - Toggle "Dynamic Client Registration" to enabled

    2. Configure your FastMCP server URL as a callback:
       - Add your server URL to the Redirects tab in WorkOS dashboard
       - Example: https://your-fastmcp-server.com/oauth2/callback

    For detailed setup instructions, see:
    https://workos.com/docs/authkit/mcp/integrating/token-verification

    Example:
        ```python
        from fastmcp.server.auth.providers.workos import AuthKitProvider

        # Create AuthKit metadata provider (JWT verifier created automatically)
        workos_auth = AuthKitProvider(
            authkit_domain="https://your-workos-domain.authkit.app",
            base_url="https://your-fastmcp-server.com",
        )

        # Use with FastMCP
        mcp = FastMCP("My App", auth=workos_auth)
        ```
    N)r    r!   r%   r   r    rl   r!   r%   rm   r   TokenVerifier | Nonec                  s   t dd |||d D }t|jd| _tt|jd| _|du r6t| j d| jd|j	d}t
 j|t| jg| jd	 dS )
a|  Initialize AuthKit metadata provider.

        Args:
            authkit_domain: Your AuthKit domain (e.g., "https://your-app.authkit.app")
            base_url: Public URL of this FastMCP server
            required_scopes: Optional list of scopes to require for all requests
            token_verifier: Optional token verifier. If None, creates JWT verifier for AuthKit
        c                 S  rs   r1   rt   ru   r1   r1   r2   rx   a  s
    z,AuthKitProvider.__init__.<locals>.<dictcomp>)r    r!   r%   r@   Nz/oauth2/jwksRS256)jwks_uriissuer	algorithmr%   )r   authorization_serversr!   )r   r   r   r>   r    rC   r   r!   r   r%   rA   rB   )rD   r    r!   r%   r   r   rE   r1   r2   rB   P  s.   


zAuthKitProvider.__init__mcp_pathr   rH   list[Route]c                   s2   t  |} fdd}|td|dgd |S )a  Get OAuth routes including AuthKit authorization server metadata forwarding.

        This returns the standard protected resource routes plus an authorization server
        metadata endpoint that forwards AuthKit's OAuth metadata to clients.

        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              
     s   z:t  4 I dH $}| j dI dH }|  | }t|W  d  I dH  W S 1 I dH s4w   Y  W dS  tyY } ztdd| dddW  Y d}~S d}~ww )zPForward AuthKit OAuth authorization server metadata with FastMCP customizations.N'/.well-known/oauth-authorization-serverserver_errorz"Failed to fetch AuthKit metadata: )errorerror_descriptioni  )r[   )rX   rY   rZ   r    raise_for_statusr_   r	   ra   )requestrb   rc   metadatare   rD   r1   r2   #oauth_authorization_server_metadata  s&   

4zGAuthKitProvider.get_routes.<locals>.oauth_authorization_server_metadatar   GET)endpointmethods)rA   
get_routesappendr
   )rD   r   routesr   rE   r   r2   r     s   zAuthKitProvider.get_routes)r    rl   r!   rl   r%   rm   r   r   r-   )r   r   rH   r   )r5   r6   r7   r8   r   rB   r   rg   r1   r1   rE   r2   r   ,  s    &1r   ))r8   
__future__r   rX   key_value.aio.protocolsr   pydanticr   r   r   pydantic_settingsr   r   starlette.responsesr	   starlette.routingr
   fastmcp.server.authr   r   r   fastmcp.server.auth.oauth_proxyr   !fastmcp.server.auth.providers.jwtr   fastmcp.settingsr   fastmcp.utilities.authr   fastmcp.utilities.loggingr   fastmcp.utilities.typesr   r   r5   r\   r   r<   rh   r   r   r1   r1   r1   r2   <module>   s,    
H 