Ë
    uPêj¥  ã                   ó®   — d Z ddlZddlmZ ddlmZmZmZmZ e G d„ d«      «       Z	e G d„ de«      «       Z
 G d	„ d
«      Z G d„ d«      Z G d„ d«      Zy)zÅ
Credential providers for proxy authentication.

This module provides a provider-agnostic interface for obtaining OAuth2/JWT tokens.
It follows the same TokenCredential protocol used by Azure SDK.
é    N)Ú	dataclass)ÚAnyÚFinalÚProtocolÚruntime_checkablec                   ó&   — e Zd ZU dZeed<   eed<   y)ÚAccessTokena  
    Represents an OAuth2 access token with expiration.

    This matches the structure used by azure.core.credentials.AccessToken.

    Attributes:
        token: The access token string (typically a JWT).
        expires_on: Unix timestamp when the token expires.
    ÚtokenÚ
expires_onN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚ__annotations__Úint© ó    úc/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy_auth/credentials.pyr	   r	      s   … ñð ƒJØ„Or   r	   c                   ó    — e Zd ZdZdedefd„Zy)ÚTokenCredentialzø
    Protocol for credential providers.

    This matches the azure.core.credentials.TokenCredential interface,
    allowing any Azure SDK credential to be used directly.

    Any class implementing get_token(scope) -> AccessToken can be used.
    ÚscopeÚreturnc                  ó   — y)zö
        Get an access token for the specified scope.

        Args:
            scope: The OAuth2 scope to request (e.g., "api://my-app/.default")

        Returns:
            AccessToken with the token string and expiration timestamp.
        Nr   )Úselfr   s     r   Ú	get_tokenzTokenCredential.get_token(   s   € ð 	r   N)r   r   r   r   r   r	   r   r   r   r   r   r      s   „ ñð
˜sð 
 {ô 
r   r   c                   ó4   — e Zd ZdZddedz  fd„Zdedefd„Zy)	ÚAzureADCredentialaß  
    Wrapper for Azure Identity credentials.

    This wraps any azure-identity credential (DefaultAzureCredential,
    ClientSecretCredential, ManagedIdentityCredential, etc.) and converts
    the token to our AccessToken format.

    If no credential is provided, it will use DefaultAzureCredential
    which tries multiple authentication methods automatically.

    Example:
        # Use default credential chain (env vars, managed identity, CLI, etc.)
        cred = AzureADCredential()

        # Or provide a specific credential
        from azure.identity import ClientSecretCredential
        azure_cred = ClientSecretCredential(tenant_id, client_id, client_secret)
        cred = AzureADCredential(credential=azure_cred)
    NÚ
credentialc                 ó$   — || _         |du| _        y)zç
        Initialize with an optional Azure credential.

        Args:
            credential: An azure-identity credential object. If None,
                       DefaultAzureCredential will be used on first token request.
        N)Ú_credentialÚ_initialized)r   r   s     r   Ú__init__zAzureADCredential.__init__J   s   € ð !+ˆÔØ&¨dÐ2ˆÕr   r   r   c                 óö   — | j                   s	 ddlm}  |«       | _        d| _         | j                  j                  |«      }t        |j                  |j                  ¬«      S # t        $ r t	        d«      ‚w xY w)a  
        Get an access token from Azure AD.

        Args:
            scope: The OAuth2 scope (e.g., "api://my-app/.default")

        Returns:
            AccessToken with the JWT and expiration.

        Raises:
            ImportError: If azure-identity is not installed.
        r   )ÚDefaultAzureCredentialTz]azure-identity is required for AzureADCredential. Install it with: pip install azure-identity©r
   r   )	r"   Úazure.identityr%   r!   ÚImportErrorr   r	   r
   r   )r   r   r%   Úresults       r   r   zAzureADCredential.get_tokenU   sx   € ð × Ò ðÝAá#9Ó#;�Ô Ø$(�Ô!ð ×(Ñ(×2Ñ2°5Ó9ˆÜ §¡¸&×:KÑ:KÔLÐLøô ò Ü!Øsóð ðús   ŽA# Á#A8)N)	r   r   r   r   r   r#   r   r	   r   r   r   r   r   r   5   s-   „ ññ(	3 3¨¡:ó 	3ðM˜sð M {ô Mr   r   c                   ó4   — e Zd ZdZdededefd„Zdedefd„Zy	)
ÚGenericOAuth2Credentialay  
    Generic OAuth2 client credentials flow.

    This works with any OAuth2 provider (Okta, Auth0, Keycloak, etc.)
    that supports the client_credentials grant type.

    Example:
        cred = GenericOAuth2Credential(
            client_id="my-client-id",
            client_secret="my-client-secret",
            token_url="https://my-idp.com/oauth2/token"
        )
    Ú	client_idÚclient_secretÚ	token_urlc                 ó<   — || _         || _        || _        d| _        y)zï
        Initialize OAuth2 client credentials.

        Args:
            client_id: OAuth2 client ID
            client_secret: OAuth2 client secret
            token_url: Token endpoint URL (e.g., "https://idp.com/oauth2/token")
        N)r,   r-   r.   Ú_cached_token)r   r,   r-   r.   s       r   r#   z GenericOAuth2Credential.__init__€   s"   € ð #ˆŒØ*ˆÔØ"ˆŒØ15ˆÕr   r   r   c                 óà  — | j                   r:| j                   j                  t        j                  «       dz   kD  r| j                   S ddl}|j	                  | j
                  d| j                  | j                  |dœ¬«      }|j                  «        |j                  «       }t        |d   t        t        j                  «       «      |j                  dd	«      z   ¬
