ó
    öÞ jž$  ã                  ó¬   • S SK Jr  S SKrS SKrS SKJr  S SKJr  S SK	J
r
  S SKJrJr  S SKJr  SS	KJrJr  SS
KJr  SSKJrJr  SSKJr   " S S5      rg)é    )ÚannotationsN)Ú	lru_cache)Ú
SSLContext)ÚAny)Ú	HTTPErrorÚURLError)Úurlparseé   )ÚPyJWKÚPyJWKSet)Údecode_complete)ÚPyJWKClientConnectionErrorÚPyJWKClientError)ÚJWKSetCachec                  óœ   • \ rS rSr       S               SS jjrSS jrSSS jjrSSS jjrSS jrSS jr	\
SS	 j5       rS
rg)ÚPyJWKClienté   Nc	                ót  • Uc  0 n[        U5      R                  R                  5       n	U	S;  a  [        SU	< S35      eXl        SU l        X`l        Xpl        X€l        U(       a&  US::  a  [        SU S35      e[        U5      U l        OSU l        U(       a   [        US9" U R                  5      n
X l        gg)	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              ÚI/var/www/html/gaurav/venv/lib/python3.13/site-packages/jwt/jwks_client.pyÚ__init__ÚPyJWKClient.__init__   sÎ   € ðj ‰?ØˆGô
 ˜#“×%Ñ%×+Ñ+Ó-ˆØÐ*Ó*Ü"Ø*¨6©*ð 5!ð "óð ð ŒØ15ˆÔØŒØŒØ&Ôæð ˜1‹}Ü&ØEÀhÀZÈqÐQóð ô "-¨XÓ!6ˆDÕà!%ˆDÔæä'°Ò@À×AUÑAUÓVˆOà#2Õ ð	 ó    c                ó  •  [         R                  R                  U R                  U R                  S9n[         R                  R                  XR                  U R                  S9 n[        R                  " U5      nSSS5        U R                   b  U R                   R#                  W5        W$ ! , (       d  f       N8= f! [        [        4 a:  n[        U[        5      (       a  UR                  5         [        SU S35      UeSnAff = f)a5  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_dataÚPyJWKClient.fetch_dataj   sÞ   € ð	Ü—‘×&Ñ&¨4¯8©8¸T¿\¹\Ð&ÐJˆAÜ—‘×'Ñ'ØŸ<™<°×1AÑ1Að (ñ àÜŸ)š) HÓ-�÷ð ×ÑÑ)Ø×Ñ×"Ñ" 7Ô+Øˆ÷#õ ûô œ,Ð'ó 	Ü˜!œY×'Ñ'Ø—‘”	Ü,Ø9¸!¸¸AÐ>óàðûð	ús6   ‚A$C  Á&B/Á=C  Â/
B=Â9C  Â=C  Ã D
Ã5DÄD
c                óô   • SnU R                   b!  U(       d  U R                   R                  5       nUc  U R                  5       n[        U[        5      (       d  [        S5      e[        R                  " U5      $ )a  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   Úgetr;   r4   Údictr   r   Ú	from_dict)r!   ÚrefreshÚdatas      r&   Úget_jwk_setÚPyJWKClient.get_jwk_set‰   sf   € ð ˆØ×ÑÑ)¶'Ø×%Ñ%×)Ñ)Ó+ˆDà‰<Ø—?‘?Ó$ˆDä˜$¤×%Ñ%Ü"Ð#SÓTÐTä×!Ò! $Ó'Ð'r)   c                óÖ   • U R                  U5      nUR                   Vs/ sH*  nUR                  S;   d  M  UR                  (       d  M(  UPM,     nnU(       d  [	        S5      eU$ s  snf )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)rC   ÚkeysÚpublic_key_useÚkey_idr   )r!   rA   r9   Újwk_set_keyÚsigning_keyss        r&   Úget_signing_keysÚPyJWKClient.get_signing_keys    sr   € ð ×"Ñ" 7Ó+ˆð  'Ÿ|š|ó
á+�Ø×)Ñ)¨]Ñ:ó à?J×?QÕ?Q÷ Ù+ð 	ð 
ö Ü"Ð#WÓXÐXàÐùò
s    A&·A&Á
A&c                óÂ   • U R                  5       nU R                  X!5      nU(       d6  U R                  SS9nU R                  X!5      nU(       d  [        SU S35      eU$ )aY  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)rA   z,Unable to find a signing key that matches: "r   )rL   Ú	match_kidr   )r!   ÚkidrK   Úsigning_keys       r&   r    ÚPyJWKClient.get_signing_key¹   sh   € ð ×,Ñ,Ó.ˆØ—n‘n \Ó7ˆæà×0Ñ0¸Ð0Ð>ˆLØŸ.™.¨Ó;ˆKæÜ&ØBÀ3À%ÀqÐIóð ð Ðr)   c                ód   • [        USS0S9nUS   nU R                  UR                  S5      5      $ )a  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ÚheaderrP   )Údecode_tokenr    r>   )r!   ÚtokenÚ
unverifiedrV   s       r&   Úget_signing_key_from_jwtÚ$PyJWKClient.get_signing_key_from_jwtÕ   s:   € ô " %Ð2DÀeÐ1LÑMˆ
Ø˜HÑ%ˆØ×#Ñ# F§J¡J¨uÓ$5Ó6Ð6r)   c                óF   • SnU  H  nUR                   U:X  d  M  Un  U$    U$ )zÿ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)rI   )rK   rP   rQ   Úkeys       r&   rO   ÚPyJWKClient.match_kidä   s5   € ð ˆãˆCØ�z‰z˜SÕ Ø!�ØàÐñ  ð
 Ðr)   )r    r   r   r   r   r   )Fé   Ti,  Né   N)r   Ústrr"   Úboolr#   Úintr$   rb   r%   Úfloatr   zdict[str, Any] | Noner   rd   r   zSSLContext | None)Úreturnr   )F)rA   rb   re   r   )rA   rb   re   úlist[PyJWK])rP   ra   re   r   )rX   zstr | bytesre   r   )rK   rf   rP   ra   re   zPyJWK | None)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r'   r;   rC   rL   r    rZ   ÚstaticmethodrO   Ú__static_attributes__© 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   r1   Úurllib.requestr-   Ú	functoolsr   Ússlr   Útypingr   Úurllib.errorr   r   Úurllib.parser	   Úapi_jwkr   r   Úapi_jwtr   rW   Ú
exceptionsr   r   r   r   r   rm   r)   r&   Ú<module>rx      s5   ðÝ "ã Û Ý Ý Ý ß ,Ý !ç $Ý 4ß DÝ &÷eò er)   