+
    „WÝjõ  ã                  óÞ  a € 0 t $ 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 ^ RIHtHt ^ RIHt Rt^xtRt^t]P*                  ! 4       t] ! R R	4      4       t] ! R
 R4      4       t/ tR]R&   / tR]R&    ! R R]4      t ! R R]4      t ! R R]4      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/R# R$ llt%R"R/R% R& llt&R"R/R' R( llt'R"R/R) R* llt(R+ R, lt)R# )-aa  Gateway-brokered RFC 8252 (OAuth 2.0 for Native Apps) authorization store.

The desktop cannot be a direct OAuth client of the upstream IDP (the Portal
``client_id`` is per gateway and only accepts the gateway's ``/auth/callback``),
so the gateway brokers: authorization server *to the desktop*, OAuth client
*to the Portal*. Desktop PKCE pair (cv_d, cc_d) + state -> ``/auth/native/authorize``
stashes a pending entry (:func:`register_pending`) keyed by an opaque
``broker_state`` riding in the gateway's own PKCE cookie -> upstream callback
or password login mints a one-time code bound to cc_d (:func:`complete_pending`)
-> desktop redeems it with cv_d at ``/auth/native/token`` (:func:`redeem_code`).
PKCE binding, single use, short TTLs, 256-bit handles compared in constant time,
no secret logging; in-memory, process-local, ``time.time`` patchable in tests.
)ÚannotationsN)Ú	dataclass)ÚDictÚOptional)ÚSessioniX  é   c                  óN   € ] tR t^&t$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R	tR
# )Ú_Pendingz>In-flight native authorization awaiting the upstream callback.ÚstrÚcode_challengeÚredirect_uriÚclient_stateÚ	client_ipÚintÚ
expires_at© N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r   ó    ÚYC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\dashboard_auth\native_flow.pyr	   r	   &   s!   ‡ áHØÓØÓØÓØƒNØ‡Or   r	   c                  ó:   € ] tR t^0t$ RtR]R&   R]R&   R]R&   RtR	# )
Ú_IssuedCodez@A minted one-time gateway authorization code bound to a Session.r
   r   r   Úsessionr   r   r   Nr   r   r   r   r   r   0   s   ‡ áJØÓØÓØ‡Or   r   zdict[str, _Pending]Ú_pendingzdict[str, _IssuedCode]Ú_issuedc                  ó   € ] tR t^<tRtRtR# )ÚNativeFlowErrorzGBase for native-flow failures (bad/expired/replayed handle, PKCE fail).r   N©r   r   r   r   r   r   r   r   r   r"   r"   <   s   † ÝQr   r"   c                  ó   € ] tR t^@tRtRtR# )ÚPendingNotFoundz=The broker_state is unknown or expired (login window lapsed).r   Nr#   r   r   r   r%   r%   @   s   † ÝGr   r%   c                  ó   € ] tR t^DtRtRtR# )ÚCodeInvalidzKThe gateway code is unknown, expired, already redeemed, or PKCE-mismatched.r   Nr#   r   r   r   r'   r'   D   s   † ÝUr   r'   c               ó    € V ^8„  d   QhRRRR/# )é   Úverifierr
   Úreturnr   )Úformats   "r   Ú__annotate__r-   H   s   € ÷ Iñ I�Cð I˜Cñ Ir   c                óÐ   € \         P                  ! V P                  R4      4      P                  4       p\        P
                  ! V4      P                  R4      P                  R4      # )zHRFC 7636 S256 transform: base64url(sha256(ascii(verifier))), no padding.Úasciió   =)ÚhashlibÚsha256ÚencodeÚdigestÚbase64Úurlsafe_b64encodeÚrstripÚdecode)r*   r4   s   & r   Ú_s256r9   H   sI   € ä�^Š^˜HŸO™O¨GÓ4Ó5×<Ñ<Ó>€FÜ×#Ò# FÓ+×2Ñ2°4Ó8×?Ñ?ÀÓHÐHr   c               ó    € V ^8„  d   QhRRRR/# )r)   Únowr   r+   ÚNoner   )r,   s   "r   r-   r-   N   s   € ÷ ñ �Cð ˜Dñ r   c                óØ   € \         \        3 FS  pVP                  4        UUu. uF  w  r#VP                  V 8  g   K  VNK  	  upp F  pVP	                  VR4       K  	  KU  	  R# u uppi )z>Drop expired pending + issued entries. Caller holds ``_lock``.N)r   r    Úitemsr   Úpop)r;   ÚstoreÚkÚvs   &   r   Ú