«      | _         | j                   S )a  
        Get an access token using OAuth2 client credentials flow.

        Tokens are cached and reused until they expire (with 60s buffer).

        Args:
            scope: The OAuth2 scope to request

        Returns:
            AccessToken with the token and expiration.
        é<   r   NÚclient_credentials)Ú
grant_typer,   r-   r   )ÚdataÚaccess_tokenÚ
expires_ini  r&   )r0   r   ÚtimeÚhttpxÚpostr.   r,   r-   Úraise_for_statusÚjsonr	   r   Úget)r   r   r9   Úresponser5   s        r   r   z!GenericOAuth2Credential.get_tokenŽ   sÊ   € ð ×Ò $×"4Ñ"4×"?Ñ"?Ä$Ç)Á)Ã+ÐPRÑBRÒ"RØ×%Ñ%Ð%ãàŸ*™*Ø�N‰Nà2Ø!Ÿ^™^Ø!%×!3Ñ!3Øñ	ð %ó 
ˆð 	×!Ñ!Ô#Ø—m‘m“oˆä(Ø�~Ñ&Üœ4Ÿ9™9›;Ó'¨$¯(©(°<ÀÓ*FÑFô
ˆÔð ×!Ñ!Ð!r   N)r   r   r   r   r   r#   r	   r   r   r   r   r+   r+   q   s4   „ ñð6 #ð 6°cð 6Àcó 6ð""˜sð "" {ô ""r   r+   c                   ó8   — e Zd ZdZdedefd„Zdefd„Zde	fd„Z
y)	ÚProxyAuthHandlera{  
    Manages OAuth2/JWT token lifecycle for proxy authentication.

    This handler:
    - Obtains tokens from the configured credential provider
    - Caches tokens to avoid unnecessary requests
    - Automatically refreshes tokens before they expire (60s buffer)
    - Generates Authorization headers for HTTP requests

    Set this as litellm.proxy_auth to automatically inject auth headers
    into all requests to your LiteLLM Proxy.

    Example:
        import litellm
        from litellm.proxy_auth import AzureADCredential, ProxyAuthHandler

        litellm.proxy_auth = ProxyAuthHandler(
            credential=AzureADCredential(),
            scope="api://my-litellm-proxy/.default"
        )
        litellm.api_base = "https://my-proxy.example.com"

        # Auth headers are now automatically injected
        response = litellm.completion(model="gpt-4", messages=[...])
    r   r   c                 ó.   — || _         || _        d| _        y)a  
        Initialize the proxy auth handler.

        Args:
            credential: A TokenCredential implementation (AzureADCredential,
                       GenericOAuth2Credential, or any custom implementation)
            scope: The OAuth2 scope to request tokens for
        N)r   r   r0   )r   r   r   s      r   r#   zProxyAuthHandler.__init__Î   s   € ð %ˆŒØˆŒ
Ø15ˆÕr   r   c                 óâ   — | j                   r.| j                   j                  t        j                  «       dz   k  r*| j                  j	                  | j
                  «      | _         | j                   S )zš
        Get a valid access token, refreshing if necessary.

        Returns:
            AccessToken that is valid for at least 60 more seconds.
        r2   )r0   r   r8   r   r   r   )r   s    r   r   zProxyAuthHandler.get_tokenÛ   sS   € ð ×!Ò! T×%7Ñ%7×%BÑ%BÄdÇiÁiÃkÐTVÑFVÒ%VØ!%§¡×!:Ñ!:¸4¿:¹:Ó!FˆDÔØ×!Ñ!Ð!r   c                 óD   — | j                  «       }dd|j                  › �iS )zŒ
        Get HTTP headers for authentication.

        Returns:
            Dict with Authorization header containing Bearer token.
        ÚAuthorizationzBearer )r   r
   )r   r
   s     r   Úget_auth_headersz!ProxyAuthHandler.get_auth_headersç   s&   € ð —~‘~Ó'ˆØ 7¨5¯;©;¨-Ð!8Ð9Ð9r   N)r   r   r   r   r   r   r#   r	   r   ÚdictrE   r   r   r   r@   r@   ³   s2   „ ñð46 ?ð 6¸3ó 6ð
"˜;ó 
"ð: $ô :r   r@   )r   r8   Údataclassesr   Útypingr   r   r   r   r	   r   r   r+   r@   r   r   r   ú<module>rI      sn   ðñó Ý !ß :Ó :ð ÷ð ó ðð ô�hó ó ð÷.9Mñ 9M÷x?"ñ ?"÷D<:ò <:r   