+
    jHàj°9  ã                  ó†  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
Ht ^ RIHtHtHtHtHtHt ^ RIHtHt ]P,                  ! ]4      tRt]! RR04      t]
! R	R
7       ! R R4      4       tR R ltR R ltR R ltR R lt R R lt!R R lt"R R lt#R R lt$RR	/R R llt%R  R! lt&R" R# lt'R$ R% lt(R# )&uA  Declarative OAuth 2.0 Authorization-Code + PKCE login for out-of-tree model-provider plugins.

A plugin declares endpoints and public-client metadata in :class:`OAuthPKCEConfig` and plugs the two
factories into the ``ProviderProfile`` hooks::

    cfg = OAuthPKCEConfig(client_id="â€¦", authorize_url="https://â€¦", token_url="https://â€¦", scopes=("â€¦",))
    ProviderProfile(name="example", auth_type="oauth_external",
                    auth_handler=pkce_auth_handler(cfg), refresh_credential=pkce_refresh_credential(cfg))

Hermes owns the security boundary: HTTPS-only endpoints (plain HTTP only for a loopback-literal host,
i.e. a local development IdP), token endpoint host checked against the same allowlist as the authorize
URL BEFORE any request, S256 PKCE, CSRF ``state`` compared in constant time, an RFC 8252 loopback
listener on the literal ``127.0.0.1`` (explicit port, ``0`` = OS-assigned), persistence as a
``PooledCredential`` and single-use refresh tokens re-read from the store under the auth lock. No token,
``state`` or verifier is ever logged.

