Ë
    îñþi—!  ã                  ó    — d dl mZ d dlZd dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZmZ ddlmZmZ dd	lmZ dd
lmZmZ ddlmZ  G d„ d«      Zy)é    )ÚannotationsN)Ú	lru_cache)Ú
SSLContext)ÚAny)Ú	HTTPErrorÚURLErroré   )ÚPyJWKÚPyJWKSet)Údecode_complete)ÚPyJWKClientConnectionErrorÚPyJWKClientError)ÚJWKSetCachec                  ó€   — e Zd Z	 	 	 	 	 	 	 d		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d
d„Zdd„Zddd„Zddd„Zdd„Zdd„Ze	dd„«       Z
y)ÚPyJWKClientNc	                óú   — |€i }|| _         d| _        || _        || _        || _        |r%|dk  rt        d|› d�«      ‚t        |«      | _        nd| _        |r$ t        |¬«      | j                  «      }	|	| _        yy)u—  A client for retrieving signing keys from a JWKS endpoint.

        ``PyJWKClient`` uses a two-tier caching system to avoid unnecessary
        network requests:

        **Tier 1 â€” JWK Set cache** (enabled by default):
        Caches the entire JSON Web Key Set response from the endpoint.
        Controlled by:

        - ``cache_jwk_set``: Set to ``True`` (the default) to enable this
          cache. When enabled, the JWK Set is fetched from the network only
          when the cache is empty or expired.
        - ``lifespan``: Time in seconds before the cached JWK Set expires.
          Defaults to ``300`` (5 minutes). Must be greater than 0.

        **Tier 2 â€” Signing key cache** (disabled by default):
        Caches individual signing keys (looked up by ``kid``) using an LRU
        cache with **no time-based expiration**. Keys are evicted only when
        the cache reaches its maximum size. Controlled by:

        - ``cache_keys``: Set to ``True`` to enable this cache.
          Defaults to ``False``.
        - ``max_cached_keys``: Maximum number of signing keys to keep in
          the LRU cache. Defaults to ``16``.

        :param uri: The URL of the JWKS endpoint.
        :type uri: str
        :param cache_keys: Enable the per-key LRU cache (Tier 2).
        :type cache_keys: bool
        :param max_cached_keys: Max entries in the signing key LRU cache.
        :type max_cached_keys: int
        :param cache_jwk_set: Enable the JWK Set response cache (Tier 1).
        :type cache_jwk_set: bool
        :param lifespan: TTL in seconds for the JWK Set cache.
        :type lifespan: float
        :param headers: Optional HTTP headers to include in requests.
        :type headers: dict or None
        :param timeout: HTTP request timeout in seconds.
        :type timeout: float
        :param ssl_context: Optional SSL context for the request.
        :type ssl_context: ssl.SSLContext or None
        Nr   z/Lifespan must be greater than 0, the input is "ú")Úmaxsize)	ÚuriÚjwk_set_cacheÚheadersÚtimeoutÚssl_contextr   r   r   Úget_signing_key)
Úselfr   Ú
cache_keysÚmax_cached_keysÚcache_jwk_setÚlifespanr   r   r   r   s
             úO/root/aria/mcps/aria-brain/venv/lib/python3.12/site-packages/jwt/jwks_client.pyÚ__init__zPyJWKClient.__init__   s—   € ðj ˆ?ØˆGØˆŒØ15ˆÔØˆŒØˆŒØ&ˆÔáð ˜1Š}Ü&ØEÀhÀZÈqÐQóð ô "-¨XÓ!6ˆDÕà!%ˆDÔáà@œi°Ô@À×AUÑAUÓVˆOà#2ˆDÕ ð	 ó    c                ón  — d}	 t         j                  j                  | j                  | j                  ¬«      }t         j                  j                  || j                  | j                  ¬«      5 }t        j                  |«      }ddd«       || j                  �| j                  j                  |«       S S # 1 sw Y   Œ3xY w# t        t        f$ r5}t        |t        «      r|j!                  «        t#        d|› d�«      |‚d}~ww xY w# | j                  �| j                  j                  |«       w w xY w)ae  Fetch the JWK Set from the JWKS endpoint.

        Makes an HTTP request to the configured ``uri`` and returns the
        parsed JSON response. If the JWK Set cache is enabled, the
        response is stored in the cache.

        :returns: The parsed JWK Set as a dictionary.
        :raises PyJWKClientConnectionError: If the HTTP request fails.
        N)Úurlr   )r   Úcontextz'Fail to fetch data from the url, err: "r   )ÚurllibÚrequestÚRequestr   r   Úurlopenr   r   ÚjsonÚloadr   Úputr   ÚTimeoutErrorÚ
isinstancer   Úcloser   )r   Újwk_setÚrÚresponseÚes        r    Ú
fetch_datazPyJWKClient.fetch_data_   s  € ð ˆð	0Ü—‘×&Ñ&¨4¯8©8¸T¿\¹\Ð&ÓJˆAÜ—‘×'Ñ'Ø˜4Ÿ<™<°×1AÑ1Að (ó ð .àÜŸ)™) HÓ-�÷.ð à×!Ñ!Ð-Ø×"Ñ"×&Ñ& wÕ/ð .÷.ð .ûô œ,Ð'ò 	Ü˜!œYÔ'Ø—‘”	Ü,Ø9¸!¸¸AÐ>óàðûð	ûð ×!Ñ!Ð-Ø×"Ñ"×&Ñ& wÕ/ð .úsB   „A+C Á/B7ÂC ÂD
 Â7C Â<C ÃDÃ0DÄDÄD
 Ä
