
    dH2                       U d Z ddlmZ ddlZ ej        e          ZddlZddlZddl	Z	ddl
ZddlZddlZddlZddlZddlZddlmZmZ ddlmZ ddlmZ dd	lmZ erdd
lmZ dZdZeeef         Zde d<   d=dZ! ej"                     ej#                    fd>dZ$ ej"                     ej#                    ddfd?dZ%d@d Z&dAd!Z' ej"                     ej#                    fdBd"Z( ej"                     ej#                    fdCd$Z) G d% d&ej*                  Z+ G d' d(ej,                  Z-dDd*Z.dEd,Z/dFd/Z0dGd2Z1dHd5Z2dId7Z3d8d9 ej"                    fdJd<Z4 e.            \  Z5Z6dS )Kz Utilities for generating and manipulating session IDs.

A session ID would typically be associated with each browser tab viewing
an application or plot. Each session has its own state separate from any
other sessions hosted by the server.

    )annotationsN)TYPE_CHECKINGAny   )ID)settings   )warn)	TypeAlias)check_session_id_signaturecheck_token_signaturegenerate_secret_keygenerate_jwt_tokengenerate_session_idget_session_idget_token_payload__bk__zlib_r   TokenPayloadreturnstrc                     t                      S )z Generate a new securely-generated secret key appropriate for SHA-256
    HMAC signatures.

    This key could be used to sign Bokeh server session IDs, for example.
    )_get_random_string     0lib/python3.11/site-packages/bokeh/util/token.pyr   r   E   s     r   
secret_keybytes | Nonesignedboolr   c                    t                      }|r%d                    |t          ||           g          }t          |          S )a   Generate a random session ID.

    Typically, each browser tab connected to a Bokeh application has its own
    session ID. In production deployments of a Bokeh app, session IDs should be
    random and unguessable - otherwise users of the app could interfere with one
    another.
    .)r   join
_signaturer   )r   r   
session_ids      r   r   r   M   sD     $%%J PXXz:j*+M+MNOO
j>>r   i,  r$   extra_payloadTokenPayload | None
expirationintc                
   t          j        t          j                                                                                  }| ||z   d}|rnd|v rt          d          t          j        |t                    
                    d          }t          j        |d          }t          |          |t          <   t          t          j        |                    }	t          |          }|s|	S |	dz   t!          |	|          z   S )	av   Generates a JWT token given a session_id and additional payload.

    Args:
        session_id (str):
            The session id to add to the token

        secret_key (str, optional) :
            Secret key (default: value of BOKEH_SECRET_KEY environment variable)

        signed (bool, optional) :
            Whether to sign the session ID (default: value of BOKEH_SIGN_SESSIONS
            environment variable)

        extra_payload (dict, optional) :
            Extra key/value pairs to include in the Bokeh session token

        expiration (int, optional) :
            Expiration time

    Returns:
        str
    )r$   session_expiryr$   z=extra_payload for session tokens may not contain 'session_id'clsutf-8	   )levelr!   )calendartimegmdtdatetimeutcnowutctimetupleRuntimeErrorjsondumps_BytesEncoderencodezlibcompress_base64_encode_TOKEN_ZLIB_KEY_ensure_bytesr#   )
r$   r   r   r%   r'   nowpayloadextra_payload_str
compressedtokens
             r   r   r   [   s    6 /"+,,..;;==
>
>C'3;KLLG >=((^___ J}-HHHOOPWXX]#4A>>>
#1*#=#= 4:g..//Ez**J 3;E:6666r   rD   c                    t          j        t          |                     d          d                             }|d         S )zExtracts the session id from a JWT token.

    Args:
        token (str):
            A JWT token containing the session_id and other data.

    Returns:
       str
    r!   r   r$   )r7   loads_base64_decodesplit)rD   decodeds     r   r   r      s7     jC(8(8(;<<==G<  r   c                V   t          j        t          |                     d          d                             }t          |v rbt          j        t          |t                                       }|t          = |                    t          j        |t                               |d= |S )zExtract the payload from the token.

    Args:
        token (str):
            A JWT token containing the session_id and other data.

    Returns:
        dict
    r!   r   r+   r$   )	r7   rF   rG   rH   r>   r;   
