
Ѯh              =   @   s	  d  Z  d d l m Z d d l m Z m Z m Z d d l m	 Z	 m
 Z
 y$ d d l m Z d d l m Z Wn2 e k
 r d d l m Z d d l m Z Yn Xd d l m Z d d l m Z d d	 l Z d d	 l 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 e rjy d d	 l  Z  Wqve k
 rfd	 Z  d
 Z! YqvXn d d	 l  Z  d d	 l" Z" e  rd d	 l# Z# y d d	 l$ Z$ Wn e k
 rd	 Z$ Yn Xd d	 l% Z% d d	 l& Z& d d l' m( Z( d d l) m* Z* m+ Z+ m, Z, m- Z- m. Z. m/ Z/ m0 Z0 m1 Z1 m2 Z2 m3 Z3 m4 Z4 m5 Z5 m6 Z6 d d l7 m8 Z8 m9 Z9 m: Z: m; Z; m< Z< d d l= m> Z> m? Z? d d l m@ Z@ mA ZA mB ZB mC ZC mD ZD mE ZE mF ZF mG ZG mH ZH mI ZI mJ ZJ mK ZK mL ZL mM ZM mN ZN mO ZO mP ZP d d d d d d d d d d d d d d d d d  d! d" d# d$ d% d& d' d( g ZQ eR e j eF rVe jS n e jT d)  d*  ZU d+ d, d- d. d/ d0 d1 g ZV d2 d3 g ZW d d4 l= mX ZX d5 ZY eG d6  ZZ eG d7  Z[ eR e j\ j] d8  pd9  Z^ Gd: d;   d; e_  Z` eF r.e ja jb Zc ed ec e ja je g  Zf d< d=   Zg n d> d=   Zg d	 d	 d? d	 d	 d? d@ dA  Zh dB dC   Zi dD d   Zj ej Zk y d dE ll mm Zj Wn e k
 rYn XdF dG dH  Zn dI dJ d  Zo e  d	 k rdI dK d  Zo dL d   Zp eF rdM dN   Zq dO dP   Zr n. d dQ l ms Zs mt Zt dR dN   Zq dS dP   Zr e@ eq dT  e@ er dU  dV d   Zu dW dX   Zv dY dZ   Zw d[ Zx eG d\  Zy d	 d] d^  Zz d_ d`   Z{ da Z| e| j} db  Z~ dc dd   Z de d   Z d Z eG dg  Z dh d   Z di dI d	 dj d  Z di dI dk d  Z eF r+di dI dl d  Z n di dI dm d  Z e@ e dn  e8 do dp dq dr  db ds dt   Z ed du j    Z ed dv j    Z ed d6 dw g  Z d	 dx dy dz  Z d{ d|   Z y d d} l m Z Wn< e k
 rd	 Z d? Z d? Z d? Z d	 Z d~ d   Z Yn Xd Z d\ Z e$ raeP rad e j k oGd k n rae$ j   Z d Z n d d l m Z e   Z d? Z eG d  Z eF rd Z y e d d  Wn e k
 rd? Z Yn Yn Xd d   Z n d Z d d   Z e@ e d  d d   Z e% j Z e Z d d   Z y e j d  d Z Wn e k
 rQd? Z Yn Xd	 d d  Z e rve j   Z n e j e    Z d d"   Z d d#   Z d Z e8 do dr dq d d d  d e d d$   Z d Z d d%   Z d Z d d&   Z d d'   Z d d(   Z d	 S)z4passlib.utils -- helpers for writing password hashes    )JYTHON)
