ó
ø¢TQc           @  s{  d  Z  d d l m 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 d l m Z m Z d d l m Z m Z m Z d d	 l m Z d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z d „  Z d „  Z d d „ Z d e f d „  ƒ  YZ d d e e  d „ Z! d d e d d „ Z" d e f d „  ƒ  YZ# d e# f d „  ƒ  YZ$ d S(   u`  
Functions for creating and restoring url-safe signed JSON objects.

The format used looks like this:

>>> signing.dumps("hello")
'ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk'

There are two components here, separated by a ':'. The first component is a
URLsafe base64 encoded JSON of the object passed to dumps(). The second
component is a base64 encoded hmac/SHA1 hash of "$first_component:$secret"

signing.loads(s) checks the signature and returns the deserialised object.
If the signature fails, a BadSignature exception is raised.

>>> signing.loads("ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk")
u'hello'
>>> signing.loads("ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk-modified")
...
BadSignature: Signature failed: ImhlbGxvIg:1QaUZC:YIye-ze3TTx7gtSv422nZA4sgmk-modified

You can optionally compress the JSON prior to base64 encoding it to save
space, using the compress=True argument. This checks if compression actually
helps and only applies compression if the result is a shorter string:

>>> signing.dumps(range(1, 20), compress=True)
'.eJwFwcERACAIwLCF-rCiILN47r-GyZVJsNgkxaFxoDgxcOHGxMKD_T7vhAml:1QaUaL:BA0thEZrp4FQVXIXuOvYJtLJSrQ'

The fact that the string is compressed is signalled by the prefixed '.' at the
start of the base64 JSON.

There are 65 url-safe characters: the 64 used by url-safe base64 and the ':'.
These functions make use of all of them.
iÿÿÿÿ(   t   unicode_literalsN(   t   settings(   t   ImproperlyConfigured(   t   baseconv(   t   constant_time_comparet   salted_hmac(   t   force_bytest	   force_strt
   force_text(   t   import_modulet   BadSignaturec           B  s   e  Z d  Z RS(   u"   
    Signature does not match
    (   t   __name__t
   __module__t   __doc__(    (    (    s,   ../Django//lib/python/django/core/signing.pyR
   3   s   t   SignatureExpiredc           B  s   e  Z d  Z RS(   u<   
    Signature timestamp is older than required max_age
    (   R   R   R   (    (    (    s,   ../Django//lib/python/django/core/signing.pyR   :   s   c         C  s   t  j |  ƒ j d ƒ S(   Nt   =(   t   base64t   urlsafe_b64encodet   strip(   t   s(    (    s,   ../Django//lib/python/django/core/signing.pyt
   b64_encodeA   s    c         C  s&   d t  |  ƒ d } t j |  | ƒ S(   NR   i   (   t   lenR   t   urlsafe_b64decode(   R   t   pad(    (    s,   ../Django//lib/python/django/core/signing.pyt
   b64_decodeE   s    c         C  s   t  t |  | | ƒ j ƒ  ƒ S(   N(   R   R   t   digest(   t   saltt   valuet   key(    (    s,   ../Django//lib/python/django/core/signing.pyt   base64_hmacJ   s    u%   django.core.signing.get_cookie_signerc         C  s³   t  j } | j d d ƒ \ } } y t | ƒ } Wn) t k
 r\ } t d | | f ƒ ‚ n Xy t | | ƒ } Wn) t k
 r› } t d | | f ƒ ‚ n X| d t  j d |  ƒS(   Nu   .i   u&   Error importing cookie signer %s: "%s"u   django.http.cookiesR   (	   R   t   SIGNING_BACKENDt   rsplitR	   t   ImportErrorR   t   getattrt   AttributeErrort
   SECRET_KEY(   R   t   modpatht   modulet   attrt   modt   et   Signer(    (    s,   ../Django//lib/python/django/core/signing.pyt   get_cookie_signerN   s    	t   JSONSerializerc           B  s    e  Z d  Z d „  Z d „  Z RS(   uW   
    Simple wrapper around json to be used in signing.dumps and
    signing.loads.
    c         C  s   t  j | d d ƒj d ƒ S(   Nt
   separatorsu   ,u   :u   latin-1(   u   ,u   :(   t   jsont   dumpst   encode(   t   selft   obj(    (    s,   ../Django//lib/python/django/core/signing.pyR.   c   s    c         C  s   t  j | j d ƒ ƒ S(   Nu   latin-1(   R-   t   loadst   decode(   R0   t   data(    (    s,   ../Django//lib/python/django/core/signing.pyR2   f   s    (   R   R   R   R.   R2   (    (    (    s,   ../Django//lib/python/django/core/signing.pyR+   ^   s   	u   django.core.signingc   	      C  s“   | ƒ  j  |  ƒ } t } | r[ t j | ƒ } t | ƒ t | ƒ d k  r[ | } t } q[ n  t | ƒ } | rz d | } n  t | d | ƒj | ƒ S(   u‹  
    Returns URL-safe, sha1 signed base64 compressed JSON string. If key is
    None, settings.SECRET_KEY is used instead.

    If compress is True (not the default) checks if compressing using zlib can
    save some space. Prepends a '.' to signify compression. This is included
    in the signature, to protect against zip bombs.

    Salt can be used to namespace the hash, so that a signed string is
    only valid for a given namespace. Leaving this at the default
    value or re-using a salt value across different parts of your
    application without good cause is a security risk.

    The serializer is expected to return a bytestring.
    i   t   .R   (	   R.   t   Falset   zlibt   compressR   t   TrueR   t   TimestampSignert   sign(	   R1   R   R   t
   serializerR8   R4   t   is_compressedt
   compressedt   base64d(    (    s,   ../Django//lib/python/django/core/signing.pyR.   j   s    c         C  s„   t  t | d | ƒj |  d | ƒƒ } t } | d  d k rP | d } t } n  t | ƒ } | rt t j | ƒ } n  | ƒ  j | ƒ S(   u}   
    Reverse of dumps(), raises BadSignature if signature fails.

    The serializer is expected to accept a bytestring.
    R   t   max_agei   R5   (	   R   R:   t   unsignR6   R9   R   R7   t
   decompressR2   (   R   R   R   R<   R@   R?   RB   R4   (    (    s,   ../Django//lib/python/django/core/signing.pyR2   ‹   s    '
	R)   c           B  s5   e  Z d d  d d „ Z d „  Z d „  Z d „  Z RS(   u   :c         C  sV   t  | ƒ |  _ t  | p t j ƒ |  _ t  | pI d |  j j |  j j f ƒ |  _ d  S(   Nu   %s.%s(	   t   strt   sepR   R#   R   t	   __class__R   R   R   (   R0   R   RD   R   (    (    s,   ../Django//lib/python/django/core/signing.pyt   __init__¡   s    	c         C  s&   t  |  j d | |  j ƒ } t | ƒ S(   Nu   signer(   R   R   R   R   (   R0   R   t	   signature(    (    s,   ../Django//lib/python/django/core/signing.pyRG   ¨   s    c         C  s/   t  | ƒ } t d ƒ | |  j |  j | ƒ f S(   Nu   %s%s%s(   R   RC   RD   RG   (   R0   R   (    (    s,   ../Django//lib/python/django/core/signing.pyR;   ­   s    c         C  s‚   t  | ƒ } |  j | k r1 t d |  j ƒ ‚ n  | j |  j d ƒ \ } } t | |  j | ƒ ƒ rn t | ƒ St d | ƒ ‚ d  S(   Nu   No "%s" found in valuei   u   Signature "%s" does not match(   R   RD   R
   R   R   RG   R   (   R0   t   signed_valueR   t   sig(    (    s,   ../Django//lib/python/django/core/signing.pyRA   ±   s    
N(   R   R   t   NoneRF   RG   R;   RA   (    (    (    s,   ../Django//lib/python/django/core/signing.pyR)   Ÿ   s   		R:   c           B  s&   e  Z d  „  Z d „  Z d d „ Z RS(   c         C  s   t  j j t t j ƒ  ƒ ƒ S(   N(   R   t   base62R/   t   intt   time(   R0   (    (    s,   ../Django//lib/python/django/core/signing.pyt	   timestamp½   s    c         C  sD   t  | ƒ } t d ƒ | |  j |  j ƒ  f } t t |  ƒ j | ƒ S(   Nu   %s%s%s(   R   RC   RD   RN   t   superR:   R;   (   R0   R   (    (    s,   ../Django//lib/python/django/core/signing.pyR;   À   s    "c         C  s   t  t |  ƒ j | ƒ } | j |  j d ƒ \ } } t j j | ƒ } | d  k	 r‰ t	 j	 ƒ  | } | | k r‰ t
 d | | f ƒ ‚ q‰ n  | S(   Ni   u   Signature age %s > %s seconds(   RO   R:   RA   R   RD   R   RK   R3   RJ   RM   R   (   R0   R   R@   t   resultRN   t   age(    (    s,   ../Django//lib/python/django/core/signing.pyRA   Å   s    N(   R   R   RN   R;   RJ   RA   (    (    (    s,   ../Django//lib/python/django/core/signing.pyR:   »   s   		(%   R   t
   __future__R    R   R-   RM   R7   t   django.confR   t   django.core.exceptionsR   t   django.utilsR   t   django.utils.cryptoR   R   t   django.utils.encodingR   R   R   t   django.utils.importlibR	   t	   ExceptionR
   R   R   R   R   R*   t   objectR+   RJ   R6   R.   R2   R)   R:   (    (    (    s,   ../Django//lib/python/django/core/signing.pyt   <module>"   s,   			!