Lives in ``hermes_cli`` because everything it drives (loopback helpers, the auth store lock, the pool)
does; every core import is deferred into the callables so a plugin may import this module while
provider discovery is still running inside ``hermes_cli.auth``'s own import.
)ÚannotationsN)Ú	dataclassÚfield)ÚAnyÚCallableÚDictÚMappingÚOptionalÚTuple)Ú	urlencodeÚurlparsezmanual:loopback_pkceú	127.0.0.1z::1T)Úfrozenc                  óâ   € ] tR t^(t$ RtR]R&   R]R&   R]R&   RtR]R&   ^ tR]R	&   R
tR]R&   Rt	R]R&   ]
! ]R7      tR]R&   ]
! ]R7      tR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR# )ÚOAuthPKCEConfiguV   Public-client OAuth metadata for one provider. No client secret â€” PKCE is the proof.ÚstrÚ	client_idÚauthorize_urlÚ	token_urlútuple[str, ...]ÚscopesÚintÚredirect_portz	/callbackÚredirect_pathNzOptional[str]Úaudience)Údefault_factoryzMapping[str, str]Úextra_authorize_paramsÚextra_token_paramsÚallowed_hostsg     €f@ÚfloatÚtimeout_secondsÚ Úlabelz7Optional[Callable[[dict[str, str]], Mapping[str, Any]]]Útoken_request© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   r   r   r   r   Údictr   r   r   r    r"   r#   Ú__static_attributes__r$   ó    ÚF/home/ubuntu/.hermes/hermes-agent/hermes_cli/auth_oauth_pkce_plugin.pyr   r   (   s‹   ‡ á`àƒNØÓØƒNØ €FˆOÓ Ø€M�3ÓØ$€M�3Ó$Ø"€HˆmÓ"Ù05ÀdÔ0KÐÐ-ÓKÙ,1À$Ô,GÐÐ)ÓGà%'€M�?Ó'Ø"€O�UÓ"Ø€Eˆ3ƒOð
 NR€MÐJ×Qr-   r   c               ó$   € V ^8„  d   QhRRRRRR/# )é   Úproviderr   ÚmessageÚcoder$   )Úformats   "r.   Ú__annotate__r5   @   s&   € ÷ Mñ M�3ð M ð M¨Cñ Mr-   c                ó,   € ^ RI Hp V! V  RV 2WR7      # )é    )Ú	AuthErrorz: )r1   r3   )Úhermes_cli.auth_constantsr8   )r1   r2   r3   r8   s   &&& r.   Ú_errr:   @   s   € Ý3á˜�z  G 9Ð-¸ÔLÐLr-   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   Úhostr   Ú	allowlistr   ÚreturnÚboolr$   )r4   s   "r.   r5   r5   F   s&   € ÷ Pñ P˜ð P¨ð P¸Dñ Pr-   c                óx   a € \         ;QJ d    V 3R  lV 4       F  '       g   K   R# 	  R# ! V 3R  lV 4       4      # )c              3  óf   <"  € T F&  pSV8H  ;'       g    SP                  R V 24      x € K(  	  R# 5i)Ú.N)Úendswith)Ú.0Úapexr<   s   & €r.   Ú	<genexpr>Ú _host_allowed.<locals>.<genexpr>G   s/   øé € ÐOÁY¸Tˆt�t‰|×8Ð8˜tŸ}™}¨q°°¨ZÓ8Ô8ÃYùs   ƒ1”1TF)Úany)r<   r=   s   f&r.   Ú_host_allowedrI   F   s,   ø€ ß‹3ÔOÁYÓO�3Œ3ÐOŠ3ÐOˆ3ÔOÁYÓOÓOÐOr-   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r0   r1   r   ÚnameÚurlr>   r$   )r4   s   "r.   r5   r5   J   s(   € ÷ ñ ˜Sð ¨ð °#ð ¸#ñ r-   c                óT  € \        \        T;'       g    R 4      P                  4       4      pVP                  ;'       g    R P	                  4       pV'       g   \        V RV R2R4      hVP                  R8w  d.   VP                  R8X  d   V\        9   g   \        V RV R2R4      hV# )r!   zOAuth z has no host.Úoauth_endpoint_invalidÚhttpsÚhttpz must use HTTPS.)r   r   ÚstripÚhostnameÚlowerr:   ÚschemeÚ_LOOPBACK_LITERALS)r1   rK   rL   Úparsedr<   s   &&&  r.   Ú_endpoint_hostrW   J   s“   € Ü”c˜#Ÿ)˜) “n×*Ñ*Ó,Ó-€FØ�O‰O×!Ð!˜r×(Ñ(Ó*€DßÜ�8˜v d V¨=Ð9Ð;SÓTÐTØ‡}�}˜Ô¨¯©¸&Ô)@ÀTÔM_ÔE_Ü�8˜v d VÐ+;Ð<Ð>VÓWÐWØ€Kr-   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   r1   r   Úcfgr   r>   ÚNoner$   )r4   s   "r.   r5   r5   T   s&   € ÷ gñ g˜cð g¨ð g¸Dñ gr-   c           	     óX  € VP                   e   R# \        VP                  ;'       g    R4      P                  4       '       g   \	        V RR4      h\        V RVP                  4      p\        V RVP                  4      p\        ;QJ d    . R VP                   4       F  NK  	  5M! R VP                   4       4      ;'       g    V3p\        W44      '       g   \	        V RV: R	\        V4       R