b2a_base64
a2b_base64Error)	b64encode	b64decode)Sequence)Iterable)lookup)update_wrapperNznot present under Jython)warn)BASE64_CHARS
AB64_CHARSHASH64_CHARSBCRYPT_CHARSBase64EngineLazyBase64Engineh64h64bigbcrypt64ab64_encodeab64_decodeb64s_encodeb64s_decode)deprecated_functiondeprecated_methodmemoized_propertyclasspropertyhybrid_method)ExpectedStringErrorExpectedTypeError)add_doc
join_bytesjoin_byte_valuesjoin_byte_elemsirangeimapPY3ujoin_unicodeunicodebyte_elem_value
nextgetterunicode_or_strunicode_or_bytes_typesget_method_functionsuppress_causePYPYr   sys_bitsunix_crypt_schemesrounds_cost_valuesconsteqsaslprep	xor_bytesrender_bytesis_same_codecis_ascii_safeto_bytes
to_unicodeto_native_str	has_crypt
test_crypt
safe_crypttickrnggetrandbytes
getrandstrgenerate_passwordis_crypt_handleris_crypt_contexthas_rounds_infohas_salt_info   g      ?Zsha512_cryptZsha256_cryptZ
sha1_cryptZbcryptZ	md5_cryptZ
bsdi_cryptZ	des_cryptZlinearZlog2)MissingBackendError      ZPASSLIB_MAX_PASSWORD_SIZEi   c               @   sj   e  Z d  Z d Z d d   Z d d   Z d d   Z d d	   Z d
 d   Z d d   Z	 d d   Z
 d S)SequenceMixinz
    helper which lets result object act like a fixed-length sequence.
    subclass just needs to provide :meth:`_as_tuple()`.
    c             C   s   t  d   d  S)Nzimplement in subclass)NotImplementedError)self rR   ../../passlib/utils/__init__.py	_as_tuple   s    zSequenceMixin._as_tuplec             C   s   t  |  j    S)N)reprrT   )rQ   rR   rR   rS   __repr__   s    zSequenceMixin.__repr__c             C   s   |  j    | S)N)rT   )rQ   idxrR   rR   rS   __getitem__   s    zSequenceMixin.__getitem__c             C   s   t  |  j    S)N)iterrT   )rQ   rR   rR   rS   __iter__   s    zSequenceMixin.__iter__c             C   s   t  |  j    S)N)lenrT   )rQ   rR   rR   rS   __len__   s    zSequenceMixin.__len__c             C   s   |  j    | k S)N)rT   )rQ   otherrR   rR   rS   __eq__   s    zSequenceMixin.__eq__c             C   s   |  j  |  S)N)r^   )rQ   r]   rR   rR   rS   __ne__   s    zSequenceMixin.__ne__N)__name__
__module____qualname____doc__rT   rV   rX   rZ   r\   r^   r_   rR   rR   rR   rS   rO      s   rO   c             C   se   t  j t |    j } | s" d S| j |  } | rJ | j t k rJ d S| t |  d j t k S)z*test if function accepts specified keywordFT   )	inspectZ	signaturer/   Z
parametersgetZkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyZparamsargrR   rR   rS   accepts_keyword   s    rn   c             C   s1   t  j t |    } | | j k p0 | j d k	 S)z*test if function accepts specified keywordN)rf   Z
getargspecr/   argskeywords)rk   rl   specrR   rR   rS   rn      s    Fc                s  t  | t  r | g } t |  j  } | r t  | t  rE | g } x< | D]4   | rg   | k rg qL   | k rL | j    qL W| rx
| D]  t   f d d   | D  r q | rx t |  D]2 \ } }	 t   |	  r P| r t |	 |  r Pq Wt |  } nr | r}xi t t	 |   D]F \ }
 }	 t |	 |  r*t |  |
 } | | d |	 k sot
  Pq*Wd } n d } | j |    q W| st |  |  _ d S)a  
    helper to update mixin classes installed in target class.

    :param target:
        target class whose bases will be modified.

    :param add:
        class / classes to install into target's base class list.

    :param remove:
        class / classes to remove from target's base class list.

    :param append:
        by default, prepends mixins to front of list.
        if True, appends to end of list instead.

    :param after:
        optionally make sure all mixins are inserted after
        this class / classes.

    :param before:
        optionally make sure all mixins are inserted before
        this class / classes.

    :param dryrun:
        optionally perform all calculations / raise errors,
        but don't actually modify the class.
    c             3   s   |  ] } t  |    Vq d  S)N)
