
    lKjP+                       d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ erddlmZ  G d de
j4                        Ze G d de             Z G d de      Zy)zuOpenID Connect RP-Initiated Logout 1.0 implementation.

https://openid.net/specs/openid-connect-rpinitiated-1_0.html
    )annotations)	dataclass)field)TYPE_CHECKING)Any)jwt)	JoseError)KeySet)JWSRegistry)add_params_to_uri)Endpoint)EndpointRequest)InvalidRequestError)OAuth2Requestc                      e Zd ZdZddZy)_NonExpiringClaimsRegistryz1Claims registry that skips expiration validation.c                     y )N )selfvalues     u/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/authlib/oidc/rpinitiated/end_session.pyvalidate_expz'_NonExpiringClaimsRegistry.validate_exp!   s        N)r   intreturnNone)__name__
__module____qualname____doc__r   r   r   r   r   r      s
    ;
r   r   c                  l    e Zd ZU dZ edd      Zded<   dZded<   dZded	<   dZ	ded
<   e
dd       Zy)EndSessionRequestzValidated end session request data.

    This object is returned by :meth:`EndSessionEndpoint.validate_request`
    and contains all the validated information from the logout request.
    NF)defaultreprzdict | Noneid_token_claims
str | Noneredirect_urilogout_hint
ui_localesc                    | j                   du S )z7Whether user confirmation is recommended before logout.N)r%   r   s    r   needs_confirmationz$EndSessionRequest.needs_confirmation2   s     ##t++r   )r   bool)r   r   r   r    r   r%   __annotations__r'   r(   r)   propertyr,   r   r   r   r"   r"   %   sJ     $)E#BO[B#L*#"K"!J
!, ,r   r"   c                  |    e Zd ZdZdZddZ	 	 	 	 ddZddZddZ	 	 	 	 ddZ		 	 	 	 	 	 	 	 ddZ
dd	Zdd
ZddZy)EndSessionEndpointaQ  OpenID Connect RP-Initiated Logout endpoint.

    This endpoint follows a two-phase pattern for interactive flows:

    1. Call ``server.validate_endpoint_request("end_session")`` to validate
       the request and get an :class:`EndSessionRequest`
    2. Check ``end_session_request.needs_confirmation`` and show UI if needed
    3. Call ``server.create_endpoint_response("end_session", end_session_request)``
       to execute logout and create the response

    Example usage::

        class MyEndSessionEndpoint(EndSessionEndpoint):
            def get_server_jwks(self):
                return load_jwks()

            def end_session(self, end_session_request):
                session.clear()


        server.register_endpoint(MyEndSessionEndpoint)


        @app.route("/logout", methods=["GET", "POST"])
        def logout():
            try:
                req = server.validate_endpoint_request("end_session")
            except OAuth2Error as error:
                return server.handle_error_response(None, error)

            if req.needs_confirmation and request.method == "GET":
                return render_template("confirm_logout.html", client=req.client)

            return server.create_endpoint_response(
                "end_session", req
            ) or render_template("logged_out.html")

    For non-interactive usage (no confirmation page), use the standard pattern::

        @app.route("/logout", methods=["GET", "POST"])
        def logout():
            return server.create_endpoint_response("end_session") or render_template(
                "logged_out.html"
            )
    end_sessionc                   |j                   j                  }|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }d}	|r| j                  |      }	d}
|r| j                  j                  |      }
n|	r| j                  |	      }
|r;|	r9|	j                  d      }t        |t              r|gn|xs g }||vrt        d	      d}|r<|
r:| j                  |
|      r(|	s| j                  |||
|      r|}|rt        |d|i      }t        ||
|	|||
      S )zValidate an end session request.

        :param request: The OAuth2Request to validate
        :returns: EndSessionRequest with validated data
        :raises InvalidRequestError: If validation fails
        id_token_hint	client_idpost_logout_redirect_uristater(   r)   Naudz&'client_id' does not match 'aud' claim)requestclientr%   r'   r(   r)   )payloaddataget_validate_id_token_hintserverquery_client#resolve_client_from_id_token_claims