2R4      h^ \        VP                  4      u;8:  d   R8:  g   M \	        V RR4      hR# )zURefuse a misdeclared config before any network request (login AND refresh call this).Nr!   zOAuth client_id is missing.Úoauth_client_id_missingr   r   c              3  ó@   "  € T F  qP                  4       x € K  	  R # 5i©N)rS   )rD   Úhs   & r.   rF   Ú"validate_config.<locals>.<genexpr>\   s   é € Ð;Ñ): A—g‘g—i�iÓ):ùs   ‚zOAuth token_url host z is not on the allowlist rB   Úoauth_token_host_rejectediÿÿ  z,OAuth redirect_port must be within 0..65535.Úoauth_redirect_invalid)r#   r   r   rQ   r:   rW   r   r   Útupler   rI   Úsortedr   r   )r1   rY   Úauthorize_hostÚ
token_hostr=   s   &&   r.   Úvalidate_configrg   T   s  € à
×ÑÒ$ÙÜˆs�}‰}×"Ð" Ó#×)Ñ)×+Ò+Ü�8Ð:Ð<UÓVÐVÜ# H¨o¸s×?PÑ?PÓQ€NÜ ¨+°s·}±}ÓE€Jß”Ñ;¨×):Ò):Ó;—‘Ñ;¨×):Ò):Ó;Ó;×PÐPÀÐ?P€IÜ˜×/Ò/Ü�8Ð4°Z±NÐB[Ü˜YÓ'Ð(¨ð+Ø,GóIð 	Ià”�C×%Ñ%Ó&Ö/¨%Ö/Ü�8ÐKÐMeÓfÐfñ 0r-   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r0   r1   r   rY   r   Údataúdict[str, str]r3   r>   údict[str, Any]r$   )r4   s   "r.   r5   r5   d   s8   € ÷ @ñ @˜#ð @ Oð @¸>ð @ÐTWð @Ð\jñ @r-   c               óB  € ^ RI Hp ^ RIHp VP                  e%   \        WP	                  \        V4      4      W#4      # / VP                  CVCRVP                  /CpVP                  '       d   VP                  RVP                  4        VP                  VP                  VRR/RV! 4       R	7      pTP"                  R8¼  d   \%        YT4      h\        YP'                  4       Y#4      #   \         d*   p\        T R
\        T4      P                    2T4      ThRp?ii ; i)zqPOST the token endpoint (or the plugin's broker) and return the rotated pool fields; the payload
is never logged.)Ú_default_verify)ÚhttpxNr   r   ÚAcceptzapplication/jsong      >@)ri   ÚheadersÚtimeoutÚverifyzOAuth token request failed: i�  )Úhermes_cli.authrm   r9   rn   r#   Ú_token_fieldsr+   r   r   r   Ú
setdefaultÚpostr   Ú	Exceptionr:   Útyper%   Ústatus_codeÚ_token_http_errorÚjson)	r1   rY   ri   r3   rm   rn   ÚbodyÚresponseÚexcs	   &&&$     r.   Ú_post_tokenr   d   s	  € õ 0Ý/à
×ÑÒ$Ü˜X×'8Ñ'8¼¸d»Ó'DÀdÓQÐQØIˆc×$Ñ$ÐI¨ÐI¨k¸3¿=¹=ÑI€DØ
‡|‡|€|Ø�‰˜
 C§L¡LÔ1ðaØ—:‘:˜cŸm™m°$ÀÐK]Ð@^Ø&*±?Ó3Dð ó Fˆð ×Ñ˜sÔ"Ü °DÓ9Ð9Ü˜§=¡=£?°DÓ?Ð?øô	 ô aÜ�8Ð;¼DÀ»I×<NÑ<NÐ;OÐPÐRVÓWÐ]`Ð`ûðaús   Â'C* Ã*DÃ5$DÄDc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r0   r1   r   ÚpayloadúMapping[str, Any]ri   rj   r3   r>   rk   r$   )r4   s   "r.   r5   r5   y   s2   € ÷ ñ ˜Cð Ð*;ð À>ð ÐY\ð Ðaoñ r-   c           	     ó
  € ^ RI HpHp \        VP	                  R4      ;'       g    R4      P                  4       pV'       g   \        V RV4      hV! VP	                  R^ 4      4      pRTR\        VP	                  R4      ;'       g    VP	                  R4      ;'       g    R4      P                  4       ;'       g    RRV'       d4   \        \        P                  ! 4       R	,          4      VR	,          ,           MRR