decompressupdate_BytesDecoder)rD   rI   decompresseds      r   r   r      s     jC(8(8(;<<==G'!!~go6N'O'OPPO$tz,MBBBCCCNr   c                0   t          |          }|r|                     dd          }t          |          dk    rdS |d         }|d         }t          ||          }t	          j        ||          }t          |           }t          |||          }	|o|	S dS )au  Check the signature of a token and the contained signature.

    The server uses this function to check whether a token and the
    contained session id was generated with the correct secret key.
    If signed sessions are disabled, this function always returns True.

    Args:
        token (str) :
            The token to check

        secret_key (str, optional) :
            Secret key (default: value of BOKEH_SECRET_KEY environment variable)

        signed (bool, optional) :
            Whether to check anything (default: value of BOKEH_SIGN_SESSIONS
            environment variable)

    Returns:
        bool

    r!   r	   r   Fr   T)r?   rH   lenr#   hmaccompare_digestr   r   )
rD   r   r   token_pieces
base_tokenprovided_token_signatureexpected_token_signaturetoken_validr$   session_id_valids
             r   r   r      s    0 z**J 0{{3**|!!5!!_
#/? #-j*#E#E  )$&>
 
 $E**
5j*fUU///4r   bool | Nonec                    t          |          }|r^|                     dd          }t          |          dk    rdS |d         }t          |d         |          }t	          j        ||          S dS )zCheck the signature of a session ID, returning True if it's valid.

    The server uses this function to check whether a session ID was generated
    with the correct secret key. If signed sessions are disabled, this function
    always returns True.
    r!   r	   r   Fr   T)r?   rH   rP   r#   rQ   rR   )r$   r   r   	id_piecesprovided_id_signatureexpected_id_signatures         r   r   r      s     z**J 
$$S!,,	y>>Q5 )! *9Q< D D"!#8
 
 	
 4r   c                        e Zd Zd fdZ xZS )r9   or   r   c                    t          |t                    rt          t          |                    S t	                                          |          S )N)bytes)
isinstancera   dictr=   superdefault)selfr_   	__class__s     r   re   z_BytesEncoder.default   sD    a 	1nQ//0000wwq!!!r   )r_   r   r   r   )__name__
__module____qualname__re   __classcell__rg   s   @r   r9   r9      s=        " " " " " " " " " "r   r9   c                  (     e Zd Zd
 fdZdd	Z xZS )rM   argsr   kwargsr   Nonec                H     t                      j        |d| j        i| d S )Nobject_hook)rd   __init__bytes_object_hook)rf   rn   ro   rg   s      r   rs   z_BytesDecoder.__init__   s-    $MD,BMfMMMMMr   objdict[Any, Any]c                |    t          |                                          dhk    rt          |d                   S |S )Nra   )setkeysrG   )rf   ru   s     r   rt   z_BytesDecoder.bytes_object_hook   s4    sxxzz??wi''!#g,///