isinstancestrr   "_is_valid_post_logout_redirect_uri&is_post_logout_redirect_uri_legitimater   r"   )r   r9   r<   r4   r5   r6   r7   r(   r)   r%   r:   r8   aud_listr'   s                 r   validate_requestz#EndSessionEndpoint.validate_requestm   so    ##1HH[)	#'88,F#G !hh}-XXl+
 "::=IO [[--i8F==oNF
 !%%e,C *3 4u39"H()*RSS
 $770  >>5v{
 4L 0?OP +%#!
 	
r   c                f    |}| j                  |       |j                  rddd|j                  fgfS y)a  Create the end session HTTP response.

        Executes the logout via :meth:`end_session`, then returns a redirect
        response if a valid redirect_uri is present, or None to let the
        application provide its own response.

        :param validated_request: The validated EndSessionRequest
        :returns: Tuple of (status_code, body, headers) for redirect, or None
        i.   LocationN)r2   r'   )r   validated_requestreqs      r   create_responsez"EndSessionEndpoint.create_response   s>     "3j#*:*:;<<<r   c                   | j                         }t        |t              rt        j                  |      }	 t        j                  ||| j                               }t        ddi      }|j                  |j                         t        |j                        S # t        $ r}t        |j                        |d}~ww xY w)z4Validate that the OP was the issuer of the ID Token.)
algorithms	essentialF)nbfN)get_server_jwksrB   dictr
   import_key_setr   decodeget_algorithmsr   validateclaimsr	   r   description)r   r4   jwkstokenclaims_registryexcs         r   r>   z*EndSessionEndpoint._validate_id_token_hint   s    
 ##%dD!((.D	@JJ}dt?R?R?TUE8k5=QRO$$U\\2 ELL!!  	@%coo6C?	@s   AB 	B?$B::B?c                |    |j                  d      }t        |t              r| j                  j	                  |      S y)zResolve client from id_token aud claim.

        When aud is a single string, resolves the client directly.
        When aud is a list, returns None (ambiguous case).
        Override for custom resolution logic.
        r8   N)r=   rB   rC   r?   r@   )r   r%   r8   s      r   rA   z6EndSessionEndpoint.resolve_client_from_id_token_claims   s6     !!%(c3;;++C00r   c                B    |j                   j                  dg       }||v S )z?Check if post_logout_redirect_uri is registered for the client.post_logout_redirect_uris)client_metadatar=   )r   r:   r6   registered_uriss       r   rD   z5EndSessionEndpoint._is_valid_post_logout_redirect_uri   s)     !00445PRTU'?::r   c                     y)aW  Confirm redirect_uri legitimacy when no id_token_hint is provided.

        Override if you have alternative confirmation mechanisms, e.g.::

            def is_post_logout_redirect_uri_legitimate(self, ...):
                return client and client.is_trusted

        By default returns False (no redirection without id_token_hint).
        Fr   )r   r9   r6   r:   r(   s        r   rE   z9EndSessionEndpoint.is_post_logout_redirect_uri_legitimate   s    & r   c                    t               )z>Return the server's JSON Web Key Set for validating ID tokens.NotImplementedErrorr+   s    r   rR   z"EndSessionEndpoint.get_server_jwks  s    !##r   c                    | j                         }t        |t              rt        j                  |      }t        j                  |      D cg c]  }|j                   c}S c c}w )zReturn the list of allowed algorithms for ID token validation.

        By default, returns all algorithms compatible with the keys in the JWKS.
        Override to restrict to specific algorithms.
        )rR   rB   rS   r
   rT   r   filter_algorithmsname)r   rZ   algs      r   rV   z!EndSessionEndpoint.get_algorithms  sU     ##%dD!((.D$/$A$A$$GH$GS$GHHHs   A#c                    t               )a|  Terminate the user's session.

        Implement this method to perform the actual logout logic,
        such as clearing session data, revoking tokens, etc.

        Use ``end_session_request.logout_hint`` to help identify the user
        (e.g. email, username) when no ``id_token_hint`` is provided.

        :param end_session_request: The validated EndSessionRequest
        re   )r   end_session_requests     r   r2   zEndSessionEndpoint.end_session  s     "##r   N)r9   r   r   r"   )rK   r"   r   z-tuple[int, Any, list[tuple[str, str]]] | None)r4   rC   r   rS   )r%   rS   r   z
Any | None)r6   rC   r   r-   )r9   r   r6   rC   r(   r&   r   r-   )r   zdict | KeySet)r   z	list[str])rl   r"   r   r   )r   r   r   r    ENDPOINT_NAMErG   rM   r>   rA   rD   rE   rR   rV   r2   r   r   r   r1   r1   <   s    ,\ "ME
N!2	6&"(
;03;	; #&
   
*$	I$r   r1   N)r    
__future__r   dataclassesr   r   typingr   r   joserfcr   joserfc.errorsr	   joserfc.jwkr
   joserfc.jwsr   authlib.common.urlsr   authlib.oauth2.rfc6749.endpointr   r   authlib.oauth2.rfc6749.errorsr   authlib.oauth2.rfc6749.requestsr   JWTClaimsRegistryr   r"   r1   r   r   r   <module>rz      st   
 # !      $  # 1 4 ; ==!6!6  , , ,,a$ a$r   