*D4c                óÚ   — d}| j                   �|s| j                   j                  «       }|€| j                  «       }t        |t        «      st        d«      ‚t        j                  |«      S )aN  Return the JWK Set, using the cache when available.

        :param refresh: Force a fresh fetch from the endpoint, bypassing
            the cache.
        :type refresh: bool
        :returns: The JWK Set.
        :rtype: PyJWKSet
        :raises PyJWKClientError: If the endpoint does not return a JSON
            object.
        Nz.The JWKS endpoint did not return a JSON object)r   Úgetr4   r.   Údictr   r   Ú	from_dict)r   ÚrefreshÚdatas      r    Úget_jwk_setzPyJWKClient.get_jwk_set|   sc   € ð ˆØ×ÑÐ)±'Ø×%Ñ%×)Ñ)Ó+ˆDàˆ<Ø—?‘?Ó$ˆDä˜$¤Ô%Ü"Ð#SÓTÐTä×!Ñ! $Ó'Ð'r"   c                ó²   — | j                  |«      }|j                  D �cg c]  }|j                  dv r|j                  r|‘Œ  }}|st	        d«      ‚|S c c}w )a§  Return all signing keys from the JWK Set.

        Filters the JWK Set to keys whose ``use`` is ``"sig"`` (or
        unspecified) and that have a ``kid``.

        :param refresh: Force a fresh fetch from the endpoint, bypassing
            the cache.
        :type refresh: bool
        :returns: A list of signing keys.
        :rtype: list[PyJWK]
        :raises PyJWKClientError: If no signing keys are found.
        )ÚsigNz2The JWKS endpoint did not contain any signing keys)r;   ÚkeysÚpublic_key_useÚkey_idr   )r   r9   r0   Újwk_set_keyÚsigning_keyss        r    Úget_signing_keyszPyJWKClient.get_signing_keys“   si   € ð ×"Ñ" 7Ó+ˆð  'Ÿ|™|ö
àØ×)Ñ)¨]Ñ:¸{×?QÒ?Qò ð
ˆð 
ñ Ü"Ð#WÓXÐXàÐùò
s    #Ac                ó¸   — | j                  «       }| j                  ||«      }|s5| j                  d¬«      }| j                  ||«      }|st        d|› d�«      ‚|S )a¡  Return the signing key matching the given ``kid``.

        If no match is found in the current JWK Set, the set is
        refreshed from the endpoint and the lookup is retried once.

        :param kid: The key ID to look up.
        :type kid: str
        :returns: The matching signing key.
        :rtype: PyJWK
        :raises PyJWKClientError: If no matching key is found after
            refreshing.
        T)r9   z,Unable to find a signing key that matches: "r   )rC   Ú	match_kidr   )r   ÚkidrB   Úsigning_keys       r    r   zPyJWKClient.get_signing_key¬   sl   € ð ×,Ñ,Ó.ˆØ—n‘n \°3Ó7ˆáà×0Ñ0¸Ð0Ó>ˆLØŸ.™.¨°sÓ;ˆKáÜ&ØBÀ3À%ÀqÐIóð ð Ðr"   c                ój   — t        |ddi¬«      }|d   }| j                  |j                  d«      «      S )aG  Return the signing key for a JWT by reading its ``kid`` header.

        Extracts the ``kid`` from the token's unverified header and
        delegates to :meth:`get_signing_key`.

        :param token: The encoded JWT.
        :type token: str or bytes
        :returns: The matching signing key.
        :rtype: PyJWK
        Úverify_signatureF)ÚoptionsÚheaderrF   )Údecode_tokenr   r6   )r   ÚtokenÚ
unverifiedrK   s       r    Úget_signing_key_from_jwtz$PyJWKClient.get_signing_key_from_jwtÈ   s:   € ô " %Ð2DÀeÐ1LÔMˆ
Ø˜HÑ%ˆØ×#Ñ# F§J¡J¨uÓ$5Ó6Ð6r"   c                ó@   — d}| D ]  }|j                   |k(  sŒ|} |S  |S )a7  Find a key in *signing_keys* that matches *kid*.

        :param signing_keys: The list of keys to search.
        :type signing_keys: list[PyJWK]
        :param kid: The key ID to match.
        :type kid: str
        :returns: The matching key, or ``None`` if not found.
        :rtype: PyJWK or None
        N)r@   )rB   rF   rG   Úkeys       r    rE   zPyJWKClient.match_kid×   s:   € ð ˆàò 	ˆCØ�z‰z˜SÓ Ø!�ØàÐð	ð
 Ðr"   )Fé   Ti,  Né   N)r   Ústrr   Úboolr   Úintr   rU   r   Úfloatr   zdict[str, Any] | Noner   rW   r   zSSLContext | None)Úreturnr   )F)r9   rU   rX   r   )r9   rU   rX   úlist[PyJWK])rF   rT   rX   r
   )rM   zstr | bytesrX   r
   )rB   rY   rF   rT   rX   zPyJWK | None)Ú__name__Ú
__module__Ú__qualname__r!   r4   r;   rC   r   rO   ÚstaticmethodrE   © r"   r    r   r      s£   „ ð !Ø!Ø"ØØ)-ØØ)-ðL3àðL3ð ðL3ð ð	L3ð
 ðL3ð ðL3ð 'ðL3ð ðL3ð 'óL3ó\0ô:(ô.ó2ó87ð òó ñr"   r   )Ú
__future__r   r*   Úurllib.requestr&   Ú	functoolsr   Ússlr   Útypingr   Úurllib.errorr   r   Úapi_jwkr
   r   Úapi_jwtr   rL   Ú
exceptionsr   r   r   r   r   r^   r"   r    ú<module>rh      s2   ðÝ "ã Û Ý Ý Ý ß ,ç $Ý 4ß DÝ &÷Yò Yr"   