ó
ø¢TQc           @  s  d  d l  m 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 d  d l m Z d  d l m Z m Z d  d	 l m Z d  d
 l m Z m Z m Z d  d l m Z d Z d a d a e e	 ƒ d „  ƒ Z d „  Z d d d „ Z  d d d „ Z! d d „ Z" d d „ Z# d „  Z$ d d d „ Z% d e& f d „  ƒ  YZ' d e' f d „  ƒ  YZ( d e( f d „  ƒ  YZ) d e' f d „  ƒ  YZ* d  e' f d! „  ƒ  YZ+ d" e' f d# „  ƒ  YZ, d$ e' f d% „  ƒ  YZ- d& e' f d' „  ƒ  YZ. d( e' f d) „  ƒ  YZ/ d S(*   iÿÿÿÿ(   t   unicode_literalsN(   t   receiver(   t   settings(   t   setting_changed(   t	   importlib(   t
   SortedDict(   t   force_bytest	   force_str(   t   ImproperlyConfigured(   t   pbkdf2t   constant_time_comparet   get_random_string(   t   ugettext_noopu   !c          K  s#   |  d d k r d  a d  a n  d  S(   Nu   settingu   PASSWORD_HASHERS(   t   Nonet   HASHERSt   PREFERRED_HASHER(   t   kwargs(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   reset_hashers   s    c         C  sE   |  d  k s |  t k r t Sy t |  ƒ } Wn t k
 r@ t SXt S(   N(   R   t   UNUSABLE_PASSWORDt   Falset   identify_hashert
   ValueErrort   True(   t   encodedt   hasher(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   is_password_usable   s    u   defaultc         C  sw   |  s t  | ƒ r t St | ƒ } t | ƒ } | j | j k } | j |  | ƒ } | rs | rs | rs | |  ƒ n  | S(   u½   
    Returns a boolean of whether the raw password matches the three
    part encoded digest.

    If setter is specified, it'll be called when you need to
    regenerate the password.
    (   R   R   t
   get_hasherR   t	   algorithmt   verify(   t   passwordR   t   settert	   preferredR   t   must_updatet
   is_correct(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   check_password(   s    c         C  s;   |  s
 t  St | ƒ } | s+ | j ƒ  } n  | j |  | ƒ S(   uâ   
    Turn a plain-text password into a hash for database storage

    Same as encode() but generates a new random salt.  If
    password is None or blank then UNUSABLE_PASSWORD will be
    returned which disallows logins.
    (   R   R   t   saltt   encode(   R   R#   R   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   make_password=   s    c         C  sþ   g  } |  s t  j }  n  x­ |  D]¥ } y: | j d d ƒ \ } } t j | ƒ } t | | ƒ } Wn* t t t f k
 r‹ t	 d | ƒ ‚ n X| ƒ  } t | d ƒ s· t	 d | ƒ ‚ n  | j
 | ƒ q Wt g  | D] } | j | f ^ qÒ ƒ a | d a d  S(   Nu   .i   u   hasher not found: %su	   algorithmu,   hasher doesn't specify an algorithm name: %si    (   R   t   PASSWORD_HASHERSt   rsplitR   t   import_modulet   getattrt   AttributeErrort   ImportErrorR   R   t   appendt   dictR   R   R   (   t   password_hasherst   hasherst   backendt   mod_patht   cls_namet   modt
   hasher_clsR   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   load_hashersP   s"    	(c         C  sz   t  |  d ƒ r |  S|  d k r9 t d k r5 t ƒ  n  t St d k rO t ƒ  n  |  t k rn t d |  ƒ ‚ n  t |  Sd S(   uÞ   
    Returns an instance of a loaded password hasher.

    If algorithm is 'default', the default hasher will be returned.
    This function will also lazy import hashers specified in your
    settings file if needed.
    u	   algorithmu   defaultu\   Unknown password hashing algorithm '%s'. Did you specify it in the PASSWORD_HASHERS setting?N(   t   hasattrR   R   R5   R   R   (   R   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   f   s    

c         C  s’   t  |  ƒ d k r d |  k s? t  |  ƒ d k rH |  j d ƒ rH d } n@ t  |  ƒ d k rr |  j d ƒ rr d } n |  j d d	 ƒ d
 } t | ƒ S(   uø   
    Returns an instance of a loaded password hasher.

    Identifies hasher algorithm by examining encoded hash, and calls
    get_hasher() to return hasher. Raises ValueError if
    algorithm cannot be identified, or if hasher is not loaded.
    i    u   $i%   u   md5$$u   unsalted_md5i.   u   sha1$$u   unsalted_sha1i   i    (   t   lent
   startswitht   splitR   (   R   R   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR      s    
!	!	i   u   *c         C  s&   |  |  } | | t  |  | ƒ 7} | S(   uˆ   
    Returns the given hash, with only the first ``show`` number shown. The
    rest are masked with ``char`` for security reasons.
    (   R7   (   t   hasht   showt   chart   masked(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt	   mask_hash”   s    
t   BasePasswordHasherc           B  sG   e  Z d  Z d Z d Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 RS(   uÌ   
    Abstract base class for password hashers

    When creating your own hasher, you need to override algorithm,
    verify(), encode() and safe_summary().

    PasswordHasher objects are immutable.
    c         C  s˜   |  j  d  k	 r t |  j  t t f ƒ r9 |  j  \ } } n |  j  } } y t j | ƒ } Wn! t k
 r| t d | ƒ ‚ n X| St d |  j	 ƒ ‚ d  S(   Nu+   Couldn't load %s password algorithm libraryu/   Hasher '%s' doesn't specify a library attribute(
   t   libraryR   t
   isinstancet   tuplet   listR   R(   R+   R   t	   __class__(   t   selft   nameR1   t   module(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   _load_libraryª   s    c         C  s   t  ƒ  S(   uJ   
        Generates a cryptographically secure nonce salt in ascii
        (   R   (   RE   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR#   ¹   s    c         C  s   t  ƒ  ‚ d S(   u9   
        Checks if the given password is correct
        N(   t   NotImplementedError(   RE   R   R   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   ¿   s    c         C  s   t  ƒ  ‚ d S(   u¥   
        Creates an encoded database value

        The result is normally formatted as "algorithm$salt$hash" and
        must be fewer than 128 characters.
        N(   RI   (   RE   R   R#   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   Å   s    c         C  s   t  ƒ  ‚ d S(   uÎ   
        Returns a summary of safe values

        The result is a dictionary and will be used where the password field
        must be displayed to construct a safe representation of the password.
        N(   RI   (   RE   R   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   safe_summaryÎ   s    N(   t   __name__t
   __module__t   __doc__R   R   R@   RH   R#   R   R$   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR?   ž   s   					t   PBKDF2PasswordHasherc           B  sA   e  Z d  Z d Z d Z e j Z d d „ Z	 d „  Z
 d „  Z RS(   u  
    Secure password hashing using the PBKDF2 algorithm (recommended)

    Configured to use PBKDF2 + HMAC + SHA256 with 10000 iterations.
    The result is a 64 byte binary string.  Iterations may be changed
    safely but you must rename the algorithm if you change SHA256.
    u   pbkdf2_sha256i'  c         C  s†   | s t  ‚ | r d | k s$ t  ‚ | s6 |  j } n  t | | | d |  j ƒ} t j | ƒ j d ƒ j ƒ  } d |  j | | | f S(   Nu   $t   digestu   asciiu   %s$%d$%s$%s(	   t   AssertionErrort
   iterationsR	   RO   t   base64t	   b64encodet   decodet   stripR   (   RE   R   R#   RQ   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   ä   s    c         C  s[   | j  d d ƒ \ } } } } | |  j k s3 t ‚ |  j | | t | ƒ ƒ } t | | ƒ S(   Nu   $i   (   R9   R   RP   R$   t   intR
   (   RE   R   R   R   RQ   R#   R:   t	   encoded_2(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   í   s    c         C  s…   | j  d d ƒ \ } } } } | |  j k s3 t ‚ t t d ƒ | f t d ƒ | f t d ƒ t | ƒ f t d ƒ t | ƒ f g ƒ S(   Nu   $i   u	   algorithmu
   iterationsu   saltu   hash(   R9   R   RP   R   t   _R>   (   RE   R   R   RQ   R#   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   ó   s    N(   RK   RL   RM   R   RQ   t   hashlibt   sha256RO   R   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRN   Ø   s   			t   PBKDF2SHA1PasswordHasherc           B  s   e  Z d  Z d Z e j Z RS(   uË   
    Alternate PBKDF2 hasher which uses SHA1, the default PRF
    recommended by PKCS #5. This is compatible with other
    implementations of PBKDF2, such as openssl's
    PKCS5_PBKDF2_HMAC_SHA1().
    u   pbkdf2_sha1(   RK   RL   RM   R   RY   t   sha1RO   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR[   þ   s   t   BCryptPasswordHasherc           B  sD   e  Z d  Z d Z d Z d Z d „  Z d „  Z d „  Z d „  Z	 RS(	   u)  
    Secure password hashing using the bcrypt algorithm (recommended)

    This is considered by many to be the most secure algorithm but you
    must first install the py-bcrypt library.  Please be warned that
    this library depends on native C code and might cause portability
    issues.
    u   bcryptu	   py-bcrypti   c         C  s   |  j  ƒ  } | j |  j ƒ S(   N(   RH   t   gensaltt   rounds(   RE   t   bcrypt(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR#     s    c         C  s5   |  j  ƒ  } | j t | ƒ | ƒ } d |  j | f S(   Nu   %s$%s(   RH   t   hashpwR   R   (   RE   R   R#   R`   t   data(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$     s    c         C  sX   | j  d d ƒ \ } } | |  j k s- t ‚ |  j ƒ  } t | | j t | ƒ | ƒ ƒ S(   Nu   $i   (   R9   R   RP   RH   R
   Ra   R   (   RE   R   R   R   Rb   R`   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   !  s    c   	      C  s   | j  d d ƒ \ } } } } } | |  j k s6 t ‚ | d  | d } } t t d ƒ | f t d ƒ | f t d ƒ t | ƒ f t d ƒ t | ƒ f g ƒ S(   Nu   $i   i   u	   algorithmu   work factoru   saltu   checksum(   R9   R   RP   R   RX   R>   (	   RE   R   R   t   emptyt   algostrt   work_factorRb   R#   t   checksum(    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   '  s    !(   u	   py-bcryptu   bcrypt(
   RK   RL   RM   R   R@   R_   R#   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR]   	  s   			t   SHA1PasswordHasherc           B  s/   e  Z d  Z d Z d „  Z d „  Z d „  Z RS(   u?   
    The SHA1 password hashing algorithm (not recommended)
    u   sha1c         C  sW   | s t  ‚ | r d | k s$ t  ‚ t j t | | ƒ ƒ j ƒ  } d |  j | | f S(   Nu   $u   %s$%s$%s(   RP   RY   R\   R   t	   hexdigestR   (   RE   R   R#   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   9  s    c         C  sO   | j  d d ƒ \ } } } | |  j k s0 t ‚ |  j | | ƒ } t | | ƒ S(   Nu   $i   (   R9   R   RP   R$   R
   (   RE   R   R   R   R#   R:   RW   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   ?  s    c         C  sy   | j  d d ƒ \ } } } | |  j k s0 t ‚ t t d ƒ | f t d ƒ t | d d ƒf t d ƒ t | ƒ f g ƒ S(   Nu   $i   u	   algorithmu   saltR;   u   hash(   R9   R   RP   R   RX   R>   (   RE   R   R   R#   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   E  s    (   RK   RL   RM   R   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRg   3  s
   		t   MD5PasswordHasherc           B  s/   e  Z d  Z d Z d „  Z d „  Z d „  Z RS(   uE   
    The Salted MD5 password hashing algorithm (not recommended)
    u   md5c         C  sW   | s t  ‚ | r d | k s$ t  ‚ t j t | | ƒ ƒ j ƒ  } d |  j | | f S(   Nu   $u   %s$%s$%s(   RP   RY   t   md5R   Rh   R   (   RE   R   R#   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   U  s    c         C  sO   | j  d d ƒ \ } } } | |  j k s0 t ‚ |  j | | ƒ } t | | ƒ S(   Nu   $i   (   R9   R   RP   R$   R
   (   RE   R   R   R   R#   R:   RW   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   [  s    c         C  sy   | j  d d ƒ \ } } } | |  j k s0 t ‚ t t d ƒ | f t d ƒ t | d d ƒf t d ƒ t | ƒ f g ƒ S(   Nu   $i   u	   algorithmu   saltR;   u   hash(   R9   R   RP   R   RX   R>   (   RE   R   R   R#   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   a  s    (   RK   RL   RM   R   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRi   O  s
   		t   UnsaltedSHA1PasswordHasherc           B  s8   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z RS(   u8  
    Very insecure algorithm that you should *never* use; stores SHA1 hashes
    with an empty salt.

    This class is implemented because Django used to accept such password
    hashes. Some older Django installs still have these values lingering
    around so we need to handle and upgrade them properly.
    u   unsalted_sha1c         C  s   d S(   Nu    (    (   RE   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR#   v  s    c         C  s5   | d k s t  ‚ t j t | ƒ ƒ j ƒ  } d | S(   Nu    u   sha1$$%s(   RP   RY   R\   R   Rh   (   RE   R   R#   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   y  s    c         C  s   |  j  | d ƒ } t | | ƒ S(   Nu    (   R$   R
   (   RE   R   R   RW   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   ~  s    c         C  sP   | j  d ƒ s t ‚ | d } t t d ƒ |  j f t d ƒ t | ƒ f g ƒ S(   Nu   sha1$$i   u	   algorithmu   hash(   R8   RP   R   RX   R   R>   (   RE   R   R:   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   ‚  s
    
(   RK   RL   RM   R   R#   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRk   k  s   			t   UnsaltedMD5PasswordHasherc           B  s8   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z RS(   u¤  
    Incredibly insecure algorithm that you should *never* use; stores unsalted
    MD5 hashes without the algorithm prefix, also accepts MD5 hashes with an
    empty salt.

    This class is implemented because Django used to store passwords this way
    and to accept such password hashes. Some older Django installs still have
    these values lingering around so we need to handle and upgrade them
    properly.
    u   unsalted_md5c         C  s   d S(   Nu    (    (   RE   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR#   ˜  s    c         C  s+   | d k s t  ‚ t j t | ƒ ƒ j ƒ  S(   Nu    (   RP   RY   Rj   R   Rh   (   RE   R   R#   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   ›  s    c         C  sM   t  | ƒ d k r. | j d ƒ r. | d } n  |  j | d ƒ } t | | ƒ S(   Ni%   u   md5$$i   u    (   R7   R8   R$   R
   (   RE   R   R   RW   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   Ÿ  s    !c         C  s7   t  t d ƒ |  j f t d ƒ t | d d ƒf g ƒ S(   Nu	   algorithmu   hashR;   i   (   R   RX   R   R>   (   RE   R   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   ¥  s    (   RK   RL   RM   R   R#   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRl   ‹  s   
			t   CryptPasswordHasherc           B  s>   e  Z d  Z d Z d Z d „  Z d „  Z d „  Z d „  Z RS(   uv   
    Password hashing using UNIX crypt (not recommended)

    The crypt module is not supported on all platforms.
    u   cryptc         C  s
   t  d ƒ S(   Ni   (   R   (   RE   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR#   µ  s    c         C  sP   |  j  ƒ  } t | ƒ d k s$ t ‚ | j t | ƒ | ƒ } d |  j d | f S(   Ni   u   %s$%s$%su    (   RH   R7   RP   t   cryptR   R   (   RE   R   R#   Rn   Rb   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR$   ¸  s    c         C  s[   |  j  ƒ  } | j d d ƒ \ } } } | |  j k s< t ‚ t | | j t | ƒ | ƒ ƒ S(   Nu   $i   (   RH   R9   R   RP   R
   Rn   R   (   RE   R   R   Rn   R   R#   Rb   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyR   ¿  s    c         C  ss   | j  d d ƒ \ } } } | |  j k s0 t ‚ t t d ƒ | f t d ƒ | f t d ƒ t | d d ƒf g ƒ S(   Nu   $i   u	   algorithmu   saltu   hashR;   i   (   R9   R   RP   R   RX   R>   (   RE   R   R   R#   Rb   (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRJ   Å  s    (	   RK   RL   RM   R   R@   R#   R$   R   RJ   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyRm   ¬  s   			(0   t
   __future__R    RR   RY   t   django.dispatchR   t   django.confR   t   django.test.signalsR   t   django.utilsR   t   django.utils.datastructuresR   t   django.utils.encodingR   R   t   django.core.exceptionsR   t   django.utils.cryptoR	   R
   R   t   django.utils.translationR   RX   R   R   R   R   R   R   R"   R%   R5   R   R   R>   t   objectR?   RN   R[   R]   Rg   Ri   Rk   Rl   Rm   (    (    (    s4   ../Django//lib/python/django/contrib/auth/hashers.pyt   <module>   s>   	
	
:&* !