
    -eT2                       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                            t          j        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
    )tz)r$   session_expiryr$   z=extra_payload for session tokens may not contain 'session_id'clsutf-8	   )levelr!   )calendartimegmdtdatetimenowtimezoneutc	timetupleRuntimeErrorjsondumps_BytesEncoderencodezlibcompress_base64_encode_TOKEN_ZLIB_KEY_ensure_bytesr#   )
r$   r   r   r%   r'   r5   payloadextra_payload_str
compressedtokens
             r   r   r   [   s    6 /"+//R[_/==GGII
J
JC'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   rF   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$   )r:   loads_base64_decodesplit)rF   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$   )	r:   rH   rI   rJ   rA   r>   
decompressupdate_BytesDecoder)rF   rK   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)rB   rJ   lenr#   hmaccompare_digestr   r   )
rF   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)rB   rJ   rR   r#   rS   rT   )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 )r<   or   r   c                    t          |t                    rt          t          |                    S t	                                          |          S )N)bytes)
isinstancerc   dictr@   superdefault)selfra   	__class__s     r   rg   z_BytesEncoder.default   sD    a 	1nQ//0000wwq!!!r   )ra   r   r   r   )__name__
__module____qualname__rg   __classcell__ri   s   @r   r<   r<      s=        " " " " " " " " " "r   r<   c                  (     e Zd Zd
 fdZdd	Z xZS )rO   argsr   kwargsr   Nonec                H     t                      j        |d| j        i| d S )Nobject_hook)rf   __init__bytes_object_hook)rh   rp   rq   ri   s      r   ru   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 )Nrc   )setkeysrI   )rh   rw   s     r   rv   z_BytesDecoder.bytes_object_hook   s4    sxxzz??wi''!#g,///
r   )rp   r   rq   r   r   rr   )rw   rx   r   r   )rj   rk   rl   ru   rv   rm   rn   s   @r   rO   rO      sW        N N N N N N       r   rO   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.   )rd   rc   codecsr=   )r   s    r   rB   rB     s7    t	J	&	& 2}Z111r   r   rr   c                ,   t          |          }| st                                           t          j                     |                                }t                              t          j        |                                                     d S d S N)	rB   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   rK   bytes | strc                    t          |           }t          j        t          j        |          d          }t          |                    d                    S )Nascii=)rB   r   decodebase64urlsafe_b64encoder   rstrip)rK   decoded_as_bytesencodeds      r   r@   r@   #  sK     %W-- mF45EFFPPGw~~c""###r   r   rc   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      =)rd   r   r   r=   rR   r   urlsafe_b64decode)r   encoded_as_bytesmods      r   rI   rI   .  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   )	rB   r   r=   rS   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   )rB   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   )rF   r   r   r   )rF   r   r   r   )rF   r   r   r   r   r   r   r   )r$   r   r   r   r   r[   r   r   )r   r|   )r   r   r   r   )r   r   r   r   r   rr   )rK   r   r   r   )r   r   r   rc   )r   r   r   r   r   r   )r   r(   r   r   r   r   r   r   )7__doc__
__future__r   logging	getLoggerrj   logr   r1   r   r4   r3   r   rS   r:   r   r>   typingr   r   
core.typesr   r   warningsr
   typing_extensionsr   __all__rA   re   r   r   __annotations__r   secret_key_bytessign_sessionsr   r   r   r   r   r   JSONEncoderr<   JSONDecoderrO   r   rB   r   r@   rI   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   