issubclass).0base)mixinrR   rS   	<genexpr>   s    z'update_mixin_classes.<locals>.<genexpr>rd   r   N)
isinstancetyperi   	__bases__removeany	enumeraterr   r[   reversedAssertionErrorinserttuple)targetaddrz   appendZbeforeafterZdryrunbasesrW   rt   Zend_idxrR   )ru   rS   update_mixin_classes   sB    			r   c             c   s   | d k  r t  d   t |  t  rn t |   } d } x | | k  rj | | } |  | |  V| } q< Wn} t |  t  r t |   } x_ t j | |  } y t |  } Wn t	 k
 r PYn Xt j
 | f |  Vq Wn t d   d S)z8
    split iterable into chunks of <size> elements.
    rd   zsize must be positive integerr   zsource must be iterableN)
ValueErrorrw   r   r[   r	   rY   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinZitrZ	chunk_itrfirstrR   rR   rS   batch  s&    
r   c             C   s)  t  |  t  r3 t  | t  s* t d   d } n? t  |  t  rf t  | t  s] t d   t } n t d   t |   t |  k } | r |  } d } | s | } d } | r xh t | |  D] \ } } | | | AO} q Wn: x7 t | |  D]& \ } } | t |  t |  AO} q W| d k S)a  Check two strings/bytes for equality.

    This function uses an approach designed to prevent
    timing analysis, making it appropriate for cryptography.
    a and b must both be of the same type: either str (ASCII only),
    or any type that supports the buffer protocol (e.g. bytes).

    Note: If a and b are of different lengths, or if an error occurs,
    a timing attack could theoretically reveal information about the
    types and lengths of a and b--but not their values.
    z)inputs must be both unicode or both bytesFr   rd   )rw   r*   r   bytesr'   r[   zipord)leftrightZis_py3_bytesZ	same_sizeZtmpresultlrrR   rR   rS   r5   ;  s,    		)compare_digest,c             C   sO   |  j    }  |  j |  r+ |  d d  }  |  s5 g  Sd d   |  j |  D S)zRsplit comma-separated string into list of elements,
    stripping whitespace.
    Nrd   c             S   s   g  |  ] } | j     q SrR   )strip)rs   elemrR   rR   rS   
<listcomp>  s   	 zsplitcomma.<locals>.<listcomp>re   )r   endswithsplit)r   seprR   rR   rS   
splitcomma  s    r   valuec                ss  t  |  t  s( t d t |   f   t j  t j   t    f d d   |  D  } t j	 d |  } | sx t
 St j } | | d  r | | d  s t d |   t j } n | } t j } t j } t j } t j } t j }	 t j }
 t j } t j } t j } xX| D]P}   |  s:t d    |  sSt d	   | |  rot d
 |   | |  rt d |   | |  rt d |   | |  rt d |   |	 |  rt d |   |
 |  rt d |   | |  rt d |   | |  r3t d |   | |  rOt d |   | |  rt d |   qW| S)a  Normalizes unicode strings using SASLPrep stringprep profile.

    The SASLPrep profile is defined in :rfc:`4013`.
    It provides a uniform scheme for normalizing unicode usernames
    and passwords before performing byte-value sensitive operations
    such as hashing. Among other things, it normalizes diacritic
    representations, removes non-printing characters, and forbids
    invalid characters such as ``\n``. Properly internationalized
    applications should run user passwords through this function
    before hashing.

    :arg source:
        unicode string to normalize & validate

    :param param:
        Optional noun identifying source parameter in error messages
        (Defaults to the string ``"value"``). This is mainly useful to make the caller's error
        messages make more sense contextually.

    :raises ValueError:
        if any characters forbidden by the SASLPrep profile are encountered.

    :raises TypeError:
        if input is not :class:`!unicode`

    :returns:
        normalized unicode string

    .. note::

        This function is not available under Jython,
        as the Jython stdlib is missing the :mod:`!stringprep` module
        (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).

    .. versionadded:: 1.6
    z$input must be unicode string, not %sc             3   s3   |  ]) }   |  s  |  r' t  n | Vq d  S)N)_USPACE)rs   c)in_table_b1in_table_c12rR   rS   rv     s   zsaslprep.<locals>.<genexpr>ZNFKCr   rd   zmalformed bidi sequence in z$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez$unassigned code points forbidden in z control characters forbidden in z$private use characters forbidden in z"non-char code points forbidden in zsurrogate codes forbidden in z!non-plaintext chars forbidden in z!non-canonical chars forbidden in z1display-modifying / deprecated chars forbidden inztagged characters forbidden in zforbidden bidi character in re   )rw   r*   r   rx   