_gc_lockedrC   N   sQ   € äœGÓ$ˆØ %§¡¤ÔD¡™˜°·±ÀÑ1C—!�!¡ÕDˆAØ�I‰I�a˜Öó Eó %ùÛDs
   £A&½A&c               ó   € V ^8„  d   QhRR/# )r)   r+   Úboolr   )r,   s   "r   r-   r-   U   s   € ÷ 9ñ 9˜Tñ 9r   c                 óV   € \        \        4      \        \        4      ,           \        8  # ©N)Úlenr   r    Ú_MAX_ENTRIESr   r   r   Ú_capacity_ok_lockedrJ   U   s   € Ü”‹MœC¤›LÕ(¬LÑ8Ð8r   c               ó    € V ^8„  d   QhRRRR/# )r)   r;   úOptional[int]r+   r   r   )r,   s   "r   r-   r-   Y   s   € ÷ 4ñ 4ˆmð 4 ñ 4r   c                óJ   € V f   \        \        P                  ! 4       4      # T # rG   )r   Útime)r;   s   &r   Ú_nowrO   Y   s   € Ø"š{Œ3Œt�yŠy‹{ÓÐ3°Ð3r   c               ó$   € V ^8„  d   QhRRRRRR/# )r)   Úbroker_stater
   ÚconsumerE   r+   r	   r   )r,   s   "r   r-   r-   ]   s!   € ÷ ñ  cð °tð Àñ r   c               ó‚   € V'       d   \         P                  M\         P                  ! V R4      pVf   \        R4      hV# )zTLook up (optionally consuming) a pending entry; :class:`PendingNotFound` if unknown.Nz'unknown or expired native authorization)r   r?   Úgetr%   )rQ   rR   Úentrys   &$ r   Ú_pop_pending_lockedrV   ]   s3   € ç$ŒX�\Š\¬(¯,©,Ð6¸ÀdÓK€EØ‚}ÜÐGÓHÐHØ€Lr   r   Ú r;   c               ó0   € V ^8„  d   QhRRRRRRRRRRRR/# )	r)   r   r
   r   r   r   r;   rL   r+   r   )r,   s   "r   r-   r-   e   s<   € ÷ ñ ØðØ*-ðØ=@ðØMPðà	ðà"%ñr   c           
     ó¸  a€ \        V4      p\        P                  ! ^ 4      p\        ;_uu_ 4        \	        V4       \        4       '       g   \        R4      h\        V3R l\        P                  4        4       4      pS'       d   V\        8¼  d   \        R4      h\        WVSV\        ,           R7      \        V&   RRR4       V#   + '       g   i     T# ; i)zêStash a pending native authorization; return an opaque ``broker_state``. ``code_challenge``
is the DESKTOP's cc_d. Raises ``NativeFlowError`` (fail closed) at store capacity or when
``client_ip`` holds ``_MAX_PENDING_PER_IP`` entries.z+native-flow authorization store at capacityc              3  óL   <"  € T F  qP                   S8X  g   K  ^x € K  	  R# 5i)é   N)r   )Ú.0rB   r   s   & €r   Ú	<genexpr>Ú#register_pending.<locals>.<genexpr>q   s   øé € ÐNÑ 1˜1·[±[ÀIÑ5M—Q’QÓ 1ùs   ƒ$š
$z8too many pending native authorizations from this address)r   r   r   r   r   N)rO   ÚsecretsÚtoken_urlsafeÚ_lockrC   rJ   r"   Úsumr   ÚvaluesÚ_MAX_PENDING_PER_IPr	   Ú_PENDING_TTL_SECONDS)r   r   r   r   r;   rQ   Úper_ips   $$$d$  r   Úregister_pendingrg   e   s«   ø€ ô ˆs‹)€CÜ×(Ò(¨Ó,€Lß	ŽÜ�3ŒÜ"×$Ò$Ü!Ð"OÓPÐPÜÔN¤§¡Ô 1ÓNÓNˆß˜Ô#6Ô6Ü!Ð"\Ó]Ð]Ü!)Ø)ÐS_Ø¨CÔ2FÕ,Fô"HŒ�Ñ÷ 
ð Ð÷ 
Žð Ðús   ±BCÃC	c               ó$   € V ^8„  d   QhRRRRRR/# )r)   rQ   r
   r;   rL   r+   r	   r   )r,   s   "r   r-   r-   z   s&   € ÷ @ñ @˜cð @¨=ð @ÀHñ @r   c               óž   € \         ;_uu_ 4        \        \        V4      4       \        V RR7      uuRRR4       #   + '       g   i     R# ; i)z3Peek (without consuming) the pending authorization.F©rR   N)ra   rC   rO   rV   )rQ   r;   s   &$r   Úget_pendingrk   z   s)   € ç	ŽÜ”4˜“9ÔÜ" <¸Ô?÷ 
