+
    „WÝjv  ã                  óH  € R t ^ RIHt ^ RIHtHt ^ RIHt ^ RIH	t	 ]! RR7       ! R R4      4       t
]! RR7       ! R	 R
4      4       t]! RR7       ! R R4      4       t ! R R]4      t ! R R]4      t ! R R]4      t ! R R]4      tR R lt ! R R]4      tR R ltR# )zFAbstract base + dataclasses + exceptions for dashboard auth providers.)Úannotations)ÚABCÚabstractmethod)Ú	dataclass)ÚOptionalT)Úfrozenc                  óz   € ] tR t^	t$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   RtR]R&   RtR# )ÚSessionz°A verified interactive identity (from ``complete_login`` / ``verify_session``). All fields
mandatory; providers without orgs set ``org_id=""``. The tokens are opaque to Hermes.ÚstrÚuser_idÚemailÚdisplay_nameÚorg_idÚproviderÚintÚ
expires_atÚaccess_tokenÚrefresh_tokenÚ Úissuer© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   Ú__static_attributes__r   ó    ÚRC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\dashboard_auth\base.pyr	   r	   	   s=   ‡ ñ]àƒLØƒJØÓØƒKØƒMØƒOØÓØÓØ€FˆC×r   r	   c                  ó>   € ] tR t^t$ RtR]R&   R]R&   RtR]R&   RtR# )	ÚTokenPrincipalu  A verified non-interactive (service-to-service) caller â€” the token analog of
:class:`Session`: one bearer token on one request, no login/cookie/refresh. ``principal`` is
an opaque stable caller id; ``scopes`` empty means "unscoped" (a route MAY enforce one).r
   Ú	principalr   ztuple[str, ...]Úscopesr   N)r   r   r   r   r   r   r#   r   r   r   r   r!   r!      s   ‡ ñ`ð ƒNØƒMØ €FˆO× r   r!   c                  ó0   € ] tR t^"t$ RtR]R&   R]R&   RtR# )Ú
LoginStarta
  First leg of the OAuth round trip: ``redirect_url`` is the IDP's authorize endpoint;
``cookie_payload`` maps cookie name -> serialised PKCE/CSRF state that the auth route sets
(HttpOnly, Secure + ``SameSite=None`` over HTTPS, TTL <= 10 min; see ``set_pkce_cookie``).r
   Úredirect_urlzdict[str, str]Úcookie_payloadr   N)r   r   r   r   r   r   r   r   r   r   r%   r%   "   s   ‡ ñbð ÓØ"×"r   r%   c                  ó   € ] tR t^+tRtRtR# )ÚProviderErrorz<IDP unreachable / transient failure. Middleware -> HTTP 503.r   N©r   r   r   r   r   r   r   r   r   r)   r)   +   s   † ÝFr   r)   c                  ó   € ] tR t^/tRtRtR# )ÚInvalidCodeErrorzLOAuth callback ``code``/``state`` failed validation. Middleware -> HTTP 400.r   Nr*   r   r   r   r,   r,   /   s   † ÝVr   r,   c                  ó   € ] tR t^3tRtRtR# )ÚInvalidCredentialsErrorzQUsername/password rejected. The route answers a generic 401 (no username oracle).r   Nr*   r   r   r   r.   r.   3   s   † Ý[r   r.   c                  ó   € ] tR t^7tRtRtR# )ÚRefreshExpiredErrorz¸This provider rejects the refresh token. Not proof of ownership in a multi-provider
deployment: middleware tries the rest and forces re-login only after every reachable one
rejects it.r   Nr*   r   r   r   r0   r0   7   s   † õr   r0   c               ó    € V ^8„  d   QhRRRR/# )é   ÚexcÚBaseExceptionÚreturnÚ	Exceptionr   )Úformats   "r   Ú__annotate__r8   =   s   € ÷ 9ñ 9 Mð 9°iñ 9r   c                óÊ  €  ^ RI p\        YP                  4      '       d   \        RT  24      # \        YP
                  TP                  34      '       d   \        RT  24      # \        YP                  4      '       d   \        RT  24      # \        YP                  4      '       d   \        RT  24      # \        RT : 24      #   \         d    \        RT : 24      u # i ; i)uÑ  Map a ``PyJWKClient.get_signing_key_from_jwt`` failure to the protocol. Only a genuine
transport failure (``PyJWKClientConnectionError``, or an unexpected JWKS shape) is a
:class:`ProviderError` (503, never forces logout). A non-JWT bearer (``DecodeError``), a JWKS
with no key for this ``kid`` (``PyJWKSetError``) or any other invalid token is simply not
verifiable by this provider -> :class:`InvalidCodeError` (``verify_session`` returns ``None``).
Folding "cannot parse" into "cannot reach" once made every opaque bearer a fast 503.