stringprepr   r   r)   unicodedataZ	normalize_UEMPTYZin_table_d1r   Zin_table_d2in_table_a1in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9r~   )r   paramdataZis_ral_charZis_forbidden_bidi_charr   r   r   r   r   r   r   r   r   r   rR   )r   r   rS   r6     sf    ,												
c             C   s   t  d t   d S)zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is N)rP   _stringprep_missing_reason)r   r   rR   rR   rS   r6     s    c             G   sH   t  |  t  r |  j d  }  |  t d d   | D  } | j d  S)a  Peform ``%`` formating using bytes in a uniform manner across Python 2/3.

    This function is motivated by the fact that
    :class:`bytes` instances do not support ``%`` or ``{}`` formatting under Python 3.
    This function is an attempt to provide a replacement:
    it converts everything to unicode (decoding bytes instances as ``latin-1``),
    performs the required formatting, then encodes the result to ``latin-1``.

    Calling ``render_bytes(source, *args)`` should function roughly the same as
    ``source % args`` under Python 2.

    .. todo::
        python >= 3.5 added back limited support for bytes %,
        can revisit when 3.3/3.4 is dropped.
    zlatin-1c             s   s3   |  ]) } t  | t  r' | j d   n | Vq d S)zlatin-1N)rw   r   decode)rs   rm   rR   rR   rS   rv   ,  s   zrender_bytes.<locals>.<genexpr>)rw   r   r   r   encode)r   ro   r   rR   rR   rS   r8     s
    c             C   s   t  j |  d  S)Nbig)int
from_bytes)r   rR   rR   rS   bytes_to_int2  s    r   c             C   s   |  j  | d  S)Nr   )r;   )r   countrR   rR   rS   int_to_bytes4  s    r   )hexlify	unhexlifyc             C   s   t  t |   d  S)N   )r   r   )r   rR   rR   rS   r   9  s    c             C   s   t  d | d >|   S)Nz%%0%dxrd   )r   )r   r   rR   rR   rS   r   ;  s    z/decode byte string as single big-endian integerz/encode integer as single big-endian byte stringc             C   s#   t  t |   t |  At |    S)z;Perform bitwise-xor of two byte strings (must be same size))r   r   r[   )r   r   rR   rR   rS   r7   A  s    c             C   s*   d | d t  |   } |  | d |  S)zE
    repeat or truncate <source> string, so it has length <size>
    rd   N)r[   )r   r   multrR   rR   rS   repeat_stringE  s    r   c             C   s)   d | d t  |   } t |  | |  S)zN
    variant of repeat_string() which truncates to nearest UTF8 boundary.
    rd   )r[   utf8_truncate)r   r   r   rR   rR   rS   utf8_repeat_stringM  s    r   s     c             C   sa   t  |   } | | k rO | d k r? t |  t  r9 t n t } |  | | | S|  d |  Sd S)z>right-pad or truncate <source> string, so it has length <size>N)r[   rw   r*   _UNULL_BNULL)r   r   ZpadZcurrR   rR   rS   right_pad_stringX  s    r   c                s   t   t  s! t  t d   t   } | d k  rL t d | |  } | | k r\  St | d |  } xG | | k  r t  |  d @d k r P| d 7} qr W| | k s t   d |       f d d	   } |   s t    S)
a  
    helper to truncate UTF8 byte string to nearest character boundary ON OR AFTER <index>.
    returned prefix will always have length of at least <index>, and will stop on the
    first byte that's not a UTF8 continuation byte (128 - 191 inclusive).
    since utf8 should never take more than 4 bytes to encode known unicode values,
    we can stop after ``index+3`` is reached.

    :param bytes source:
    :param int index:
    :rtype: bytes
    r   r            rd   Nc                 sN   y  j  d  }  Wn t k
 r+ d SYn X|  j   j  d   sJ t  d S)Nzutf-8T)r   UnicodeDecodeError