��‹ús	   �!;»A	c               ó(   € V ^8„  d   QhRRRRRRRR/# )r)   rQ   r
   r   r   r;   rL   r+   r   )r,   s   "r   r-   r-   �   s)   € ÷ ñ  3ð °Gð À-ð Ð[^ñ r   c               óX  € \        V4      p\        ;_uu_ 4        \        V4       \        V RR7      p\	        4       '       g   \        R4      h\        P                  ! ^ 4      p\        VP                  VV\        ,           R7      \        V&   RRR4       V#   + '       g   i     X# ; i)z}Consume a pending authorization (single use) and mint a one-time gateway code bound to the
desktop's challenge + ``session``.Trj   z"native-flow code store at capacity)r   r   r   N)rO   ra   rC   rV   rJ   r"   r_   r`   r   r   Ú_CODE_TTL_SECONDSr    )rQ   r   r;   ÚpendingÚgw_codes   &$$  r   Úcomplete_pendingrq   �   sˆ   € ô ˆs‹)€Cß	ŽÜ�3ŒÜ% l¸DÔAˆÜ"×$Ò$Ü!Ð"FÓGÐGÜ×'Ò'¨Ó+ˆÜ&Ø"×1Ñ1¸7ØÔ.Õ.ô0Œ�Ñ÷ 
ð €N÷ 
Žð €Nús   šA4BÂB)	c               ó(   € V ^8„  d   QhRRRRRRRR/# )r)   Úcoder
   Úcode_verifierr;   rL   r+   r   r   )r,   s   "r   r-   r-   ‘   s)   € ÷ ñ ˜ð ¨Sð °}ð ÐPWñ r   c                ó’  € \        V4      p\        ;_uu_ 4        \        V4       \        P	                  V R4      pRRR4       Xf   \        R4      hVP                  V8  d   \        R4      h\        P                  ! VP                  \        V4      4      '       g   \        R4      hVP                  #   + '       g   i     L‚; i)z°Verify PKCE + consume a gateway code; return the bound :class:`Session`. The entry is popped
BEFORE the PKCE check so a wrong verifier cannot be retried (no oracle, no replay).Nz*unknown, expired, or already-redeemed codezcode expiredzPKCE verification failed)rO   ra   rC   r    r?   r'   r   ÚhmacÚcompare_digestr   r9   r   )rs   rt   r;   Úissueds   $$$ r   Úredeem_codery   ‘   s–   € ô ˆs‹)€Cß	ŽÜ�3ŒÜ—‘˜T 4Ó(ˆ÷ 
ð ‚~ÜÐFÓGÐGØ×Ñ˜3ÔÜ˜.Ó)Ð)Ü×Ò˜v×4Ñ4´e¸MÓ6J×KÒKÜÐ4Ó5Ð5Ø�>‰>Ð÷ 
�ús   š"B6Â6C	c               ó   € V ^8„  d   QhRR/# )r)   r+   r<   r   )r,   s   "r   r-   r-   ¡   s   € ÷ ñ ˜$ñ r   c                 ó¬   € \         ;_uu_ 4        \        P                  4        \        P                  4        RRR4       R#   + '       g   i     R# ; i)z+Test-only: drop all pending + issued state.N)ra   r   Úclearr    r   r   r   Ú_reset_for_testsr}   ¡   s&   € ç	ŽÜ�‰ÔÜ�‰Œ÷ 
��Šús   �)AÁA	)*Ú__conditional_annotations__r   Ú
__future__r   r5   r1   rv   r_   Ú	threadingrN   Údataclassesr   Útypingr   r   Úhermes_cli.dashboard_auth.baser   re   rn   rI   rd   ÚLockra   r	   r   r   r   r    Ú	Exceptionr"   r%   r'   r9   rC   rJ   rO   rV   rg   rk   rq   ry   r}   )r~   s   @r   Ú<module>r†      s  øðôõ #ã Û Û Û Û Û Ý !ß !å 2àÐ ØÐ Ø€ð Ð à�ŠÓ€ð ÷ð ó ðð ÷ð ó ðð !#€Ð
Ó "Ø"$€Ð	Ó $ôR�iô RôH�oô HôV�/ô VõIõõ9õ4õðØSUðà÷ð*@¸4÷ @ðÐRV÷ ð Àt÷ ÷ r   