
    j                    2   d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	  ed           G d d	                      Z
 ed           G d
 d                      Z G d de          Z G d de          Z G d de          Z G d de          ZddZdS )zFAbstract base + dataclasses + exceptions for dashboard auth providers.    )annotations)ABCabstractmethod)	dataclass)OptionalT)frozenc                  d    e Zd ZU dZded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   dS )Sessionu   A verified identity. Returned by ``complete_login`` and ``verify_session``.

    All fields are mandatory. Providers that don't have a concept of orgs
    should set ``org_id`` to an empty string. ``access_token`` and
    ``refresh_token`` are opaque to Hermes — provider-specific.
    struser_idemaildisplay_nameorg_idproviderint
expires_ataccess_tokenrefresh_tokenN__name__
__module____qualname____doc____annotations__     =/usr/local/lib/hermes-agent/hermes_cli/dashboard_auth/base.pyr
   r
   	   so           LLLJJJKKKMMMOOOr   r
   c                  (    e Zd ZU dZded<   ded<   dS )
LoginStartu  First leg of the OAuth round trip.

    ``redirect_url`` is the URL the browser must navigate to (e.g. the
    Portal's ``/oauth/authorize``). ``cookie_payload`` is a dict of cookie
    name → serialised value that the auth route will ``Set-Cookie`` on the
    response. Used for PKCE state, CSRF nonces, etc. Cookies set here MUST
    be HttpOnly + Secure (when over HTTPS) + SameSite=Lax with a TTL ≤ 10
    minutes (the login lifetime).
    r   redirect_urlzdict[str, str]cookie_payloadNr   r   r   r   r   r      s6           """"""r   r   c                      e Zd ZdZdS )ProviderErrorzmIDP unreachable, network error, or other transient failure.

    Middleware translates this to HTTP 503.
    Nr   r   r   r   r   r   r   r#   r#   ,              r   r#   c                      e Zd ZdZdS )InvalidCodeErrorzlThe OAuth callback ``code`` / ``state`` failed validation.

    Middleware translates this to HTTP 400.
    Nr$   r   r   r   r'   r'   3   r%   r   r'   c                      e Zd ZdZdS )RefreshExpiredErroruh   The refresh token is dead.

    Middleware clears cookies and forces re-login (302 → ``/login``).
    Nr$   r   r   r   r)   r)   :   r%   r   r)   c                      e Zd ZU dZdZded<   dZded<   edd	            Zedd            Z	edd            Z
edd            Zedd            ZdS )DashboardAuthProvideru  Protocol every dashboard-auth provider plugin implements.

    Lifecycle:
      1. ``start_login`` — user clicks "Log in with X" on the login page.
         Provider returns a redirect URL and any PKCE/CSRF state to stash
         in short-lived cookies.
      2. Browser bounces through the OAuth IDP and lands at /auth/callback.
      3. ``complete_login`` — exchange the code + verifier for a Session.
      4. ``verify_session`` — called on every request to validate the
         access token in the cookie. Returns ``None`` if the token is
         expired or invalid (middleware then triggers refresh or logout).
      5. ``refresh_session`` — called when the access token is near expiry.
         Returns a new Session with rotated tokens.
      6. ``revoke_session`` — called on /auth/logout. Best-effort.

    Failure semantics:
      * ``start_login`` may raise ``ProviderError`` if the IDP is
        unreachable.
      * ``complete_login`` raises ``InvalidCodeError`` on bad code/state;
        ``ProviderError`` if the IDP is unreachable.
      * ``verify_session`` returns ``None`` on expiry / unknown token;
        raises ``ProviderError`` if the IDP is unreachable. Middleware
        treats expiry and unreachable differently (expiry → refresh;
        unreachable → 503).
      * ``refresh_session`` raises ``RefreshExpiredError`` when the
        refresh token is also invalid; middleware then forces re-login.
        Raises ``ProviderError`` on network failure.
      * ``revoke_session`` is best-effort and must not raise.

    Subclasses MUST set ``name`` (lowercase identifier, stable forever)
    and ``display_name`` (user-facing label on the login page).
     r   namer   redirect_urireturnr   c                   d S Nr   )selfr.   s     r   start_loginz!DashboardAuthProvider.start_loginf   s    ?Bsr   codestatecode_verifierr
   c                   d S r1   r   )r2   r4   r5   r6   r.   s        r   complete_loginz$DashboardAuthProvider.complete_logini   s	     #r   r   Optional[Session]c                   d S r1   r   )r2   r   s     r   verify_sessionz$DashboardAuthProvider.verify_sessions   s    ILr   r   c                   d S r1   r   r2   r   s     r   refresh_sessionz%DashboardAuthProvider.refresh_sessionv   s    ADr   Nonec                   d S r1   r   r=   s     r   revoke_sessionz$DashboardAuthProvider.revoke_sessiony   s    =@Sr   N)r.   r   r/   r   )
r4   r   r5   r   r6   r   r.   r   r/   r
   )r   r   r/   r9   )r   r   r/   r
   )r   r   r/   r?   )r   r   r   r   r-   r   r   r   r3   r8   r;   r>   rA   r   r   r   r+   r+   A   s          B DNNNNLBBB ^B   ^ LLL ^LDDD ^D@@@ ^@@@r   r+   clstyper/   r?   c                `   d}d}|D ].}t          | |d          }|st          | j         d|          /|D ]9}t          t          | |d                    st          | j         d|           :t          | dd          r+t          | j         dt	          | j                             dS )	a+  Raise ``TypeError`` if ``cls`` doesn't fully implement the provider protocol.

    Call this in every provider plugin's unit tests::

        def test_protocol_compliance():
            assert_protocol_compliance(MyProvider)

    Returns ``None`` on success so callers can assert it explicitly.
    )r3   r8   r;   r>   rA   )r-   r   r,   z missing or empty attribute: Nz missing method: __abstractmethods__z% has unimplemented abstract methods: )getattr	TypeErrorr   callablesortedrE   )rB   required_methodsrequired_attrsattrvalmethods         r   assert_protocol_compliancerO   }   s    .N  c4$$ 	<FFdFF  	 # H HVT2233 	Hs|FFfFFGGG	H s)400 
| 1 1c-..1 1
 
 	

 
r   N)rB   rC   r/   r?   )r   
__future__r   abcr   r   dataclassesr   typingr   r
   r   	Exceptionr#   r'   r)   r+   rO   r   r   r   <module>rU      s   L L " " " " " " # # # # # # # # ! ! ! ! ! !       $       $ $# # # # # # # #    I       y       )   9A 9A 9A 9A 9AC 9A 9A 9Ax!
 !
 !
 !
 !
 !
r   