startswithr~   )text)r   r   rR   rS   sanity_check  s    	z#utf8_truncate.<locals>.sanity_check)rw   r   r    r[   maxminr+   r~   )r   indexr   r   rR   )r   r   rS   r   c  s"    r   s	    
 aA:#!asciic             C   s   t  j |   t k S)zRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16))_ASCII_TEST_UNICODEr   _ASCII_TEST_BYTES)codecrR   rR   rS   is_ascii_codec  s    r   c             C   s<   |  | k r d S|  o | s  d St  |   j t  |  j k S)z3Check if two codec names are aliases for same codecTF)_lookup_codecname)r   r   rR   rR   rS   r9     s
    s      c                s8   t  |  t  r t n t   t   f d d   |  D  S)z<Check if string (bytes or unicode) contains only 7-bit asciic             3   s   |  ] } |   k  Vq d  S)NrR   )rs   r   )r   rR   rS   rv     s    z is_ascii_safe.<locals>.<genexpr>)rw   r   _B80_U80all)r   rR   )r   rS   r:     s    zutf-8c             C   s}   | s t   t |  t  rN | rG t | |  rG |  j |  j |  S|  Sn+ t |  t  rj |  j |  St |  |   d S)a  Helper to normalize input to bytes.

    :arg source:
        Source bytes/unicode to process.

    :arg encoding:
        Target encoding (defaults to ``"utf-8"``).

    :param param:
        Optional name of variable/noun to reference when raising errors

    :param source_encoding:
        If this is specified, and the source is bytes,
        the source will be transcoded from *source_encoding* to *encoding*
        (via unicode).

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * unicode strings will be encoded using *encoding*, and returned.
        * if *source_encoding* is not specified, byte strings will be
          returned unchanged.
        * if *source_encoding* is specified, byte strings will be transcoded
          to *encoding*.
    N)r~   rw   r   r9   r   r   r*   r   )r   encodingr   Zsource_encodingrR   rR   rS   r;     s    c             C   sN   | s t   t |  t  r |  St |  t  r; |  j |  St |  |   d S)a  Helper to normalize input to unicode.

    :arg source:
        source bytes/unicode to process.

    :arg encoding:
        encoding to use when decoding bytes instances.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * returns unicode strings unchanged.
        * returns bytes strings decoded using *encoding*
    N)r~   rw   r*   r   r   r   )r   r   r   rR   rR   rS   r<     s    c             C   sB   t  |  t  r |  j |  St  |  t  r/ |  St |  |   d  S)N)rw   r   r   r*   r   )r   r   r   rR   rR   rS   r=     s
    c             C   sB   t  |  t  r |  St  |  t  r/ |  j |  St |  |   d  S)N)rw   r   r*   r   r   )r   r   r   rR   rR   rS   r=     s
    a>  Take in unicode or bytes, return native string.

    Python 2: encodes unicode using specified encoding, leaves bytes alone.
    Python 3: leaves unicode alone, decodes bytes using specified encoding.

    :raises TypeError: if source is not unicode or bytes.

    :arg source:
        source unicode or bytes string.

    :arg encoding:
        encoding to use when encoding unicode or decoding bytes.
        this defaults to ``"utf-8"``.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :returns: :class:`str` instance
    Z
deprecatedz1.6Zremovedz1.7c             C   s   t  |  | d d S)z'deprecated, use to_native_str() insteadr   hash)r=   )r   r   rR   rR   rS   to_hash_str$  s    r   z true t yes y on 1 enable enabledz#false f no n off 0 disable disablednoneZbooleanc             C   s   | d k s t   t |  t  r| |  j   j   } | t k rC d S| t k rS d S| t k rc | St d | |  f   n- t |  t	  r |  S|  d k r | St	 |   Sd S)z\
    helper to convert value to boolean.
    recognizes strings such as "true", "false"
    TFNzunrecognized %s value: %r)TFN)
