ó
ÌŸ!^c           @  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 Z d d l 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 e j d	 ƒ 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 deserialized 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   baseconv(   t   constant_time_comparet   salted_hmac(   t   force_bytest	   force_strt
   force_text(   t   import_stringu   ^[A-z0-9-_=]*$t   BadSignaturec           B  s   e  Z d  Z RS(   u"   
    Signature does not match
    (   t   __name__t
   __module__t   __doc__(    (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR	   6   s   t   SignatureExpiredc           B  s   e  Z d  Z RS(   u<   
    Signature timestamp is older than required max_age
    (   R
   R   R   (    (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR   =   s   c         C  s   t  j |  ƒ j d ƒ S(   Nt   =(   t   base64t   urlsafe_b64encodet   strip(   t   s(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt
   b64_encodeD   s    c         C  s&   d t  |  ƒ d } t j |  | ƒ S(   NR   i   (   t   lenR   t   urlsafe_b64decode(   R   t   pad(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt
   b64_decodeH   s    c         C  s   t  t |  | | ƒ j ƒ  ƒ S(   N(   R   R   t   digest(   t   saltt   valuet   key(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt   base64_hmacM   s    u%   django.core.signing.get_cookie_signerc         C  s2   t  t j ƒ } t t j ƒ } | d | d |  ƒS(   Ns   django.http.cookiesR   (   R   R   t   SIGNING_BACKENDR   t
   SECRET_KEY(   R   t   SignerR   (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt   get_cookie_signerQ   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=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR$   \   s    c         C  s   t  j | j d ƒ ƒ S(   Nu   latin-1(   R#   t   loadst   decode(   R&   t   data(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR(   _   s    (   R
   R   R   R$   R(   (    (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR!   W   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(	   R'   R   R   t
   serializerR.   R*   t   is_compressedt
   compressedt   base64d(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR$   c   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   R+   (	   R   R0   t   unsignR,   R/   R   R-   t
   decompressR(   (   R   R   R   R2   R6   R5   R8   R*   (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR(   „   s    '
	R   c           B  s5   e  Z d d  d d „ Z d „  Z d „  Z d „  Z RS(   u   :c         C  su   | p t  j |  _ t | ƒ |  _ t j |  j ƒ rF t d | ƒ ‚ n  t | ph d |  j j	 |  j j
 f ƒ |  _ d  S(   NuJ   Unsafe Signer separator: %r (cannot be empty or consist of only A-z0-9-_=)u   %s.%s(   R   R   R   R   t   sept   _SEP_UNSAFEt   matcht
   ValueErrort	   __class__R   R
   R   (   R&   R   R9   R   (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt   __init__š   s    c         C  s&   t  |  j d | |  j ƒ } t | ƒ S(   Nu   signer(   R   R   R   R   (   R&   R   t	   signature(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR?   ¥   s    c         C  s/   t  | ƒ } t d ƒ | |  j |  j | ƒ f S(   Nu   %s%s%s(   R   t   strR9   R?   (   R&   R   (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR1   ª   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   R9   R	   t   rsplitR   R?   R   (   R&   t   signed_valueR   t   sig(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR7   ®   s    
N(   R
   R   t   NoneR>   R?   R1   R7   (    (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR   ˜   s   		R0   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(   R&   (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt	   timestampº   s    c         C  sD   t  | ƒ } t d ƒ | |  j |  j ƒ  f } t t |  ƒ j | ƒ S(   Nu   %s%s%s(   R   R@   R9   RH   t   superR0   R1   (   R&   R   (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR1   ½   s    "c         C  s®   t  t |  ƒ j | ƒ } | j |  j d ƒ \ } } t j j | ƒ } | d k	 rª t	 | t
 j ƒ rr | j ƒ  } n  t j ƒ  | } | | k rª t d | | f ƒ ‚ qª n  | S(   uk   
        Retrieve original value and check it wasn't signed more
        than max_age seconds ago.
        i   u   Signature age %s > %s secondsN(   RI   R0   R7   RA   R9   R   RE   R)   RD   t
   isinstancet   datetimet	   timedeltat   total_secondsRG   R   (   R&   R   R6   t   resultRH   t   age(    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR7   Â   s    N(   R
   R   RH   R1   RD   R7   (    (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyR0   ¸   s   		('   R   t
   __future__R    R   RK   R#   t   reRG   R-   t   django.confR   t   django.utilsR   t   django.utils.cryptoR   R   t   django.utils.encodingR   R   R   t   django.utils.module_loadingR   t   compileR:   t	   ExceptionR	   R   R   R   R   R    t   objectR!   RD   R,   R$   R(   R   R0   (    (    (    s=   /var/www/Virtualenvs/nocn/build/Django/django/core/signing.pyt   <module>"   s0   			! 