V! 4       /# )zbPool fields from a token-endpoint payload; a response without ``refresh_token`` keeps the old one.)Ú_coerce_ttl_secondsÚ
_utc_now_zÚaccess_tokenr!   z-OAuth token response carried no access_token.Ú
expires_inÚrefresh_tokenNÚexpires_at_mséè  Úlast_refresh)	rs   r„   r…   r   ÚgetrQ   r:   r   Útime)r1   r�   ri   r3   r„   r…   r†   Úttls   &&&&    r.   rt   rt   y   sÈ   € ç?ä�w—{‘{ >Ó2×8Ð8°bÓ9×?Ñ?ÓA€LßÜ�8ÐLÈdÓSÐSÙ
˜gŸk™k¨,¸Ó:Ó
;€Cà˜Øœ˜WŸ[™[¨Ó9×\Ð\¸T¿X¹XÀoÓ=V×\Ð\ÐZ\Ó]×cÑcÓe×mÐmÐimØÇœœTŸYšY›[¨4Õ/Ó0°3¸µ:Ö=È$Ø™
›ð	ð r-   c               ó$   € V ^8„  d   QhRRRRRR/# )r0   r1   r   r}   r   Úfallback_coder$   )r4   s   "r.   r5   r5   ‰   s&   € ÷ jñ j ð j¨sð jÀ3ñ jr-   c                óh  € ^ RI Hp Rp VP                  4       p\        V\        4      '       d3   \        VP                  R4      ;'       g    R4      P                  4       pYC9   d   \        T RTP                   RT R2T4      # \        T RTP                   R2T4      #   \         d    Rp LNi ; i)uÀ   Map a failed token HTTP response. A grant-dead JSON ``error`` value becomes the
error's ``code`` â€” the pool's plugin recovery treats those codes as terminal. The
response body is not logged.)Ú_OAUTH_GRANT_DEAD_CODESr!   Úerrorz%OAuth token request failed with HTTP ú (z).rB   )rs   r’   r{   Ú
isinstancer+   r   rŒ   rQ   rw   r:   ry   )r1   r}   r�   r’   r“   r�   s   &&&   r.   rz   rz   ‰   s¸   € õ 8à€EðØ—-‘-“/ˆÜ�gœt×$Ò$Ü˜Ÿ™ GÓ,×2Ð2°Ó3×9Ñ9Ó;ˆEð Ô'Ü�HÐ EÀh×FZÑFZÐE[Ð[]Ð^cÐ]dÐdfÐgÐinÓoÐoÜ�ÐAÀ(×BVÑBVÐAWÐWXÐYÐ[hÓiÐiøô	 ô ØŠðús   ŠAB! ÁB! Â!B1Â0B1c               ó    € V ^8„  d   QhRRRR/# )r0   Úargsr   r>   r   r$   )r4   s   "r.   r5   r5   ›   s   € ÷ 8ñ 8˜ð 8 ñ 8r-   c                óº   € \        \        V RR4      ;'       g    R4      P                  4       P                  4       p^ RIHp V! V4      pVe   VP                  # T# )zRCanonical profile name for the credential pool. ``args.provider`` may be an alias.r1   r!   )Úget_provider_profile)r   ÚgetattrrQ   rS   Ú	providersr™   rK   )r—   Úrawr™   Úprofiles   &   r.   Ú_pool_providerrž   ›   sP   € ä
Œg�d˜J¨Ó+×1Ð1¨rÓ
2×
8Ñ
8Ó
:×
@Ñ
@Ó
B€CÝ.Ù" 3Ó'€GØ"Ò.ˆ7�<‰<Ð7°CÐ7r-   Úopen_browserc               ó(   € V ^8„  d   QhRRRRRRRR/# )	r0   r1   r   rY   r   rŸ   r?   r>   rk   r$   )r4   s   "r.   r5   r5   £   s)   € ÷ 3+ñ 3+�Cð 3+˜oð 3+Àð 3+ÐP^ñ 3+r-   c               ó¢  a € ^ RI HpHpHpHpHpHpHp	 \        S V4       VP                  P                  R4      '       d   VP                  MRVP                   2p
V 3R lpT! Y¡P                  ;'       g    S R7      w  rÍV! R\        VP                  4      WËRR7      pRVP                  ^,           V
 2pV! 4       p\        P                   ! ^ 4      p/ VP"                  CR	VP$                  R
RRVRVRV! V4      RR/CpVP&                  '       d   RP)                  VP&                  4      VR&   VP*                  '       d   VP*                  VR&   VP,                   \/        VP,                  4      P0                  '       d   RMR \3        V4       2p\5        RVP                  ;'       g    S  RV R24       \5        RV R\        VP6                  4       R24       V! V4       V'       d%   V! 4       '       d    \8        P:                  ! V4        V	! WíVP6                  VRR7      pTPC                  R 4      '       d-   T! R!TPC                  R"4      ;'       g
    TR ,           2R#4      h\D        PF                  ! \I        TPC                  R4      ;'       g    R$4      T4      '       g
   T! R%R&4      h\I        TPC                  R4      ;'       g    R$4      PK                  4       pT'       g
   T! R'R(4      h\M        S TR)R*RTRTR+T/R,R-7      #   \<         d    \5        R4        ELi ; i  \>         d    \5        R4       \A        ^‚4      hi ; i).zZRun the browser Authorization-Code + PKCE flow; returns the pool fields for the new grant.)Ú_bind_loopback_callback_serverÚ_can_open_graphical_browserÚ_make_loopback_callback_handlerÚ_pkce_code_challengeÚ_pkce_code_verifierÚ_print_loopback_ssh_hintÚ_serve_loopback_callbackÚ/c                ó   <€ \        SW4      # r^   )r:   )r2   r3   r1   s   &&€r.   Ú<lambda>Úlogin.<locals>.<lambda>«   s   ø€ ¤ X¨wÔ =r-   )Údisplay_namer   Úoauth_callback_bind_failed)ÚerrÚbind_failed_codezhttp://127.0.0.1:r   Úresponse_typer3   Úredirect_uriÚstateÚcode_challengeÚcode_challenge_methodÚS256Ú Úscoper   Ú&Ú?z(
Open this URL to authorize Hermes with z:
  Ú
zWaiting for callback on z
 (timeout zs, Ctrl+C to cancel)...z<Could not open the browser automatically; use the URL above.Úoauth_callback_timeout)r    r¯   Útimeout_codez
Login cancelled.r“   zauthorization failed: Úerror_descriptionÚoauth_authorization_deniedr!   uP   callback state mismatch â€” the redirect did not come from this login. Aborting.Úoauth_state_mismatchz'callback carried no authorization code.Úoauth_no_codeÚ
grant_typeÚauthorization_codeÚcode_verifierÚoauth_token_exchange_failed©r3   )'Úhermes_cli.auth_device_flowr¢   r£   r¤   r¥   r¦   r§   r¨   rg   r   Ú
startswithr"   r   r   Úserver_addressÚsecretsÚtoken_urlsafer   r   r   Újoinr   r   r   Úqueryr   Úprintr    Ú
webbrowserÚopenrw   ÚKeyboardInterruptÚ
SystemExitrŒ   ÚhmacÚcompare_digestr   rQ   r   )r1   rY   rŸ   r¢   r£   r¤   r¥   r¦   r§   r¨   Úpathr¯   Úhandler_clsÚresultÚserverr²   Úverifierr³   Úparamsr   Úcallbackr3   s   f&$                   r.   ÚloginrÜ   £   s/  ø€ ÷g÷ gñ gô �H˜cÔ"Ø #× 1Ñ 1× <Ñ <¸S× AÒ Aˆ3×ÒÈÈ3×K\ÑK\ÐJ]ÐG^€DÜ
=€CÙ9¸$ÏYÉY×MbÐMbÐZbÔcÑ€KÙ+Ø”S˜×*Ñ*Ó+¨[ÐTpôr€Fà& v×'<Ñ'<¸QÕ'?Ð&@ÀÀÐG€LÙ"Ó$€HÜ×!Ò! "Ó%€Eð)Ø
×
$Ñ
$ð)Ø&1°3·=±=À/ÐSYØ˜ g¨uÐ6FÑH\Ð]eÓHfØ ñ)€Fð ‡z‡z€zØŸ(™( 3§:¡:Ó.ˆˆw‰Ø
‡|‡|€|Ø Ÿ\™\ˆˆzÑØ×(Ñ(Ð)´¸#×:KÑ:KÓ1L×1R×1RÐ1R©#ÐX[Ð)\Ô]fÐgmÓ]nÐ\oÐp€Mä	Ð5°c·i±i×6KÐ6KÀ8Ð5LÈEÐR_ÐQ`Ð`bÐ
cÔdÜ	Ð$ \ N°*¼SÀ×ATÑATÓ=UÐ<VÐVmÐ
nÔoÙ˜\Ô*ßÑ3×5Ò5ð	RÜ�OŠO˜MÔ*ðÙ+Ø¨C×,?Ñ,?ÀSÐWoôqˆð ‡|�|�G×ÒÙÐ*¨8¯<©<Ð8KÓ+L×+aÐ+aÐPXÐY`ÕPaÐ*bÐcØ.ó0ð 	0ä×Òœs 8§<¡<°Ó#8×#>Ð#>¸BÓ?À×GÒGÙÐdØ(ó*ð 	*äˆx�|‰|˜FÓ#×)Ð) rÓ*×0Ñ0Ó2€DßÙÐ;¸_ÓMÐMÜ�x ØÐ*¨F°D¸.È,ÐXgÐiqð'à)ô+ð +øô% ô 	RÜÐP×Qð	Rûô
 ô ÜÐ"Ô#Ü˜‹oÐðús   Ç=L ÈL, ÌL)Ì(L)Ì,"Mc               ó(   € V ^8„  d   QhRRRRRRRR/# )r0   r†   r   r‰   Únow_msr   r>   r?   r$   )r4   s   "r.   r5   r5   Ù   s.   € ÷ lñ l˜Sð l°ð l¸cð lÀdñ lr-   c                óž   € \        \        T ;'       g    R 4      P                  4       4      ;'       d    VRJ ;'       g    \        V4      V8„  # )r!   N)r?   r   rQ   r   )r†   r‰   rÞ   s   &&&r.   Ú
_is_usablerà   Ù   sD   € Ü”�L×&Ð& BÓ'×-Ñ-Ó/Ó0×kÐk°mÀtÐ6K×6jÐ6jÌsÐS`ÓOaÐdjÑOjÐkr-   c               ó    € V ^8„  d   QhRRRR/# )r0   rY   r   r>   zCallable[[str, Any], bool]r$   )r4   s   "r.   r5   r5   Ý   s   € ÷ #ñ #˜?ð #Ð/Iñ #r-   c                ó   a € R V 3R llpV# )zµ``ProviderProfile.auth_handler`` owning add/status/logout; ``refresh`` is declined so the
credential pool's generic refresh (which calls :func:`pkce_refresh_credential`) handles it.c               ó$   € V ^8„  d   QhRRRRRR/# )r0   Úactionr   r—   r   r>   r?   r$   )r4   s   "r.   r5   Ú'pkce_auth_handler.<locals>.__annotate__á   s!   € ÷ ñ ˜ð  3ð ¨4ñ r-   c                óX  <a€ ^ RI HpHpHp \	        V4      pV R8X  dã   \        VS\        VRR4      '       * R7      pV! V4      P                  T! R!RTR\        P                  ! 4       P                  R,          R	SP                  ;'       g    TR
VR^ R\        /VBRRRSP                  RRP                  SP                  4      ///B 4      p\!        RSP                  ;'       g    T RVP"                   R24       R# V R8X  dÂ   V! V4      P%                  4       p\'        \(        P(                  ! 4       R,          4      oV'       g   \!        V R24       R# \*        ;QJ d    V3R lV 4       F  '       g   K   RM	  RM! V3R lV 4       4      '       d   \!        V R\-        V4       24       R# \!        V RV R24       R# V R8X  d[   V! V4      p	\-        V	P%                  4       4      p
\/        V
^ R"4       F  pV	P1                  V4       K  	  \!        RV RV
 R 24       R# R# )#r7   )ÚAUTH_TYPE_OAUTHÚPooledCredentialÚ	load_poolÚaddÚ
no_browserF)rŸ   r1   Úid:Né   Nr"   Ú	auth_typeÚpriorityÚsourceÚextraÚ
oauth_pkcer   r¸   r·   zSigned in to z; credential z added to the pool.TÚstatusrŠ   z: logged outc              3  óf   <"  € T F&  p\        VP                  VP                  S4      x € K(  	  R # 5ir^   )rà   r†   r‰   )rD   ÚerÞ   s   & €r.   rF   Ú5pkce_auth_handler.<locals>.handler.<locals>.<genexpr>ò   s'   øé € ÐZÑRYÈQ”Z §¡°·±À×HÐHÓRYùs   ƒ.1z5: logged in
  auth_type: oauth (pkce)
  credentials: u7   : expired (needs refresh) â€” run `hermes auth refresh Ú`ÚlogoutzLogged out of r”   z credential(s) removed)r$   éÿÿÿÿ)Úagent.credential_poolrç   rè   ré   rž   rÜ   rš   Ú	add_entryÚuuidÚuuid4Úhexr"   ÚPOOL_SOURCEr   rÌ   r   rÎ   rì   Úentriesr   r�   rH   ÚlenÚrangeÚremove_index)rä   r—   rç   rè   ré   r1   ÚtokensÚentryr   ÚpoolÚcountÚindexrÞ   rY   s   &&          @€r.   ÚhandlerÚ"pkce_auth_handler.<locals>.handlerá   s  ù€ ßVÑVä! $Ó'ˆØ�UŒ?Ü˜8 S¼7À4ÈÐW\Ó;]Ô7]Ô^ˆFÙ˜hÓ'×1Ñ1Ñ2Bñ 3cØ!ð3cÜ&*§j¢j£l×&6Ñ&6°rÕ&:ð3cØBEÇ)Á)×BWÐBWÈxð3cà)ð3cà45ð3cä>Ið3càMSñ3cð $ k°3·=±=À'È3Ï8É8ÐTW×T^ÑT^ÓK_Ð%`Ðaò3có dˆEô �M #§)¡)×"7Ð"7¨xÐ!8¸ÀeÇhÁhÀZÐObÐcÔdÙØ�XÔÙ Ó)×1Ñ1Ó3ˆGÜœŸš› tÕ+Ó,ˆFßÜ˜˜
 ,Ð/Ô0ñ
 ÷	 “ÔZÑRYÓZ——’ÔZÑRYÓZ×ZÒZÜ˜˜