r~   rw   r.   lowerr   	_true_set
_false_set	_none_setr   bool)r   r   r   ZcleanrR   rR   rS   as_bool-  s    r   c             C   sL   t  s t |  t  r d Sy |  j d  d SWn t k
 rG d SYn Xd S)z
    UT helper --
    test if value is safe to pass to crypt.crypt();
    under PY3, can't pass non-UTF8 bytes to crypt.crypt.
    Tzutf-8FN)crypt_accepts_bytesrw   r   r   r   )r   rR   rR   rS   is_safe_crypt_inputG  s    r   )cryptc             C   s   d  S)NrR   )secretr   rR   rR   rS   r@   ]  s    T   r   )nullcontextz*:!s   Zxxc             C   sl  t  r] t |  t  r$ |  j d  }  t |  k r< t d   t | t  r | j d  } n t |  t  r |  } y |  j d  }  Wn t k
 r d  SYn X|  j d  | k s t	 d   t
 |  k r t d   t | t  r | j d  } y! t  t |  |  } Wd  QRXWn t k
 r.d  SYn Xt | t  rM| j d  } | sd| d t k rhd  S| S)Nzutf-8znull character in secretr   z"utf-8 spec says this can't happen!r   )r   rw   r*   r   r   r   r   r   r   r~   _NULL_safe_crypt_lock_cryptOSError_invalid_prefixes)r   r   Zorigr   rR   rR   rS   r@     s:    			c          
   C   s   t  |  t  r |  j d  }  t |  k r6 t d   t  | t  rT | j d  } t  t |  |  } Wd  QRX| s{ d  S| j d  } | d t k r d  S| S)Nzutf-8znull character in secretr   r   )	rw   r*   r   r   r   r   r   r   r   )r   r   r   rR   rR   rS   r@     s    a  Wrapper around stdlib's crypt.

    This is a wrapper around stdlib's :func:`!crypt.crypt`, which attempts
    to provide uniform behavior across Python 2 and 3.

    :arg secret:
        password, as bytes or unicode (unicode will be encoded as ``utf-8``).

    :arg hash:
        hash or config string, as ascii bytes or unicode.

    :returns:
        resulting hash as ascii unicode; or ``None`` if the password
        couldn't be hashed due to one of the issues:

        * :func:`crypt()` not available on platform.

        * Under Python 3, if *secret* is specified as bytes,
          it must be use ``utf-8`` or it can't be passed
          to :func:`crypt()`.

        * Some OSes will return ``None`` if they don't recognize
          the algorithm being used (though most will simply fall
          back to des-crypt).

        * Some OSes will return an error string if the input config
          is recognized but malformed; current code converts these to ``None``
          as well.
    c             C   sJ   t  | t  s% t d t |    | s7 t d   t |  |  | k S)zcheck if :func:`crypt.crypt` supports specific hash
    :arg secret: password to test
    :arg hash: known hash of password to use as reference
    :returns: True or False
    z#hash must be unicode_or_str, got %szhash must be non-empty)rw   r-   r~   rx   r@   )r   r   rR   rR   rS   r?     s    
c             C   sE   t  j d |   } | rA t d d   | j d  j d  D  Sd S)zhelper to parse version stringz(\d+(?:\.\d+)+)c             s   s   |  ] } t  |  Vq d  S)N)r   )rs   r   rR   rR   rS   rv     s    z parse_version.<locals>.<genexpr>rd   .N)researchr   groupr   )r   mrR   rR   rS   parse_version  s    )r   rd   c             C   s   d d l  m } t |  d  rb t |  d  rb y |  j   }  Wn! t k
 ra |  j d  }  Yn Xt d  |  t t d  r t j   n d	 t	 t
    t j   t   t r t j d
  j d  n d f } t | | j d   j   d  S)z.generate prng seed value from system resourcesr   )sha512getstategetrandbitsrd      z%s %s %s %.15f %.15f %sgetpidN    zlatin-1zutf-8r   i   )Zhashlibr   hasattrr   rP   r   r(   osr  idobjecttimerA   has_urandomurandomr   r   r   Z	hexdigest)r   r   r   rR   rR   rS   genseed  s    		(r
  c                s,     s
 t  S   f d d   } t |    S)z]return byte-string containing *count* number of randomly generated bytes, using specified rngc              3   sM    j    d > }  d } x- |   k  rH |  d @V|  d L}  | d 7} q Wd  S)Nr   r      rd   )r   )r   r   )r   rB   rR   rS   helperM  s    	
