B
    ‹æ@\Q!  ã               @   sü   d Z ddlmZmZmZ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mZ ddlmZ ddlmZ dZdd	„ Ze ¡ e ¡ fd
d„Ze ¡ e ¡ fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdde ¡ fdd„Z eƒ \Z!Z"dS )zñ 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.

é    )Úabsolute_importÚdivisionÚprint_functionÚunicode_literalsN)Úbinary_type)Úsettings)Úencode_utf8)Úcheck_session_id_signatureÚgenerate_secret_keyÚgenerate_session_idc               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   ú4lib/python3.7/site-packages/bokeh/util/session_id.pyr
   7   s    r
   c             C   s6   t | ƒ} |r(t| d}|d t|| ƒ S t| dS d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.

    If session IDs are signed with a secret key, the server can
    verify that the generator of the session ID was "authorized"
    (the generator had to know the secret key). This can be used
    to have a separate process, such as another web application,
    which generates new sessions on a Bokeh server. This other
    process may require users to log in before redirecting them to
    the Bokeh server with a valid session ID, for example.

    Args:
        secret_key (str, optional) : Secret key (default: value of 'BOKEH_SECRET_KEY' env var)
        signed (bool, optional) : Whether to sign the session ID (default: value of
                                  'BOKEH_SIGN_SESSIONS' env var)

    )Ú
secret_keyú-N)Ú_ensure_bytesr   Ú
_signature)r   ÚsignedÚbase_idr   r   r   r   ?   s
    
r   c             C   s^   t |ƒ}|rV|  dd¡}t|ƒdkr(dS |d }|d }t||ƒ}t t|ƒt|ƒ¡S dS dS )a-  Check 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.

    Args:
        session_id (str) : The session ID to check
        secret_key (str, optional) : Secret key (default: value of 'BOKEH_SECRET_KEY' env var)
        signed (bool, optional) : Whether to check anything (default: value of
                                  'BOKEH_SIGN_SESSIONS' env var)

    r   é   é   Fr   TN)r   ÚsplitÚlenr   ÚhmacZcompare_digestr   )Z
session_idr   r   Úpiecesr   Zprovided_signatureZexpected_signaturer   r   r   r	   ]   s    
r	   c              C   sb   dd l } y|  ¡ } d}W n@ tk
rX   dd l}| d¡ t ¡ d krP| d¡ d}Y nX | |fS )Nr   TzjA secure pseudo-random number generator is not available on your system. Falling back to Mersenne Twister.z¡A 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)ÚrandomZSystemRandomÚNotImplementedErrorÚwarningsÚwarnr   r   )r   Úusing_sysrandomr   r   r   r   Ú_get_sysrandomƒ   s    


r    c             C   s*   | d krd S t | tƒr| S t | d¡S d S )Nzutf-8)Ú
isinstancer   ÚcodecsÚencode)r   r   r   r   r   ˜   s
    
r   c             C   s<   t |ƒ}| s8t t dt ¡ t ¡ |f  d¡¡ ¡ ¡ d S )Nz%s%s%szutf-8)	r   r   ZseedÚhashlibÚsha256ÚgetstateÚtimer#   Údigest)r   r   r   r   r   Ú_reseed_if_needed¡   s    r)   c             C   s(   t | ƒ}t t |¡d¡}t| d¡ƒS )NÚasciiú=)r   r"   ÚdecodeÚbase64Zurlsafe_b64encodeÚstrÚrstrip)ZdecodedZdecoded_as_bytesZencodedr   r   r   Ú_base64_encode²   s    r0   c             C   s0   t |ƒ}t | d¡} t || tj¡}t| ¡ ƒS )Nzutf-8)	r   r"   r#   r   Únewr$   r%   r0   r(   )r   r   Zsignerr   r   r   r   º   s    r   é,   Z>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789c                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)r   Zchoice)Ú.0Úi)Úallowed_charsr   r   ú	<genexpr>Ì   s    z%_get_random_string.<locals>.<genexpr>)r   r)   r   ÚjoinÚrange)Úlengthr6   r   r   )r6   r   r   À   s    

r   )#Ú__doc__Z
__future__r   r   r   r   ZloggingZ	getLoggerÚ__name__Úlogr-   r"   r$   r   r'   Zsixr   Zbokeh.settingsr   Zbokeh.util.stringr   Ú__all__r
   Zsecret_key_bytesZsign_sessionsr   r	   r    r   r)   r0   r   r   r   r   r   r   r   r   Ú<module>   s2   
	%	