U
    /e0                     @  s  d Z ddlmZ ddlZe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mZmZ ddlmZ ddlmZ dZd	Zeeef Zd
dddZe e fddddddZ e e ddfdddddd
dddZ!d
ddddZ"d
ddddZ#e e fd
dddd d!d"Z$e e fd
dd#dd$d%d&Z%d'dd(d)Z&d*dd+d,d-Z'ddd.d/d0d1Z(d2d
d3d4d5Z)d2d6d7d8d9Z*d
dd
d:d;d<Z+d=d>e fdd
dd
d?d@dAZ,e& \Z-Z.dS )Bz 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)AnyDictTupleUnion   )ID)settings)check_session_id_signaturecheck_token_signaturegenerate_secret_keygenerate_jwt_tokengenerate_session_idget_session_idget_token_payloadZ__bk__zlib_str)returnc                   C  s   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 r   r   4/tmp/pip-unpacked-wheel-f5fndrjf/bokeh/util/token.pyr   F   s    r   zbytes | Noneboolr   )
secret_keysignedr   c                 C  s&   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_idr   r   r   r   N   s    	r   i,  zTokenPayload | Noneint)r   r   r   extra_payload
expirationr   c           
      C  s   t tj  }| || d}|r`d|kr6tdt|	d}t
j|dd}t||t< tt|}	t|}|s~|	S |	d t|	| S )ax  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 varariable)

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

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

        expiration (int, optional) :
            Expiration time

    Returns:
        str
    )r   Zsession_expiryr   z=extra_payload for session tokens may not contain 'session_id'utf-8	   )levelr   )calendartimegmdtdatetimeutcnowutctimetupleRuntimeErrorjsondumpsencodezlibcompress_base64_encode_TOKEN_ZLIB_KEY_ensure_bytesr   )
r   r   r   r   r   nowpayloadZextra_payload_str
compressedtokenr   r   r   r   \   s    r   )r5   r   c                 C  s    t 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)r5   decodedr   r   r   r      s    
r   TokenPayloadc                 C  sR   t t| dd }t|krHtt|t }|t= |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*   r6   r7   r8   r0   r-   
decompressupdate)r5   r9   decompressedr   r   r   r      s    
r   )r5   r   r   r   c           
      C  sn   t |}|rj| dd}t|dkr(dS |d }|d }t||}t||}t| }t|||}	|oh|	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   Fr   T)r1   r8   lenr   hmaccompare_digestr   r
   )
r5   r   r   Ztoken_piecesZ
base_tokenZprovided_token_signatureZexpected_token_signatureZtoken_validr   Zsession_id_validr   r   r   r      s     
 r   zbool | None)r   r   r   r   c                 C  sN   t |}|rJ| dd}t|dkr(dS |d }t|d |}t||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)r1   r8   r?   r   r@   rA   )r   r   r   Z	id_piecesZprovided_id_signatureZexpected_id_signaturer   r   r   r
      s    	 r
   zTuple[Any, bool]c                  C  sl   dd l } z|  }d}||fW S  tk
rf   dd l}|d t d krV|d d}| |f Y S X d S )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NotImplementedErrorwarningswarnr	   r   )rB   Z	sysrandomusing_sysrandomrE   r   r   r   _get_sysrandom   s    


rH   zUnion[str, bytes, None])r   r   c                 C  s*   | d krd S t | tr| S t| dS d S Nr    )
isinstancebytescodecsr,   )r   r   r   r   r1      s
    
r1   None)rG   r   r   c                 C  sB   t |}| s>t  t  |d}tt|  d S rI   )	r1   rB   getstatetimer,   seedhashlibsha256digest)rG   r   datar   r   r   _reseed_if_needed	  s    rU   zUnion[bytes, str])r9   r   c                 C  s(   t | }tt|d}t|dS )Nascii=)r1   rL   decodebase64urlsafe_b64encoder   rstrip)r9   Zdecoded_as_bytesencodedr   r   r   r/     s    r/   rK   )r\   r   c                 C  s\   t | trt| dn| }t|d }|dkr>|dd|   }t|d dksRtt|S )NrV      r      =)rJ   r   rL   r,   r?   AssertionErrorrY   urlsafe_b64decode)r\   Zencoded_as_bytesmodr   r   r   r7   !  s    r7   )base_idr   r   c                 C  s<   t |}t| d}|d k	s tt||tj}t|	 S rI   )
r1   rL   r,   r_   r@   newrQ   rR   r/   rS   )rb   r   Zbase_id_encodedZsignerr   r   r   r   +  s
    r   ,   Z>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)lengthallowed_charsr   r   c                   s.   t |}tt| d fd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  s   | ]}t  V  qd S )N)rB   choice).0_rf   r   r   	<genexpr>>  s     z%_get_random_string.<locals>.<genexpr>)r1   rU   rG   r   range)re   rf   r   r   rk   r   r   2  s    

r   )/__doc__
__future__r   logging	getLogger__name__logrY   r#   rL   r&   r%   rQ   r@   r*   rO   r-   typingr   r   r   r   Z
core.typesr   r	   __all__r0   r   r:   r   Zsecret_key_bytesZsign_sessionsr   r   r   r   r   r
   rH   r1   rU   r/   r7   r   r   rB   rG   r   r   r   r   <module>   s\   

)+	