zgetrandbytes.<locals>.helper)_BEMPTYr#   )rB   r   r  rR   )r   rB   rS   rC   B  s    	c                s    d k  r t  d   t      d k r< t  d    d k rP    S     f d d   } t   t  r t |    St |    Sd S)z|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngr   zcount must be >= 0zalphabet must not be emptyrd   c              3   sT    j  d    }  d } x1 |  k  rO   |   V|   }  | d 7} q Wd  S)Nr   rd   )Z	randrange)r   r   )charsetr   lettersrB   rR   rS   r  f  s    
zgetrandstr.<locals>.helperN)r   r[   rw   r*   r)   r$   )rB   r  r   r  rR   )r  r   r  rB   rS   rD   W  s    	Z42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0Zreplacementz/passlib.pwd.genword() / passlib.pwd.genphrase()
   c             C   s   t  t | |   S)aw  generate random password using given length & charset

    :param size:
        size of password.

    :param charset:
        optional string specified set of characters to draw from.

        the default charset contains all normal alphanumeric characters,
        except for the characters ``1IiLl0OoS5``, which were omitted
        due to their visual similarity.

    :returns: :class:`!str` containing randomly generated password.

    .. note::

        Using the default character set, on a OS with :class:`!SystemRandom` support,
        this function should generate passwords with 5.7 bits of entropy per character.
    )rD   rB   )r   r  rR   rR   rS   rE   v  s    r   setting_kwdscontext_kwdsverifyr   identifyc                s   t    f d d   t D  S)z4check if object follows the :ref:`password-hash-api`c             3   s   |  ] } t    |  Vq d  S)N)r  )rs   r   )objrR   rS   rv     s    z#is_crypt_handler.<locals>.<genexpr>)r   _handler_attrs)r  rR   )r  rS   rF     s    needs_update	genconfiggenhashencryptc                s   t    f d d   t D  S)zOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec             3   s   |  ] } t    |  Vq d  S)N)r  )rs   r   )r  rR   rS   rv     s    z#is_crypt_context.<locals>.<genexpr>)r   _context_attrs)r  rR   )r  rS   rG     s    c             C   s%   d |  j  k o$ t |  d d  d k	 S)z_check if handler provides the optional :ref:`rounds information <rounds-attributes>` attributesroundsZ
min_roundsN)r  getattr)handlerrR   rR   rS   rH     s    c             C   s%   d |  j  k o$ t |  d d  d k	 S)z[check if handler provides the optional :ref:`salt information <salt-attributes>` attributesZsaltZmin_salt_sizeN)r  r  )r  rR   rR   rS   rI     s    r   )r   rJ   r   )r   r   r   )r   r  r  r  r   r  )r  r  r  r  r  r  )rc   passlib.utils.compatr   Zbinasciir   r   r   Z_BinAsciiErrorbase64r   r   collections.abcr   r	   ImportErrorcollectionscodecsr
   r   	functoolsr   r   rf   logging	getLoggerr`   logZmathr  sysZrandomr   r   r   r  r   	threadingZtimeittypeswarningsr   Zpasslib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   Zpasslib.utils.decorr   r   r   r   r   Zpasslib.excr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   __all__r   maxsizeZmaxintr2   r3   r4   rK   r  r   r   environrg   ZMAX_PASSWORD_SIZEr  rO   Z	ParameterZVAR_KEYWORDrj   setZVAR_POSITIONALrh   rn   r   r   r5   Zstr_consteqZhmacr   r   r6   r8   r   r   r   r   r7   r   r   r   r   r   r   r   r   r   r   r9   r   r   r:   r;   r<   r=   r   r   r   r   r   r   r   r   r   r>   r   Zcrypt_needs_lockr   r@   r   Zpypy_version_infoLockr   r   r   r?   Zdefault_timerZtimerrA   r   r	  r  rP   r
  ZSystemRandomrB   ZRandomrC   rD   Z
_52charsetrE   r  rF   r  rG   rH   rI   rR   rR   rR   rS   <module>   s   X(p	.	V>F%+		
/	
!    
