Ë
    ï%9jž$  ã                  ó¬   — 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 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)Úurlparseé   )Ú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	                óf  — |€i }t        |«      j                  j                  «       }	|	dvrt        d|	›d�«      ‚|| _        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
        N)ÚhttpÚhttpszInvalid JWKS URI scheme z(: only 'http' and 'https' are supported.r   z/Lifespan must be greater than 0, the input is "ú")Úmaxsize)r	   ÚschemeÚlowerr   ÚuriÚjwk_set_cacheÚheadersÚtimeoutÚssl_contextr   r   Úget_signing_key)Úselfr   Ú
cache_keysÚmax_cached_keysÚcache_jwk_setÚlifespanr   r   r   r   r   s              úK/var/www/html/truck-me/venv/lib/python3.12/site-packages/jwt/jwks_client.pyÚ__init__zPyJWKClient.__init__   sÚ   € ðj ˆ?ØˆGô
 ˜#“×%Ñ%×+Ñ+Ó-ˆØÐ*Ñ*Ü"Ø*¨6¨*ð 5!ð "óð ð ˆŒØ15ˆÔØˆŒØˆŒØ&ˆÔáð ˜1Š}Ü&ØEÀhÀZÈqÐQóð ô "-¨XÓ!6ˆDÕà!%ˆDÔáà@œi°Ô@À×AUÑAUÓVˆOà#2ˆDÕ ð	 ó    c                ó  — 	 t         j                  j                  | j                  | j                  ¬«      }t         j                  j                  || j                  | j                  ¬«      5 }t        j                  |«      }ddd«       | j                   �| j                   j#                  «       S # 1 sw Y   Œ2xY w# t        t        f$ r5}t        |t        «      r|j                  «        t        d|› d�«      |‚d}~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.
        )Úurlr   )r   ÚcontextNz'Fail to fetch data from the url, err: "r   )ÚurllibÚrequestÚRequestr   r   Úurlopenr   r   ÚjsonÚloadr   ÚTimeoutErrorÚ
isinstancer   Úcloser   r   Úput)r    ÚrÚresponseÚjwk_setÚes        r%   Ú
fetch_datazPyJWKClient.fetch_dataj   sâ   € ð	Ü—‘×&Ñ&¨4¯8©8¸T¿\¹\Ð&ÓJˆAÜ—‘×'Ñ'Ø˜4Ÿ<™<°×1AÑ1Að (ó ð .àÜŸ)™) HÓ-�÷.ð ×ÑÐ)Ø×Ñ×"Ñ" 7Ô+Øˆ÷#.ð .ûô œ,Ð'ò 	Ü˜!œYÔ'Ø—‘”	Ü,Ø9¸!¸¸AÐ>óàðûð	ús0   ‚A+C  Á-B4ÂC  Â4B=Â9C  Ã DÃ0C?Ã?D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   Úgetr9   r2   Ú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    r>   r7   Ú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)r>   z,Unable to find a signing key that matches: "r   )rH   Ú	match_kidr   )r    ÚkidrG   Ú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ÚheaderrK   )Údecode_tokenr   r;   )r    ÚtokenÚ
unverifiedrP   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)rE   )rG   rK   rL   Úkeys       r%   rJ   zPyJWKClient.match_kidä   s:   € ð ˆàò 	ˆCØ�z‰z˜SÓ Ø!�ØàÐð	ð
 Ðr'   )Fé   Ti,  Né   N)r   Ústrr!   Úboolr"   Úintr#   rZ   r$   Úfloatr   zdict[str, Any] | Noner   r\   r   zSSLContext | None)Úreturnr   )F)r>   rZ   r]   r   )r>   rZ   r]   úlist[PyJWK])rK   rY   r]   r   )rR   zstr | bytesr]   r   )rG   r^   rK   rY   r]   zPyJWK | None)Ú__name__Ú
__module__Ú__qualname__r&   r9   r@   rH   r   rT   ÚstaticmethodrJ   © r'   r%   r   r      s£   „ ð !Ø!Ø"ØØ)-ØØ)-ðV3àðV3ð ðV3ð ð	V3ð
 ðV3ð ðV3ð 'ðV3ð ðV3ð 'óV3ópô>(ô.ó2ó87ð òó ñr'   r   )Ú
__future__r   r/   Úurllib.requestr+   Ú	functoolsr   Ússlr   Útypingr   Úurllib.errorr   r   Úurllib.parser	   Úapi_jwkr   r   Úapi_jwtr   rQ   Ú
exceptionsr   r   r   r   r   rc   r'   r%   ú<module>rn      s5   ðÝ "ã Û Ý Ý Ý ß ,Ý !ç $Ý 4ß DÝ &÷eò er'   