r   )rn   r   ro   r   r   rp   )ru   rv   r   r   )rh   ri   rj   rs   rt   rk   rl   s   @r   rM   rM      sW        N N N N N N       r   rM   tuple[Any, bool]c                     dd l } 	 |                                 }d}||fS # t          $ r: t          d           t	          j                    t          d           d}| |fcY S w xY w)Nr   TzjA secure pseudo-random number generator is not available on your system. Falling back to Mersenne Twister.zA secure pseudo-random number generator is not available and no BOKEH_SECRET_KEY has been set. Setting a secret key will mitigate the lack of a secure generator.F)randomSystemRandomNotImplementedErrorr
   r   r   )r|   	sysrandomusing_sysrandoms      r   _get_sysrandomr      s    
 MMM'''))	/)) ' ' ' A 	B 	B 	B  ( E F F F  &&&&'s     AA$#A$str | bytes | Nonec                b    | d S t          | t                    r| S t          j        | d          S Nr-   )rb   ra   codecsr:   )r   s    r   r?   r?     s7    t	J	&	& 2}Z111r   r   rp   c                ,   t          |          }| st                                           t          j                     |                                }t                              t          j        |                                                     d S d S N)	r?   r|   getstatetimer:   seedhashlibsha256digest)r   r   datas      r   _reseed_if_neededr     s    z**J 3 //##@TY[[@*@@GGIIGN4((//11222223 3r   rI   bytes | strc                    t          |           }t          j        t          j        |          d          }t          |                    d                    S )Nascii=)r?   r   decodebase64urlsafe_b64encoder   rstrip)rI   decoded_as_bytesencodeds      r   r=   r=   #  sK     %W-- mF45EFFPPGw~~c""###r   r   ra   c                    t          | t                    rt          j        | d          n| }t	          |          dz  }|dk    r|dd|z
  z  z   }t	          |          dz  dk    sJ t          j        |          S )Nr      r      =)rb   r   r   r:   rP   r   urlsafe_b64decode)r   encoded_as_bytesmods      r   rG   rG   .  s    :DWc:R:R_v}Wg666X_


!
#C
axx+tq3w/?@ !!A%!++++#$4555r   base_idc                    t          |          }t          j        | d          }|J t          j        ||t
          j                  }t          |                                          S r   )	r?   r   r:   rQ   newr   r   r=   r   )r   r   base_id_encodedsigners       r   r#   r#   8  sW    z**JmGW55O!!!Xj/7>BBF&--//***r   ,   >abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789lengthallowed_charsc                    t          |          }t          t          |           d                    fdt	          |           D                       S )z Return a securely generated random string.

    With the a-z, A-Z, 0-9 character set:
    Length 12 is a 71-bit value. log_2((26+26+10)^12) =~ 71
    Length 44 is a 261-bit value. log_2((26+26+10)^44) = 261

     c              3  L   K   | ]}t                                         V  d S r   )r|   choice).0_r   s     r   	<genexpr>z%_get_random_string.<locals>.<genexpr>L  s/      GGA6==//GGGGGGr   )r?   r   r   r"   range)r   r   r   s    ` r   r   r   ?  sO     z**Joz22277GGGGvGGGGGGr   )r   r   )r   r   r   r   r   r   )r$   r   r   r   r   r   r%   r&   r'   r(   r   r   )rD   r   r   r   )rD   r   r   r   )rD   r   r   r   r   r   r   r   )r$   r   r   r   r   rY   r   r   )r   rz   )r   r   r   r   )r   r   r   r   r   rp   )rI   r   r   r   )r   r   r   ra   )r   r   r   r   r   r   )r   r(   r   r   r   r   r   r   )7__doc__
__future__r   logging	getLoggerrh   logr   r0   r   r3   r2   r   rQ   r7   r   r;   typingr   r   
core.typesr   r   warningsr
   typing_extensionsr   __all__r>   rc   r   r   __annotations__r   secret_key_bytessign_sessionsr   r   r   r   r   r   JSONEncoderr9   JSONDecoderrM   r   r?   r   r=   rG   r#   r   r|   r   r   r   r   <module>r      sn     # " " " " " g!!             % % % % % % % %                   ,++++++   sCx. ( ( ( (        4M83L3N3N'=x'='?'?     3L(2K2M2M&<h&<&>&><@),	'7 '7 '7 '7 '7R! ! ! !   & 6OX5N5P5P)?)?)A)A( ( ( ( (V ;T(:S:U:U5KX5K5M5M    :" " " " "D$ " " "    D$   ' ' ' '(2 2 2 2
3 
3 
3 
3$ $ $ $6 6 6 6+ + + + ]#<8#<#>#>H H H H H& ).** r   