Ð"YÔZ]Ð^eÓZfÐYgÐhÔiñ ô ˜˜
Ð"YÐZbÐYcÐcdÐeÔfÙØ�XÔÙ˜XÓ&ˆDÜ˜Ÿ™›Ó'ˆEÜ˜u a¨Ö,�Ø×!Ñ! %Ö(ñ -ä�N 8 *¨B¨u¨gÐ5LÐMÔNÙÙr-   r$   )rY   r	  s   f r.   Úpkce_auth_handlerr  Ý   s   ø€ ÷ð ð> €Nr-   c               ó    € V ^8„  d   QhRRRR/# )r0   rY   r   r>   z"Callable[[Any], Mapping[str, Any]]r$   )r4   s   "r.   r5   r5     s   € ÷ ñ  ð Ð5Wñ r-   c                ó   a € R V 3R llpV# )a  ``ProviderProfile.refresh_credential``: rotate one pooled row via the refresh_token grant.

Refresh tokens are single-use, so the store is re-read under the auth lock first: a peer that
already rotated this row is adopted instead of spending its (now-revoked) refresh token again.
c               ó    € V ^8„  d   QhRRRR/# )r0   r  r   r>   r‚   r$   )r4   s   "r.   r5   Ú-pkce_refresh_credential.<locals>.__annotate__
  s   € ÷ Qñ Q�sð QÐ0ñ Qr-   c           
     ó  <a € ^ RI HpHp \        S P                  4      p\        VS	4       V! 4       ;_uu_ 4        \        V 3R lV! V4       4       R4      ;'       g    / p\        VP                  R4      ;'       g    R4      P                  4       pV'       d¼   TS P                  ;'       g    R8w  d¡   \        VP                  R4      VP                  R4      \        \        P                  ! 4       R,          4      4      '       dM   \        P                  R	VS P                  4       R Uu/ uF  qfVP                  V4      bK  	  upuuRRR4       # T;'       g.    \        S P                  ;'       g    R4      P                  4       pV'       g   \!        VR
