σ
mάJ]c           @` sL  d  Z  d d l m Z m Z m Z 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 m Z d d l m Z d d l m Z d Z d
   Z e j   e j   d  Z e j   e j   d  Z d   Z d   Z d   Z d   Z d   Z d d e j   d  Z  e   \ Z! Z" d S(   uρ    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.

i    (   t   absolute_importt   divisiont   print_functiont   unicode_literalsN(   t   binary_type(   t   settings(   t   encode_utf8u   check_session_id_signatureu   generate_secret_keyu   generate_session_idc           C` s   t    S(   u¬   
    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.
    (   t   _get_random_string(    (    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   generate_secret_key7   s    c         C` sG   t  |   }  | r6 t d |   } | d t | |   St d |   Sd S(   uΰ  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)

    t
   secret_keyu   -N(   t   _ensure_bytesR   t
   _signature(   R	   t   signedt   base_id(    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   generate_session_id?   s
    c         C` s   t  |  } | ry |  j d d  } t |  d k r: t S| d } | d } t | |  } t j t |  t |   St Sd S(   u-  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)

    u   -i   i   i    N(	   R
   t   splitt   lent   FalseR   t   hmact   compare_digestR   t   True(   t
   session_idR	   R   t   piecesR   t   provided_signaturet   expected_signature(    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   check_session_id_signature]   s    

c          C` s   d d  l  }  y |  j   }  t } WnR t k
 rv d d  l } | j d  t j   d  k rm | j d  n  t	 } n X|  | f S(   Ni    uj   A secure pseudo-random number generator is not available on your system. Falling back to Mersenne Twister.u‘   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.(
   t   randomt   SystemRandomR   t   NotImplementedErrort   warningst   warnR   R	   t   NoneR   (   R   t   using_sysrandomR   (    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   _get_sysrandom   s    

c         C` s7   |  d  k r d  St |  t  r# |  St j |  d  Sd  S(   Nu   utf-8(   R   t
   isinstanceR   t   codecst   encode(   R	   (    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyR
      s
    c         C` sW   t  |  } |  sS t j t j d t j   t j   | f j d   j    n  d  S(   Nu   %s%s%su   utf-8(	   R
   R   t   seedt   hashlibt   sha256t   getstatet   timeR$   t   digest(   R    R	   (    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   _reseed_if_needed‘   s    		c         C` s:   t  |   } t j t j |  d  } t | j d   S(   Nu   asciiu   =(   R
   R#   t   decodet   base64t   urlsafe_b64encodet   strt   rstrip(   t   decodedt   decoded_as_bytest   encoded(    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   _base64_encode²   s    c         C` sF   t  |  } t j |  d  }  t j | |  t j  } t | j    S(   Nu   utf-8(	   R
   R#   R$   R   t   newR&   R'   R4   R*   (   R   R	   t   signer(    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyR   Ί   s    i,   u>   abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789c         ` s<   t  |  } t t |  d j   f d   t |   D  S(   uΧ   
    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
    u    c         3` s   |  ] } t  j    Vq d  S(   N(   R   t   choice(   t   .0t   i(   t   allowed_chars(    s4   lib/python2.7/site-packages/bokeh/util/session_id.pys	   <genexpr>Μ   s    (   R
   R+   R    t   joint   range(   t   lengthR:   R	   (    (   R:   s4   lib/python2.7/site-packages/bokeh/util/session_id.pyR   ΐ   s    
(   u   check_session_id_signatureu   generate_secret_keyu   generate_session_id(#   t   __doc__t
   __future__R    R   R   R   t   loggingt	   getLoggert   __name__t   logR-   R#   R&   R   R)   t   sixR   t   bokeh.settingsR   t   bokeh.util.stringR   t   __all__R   t   secret_key_bytest   sign_sessionsR   R   R!   R
   R+   R4   R   R   R   R    (    (    (    s4   lib/python2.7/site-packages/bokeh/util/session_id.pyt   <module>   s6   "  		%						