* ``jwt.DecodeError`` â€” the bearer is not a JWT at all (an opaque peer key, a legacy session token,
garbage). #94558: hosted agents answered every non-JWT bearer with a fast 503 ``Auth provider 'nous'
unreachable`` even though Portal was healthy, because "cannot parse" and "cannot reach" were folded into
one branch. * ``jwt.PyJWKSetError`` â€” the JWKS was fetched fine but holds no key for this token's
``kid`` (rotated/foreign key).
NzJWKS lookup failed: z'token not verifiable by this provider: )
Újwtr6   r)   Ú
isinstanceÚPyJWKClientConnectionErrorÚDecodeErrorÚPyJWKSetErrorr,   ÚPyJWKClientErrorÚInvalidTokenError)r3   r:   s   & r   Úclassify_jwks_lookup_errorrA   =   sÜ   € ð=Ûô
 �#×5Ñ5×6Ò6ÜÐ3°C°5Ð9Ó:Ð:Ü�#Ÿ™¨×):Ñ):Ð;×<Ò<ÜÐ"IÈ#ÈÐ OÓPÐPÜ�#×+Ñ+×,Ò,ÜÐ3°C°5Ð9Ó:Ð:Ü�#×,Ñ,×-Ò-ÜÐ"IÈ#ÈÐ OÓPÐPÜÐ/°©wÐ7Ó8Ð8øô ô =ÜÐ3°C±7Ð;Ó<Ò<ð=ús   ‚C ÃC"Ã!C"c                  óè   € ] tR t^\t$ RtRtR]R&   RtR]R&   RtR]R&   Rt	R]R	&   R
t
R]R&   ]R R l4       t]R R l4       t]R R l4       t]R R l4       t]R R l4       tR R ltR R ltRtR# )ÚDashboardAuthProvidera»  Protocol every dashboard-auth provider plugin implements.

Lifecycle: ``start_login`` (redirect URL + PKCE state) -> IDP -> ``complete_login`` (code +
verifier -> Session) -> ``verify_session`` per request -> ``refresh_session`` near expiry ->
``revoke_session`` on logout (best-effort, must not raise). Failure semantics: ``start_login``
/ ``complete_login`` raise ``ProviderError`` when the IDP is unreachable, ``complete_login``
``InvalidCodeError`` on a bad code/state; ``verify_session`` returns ``None`` for
expired/unknown tokens (middleware refreshes) and raises ``ProviderError`` when unreachable
(503); ``refresh_session`` raises ``RefreshExpiredError`` when the token is invalid for that
provider (a foreign opaque token looks expired, so middleware tries the rest) and
``ProviderError`` on network failure (503, cookies kept).

Subclasses MUST set ``name`` (stable lowercase id) and ``display_name``. Capability flags:
``supports_password`` (credential form + ``complete_password_login``; OAuth methods may be
``NotImplementedError`` stubs), ``supports_token`` (``verify_token`` for the token-auth seam),
``supports_session`` (False for token-only credentials such as drain, never offered a login).
r   r
   Únamer   FÚboolÚsupports_passwordÚsupports_tokenTÚsupports_sessionc               ó    € V ^8„  d   QhRRRR/# )r2   Úredirect_urir
   r5   r%   r   )r7   s   "r   r8   Ú"DashboardAuthProvider.__annotate__u   s   € ×BÑB¨3ÐB°:ÑBr   c               	ó   € R # ©Nr   )ÚselfrJ   s   &$r   Ústart_loginÚ!DashboardAuthProvider.start_logint   s   € Ù?Br   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )r2   Úcoder
   ÚstateÚcode_verifierrJ   r5   r	   r   )r7   s   "r   r8   rK   x   s;   € ÷ _ñ _Øð_Ø#&ð_Ø7:ð_ØJMð_ØRYñ_r   c               	ó   € R # rM   r   )rN   rR   rS   rT   rJ   s   &$$$$r   Úcomplete_loginÚ$DashboardAuthProvider.complete_loginw   s   € á[^r   c               ó    € V ^8„  d   QhRRRR/# )r2   r   r
   r5   zOptional[Session]r   )r7   s   "r   r8   rK   |   s   € ×LÑL¨cÐLÐ6GÑLr   c               	ó   € R # rM   r   )rN   r   s   &$r   Úverify_sessionÚ$DashboardAuthProvider.verify_session{   s   € ÙILr   c               ó    € V ^8„  d   QhRRRR/# )r2   r   r
   r5   r	   r   )r7   s   "r   r8   rK      s   € ×DÑD°ÐD¸ÑDr   c               	ó   € R # rM   r   ©rN   r   s   &$r   Úrefresh_sessionÚ%DashboardAuthProvider.refresh_session~   s   € ÙADr   c               ó    € V ^8„  d   QhRRRR/# )r2   r   r
   r5   ÚNoner   )r7   s   "r   r8   rK   ‚   s   € ×@Ñ@¨sÐ@°tÑ@r   c               	ó   € R # rM   r   r^   s   &$r   Úrevoke_sessionÚ$DashboardAuthProvider.revoke_session�   s   € Ù=@r   c               ó$   € V ^8„  d   QhRRRRRR/# )r2   Úusernamer
   Úpasswordr5   r	   r   )r7   s   "r   r8   rK   „   s&   € ÷ Sñ S°3ð SÀ#ð SÈ'ñ Sr   c               óD   € \        \        V 4      P                   R24      h)uE  Verify a username/password pair and mint a :class:`Session` (only called when