R4      hRRRV/pS	P"                  '       d   RP%                  S	P"                  4      VR&   \'        VS	VRR7      uuRRR4       # u upi   + '       g   i     R# ; i)r7   )Ú_auth_store_lockÚread_credential_poolc              3  óœ   <"  € T FA  p\        V\        4      '       g   K  VP                  R 4      SP                  8X  g   K=  Vx € KC  	  R# 5i)rì   N)r•   r+   rŒ   rì   )rD   Úrowr  s   & €r.   rF   Ú;pkce_refresh_credential.<locals>.refresh.<locals>.<genexpr>  s>   øé € ð TÑ+I CÜ)¨#¬t×4ô  Ø9<¿¹À»È%Ï(É(Ñ9R÷  šCÓ+Iùs   ƒA AÁ
ANrˆ   r!   r†   r‰   rŠ   z@%s entry %s: adopting a peer's rotation, refresh token not spentz*no refresh_token on the pooled credential.Úoauth_refresh_no_tokenrÂ   r·   r¸   Úoauth_refresh_failedrÆ   )r†   rˆ   r‰   r‹   )rs   r  r  r   r1   rg   ÚnextrŒ   rQ   rˆ   rà   r   r�   ÚloggerÚdebugrì   r:   r   rÌ   r   )
r  r  r  r1   Úon_diskÚdisk_refreshÚkrˆ   ri   rY   s
   f        €r.   ÚrefreshÚ(pkce_refresh_credential.<locals>.refresh
  s«  ù€ ßJä�u—~‘~Ó&ˆÜ˜ #Ô&Ù×ÕÜô TÑ+?ÀÔ+Ió TØUYó[÷ að aØ^`ð ä˜wŸ{™{¨?Ó;×AÐA¸rÓB×HÑHÓJˆLß °×1DÑ1D×1JÐ1JÈÔ KÔPZØ—K‘K Ó/°·±¸_Ó1MÌsÔSW×S\ÒS\ÓS^ÐaeÕSeÓOf÷Qhò Qhä—‘Ð_ÐaiÐkp×ksÑksÔtÙ3uÓvÑ3u¨a˜7Ÿ;™; q›>Ò)Ñ3uÑv÷  Òð )×RÐR¬C°×0CÑ0C×0IÐ0IÀrÓ,J×,PÑ,PÓ,RˆMß Ü˜8Ð%QÐSkÓlÐlØ  /°?ÀMÐRˆDØ�z�zˆzØ #§¡¨¯©Ó 4��W‘Ü˜x¨¨dÐ9OÔP÷  Òùò w÷  ×ÐúsO   »AG7Á?G7ÂG7Â0B G7Ä0G2Å
G7ÅG7Å G7Å9G7Æ$G7Æ;,G7Ç2G7Ç7H	r$   )rY   r  s   f r.   Úpkce_refresh_credentialr     s   ø€ ÷Qð Qð* €Nr-   ))r)   Ú
__future__r   rÓ   ÚloggingrÊ   r�   rü   rÏ   Údataclassesr   r   Útypingr   r   r   r   r	   r
   Úurllib.parser   r   Ú	getLoggerr%   r  rÿ   Ú	frozensetrU   r   r:   rI   rW   rg   r   rt   rz   rž   rÜ   rà   r  r   r$   r-   r.   Ú<module>r(     s¾   ðñõ* #ã Û Û Û Û Û ß (ß @× @ß ,à	×	Ò	˜8Ó	$€à$€Ù ¨UÐ3Ó4Ð ñ �$Ô÷Rð Ró ðRõ.MõPõõgõ @õ*õ jõ$8ð3+Àt÷ 3+õllõ#÷Lr-   