``supports_password``). Raise ``InvalidCredentialsError`` on rejection (SHOULD be constant
time for unknown users â€” no timing oracle) and ``ProviderError`` when the store is
unreachable. The default raises so a mis-flagged provider fails loudly.zd does not support password login (set supports_password = True and override complete_password_login)©ÚNotImplementedErrorÚtyper   )rN   rg   rh   s   &$$r   Úcomplete_password_loginÚ-DashboardAuthProvider.complete_password_login„   s/   € ô
 "Ü�D‹z×"Ñ"Ð#ð $Rð RóSð 	Sr   c               ó    € V ^8„  d   QhRRRR/# )r2   Útokenr
   r5   zOptional[TokenPrincipal]r   )r7   s   "r   r8   rK   �   s   € ÷ Eñ E Sð EÐ-Eñ Er   c               óD   € \        \        V 4      P                   R24      h)ae  Verify a non-interactive bearer token; return its principal. Mirrors ``verify_session``:
return ``None`` (never raise) for an unrecognised token so the seam falls through; raise
``ProviderError`` ONLY for a genuine backing-store outage. Shared secrets MUST be compared
with ``hmac.compare_digest``. The default raises so a mis-flagged provider fails loudly.zR does not support token auth (set supports_token = True and override verify_token)rj   )rN   rp   s   &$r   Úverify_tokenÚ"DashboardAuthProvider.verify_token�   s/   € ô
 "Ü�D‹z×"Ñ"Ð#ð $Dð DóEð 	Er   r   N)r   r   r   r   r   rD   r   r   rF   rG   rH   r   rO   rV   rZ   r_   rd   rm   rr   r   r   r   r   rC   rC   \   sœ   ‡ ñð" €Dˆ#ƒNØ€L�#ÓØ#Ð�tÓ#Ø €N�DÓ Ø!Ð�dÓ!àÜBó ØBàô_ó ð_ð ÜLó ØLàÜDó ØDàÜ@ó Ø@õS÷Eñ Er   rC   c               ó    € V ^8„  d   QhRRRR/# )r2   Úclsrl   r5   rb   r   )r7   s   "r   r8   r8   —   s   € ÷ eñ e Dð e¨Tñ er   c                ón  € R F0  p\        WR4      '       d   K  \        V P                   RV: 24      h	  R F8  p\        \        WR4      4      '       d   K   \        V P                   RV 24      h	  \        V RR4      '       d.   \        V P                   R\	        V P
                  4       24      hR# )	zvRaise ``TypeError`` if ``cls`` doesn't fully implement the protocol (call it from every
provider plugin's unit tests).r   z missing or empty attribute: Nz missing method: Ú__abstractmethods__z% has unimplemented abstract methods: )rD   r   )rO   rV   rZ   r_   rd   )ÚgetattrÚ	TypeErrorr   ÚcallableÚsortedrw   )ru   ÚattrÚmethods   &  r   Úassert_protocol_compliancer~   —   s´   € ó )ˆÜ�s "×%Ô%Ü˜sŸ|™|˜nÐ,IÈ$ÉÐRÓSÐSñ )ó%ˆäœ ¨TÓ2×3Ô3Ü˜sŸ|™|˜nÐ,=¸f¸XÐFÓGÐGñ%ô ˆsÐ)¨4×0Ò0ÜØ�|‰|ˆnÐAÄ&È×I`ÑI`ÓBaÐAbÐcóeð 	eñ 1r   N)r   Ú
__future__r   Úabcr   r   Údataclassesr   Útypingr   r	   r!   r%   r6   r)   r,   r.   r0   rA   rC   r~   r   r   r   Ú<module>rƒ      s¾   ðÙ LÝ "ç #Ý !Ý ñ �$Ô÷ð ó ðñ �$Ô÷!ð !ó ð!ñ �$Ô÷#ð #ó ð#ôG�Iô GôW�yô Wô\˜iô \ô˜)ô õ9ô>8E˜Cô 8E÷ver   