403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /lib/python3.9/site-packages/passlib/tests/__pycache__/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /lib/python3.9/site-packages/passlib/tests/__pycache__/utils.cpython-39.opt-1.pyc
a

f�WcU@�@s�dZddlmZddlmZddlZddlmZmZddl	Z	ddl
Z
e
�e�Z
ddlZddlZddlZddlZddlZddlZddlZddlmZmZddlmZmZddlZddlmZdd	lmZdd
lmZddl m!Z!ddl"m#Z$m%Z%m&Z&m'Z'm(Z(ddl)m*Z*m+Z+m,Z,m-Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4dd
lm5Z5m6Z6m7Z7m8Z8m9Z9m:Z:ddl;m<Z<ddl=m>m?Z@gd�ZAzddlBZCWneD�y�dZEYn0dZEdd�ZFdd�ZGeGe3�ZHgd�ZIeI�JejK�Ldd��M��N��ZOdNdd�ZPdd�ZQdOdd�ZRdd �ZSdPd!d"�ZTd#d$�ZUd%d&�ZVd'd(�ZWejXd)d*��ZYd+d,�ZZd-d.�Z[d/d0�Z\d1d2�Z]d3d4�Z^d5d6�Z_dQd9d:�Z`dRd=d>�ZaGd?d@�d@e$�Z#dAdgZbdBdC�ZcGdDdE�dEe#�ZdGdFdG�dGed�ZeGdHdI�dIed�ZfGdJdK�dKed�ZgGdLdM�dMejh�ZidS)Szhelpers for passlib unittests�)�with_statement)�	unhexlifyN)�wraps�partial)�PasslibHashWarning�PasslibConfigWarning)�PY3�JYTHON)�warn)�exc)�MissingBackendError)�TestCase�skip�skipIf�
skipUnless�SkipTest)
�has_rounds_info�
has_salt_info�rounds_cost_values�rng�
getrandstr�
is_ascii_safe�
to_native_str�
repeat_string�tick�batch)�	iteritems�irange�u�unicode�PY2�nullcontext)�
classproperty)�	TEST_MODE�set_file�get_filer
�HandlerCaseFTcCs8tj�|�}tj�|�|kr4t�d�t�|d�qdS)zensure file's mtime has changed皙�����?N)�os�path�getmtime�time�sleep�utime)r)Zlast�r.�7/usr/lib/python3.9/site-packages/passlib/tests/utils.py�ensure_mtime_changed;s
r0cs&�fdd��t�fdd�td�D��S)Ncs"��}}||kr��}q
||S�Nr.)�startZcur��timerr.r/�sampleEs
z%_get_timer_resolution.<locals>.samplec3s|]}��VqdSr1r.��.0�_)r5r.r/�	<genexpr>J�z(_get_timer_resolution.<locals>.<genexpr>�)�min�ranger3r.)r5r4r/�_get_timer_resolutionDsr>)�quick�default�fullZPASSLIB_TEST_MODEr@cCs0|rtt�|�krdS|r,tt�|�kr,dSdS)a�check if test for specified mode should be enabled.

    ``"quick"``
        run the bare minimum tests to ensure functionality.
        variable-cost hashes are tested at their lowest setting.
        hash algorithms are only tested against the backend that will
        be used on the current host. no fuzz testing is done.

    ``"default"``
        same as ``"quick"``, except: hash algorithms are tested
        at default levels, and a brief round of fuzz testing is done
        for each hash.

    ``"full"``
        extra regression and internal tests are enabled, hash algorithms are tested
        against all available backends, unavailable ones are mocked whre possible,
        additional time is devoted to fuzz testing.
    FT)�
_test_mode�_TEST_MODES�index)r<�maxr.r.r/r#Ts
r#cCs$t|d�rdSd|jvp"t|tj�S)z'check if handler supports 'relaxed' kwd�orig_prefixF�relaxed)�hasattr�setting_kwds�
issubclass�uhZGenericHandler��handlerr.r.r/�has_relaxed_settingps

�rNcCst|�}||dd�jS)z'get effective rounds value from handlerT)�rounds�use_defaults)�unwrap_handlerrO)rMrOr.r.r/�get_effective_rounds|srRc	CsVz|��}Wnty YdS0z"|�d�|��|kW|�|�S|�|�0dS)z*check if backend is the default for sourceFr@N)�get_backendr�set_backend)rM�backend�origr.r.r/�is_default_backend�s

�rWccsZ|dur|��}|j}|r(|�|�dnd}||d�D]}||kr8|�|�r8|Vq8dS)z�
    iterate over alternate backends available to handler.

    .. warning::
        not thread-safe due to has_backend() call
    N�r)rS�backendsrD�has_backend)rM�current�fallbackrY�idxrUr.r.r/�iter_alt_backends�sr^cOst|i|��D]
}|SdSr1)r^)�args�kwdsrUr.r.r/�get_alt_backend�sracCst|d�r|j}q|S)z5return original handler, removing any wrapper objects�wrapped)rHrbrLr.r.r/rQ�s
rQcCsf||krdSt|tj�r4|r0||kr(dS|j}qdSt|t�rTt|tj�rTt||�Std|f��dS)zG
    test if <handler> was derived from <base> via <base.using()>.
    TFz%don't know how to inspect handler: %rN)�
isinstancerK�
PrefixWrapperZ
_derived_from�typerJZMinimalHandler�NotImplementedError)rM�baser.r.r/�handler_derived_from�s
rhc#s�t|t�rJt|tj�rJ|j��fdd�}||_zdVW�|_q��|_0nHt|tj�r�t|j��dVWd�q�1s|0Yn
dVdSdS)a
    internal helper for do_config_encrypt() --
    context manager which temporarily replaces handler's _calc_checksum()
    with one that uses min_rounds; useful when trying to generate config
    with high rounds value, but don't care if output is correct.
    cs:|j}z&|j|_�|g|�Ri|��W||_S||_0dSr1)rO�
min_rounds)�selfr_r`rO�rbr.r/�wrapper�s�z&patch_calc_min_rounds.<locals>.wrapperN)	rcrerJrKZ	HasRoundsZ_calc_checksumrd�patch_calc_min_roundsrb)rMrlr.rkr/rm�s&rmcCsLt|t�r|�d�}t|d��}|�|�Wd�n1s>0YdS)zset file to specified bytes�utf-8�wbN)rcr�encode�open�write)r)Zcontent�fhr.r.r/r$�s

r$cCs6t|d��}|��Wd�S1s(0YdS)zread file as bytes�rbN)rq�read)r)rsr.r.r/r%�sr%cCsJt|t�s|Str|�d�Sz|�d�WStyD|�d�YS0dS)z*convert native string to non-native stringrn�latin-1N)rc�strrrp�decode�UnicodeDecodeError��sourcer.r.r/�tonn�s

r|cCstt�dd|��S)zT
    helper for represent byte strings in hex.

    usage: ``hb("deadbeef23")``
    z\s�)r�re�subrzr.r.r/�hb�sr�cCs||kr|S||kr|S|Sr1r.)�value�lower�upperr.r.r/�limit�s
r�cCst�}t�||krqdS)zAbecause time.sleep() doesn't even have 10ms accuracy on some OSesN�r)Zdelayr2r.r.r/�
quicksleepsr�rX�
c
Cstddlm}ddlm}|||p"dd�}d}t�|}t|�||��}	t�|krf|	|t||d��fS|d9}q6dS)	z�
    timeit() wrapper which tries to get as accurate a measurement as possible w/in maxtime seconds.

    :returns:
        ``(avg_seconds_per_call, log10_number_of_repetitions)``
    r)�Timer��logr})�setuprXr�N)Ztimeitr��mathr�rr<�repeat�int)
�funcr�ZmaxtimeZbestofr�r�r4Znumber�endZdeltar.r.r/�	time_call	s

r����F"*�!cs��fdd�}|S)z<
    decorator run test method w/ multiple fixed seeds.
    cst�����fdd��}|S)Ncs8t���}t��D] }|�d�|d<�|i|��qdS)N� �seed)�random�Randomr�getrandbits)r_r`rr8)�countr��master_seedr.r/rl s
z6run_with_fixed_seeds.<locals>.builder.<locals>.wrapper)r)r�rl�r�r��r�r/�buildersz%run_with_fixed_seeds.<locals>.builderr.)r�r�r�r.r�r/�run_with_fixed_seedssr�cs.eZdZdZdZ�fdd�Zedd��Zedd��Zd	Z	d	Z
�fd
d�Zdd
�Zd	Z
dd�Zd3�fdd�	Zdd�ZeZZd4dd�ZGdd�dej�Zd5dd�Zd6dd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Ze��Z dZ!dZ"d7d'd(�Z#e$e%d)�Z&e'j(�fd*d+��Z)dZ*d,d-�Z+d8d/d0�Z,d1d2�Z-�Z.S)9r
aRpasslib-specific test case class

    this class adds a number of features to the standard TestCase...
    * common prefix for all test descriptions
    * resets warnings filter & registry for every test
    * tweaks to message formatting
    * __msg__ kwd added to assertRaises()
    * suite of methods for matching against warnings
    Ncs0tt|���}|j}|r,d||p&t|�f}|S)z;wrap shortDescription() method to prepend descriptionPrefixz%s: %s)�superr
�shortDescription�descriptionPrefixrw)rj�desc�prefix��	__class__r.r/r�Bs
zTestCase.shortDescriptioncCs |j}|�d�pt|d|d�S)Nr8z_%s__unittest_skipF)�__name__�
startswith�getattr)�cls�namer.r.r/�__unittest_skip__Ns
�zTestCase.__unittest_skip__cCs|jSr1)r��r�r.r.r/�__test__UszTestCase.__test__Tcs(tt|���|��|�tdd�dS)NZENABLE_DEBUG_ONLY_REPRT)r�r
�setUp�
setUpWarnings�	patchAttrr�rjr�r.r/r�dszTestCase.setUpcCsH|jrDt�}|��|�|j�t�dd�t�dd�t�dd�dS)z6helper to init warning filters before subclass setUp()�ignorez<the method .*\.(encrypt|genconfig|genhash)\(\) is deprecatedz&the 'vary_rounds' option is deprecatedz0Support for `(py-bcrypt|bcryptor)` is deprecatedN)�resetWarningState�reset_warnings�	__enter__�
addCleanup�__exit__�warnings�filterwarnings)rj�ctxr.r.r/r�js	zTestCase.setUpWarningscCs4|jr(|r(|���d�r(d|��|fS|p.|SdS)N�:z%s %s)�longMessage�rstrip�endswith)rj�msg�stdr.r.r/�_formatMessage�szTestCase._formatMessagec	
s�|�dd�}|dur4tt|�j|dg|�Ri|��Sz||i|��}Wn(|yn}z|WYd}~Sd}~00d||f}|�|�||���dS)N�__msg__z-function returned %r, expected it to raise %r)�popr�r
�assertRaises�failureExceptionr�)	rjZ	_exc_typeZ	_callabler_r`r��result�errr�r�r.r/r��s���zTestCase.assertRaisescOstd��dS)Nz%this alias is deprecated by unittest2)�AssertionError)rj�a�kr.r.r/�assertEquals�szTestCase.assertEqualsc	Cs�t|d�r|}	|j}nd}	|r0|�t|�||�|rF|�t|�||�|rX|�|||�|s`|r�|	sltd��|	j}
|
�d�s�|
�d�r�|
dd�}
|r�|�|
||�|r�|�|
||�|r�|	s�td��|�|	j	||�dS)z�check if warning matches specified parameters.
        'warning' is the instance of Warning to match against;
        can also be instance of WarningMessage (as returned by catch_warnings).
        �categoryNz7matching on filename requires a WarningMessage instancez.pycz.pyo���z5matching on lineno requires a WarningMessage instance)
rH�message�assertEqualrw�assertRegex�assertIsInstance�	TypeError�filenamer��lineno)rj�warning�
message_rer�r�Zfilename_rer�r�r�Zwmsg�realr.r.r/�
assertWarning�s0
zTestCase.assertWarningcs0eZdZdZ�fdd�Zdd�Zdd�Z�ZS)zTestCase._AssertWarningListz'context manager for assertWarningList()cs,||_||_ttj|�|_|jjdd�dS)NT��record)�caser`r�r
�_AssertWarningList�_AssertWarningList__super�__init__)rjr�r`r�r.r/r��sz$TestCase._AssertWarningList.__init__cCs|j��|_dSr1)r�r�r�r�r.r.r/r��sz%TestCase._AssertWarningList.__enter__cGs4|jj|�|ddur0|jj|jfi|j��dS�Nr)r�r�r��assertWarningListr�r`)rj�exc_infor.r.r/r��sz$TestCase._AssertWarningList.__exit__�r��
__module__�__qualname__�__doc__r�r�r��
__classcell__r.r.r�r/r��sr�c	Cs
|dur|j|||d�St|ttf�s,|g}t|�D]�\}}t|t�rRt|d�}n2t|t�rrt|t	�rrt|d�}nt|t�s�t
d��z||}Wnty�Yq�Yn0|j|fd|i|��q4t
|�t
|�kr�dSdt
|�t
|�|�|�|f}|�|�||���dS)zBcheck that warning list (e.g. from catch_warnings) matches patternN)r�r�)r��r�z#entry must be str, warning, or dictr�z0expected %d warnings, found %d: wlist=%s desc=%r)r�rc�list�tuple�	enumeraterw�dictrerJ�Warningr��
IndexErrorr��len�_formatWarningListr�r�)rj�wlistr�r�r]�entry�datar�r.r.r/r��s,

�zTestCase.assertWarningListcOs4|durg}|j||g|�Ri|��|dd�=dS)zD[deprecated] assertWarningList() variant that clears list afterwardsN)r�)rjr�r�r_r`r.r.r/�consumeWarningListszTestCase.consumeWarningListcCsZd}t|d�r:d|j|jf}|jr4|d|jf7}|j}t|�}d|j|jt|�|fS)Nr}r�z filename=%r lineno=%rz line=%rz<%s.%s message=%r%s>)	rHr�r��liner�rer�r�rw)rjr��tailr�r.r.r/�_formatWarnings

�zTestCase._formatWarningcsdd��fdd�|D��S)Nz[%s]�, c3s|]}��|�VqdSr1)r�)r7r�r�r.r/r9r:z.TestCase._formatWarningList.<locals>.<genexpr>)�join)rjr�r.r�r/r�szTestCase._formatWarningListcCs.ddlm}|s*ddlm}|�d|��dS)z,helper to skip test if stringprep is missingr)�
stringprep)�_stringprep_missing_reasonz%not available - stringprep module is N)�
passlib.utilsr�r��skipTest)rjr�r�r.r.r/�require_stringpreps�zTestCase.require_stringprepcCst|�s|�d|��dS)z8skip test for all PASSLIB_TEST_MODE values below <level>zrequires >= %r test modeN)r#r�)rj�levelr.r.r/�require_TEST_MODE!szTestCase.require_TEST_MODEcCstr|�d�SdS)z'skip test if writeable FS not availablez.GAE doesn't offer read/write filesystem accessN)�GAEr�r�r.r.r/�require_writeable_filesystem&sz%TestCase.require_writeable_filesystemr@c	Cs*|j}|r||vr||S|j���|j}|rL||vrL||Wd�S|sZi}|_|pbtj}|dur�ttj�d�p�tj�d�p�t�	d��}t_t
�d|�t|�}d�
t|�|j|j|j|g�}t�|�d����}t|dd�d�}t�|�}||<|Wd�S1�s0YdS)	aU
        Return a :class:`random.Random` object for current test method to use.
        Within an instance, multiple calls with the same name will return
        the same object.

        When first created, each RNG will be seeded with value derived from
        a global seed, the test class module & name, the current test method name,
        and the **name** parameter.

        The global seed taken from the $RANDOM_TEST_SEED env var,
        the $PYTHONHASHSEED env var, or a randomly generated the
        first time this method is called. In all cases, the value
        is logged for reproducibility.

        :param name:
            name to uniquely identify separate RNGs w/in a test
            (e.g. for threaded tests).

        :param seed:
            override global seed when initialzing rng.

        :rtype: random.Random
        NZRANDOM_TEST_SEEDZPYTHONHASHSEEDr�zusing RANDOM_TEST_SEED=%d�
rn�)�
_random_cache�_random_global_lockr
�_random_global_seedr�r(�environ�get�sys_rngr�r��inforer�rwr�r��_testMethodName�hashlibZsha256rp�	hexdigestr�r�)	rjr�r��cacheZglobal_seedr�r{�digestr�r.r.r/�	getRandom9s4



����zTestCase.getRandom�subTestc/s�ddd�}|��}||i|��}|jr>tt|�j|i|��}nt�}|��|�d|�z
dVWn\ty~|�d|�Yn@ty�}z(|�	d|t
|�jt|���WYd}~n
d}~00Wd�n1s�0Y|�d|�dS)	zt
        wrapper/backport for .subTest() which also traps SkipTest errors.
        (see source for details)
        Nc[s@|rd|nd}|r4|dd�dd�|��D��7}|��p>dS)Nz[%s] r}z(%s)� css|]}dt|�VqdS)z%s=%rN)r�)r7�itemr.r.r/r9�r:z:TestCase.subTest.<locals>._render_title.<locals>.<genexpr>z	<subtest>)r��items�strip)Z_msg�params�outr.r.r/�
_render_title�s z'TestCase.subTest.<locals>._render_titlezrunning subtest: %szsubtest skipped: %szsubtest failed: %s: %s: %rzsubtest passed: %s)N)
�	getLogger�has_real_subtestr�r
rr!r
r�	Exceptionr�rer�rw)rjr_r`rZtest_log�titler�r�r�r.r/r|s"

6zTestCase.subTestcsb|��tj|i|��\}}t�|�|j��durTg�|_�fdd�}|�|���|�|S)z1create temp file that's cleaned up at end of testNcs.�D]}tj�|�rt�|�q�dd�=dSr1)r(r)�exists�remove)r)�Zqueuer.r/�cleaner�sz TestCase.mktemp.<locals>.cleaner)r�tempfileZmkstempr(�close�
_mktemp_queuer��append)rjr_r`�fdr)r r.rr/�mktemp�s



zTestCase.mktempFcszzt���}Wn0ty>|r"���fdd�}|�|�Yn0|�t��|�|rjt||�}t|�|�t��|�dS)z=monkeypatch object value, restoring original value on cleanupcs&zt���Wnty Yn0dSr1)�delattr�AttributeErrorr.��attr�objr.r/�cleanup�sz#TestCase.patchAttr.<locals>.cleanupN)r�r(r��setattrrr)rjr+r*r�Zrequire_existing�wraprVr,r.r)r/r��s
zTestCase.patchAttrcCs@t|�}|jdt|d|j�}|j}|r6|d|}t�|�S)z9
        return logger named after current test.
        �.r�)rer�r�r�r�loggingr)rjr�r)r�r.r.r/r�szTestCase.getLogger)N)NNNNNNN)NNN)N)r@N)TF)/r�r�r�r�r�r�r"r�r�Z_TestCase__unittest_skipr�r�r�r�r�r�r�ZassertNotEqualsZassertRegexMatchesr�r��catch_warningsr�r�r�r�r�r�r�r�	threading�LockrrrrrH�	_TestCaser�
contextlib�contextmanagerrr#r&r�rr�r.r.r�r/r
-sR


�
0


A
8
r
�anycCs
d|_|S)a0
    decorator for HandlerCase.create_backend_case() --
    used to decorate methods that should be run even if backend isn't present
    (by default, full test suite is skipped when backend is missing)

    NOTE: tests decorated with this should not rely on handler have expected (or any!) backend.
    T)�_doesnt_require_backendr�r.r.r/�doesnt_require_backend�sr9cs<eZdZdZdZdZgZgZgZgZ	gZ
gd�Zed�ed�dgZ
dZdZdZdZedd	��Zd
Zedd��Zed
d��Zdd�Zd�dd�Zdd�Zdd�Zdd�Zd�dd�Zd�dd�Zdd�Z dd �Z!d!d"�Z"d�d#d$�Z#d%Z$ed&d'��Z%ed(d)��Z&dZ'd*d+�Z(�fd,d-�Z)d.d/�Z*d0d1�Z+d2d3�Z,d�d4d5�Z-d6d7�Z.d8d9�Z/d:d;�Z0d<d=�Z1d>d?�Z2d@dA�Z3edBdC��Z4dDdE�Z5dFdG�Z6dHdI�Z7dZ8dJdK�Z9dLdM�Z:edNdO��Z;dPdQ�Z<dRdS�Z=dTdU�Z>dVdW�Z?dXdY�Z@dZd[�ZA�fd\d]�ZBd^d_�ZCd`da�ZDdbdc�ZEddde�ZFdfdg�ZGdhdi�ZHdjdk�ZIdldm�ZJdndo�ZKdpdq�ZLdrds�ZMdtdu�ZNdvdw�ZOdxdy�ZPdzd{�ZQd|d}�ZRd~d�ZSd�d��ZTd�d��ZUd�d��ZVd�d��ZWd�d��ZXd�d��ZYd�d��ZZd�d��Z[d�d��Z\d�d��Z]gZ^d�d��Z_d�d��Z`d�d��Zad�d��Zbd�d�d��Zcd�d��Zded�d���Zeed�d���Zfd�Zgd�d�d��Zhd�d��ZiGd�d��d�ej�Zkd�d��Zl�ZmS)�r&a�base class for testing password hash handlers (esp passlib.utils.handlers subclasses)

    In order to use this to test a handler,
    create a subclass will all the appropriate attributes
    filled as listed in the example below,
    and run the subclass via unittest.

    .. todo::

        Document all of the options HandlerCase offers.

    .. note::

        This is subclass of :class:`unittest.TestCase`
        (or :class:`unittest2.TestCase` if available).
    N))Z	des_cryptZ
6f8c114b58f2c)Z	md5_cryptz"$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.)Zsha512_cryptzx$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwcelCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1�testu€¥$s€¥$FcCsdt|jdd�vrdSdS)N�os_cryptrYr.�)r�rMr�r.r.r/�forbidden_charactersZsz HandlerCase.forbidden_charactersTcCs,|j}|j}t|d�r(|d|��f7}|S)NrSz
 (%s backend))rMr�rHrS)rjrMr�r.r.r/r�gs

zHandlerCase.descriptionPrefixccsV|jD]\}}||fVq|jD]\}}}||fVq |jD]\}}}||fVq<dS)z*iterate through known (secret, hash) pairsN)�known_correct_hashes�known_correct_configs�known_alternate_hashes)r��secret�hash�config�altr.r.r/�iter_known_hashesvszHandlerCase.iter_known_hashescCst|���}|���|�S)z#test random sample secret/hash pair)r�rEr�choice)rjZknownr.r.r/�get_sample_hash�szHandlerCase.get_sample_hashcCs�|�||�}|�|dup|dud|f�|jjs6|rZ|s>dS|sNd||f}|�|��n"|rbdS|srd||f}|�|��dS)z>helper to check verify() outcome, honoring is_disabled_handlerTFz'verify() returned non-boolean value: %rNz4verify incorrectly returned True: secret=%r, hash=%rz!verify failed: secret=%r, hash=%r)�	do_verify�
assertTruerM�is_disabledr�)rjrArBr��negater�r.r.r/�check_verify�s"��zHandlerCase.check_verifycCs|�|td||f�dS)Nz'%s() failed to return native string: %r)r�rw)rjr�Z	func_namer.r.r/�check_returned_native_str�s
�z%HandlerCase.check_returned_native_strcCs||j}d|jvrxd|vrx|j}|j}tdd�r>td|�|d<n:d}t|dd�dkr\||8}n|d|>}td||�|d<dS)	z0subclassable method to populate default settingsrOr?�rEr;�rounds_costN�log2rX)rMrIri�default_roundsr#rEr�)rjr`rM�mn�dfZfactorr.r.r/�populate_settings�s

zHandlerCase.populate_settingscCs|S)z?subclassable method allowing 'secret' to be encode context kwdsr.)rjrAr`r.r.r/�populate_context�szHandlerCase.populate_contextcKs�|�|�|duri}|�||�}|r�g}|rH|jfi|��|�d�|�|��(|p\|jj|fi|��Wd�S1s�0Yn$|p�|jjfi|��j|fi|��SdS)z3call handler's hash() method with specified optionsNz"passing settings to.*is deprecated)	rTrU�updater$r�rMZencrypt�usingrB)rjrA�use_encryptrM�context�settingsr�r.r.r/�
do_encrypt�s

8zHandlerCase.do_encryptcKs&|�||�}|p|jj||fi|��S)zcall handler's verify method)rUrM�verify)rjrArBrMr`r.r.r/rH�szHandlerCase.do_verifycCs|j�|�S)zcall handler's identify method)rM�identify�rjrBr.r.r/�do_identify�szHandlerCase.do_identifycKs|�|�|jjfi|��S)z6call handler's genconfig method with specified options)rTrM�	genconfig)rjr`r.r.r/�do_genconfig�s
zHandlerCase.do_genconfigcKs"|�||�}|jj||fi|��S)z4call handler's genhash method with specified options)rUrM�genhash)rjrArCr`r.r.r/�
do_genhash�szHandlerCase.do_genhashcKsl|p|jjfi|��}|dur"i}|�d|�}t|��"|j|fi|��Wd�S1s^0YdS)z�
        return sample hash for handler, w/o caring if digest is valid
        (uses some monkeypatching to minimize digest calculation cost)
        Nr})rMrWrUrmrB)rjrMrYrZrAr.r.r/�do_stub_encrypt�s
zHandlerCase.do_stub_encryptzbackend not availablecCs0|j}t||�std�sdS|�|�r*dS|jS)z�
        helper for create_backend_case() --
        returns reason to skip backend, or None if backend should be tested
        rAz$only default backend is being testedN)rMrWr#rZ�_BACKEND_NOT_AVAILABLE)r�rUrMr.r.r/�_get_skip_backend_reason�s
z$HandlerCase._get_skip_backend_reasonc	CsX|j}|j}|f}|dkr$|tf7}td||f|td||f||�|�|jd��}|S)Nr;z
%s_%s_testz%s (%s backend))r�rU�_skip_backend_reasonr�)rMr��OsCryptMixinrer�rfr�)r�rUrMr��bases�subclsr.r.r/�create_backend_cases 


��
zHandlerCase.create_backend_casecCst||jd�}t|dd�S)z]
        check if current test method decorated with doesnt_require_backend() helper
        Nr8F)r�r)rj�methr.r.r/�_test_requires_backendsz"HandlerCase._test_requires_backendcs�|��}|r|jr|�|j��tt|���|j}|j}|r�t|d�sNt	d��z |�
|j|���|�|�Wnt
jjy�|r��Yn0ddlm}|�|d|�d��dS)NrTz)handler doesn't support multiple backendsr)�handlersrzsalt generator)rmrgr�r�r&r�rMrUrH�RuntimeErrorr�rTrSrKrrr�rnr�r)rjZtest_requires_backendrMrUrnr�r.r/r�$s"

zHandlerCase.setUpcs�|j��fdd�}|d�}|�|d�|�|td�|�|��|kd�|�t�d|�d|f�|d	�}|�|d
ud�|�|td�|d
�}|�|d
ud�|�|td�d
S)zvalidate required attributescst�|d�Sr1)r��r�rLr.r/�gaHsz3HandlerCase.test_01_required_attributes.<locals>.gar�zname not defined:zname must be native strzname not lower-case:z^[a-z0-9_]+$z&name must be alphanum + underscore: %rrINzsetting_kwds must be defined:zsetting_kwds must be a tuple:Zcontext_kwdszcontext_kwds must be defined:zcontext_kwds must be a tuple:)rMrIr�rwr�r~�matchr�)rjrqr�rZrYr.rLr/�test_01_required_attributesEs�z'HandlerCase.test_01_required_attributescCsT|��}|�|d�|�d|�}|�|d�|�d|�|�|�|�d|f�dS)z�test basic config-string workflow

        this tests that genconfig() returns the expected types,
        and that identify() and genhash() handle the result correctly.
        r`�stubrbr}z4identify() failed to identify genconfig() output: %rN)rarMrcrHrIr_)rjrCr�r.r.r/�test_02_config_workflowes
��z#HandlerCase.test_02_config_workflowcCs.|j}|��}|�||�|�|j|j�dS)ztest basic using() workflowN)rMrWZassertIsNotr�r�)rjrMrjr.r.r/�test_02_using_workflow�sz"HandlerCase.test_02_using_workflowc
Csd}|jD]�}|j||d�}|�|d�|�||�|j||dd�|�||�}|�|d�|jjr�|jr�|�||d|||f�n|�	||d|||f�|�||�}|�|d�|jjr�|js�|�	||d	||||f�n|�||d
||||f�|�
|�|��q
dS)z�test basic hash-string workflow.

        this tests that hash()'s hashes are accepted
        by verify() and identify(), and regenerated correctly by genhash().
        the test is run against a couple of different stock passwords.
        rt)rXrBT)rKrbzBgenhash() failed to salt result hash: secret=%r hash=%r: result=%rz@genhash() failed to reproduce hash: secret=%r hash=%r: result=%rzYgenhash() failed to reproduce disabled-hash: secret=%r hash=%r other_secret=%r: result=%rzGgenhash() duplicated hash: secret=%r hash=%r wrong_secret=%r: result=%rN)�stock_passwordsr[rMrLrcrMrJ�disabled_contains_salt�assertNotEqualr�rIr_)rj�
use_16_legacyZwrong_secretrAr��otherr.r.r/�test_03_hash_workflow�s2

�
�

�

�z!HandlerCase.test_03_hash_workflowcCs|jdd�dS)zEtest hash-string workflow with legacy .encrypt() & .genhash() methodsT)rzN)r|r�r.r.r/�test_03_legacy_hash_workflow�sz(HandlerCase.test_03_legacy_hash_workflowcCs�|�td��}|�|d�|�dt|��|�td�t|��|�dt|��}|�|d�|jjrv|jrv|�||�n|�	||�|�td�t|��}|�|d�|jjr�|jr�|�||�n|�	||�|�
|�t|���dS)z#test hashes can be unicode or bytesrtrBrbN)r[r|rMrLrcrMrJrxryr�rIr_)rjr�r{r.r.r/�test_04_hash_types�szHandlerCase.test_04_hash_typescCs�|j}t|d�s|�d��|�|j|���|jD]|}|�|t�|�	|t
d|f�|�|�}|dur�|�|�|�|��|�q2|dur�|�
t|j|�q2td||f��q2dS)ztest multi-backend supportrTzhandler only has one backendzinvalid backend name: %rTFz*has_backend(%r) returned invalid value: %rN)rMrHr�r�rTrSrYr�rw�assertNotIn�RESERVED_BACKEND_NAMESrZr�r�rr�)rjrMrU�retr.r.r/�test_05_backends�s(


�


��zHandlerCase.test_05_backendscCsd|jjvr|�d��dS)N�saltzhandler doesn't have salt)rMrIr�r�r.r.r/�require_salt!szHandlerCase.require_saltcCs |��t|j�s|�d��dS)Nz!handler doesn't provide salt info)r�rrMr�r�r.r.r/�require_salt_info%s
zHandlerCase.require_salt_infocCs|��|j}|j}|jdu}|r4|jdkr4|d��|jdkrF|d��|r^|j|jkr^|d��|j|jkrr|d��|r�|j|jkr�|d��d	|jvr�|r�|j|jkr�td
|jf�|j	r�|j
s�|d��|j
D]}||j	vr�|d|f��q�n|j
s�|d
��dS)z!validate optional salt attributesNrXzmax_salt_chars must be >= 1rzmin_salt_chars must be >= 0z(min_salt_chars must be <= max_salt_charsz*default_salt_size must be >= min_salt_sizez*default_salt_size must be <= max_salt_size�	salt_sizezT%s: hash handler supports range of salt sizes, but doesn't offer 'salt_size' settingz$default_salt_chars must not be emptyzEdefault_salt_chars must be subset of salt_chars: %r not in salt_charsz;default_salt_chars MUST be specified if salt_chars is empty)r�r�rM�
max_salt_size�
min_salt_size�default_salt_sizerIr
r��
salt_chars�default_salt_chars)rjr�r�Zmx_set�cr.r.r/� test_10_optional_salt_attributes*s4

�

z,HandlerCase.test_10_optional_salt_attributescCs,|j}ddlm}t|j|t|j�d��S)z%calculate number of salt bits in hashrr��)rMr�r�r�r�r�r�)rjrMr�r.r.r/�	salt_bitsSs
�zHandlerCase.salt_bitscsD���tdd�j����fdd�}|�j�|�fdd��dS)z4test hash() / genconfig() creates new salt each timerXrcs<|�}t��D]}|�}||krdSq��d�f��dS)Nz.failed to find different salt after %d samples)rr�)r�Zvalue1r8Zvalue2��samplesrjr.r/�sampleris�z0HandlerCase.test_11_unique_salt.<locals>.samplercs
��d�S�Nrt)r[r.r�r.r/�<lambda>rr:z1HandlerCase.test_11_unique_salt.<locals>.<lambda>N)r�rEr�ra)rjr�r.r�r/�test_11_unique_salt_s

zHandlerCase.test_11_unique_saltcCs�|��|j}|jdd�}|j}||}|j|d�|jd|d�|dkrf|jt|j|dd�d�|jt|jd|dd�dS)z.test hash() / genconfig() honors min_salt_sizerrX�r�rt�r�Nr�)r�rMr�r�rar[r��
ValueError)rjrM�	salt_charZmin_size�s1r.r.r/�test_12_min_salt_sizets

��z!HandlerCase.test_12_min_salt_sizec	Cs@|��|j}|j}|jdd�}|dus2|dkrp|d}|j|d�}|j||d�}|�||�|jdd�n�||}|j|d�}|j|d�||}|jt|j|d�|jt|j|dd�t|��rt	j
dd	��|j|dd
�}Wd�n1s�0Y|�||�|j|k�r<|j|dd�d�}|�||�dS)z.test hash() / genconfig() honors max_salt_sizerrXNiir�r�Tr�)r�rGr�)
r�rMr�r�rdryr�r�rNr�r1r�r�)	rjrM�max_sizer�r�Zc1Zc2�s2Zc3r.r.r/�test_13_max_salt_size�s.
,z!HandlerCase.test_13_max_salt_sizecCs |jrddlm}|�|�}|S)zprepare generated saltr)�bcrypt64)�fuzz_salts_need_bcrypt_repairZpasslib.utils.binaryr�Z
repair_unused)rjr�r�r.r.r/�prepare_salt�s
zHandlerCase.prepare_saltc
Cs�|��|j}|j}|j}|j}t|t�}t||p4d�D]0}t|�|krRt	||�}|�
|�}|j|d�q8td�}|r�|�
d�}t|d�}|D]*}	|	|vr�|jt|j|	|d|	fd�q�dS)	ztest hash() honors salt_charsr�r�uÿrvrXzinvalid salt char %r:)r�r�N)r�rMr�r�r�rc�bytesrr�rr�rdrrprEr�r�)
rjrM�mxrR�cs�rawr�r{�chunkr�r.r.r/�test_14_salt_chars�s(




�zHandlerCase.test_14_salt_charscCst|jdd�rtStSdS)z)hack to determine salt keyword's datatypeZ_salt_is_bytesFN)r�rMr�rr�r.r.r/�	salt_type�szHandlerCase.salt_typecCs�|��|j}t|jdd�pd}Gdd�dt�}|jt|jd|�d�|turj|jt|jdt	d�|d�|t
us�tr~|tus�|jt|jdd	|d�d
S)ztest non-string salt valuesr�r�c@seZdZdS)z+HandlerCase.test_15_salt_type.<locals>.fakeN)r�r�r�r.r.r.r/�fake�sr�rtr��x�xN)r�r�r�rM�objectr�r�r[rrr�r )rjr�r�r�r.r.r/�test_15_salt_type�szHandlerCase.test_15_salt_typecCs�|��|j}|j}|j}|j}|jt|jdd�|�t	g��|jddd�}Wd�n1sb0Y|�
|j|�|r�|jt|j|dd�|�t	g��"|j|ddd�}Wd�n1s�0Y|�
|j|�||k�rJ|j|dd�}|�
|j|d�|�
|j|�|j|dd�}|�
|j|d�|�
|j|�||k�rZ|}n|d}|jt|�d�}|�
|j|�|jt|jt|�dd�|j|d	�}|�
|j|�dS)
z$Handler.using() -- default_salt_sizer�)r�T)r�rGNrXr��xxxr�)r�rMr�r�r�r�r�rWr�rr�rw)rjrMrRr�rS�temp�refr.r.r/�test_using_salt_sizes:,0

z HandlerCase.test_using_salt_sizecCst|j�s|�d��dS)Nzhandler lacks rounds attributes)rrMr�r�r.r.r/�require_rounds_info7s
zHandlerCase.require_rounds_infocCs�|��|j}|j}|jdur&|d��|jdkr8|d��|jdkrJ|d��|j|jkr^|d��|jdur�|j|jkr||d��|j|jkr�|d	��|jtvr�|d
|jf��dS)z#validate optional rounds attributesNzmax_rounds not specifiedrXzmax_rounds must be >= 1rzmin_rounds must be >= 0z min_rounds must be <= max_roundsz$default_rounds must be >= min_roundsz$default_rounds must be <= max_roundsz unknown rounds cost constant: %r)r�rMr��
max_roundsrirQrOr)rjr�r�r.r.r/�"test_20_optional_rounds_attributes;s$




z.HandlerCase.test_20_optional_rounds_attributescCs`|��|j}|j}|j|d�|jd|d�|jt|j|dd�|jt|jd|dd�dS)z+test hash() / genconfig() honors min_rounds�rOrtrXN)r�rMrirar[r�r�)rjrMrir.r.r/�test_21_min_roundsYszHandlerCase.test_21_min_roundscCsp|��|j}|j}|durJ|jt|j|dd�|jt|jd|dd�|dur`|jdd�n|j|d�dS)z+test hash() / genconfig() honors max_roundsNrXr�rti���)r�rMr�r�r�rar[rd)rjrMr�r.r.r/�test_21b_max_roundsiszHandlerCase.test_21b_max_roundsc
s�|��|j}|jdkr8|�|��}t��fdd��|_|j}|j}|j}|pPd|d}||krj|d7}||d}|p|d|d}|jdkr�|dO}|dO}|dO}d}nd}|�	g�� |j|||d�}	Wd�n1s�0Y||	||||fS)	zU
        setup test helpers for testing handler.using()'s rounds parameters.
        Z
bsdi_cryptcst�|���Sr1)r��_generate_roundsr�)r��orig_handlerr.r/r��r:z9HandlerCase._create_using_rounds_helper.<locals>.<lambda>i'r�rX)�min_desired_rounds�max_desired_roundsrQN)
r�rMr�rW�classmethodr�rir�rQr�)
rjrM�orig_min_rounds�orig_max_rounds�orig_default_rounds�medium�small�large�adjrjr�)r�r/�_create_using_rounds_helpers6

�$z'HandlerCase._create_using_rounds_helperc
Cs�|��|j}|j}|j}|j}|��\}}}}}}	|�|j|�|�|j|�|�|jd�|�|jd�|�|j|�|�|j|�|�|j|�|�|j|�|�|j|�|�|j|�dS)z@
        HasRounds.using() -- sanity check test harness
        N)	r�rMrir�rQr�r�r�r�)
rjrMr�r�r�rjr�r�r�r�r.r.r/�test_has_rounds_using_harness�s z)HandlerCase.test_has_rounds_using_harnesscCs�|��\}}}}}}|j}|j}|j}	|dkr�|jt|j||d�|�tg��"|j||dd�}
Wd�n1sx0Y|�	|
j
|�|r�|jt|j||d�|�tg��"|j||dd�}
Wd�n1s�0Y|�	|
j
|�|�g�� |j||d�}
Wd�n1�s(0Y|�	|
j
||�|j|d|d�}
|�	|
j
|d|�|�g�� |j||d�}
Wd�n1�s�0Y|�	|
j
||�|�	t|||�||�|�	t||�|�|�g��*|�	t|||�||�Wd�n1�s$0Y|j|d�}
|�	|
j
|�|jt|�d�}
|�	|
j
|�|jt|jt|�dd�dS)	zF
        HasRounds.using() -- min_rounds / min_desired_rounds
        r�r�T)r�rGNr��rir�)
r�rir�rQr�r�rWr�rr�r�rRrw)rjrMrjr�r�r�r�r�r�r�r�r.r.r/�"test_has_rounds_using_w_min_rounds�s>0000:z.HandlerCase.test_has_rounds_using_w_min_roundsc
Cs�|��\}}}}}}|j}|j}|dkr�|jt|j||d�|�tg��"|j||dd�}	Wd�n1sr0Y|�|	j	|�|r�|jt|j||d�|�tg��"|j||dd�}	Wd�n1s�0Y|�|	j	|�|�t
g�� |j||d�}	Wd�n1�s$0Y|�|	j	|�|jt|j||||d�|j|d|d�}	|�|	j|d|�|�g�� |j||d�}	Wd�n1�s�0Y|�|	j	||�|�t|||�||�|�t||�|�|�g��*|�t|||�||�Wd�n1�s80Y|j|d	�}	|�|	j	|�|jt
|�d�}	|�|	j	|�|jt|jt
|�d
d�dS)zF
        HasRounds.using() -- max_rounds / max_desired_rounds
        r)r�T)r�rGN�r�r�r�r��r�r�)r�rir�r�r�rWr�rr�r�rr�rRrw)
rjrMrjr�r�r�r�r�r�r�r.r.r/�$test_has_rounds_replace_w_max_rounds�sD000
�0:z0HandlerCase.test_has_rounds_replace_w_max_roundsc	Cs�|��\}}}}}}|j}|j||d�}|�|j||�|j||d�}|�|j||�|jt|j||d�|r�|jt|j||d�|�t|�|�|�t|||�||�|jt|�d�}|�|j|�|jt|jt|�dd�dS)z5
        HasRounds.using() -- default_rounds
        r�r�)rQr�N)	r�r�rWr�rQr�r�rRrw�	rjrMrjr�r�r�r�r�r�r.r.r/�&test_has_rounds_using_w_default_rounds8sz2HandlerCase.test_has_rounds_using_w_default_roundsc	Cs�|��\}}}}}}|j}|j||d�}|�|j||�|�|j||�|�|j||�|j|d|||||d�}|�|j||�|�|j|�|�|j||�dS)z-
        HasRounds.using() -- rounds
        r�rX)rOrirQr�N)r�r�rWr�r�rQr�r�r.r.r/�test_has_rounds_using_w_rounds^s�z*HandlerCase.test_has_rounds_using_w_roundscs�|��\}�}}}}�fdd�}|�|d�d�|�|d�d�|�|d�d�|�|d�d�|�|d�d�|�t|d�|�t|d	�d
S)z:
        HasRounds.using() -- vary_rounds parsing
        cs�j|d�jS)N��vary_rounds)rWr��r��rjr.r/�parsezszFHandlerCase.test_has_rounds_using_w_vary_rounds_parsing.<locals>.parser'z0.1z10%��Z1000g��������g�������?N)r�r�r�r�)rjrMr�r�r�r�r�r.r�r/�+test_has_rounds_using_w_vary_rounds_parsingssz7HandlerCase.test_has_rounds_using_w_vary_rounds_parsingc	s���\}�}}}}dd�����fdd�}|d||�|d||�||||||�|dt||d�t||d��|jdkr�|d	||�|d
||�|d|||�nl��jdd��\}}��|t||d
����|t||d����|t||d����|t||d��dS)z=
        HasRounds.using() -- vary_rounds generation
        cs*t�fdd�td�D��}t|�t|�fS)Nc3s|]}t��VqdSr1)rRr6r�r.r/r9�r:zjHandlerCase.test_has_rounds_using_w_vary_rounds_generation.<locals>.get_effective_range.<locals>.<genexpr>r�)�setrr<rE)r��seenr.r�r/�get_effective_range�szWHandlerCase.test_has_rounds_using_w_vary_rounds_generation.<locals>.get_effective_rangecs8�j|d�}�|�\}}��||d���||d�dS)Nr�z"vary_rounds had wrong lower limit:z"vary_rounds had wrong upper limit:)rWr�)r�r�r�r�Z
seen_lowerZ
seen_upper�r�rjrjr.r/�assert_rounds_range�szWHandlerCase.test_has_rounds_using_w_vary_rounds_generation.<locals>.assert_rounds_rangerz0%�2rPz1%z49%z50%r���?g�������?g333333�?g�?N)r�rEr<rOrW�assertGreaterEqualZassertLessEqual)	rjrMr�r�r�r�r�r�r�r.r�r/�.test_has_rounds_using_w_vary_rounds_generation�s  
z:HandlerCase.test_has_rounds_using_w_vary_rounds_generationcCs�|��\}}}}}}|j|d|dd�}|j||d�}|j||d�}	|j||d�}
|�|�|��|�|�|	��|�|�|
��|�|�|��|�|�|	��|�|�|
��dS)zF
        HasRounds.using() -- desired_rounds + needs_update()
        r�r�r�N)r�rWrd�assertFalseZneeds_updaterI)rjrMrjr�r�r�r�r�Z
small_hashZmedium_hashZ
large_hashr.r.r/�&test_has_rounds_using_and_needs_update�sz2HandlerCase.test_has_rounds_using_and_needs_updatecCs*|j}t|t�rt|tj�s&|�d��dS)Nz)handler doesn't derive from HasManyIdents)rMrcrerJrKZ
HasManyIdentsr�)rjrMr.r.r/�require_many_idents�szHandlerCase.require_many_identscCs6|j}|��|�d|jv�|jD]}|�|td�q$|�t|j�dkd�|�|jtd�|�|j|jvd�|j	r�t
|j	�D]<\}}|�|td�|�|td�|�||jvd	|f�q�|}|��d}|�|�}|d=|fd|ji|��|j
t|fi|��|fd
di|��|j
t|fddi|��d
S)z$validate HasManyIdents configuration�identz!cls.ident_values must be unicode:rXz'cls.ident_values must have 2+ elements:z"cls.default_ident must be unicode:z9cls.default_ident must specify member of cls.ident_valuesz'cls.ident_aliases keys must be unicode:z)cls.ident_aliases values must be unicode:z:cls.ident_aliases must map to cls.ident_values members: %rrPT�xXxN)rMr�rIrI�ident_valuesr�rr��
default_ident�
ident_aliasesrrG�	parsehashr�r�r�)rjr�r��aliasr�rMrBr`r.r.r/�test_30_HasManyIdents�sF
��
�����
z!HandlerCase.test_30_HasManyIdentscCs6|��|j}|j}|jD]}||krq>qtd||jf��dd�}|��}|�|j|�|j|d�}|�|j|�|�|j|�|�||�|�|�||�|�|jt|jdd�|j|d�}|�|j|�|�|j|�|jt	|j||d�|j
�r2|j
��D],\}}|j|d�}|j|j|d|d	��qd
S)z=HasManyIdents.using() -- 'default_ident' and 'ident' keywordsz6expected to find alternate ident: default=%r values=%rcSst|�}|dd�jS)NT)rP)rQr�r�r.r.r/�effective_identsz?HandlerCase.test_has_many_idents_using.<locals>.effective_ident)r�r�)r�)r�r�z	alias %r:�r�N)r�rMr�r�r�rWr�r�r�r�r�r)rjrMZ
orig_identZ	alt_identr�rjr�r�r.r.r/�test_has_many_idents_usings4
�z&HandlerCase.test_has_many_idents_usingcs�|j��jdur"|�d�j�dS�js4|��j�d�jvrN|��j�dS�fdd�}|�|d��j�|�|d�d�|�|d�d�|�|d�d�|�|d�d�|�	t
|d	�dS)
zH
        validate 'truncate_error' setting & related attributes
        N�truncate_errorcs�j|d�jS)N�r�)rWr�r���hasherr.r/�parse_valueSsz<HandlerCase.test_truncate_error_setting.<locals>.parse_valueT�trueFZfalser�)rM�
truncate_sizerrIr�r��truncate_verify_rejectrIr�r�r�)rjr�r.r�r/�test_truncate_error_setting;s 

z'HandlerCase.test_truncate_error_settingcCs�|j}|jdur(|�|jd�|�d��d}d}|�|�}|j}|j|�||�|dd�|dd�|}|�|�||�d	�dS)
zO
        test no password size limits enforced (if truncate_size=None)
        NrXztruncate_size is setatoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretstoo many secretsr�zverify rejected correct secretr�r�z full password not used in digest)	rMr�r�r�r[rJr�rHr�)rjr�rArDrBZverify_successZ
alt_secretr.r.r/�test_secret_wo_truncate_size\s

	
��z(HandlerCase.test_secret_wo_truncate_sizecCs�|j}|j}|s|�d��tj}d|jvrJ|jdd�}|jdd�}tj}n|jrZd}|}n|}d}d}d}t	||d	�}|dd
�}	|dd
�|}
|	dd
�|}|j
}|o�|j}
||fD]Z}|j|	|d�}|�
|j|	||d�|�|�|j|||d�d�|�
|j|||d�|
�q�|�rv|j||d�}|�
|j|||d�|�|�
|j|
||d�|�|�|j|	||d��|�r�|j||j||d�}|�
|j|�dS)
zQ
        test password size limits raise truncate_error (if appropriate)
        ztruncate_size not setr�Fr�TNztoo many secretsr�rXr�rLz truncate_size value is too large)rMr�r�r�PasswordSizeErrorrIrWZPasswordTruncateErrorr�rrJr�r[r�rHr�rIr�r�)rjrMr�Zsize_error_typeZ
without_errorZ
with_errorrgrDZlong_secretZshort_secretZalt_long_secretZalt_short_secretZshort_verify_successZlong_verify_successZcand_hasherZ
short_hashZ	long_hashr�r.r.r/�test_secret_w_truncate_size|sz

������������
�z'HandlerCase.test_secret_w_truncate_sizecCs�|jdu}|jdv}d}d}|�|�}|rH|jjsH|�|�||�d�n|�|�||�d�|�|�}|r�|jjs�|�|�||�d�n|�|�||�d�|�||�}|s�|jjr�|js�|�	||d�n|�
||d�d	S)
ztest password case sensitivityT)Tzverify-onlyr:ZTESTz%verify() should not be case sensitivez!verify() should be case sensitivez&genhash() should not be case sensitivez"genhash() should be case sensitiveN)�secret_case_insensitiver[rMrJrIrHr�rcrxr�ry)rjZhash_insensitiveZverify_insensitiver�r��h1�h2r.r.r/�test_61_secret_case_sensitive�s8


��
����z)HandlerCase.test_61_secret_case_sensitivecCsx|��d}|�t|jd�|�t|jd|�|�t|jd|�|�t|jd�|�t|jd|�|�t|jd|�dS)z&test non-string passwords are rejectedrXN)rGr�r�r[rcrHr^r.r.r/�test_62_secret_border	sz!HandlerCase.test_62_secret_bordercCsvddlm}ddlm}dd|}|��d}|�||j||�}|�|j|�|�||j	|�|�||j
||�dS)z"test MAX_PASSWORD_SIZE is enforcedr)r�)�MAX_PASSWORD_SIZEr/rXN)�passlib.excr�r�r�rGr�rcr�r�r[rH)rjr�r�rArBr�r.r.r/�test_63_large_secret	sz HandlerCase.test_63_large_secretcCsj|j}|s|�d��td�}t|t�rDddlm}||�}|�d�}|D]}|�t	|j
|||�qHdS)z1test forbidden characters not allowed in passwordznone listedrtr)�iter_byte_chars�asciiN)r=r�rrcr��passlib.utils.compatrrpr�r�r[)rj�charsrgrr�r.r.r/�test_64_forbidden_chars)	s


z#HandlerCase.test_64_forbidden_charscCs|�|i�}t|�Sr1)rUr�rjrAr.r.r/�is_secret_8bit9	szHandlerCase.is_secret_8bitcCs@tr<|jdkr<t|t�r<z|�d�Wnty:YdS0dS)zl
        check if we're expecting potential verify failure due to crypt.crypt() encoding limitation
        r;rnTF)rrUrcr�rxryrr.r.r/�expect_os_crypt_failure=	sz#HandlerCase.expect_os_crypt_failurec	Cs�|�|jp|jd�d}|��D]�\}}|�|�r6d}|�|�|�d|f�|�|�}zd|�||d||f�|�||�}|�	|t
d|f�|jjr�|j
r�Wq |�||d|||f�Wq ty�|sЂYq 0q |s�td|j�d	S)
ztest known hasheszOtest must set at least one of 'known_correct_hashes' or 'known_correct_configs'FTz&identify() failed to identify hash: %rz1verify() of known hash failed: secret=%r, hash=%r�,genhash() failed to return native string: %rzGgenhash() failed to reproduce known hash: secret=%r, hash=%r: result=%rz%s: no 8-bit secrets testedN)rIr>r?rErr_r	rLrcr�rwrMrJrxr�rr
r�)rjZsaw8bitrArBr	r�r.r.r/�test_70_hashesH	s:�
�

��
�

zHandlerCase.test_70_hashesc
Cs�|js|�d��|jD]�\}}}|�|�|�d|f�|�||d||f�|�||�}|�|td|f�|jj	r~|j
r~q|�||d||||f�qdS)ztest known alternate hasheszno alternate hashes providedz0identify() failed to identify alternate hash: %rz;verify() of known alternate hash failed: secret=%r, hash=%rr
zYgenhash() failed to normalize known alternate hash: secret=%r, alt=%r, hash=%r: result=%rN)r@r�rIr_rLrcr�rwrMrJrxr�)rjrDrArBr�r.r.r/�test_71_alternatest	s(
��
��

�zHandlerCase.test_71_alternatesc
Cs�|jjs |�|jd�|�d��|js0|�d��|jrDtjdtd�|jD]x\}}}|�	|�
|�d|f�|jt|j
||d|fd�|�||�}|�|td	|f�|�||d
||||f�qJdS)ztest known config stringsz&handler should not have config stringszhash has no settingszno config strings providedr�r�z5identify() failed to identify known config string: %rz+verify() failed to reject config string: %r�r�r
z^genhash() failed to reproduce known hash from config: secret=%r, config=%r, hash=%r: result=%rN)rMrIr�r?r��filter_config_warningsr�r�rrIr_r�r�rHrcr�rwr�)rjrCrArBr�r.r.r/�test_72_configs�	s6�

�����

�zHandlerCase.test_72_configscCsp|js|�d��|jD]T}|�|�|�d|f�|jt|jd|d|fd�|jt|jd|d|fd�qdS)z)test known unidentifiably-mangled stringszno unidentified hashes providedz?identify() incorrectly identified known unidentifiable hash: %rrtz:verify() failed to throw error for unidentifiable hash: %rr
z;genhash() failed to throw error for unidentifiable hash: %rN)�known_unidentified_hashesr�r�r_r�r�rHrcr^r.r.r/�test_73_unidentified�	s$

������z HandlerCase.test_73_unidentifiedcCsp|js|�d��|jD]T}|�|�|�d|f�|jt|jd|d|fd�|jt|jd|d|fd�qdS)z-test known identifiable-but-malformed stringszno malformed hashes providedz6identify() failed to identify known malformed hash: %rrtz5verify() failed to throw error for malformed hash: %rr
z6genhash() failed to throw error for malformed hash: %rN)�known_malformed_hashesr�rIr_r�r�rHrcr^r.r.r/�test_74_malformed�	s$

������zHandlerCase.test_74_malformedc	Cs�|jr|�d��|js |�d��|jD]�\}}||jjkr�|�|�|�d|f�|�d|�|�d|�}|�	|t
d|f�q&|�|�|�d||f�|jt
|jd|d||fd�|jt
|jd|d	||fd�q&d
S)ztest known foreign hashes�not applicablezno foreign hashes providedz,identify() failed to identify known hash: %rrtr
z:identify() incorrectly identified hash belonging to %s: %rz;verify() failed to throw error for hash belonging to %s: %rr
z<genhash() failed to throw error for hash belonging to %s: %rN)�accepts_all_hashesr��known_other_hashesrMr�rIr_rHrcr�rwr�r�r�)rjr�rBr�r.r.r/�test_75_foreign�	s:

��������zHandlerCase.test_75_foreigncCs|�t|jd�|�t|jdd�|�t|jdd�|�t|jd�|�t|jdd�|�t|jdd�td�dfD]~}|jr�|�|�|��|�d|�|�d|�}|�|d�qt|�	|�|�d�|jt
|jd|dd	�|jt
|jd|d
d	�qt|�d�|�d�dS)
z#test non-string hashes are rejectedNrtrXr}r:rbz,identify() incorrectly identified empty hashz$verify() failed to reject empty hashr
z%genhash() failed to reject empty hashu€¥$uabc‘)r�r�r_rHrcrrrIrMr�r�)rjrBr�r.r.r/�test_76_hash_border
s.���
zHandlerCase.test_76_hash_bordercCst|jd�std��dS)Nr�zparsehash() not implemented)rHrMrr�r.r.r/�require_parsehash2
szHandlerCase.require_parsehashc	Cs�|��|j}|�d�}|�|�}|�|t�|j|dd�}|��}|�dd�|�||�|j|dd�}|��}t	r�t
jdd	td
�dD]:}||vr�|�
||||�|�||�||||<q�|�||�dS)z
        parsehash()
        rtF)�checksumrNT)Zsanitizer�z(.*unequal comparison failed to convert.*r�)r�r)rrMr[r�r�r��copyr�r�r r�r��UnicodeWarningry�assert_is_masked)	rjrMrBr�Zresult2Zcorrect2Zresult3Zcorrect3�keyr.r.r/�test_70_parsehash6
s*

�zHandlerCase.test_70_parsehashcCs\|durdS|�|t�t|�dkr(|n
|dd�}t|�tdg�krJdS|�d|��dS)zQ
        check value properly masked by :func:`passlib.utils.mask_value`
        Nr���*Tzvalue not masked: %r)r�rr�r��fail)rjr�r�r.r.r/r]
szHandlerCase.assert_is_maskedcCsN|��|j}|s|�d��|jD]&\}}|j�|�}|�||d|�q"dS)z.
        parsehash() -- known outputs
        zno samples presentzhash=%r:N)r�known_parsehash_resultsr�rMr�r�)rjr�rBZcorrectr�r.r.r/�test_71_parsehash_resultsk
s
z%HandlerCase.test_71_parsehash_resultscs�|jjr|�d��ddlm}|j}|dkr6|�d��|j|d�}dd��|rZt��j	}nd}|j
|d	�}|�||�}t�
d
|j||t|�d��fdd
�|D���|�}||}	d}
|�|	k�r�|��}|d}|d}
|d}|d}|r�||d<|j|fi|��}|D]�}�|�}|||fi|��}|dk�r8�q|�sT|�d||||f��|��dk�r||
|fi|��}|�r|dk�r|�d||
|||f���q|
d7}
q�t�
d|j||�||
�dS)afuzz testing -- random passwords and options

        This test attempts to perform some basic fuzz testing of the hash,
        based on whatever information can be found about it.
        It does as much as it can within a fixed amount of time
        (defaults to 1 second, but can be overridden via $PASSLIB_TEST_FUZZ_TIME).
        It tests the following:

        * randomly generated passwords including extended unicode chars
        * randomly selected rounds values (if rounds supported)
        * randomly selected salt sizes (if salts supported)
        * randomly selected identifiers (if multiple found)
        * runs output of selected backend against other available backends
          (if any) to detect errors occurring between different backends.
        * runs output against other "external" verifiers such as OS crypt()

        :param report_thread_state:
            if true, writes state of loop to current_thread().passlib_fuzz_state.
            used to help debug multi-threaded fuzz test issues (below)
        rrr��disabled by test mode��threadedcSs|jp
|j��dSr�)r�r��
splitlines)�vr.r.r/�vname�
sz-HandlerCase.test_77_fuzz_input.<locals>.vnamez	fuzz testrpz.%s: %s: started; max_time=%r verifiers=%d (%s)r�c3s|]}�|�VqdSr1r.)r7r)�r*r.r/r9�
r:z1HandlerCase.test_77_fuzz_input.<locals>.<genexpr>rAr{rZrYrzAfailed to verify against %r verifier: secret=%r config=%r hash=%rr'z\was able to verify wrong password using %s: wrong_secret=%r real_secret=%r config=%r hash=%rrXz!%s: %s: done; elapsed=%r count=%rN)rMrJr�r�r�
max_fuzz_time�get_fuzz_verifiersr2�current_threadr�r�FuzzHashGeneratorr��debugr�r�r��generater[r�r�)rjr'rZmax_time�	verifiersZthread_namer�	generatorr2�stopr�ZoptsrAr{rZr�rBr\r�r�r.r+r/�test_77_fuzz_input|
s`

�

��

�zHandlerCase.test_77_fuzz_inputcs��d�ddl��jjr$��d���j}|dks<�jdkrF��d������dg����fdd�����fd	d
���fdd�t|�D�}�j|d
}d}|D]0}|�	|�|�
�s�q�t�d|j
|�|d7}q��dr��d�d|f��|�r��d||f��dS)z�multithreaded fuzz testing -- random password & options using multiple threads

        run test_77 simultaneously in multiple threads
        in an attempt to detect any concurrency issues
        (e.g. the bug fixed by pybcrypt 0.3)
        rArNrrXr%cshz�jdd�WnRty"YnB�� �dd7<Wd�n1sR0Y�Yn0dS)NTr&rrX)r5rr.)�failed�failed_lockrjr.r/rl�
s.z3HandlerCase.test_78_fuzz_threading.<locals>.wrappercsBt��}d||j|j�jf}�j�|d�}|�d�|��|S)NzFuzz-Thread-%d ('%s:%s.%s'))�targetr�T)rer�r�r�Thread�	setDaemonr2)�nr�r��thread)rjr2rlr.r/�launch�
s�
z2HandlerCase.test_78_fuzz_threading.<locals>.launchcsg|]}�|��qSr.r.)r7r;)r=r.r/�
<listcomp>�
r:z6HandlerCase.test_78_fuzz_threading.<locals>.<listcomp>r z%s timed out after %f secondszH%d/%d threads failed concurrent fuzz testing (see error log for details)zP%d/%d threads stalled during concurrent fuzz testing (see error log for details))r�r2rMrJr��fuzz_thread_countr,r3rr��is_aliver��errorr�r")rjZthread_count�threads�timeoutZstalledr<r.)r6r7r=rjr2rlr/�test_78_fuzz_threading�
s8


	


��z"HandlerCase.test_78_fuzz_threadingcCs@ttj�d�pd�}|r|Stdd�r*dStdd�r8dSdSdS)	z'amount of time to spend on fuzz testingZPASSLIB_TEST_FUZZ_TIMErr?rNr@rX�N)�floatr(rrr#�rjr�r.r.r/r,s

zHandlerCase.max_fuzz_timecCs2ttj�d�pd�}|r|Stdd�r*dSdSdS)z+number of threads for threaded fuzz testingZPASSLIB_TEST_FUZZ_THREADSrr?rNr�N)r�r(rrr#rGr.r.r/r?$s
zHandlerCase.fuzz_thread_count)�fuzz_verifier_defaultcsv|j�g}|jD]"}t||��}|dur|�|�qt�d�rrtd�rr|sr�fdd�}t��D]}|�||��q^|S)z�return list of password verifiers (including external libs)

        used by fuzz testing.
        verifiers should be callable with signature
        ``func(password: unicode, hash: ascii str) -> ok: bool``.
        NrYrAcs*��fdd�}d�d|_�d|_|S)Nc	s<���}z"������||�W��|�S��|�0dSr1)rSrTr\)rArBZorig_backend)rUrMr.r/r�Ms

�z;HandlerCase.get_fuzz_verifiers.<locals>.maker.<locals>.funcZcheck_Z_backend�-backend)r�r�)rUr�rL)rUr/�makerLs
z-HandlerCase.get_fuzz_verifiers.<locals>.maker)rM�fuzz_verifiersr�r$rHr#r^)rjr'r2Zmethod_namer�rJrUr.rLr/r-8s
zHandlerCase.get_fuzz_verifierscs*�fdd�}�jr �jd|_nd|_|S)Ncs�j||fi|��Sr1)rH)rArBr�r�r.r/�
check_default^sz8HandlerCase.fuzz_verifier_default.<locals>.check_defaultrIrj)rUr�)rjrLr.r�r/rH\s
z!HandlerCase.fuzz_verifier_defaultc@sveZdZdZed�ZdZedddd�ZiZ	dd	�Z
d
d�Zdd
�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�ZdS)zHandlerCase.FuzzHashGeneratorz�
        helper which takes care of generating random
        passwords & configuration options to test hash with.
        separate from test class so we can create one per thread.
        uqwertyASDF1234<>.@*#! áəБℓrn�
random_rounds�random_salt_size�random_ident)rOr�r�cCs||_|j|_||_dSr1)r:rMr)rjr:rr.r.r/r��sz&HandlerCase.FuzzHashGenerator.__init__cs4�fdd�}���\}}t|||�j�|�j�d�S)z�
            generate random password and options for fuzz testing.
            :returns:
                `(secret, other_secret, settings_kwds, context_kwds)`
            cs6i}|��D]$\}}t�|��}|dur|||<q|Sr1)rr�)�maprrrlr�r�r.r/�gendict�s
z7HandlerCase.FuzzHashGenerator.generate.<locals>.gendict)rAr{rZrY)�random_password_pairr��settings_map�context_map)rjrQrAr{r.r�r/r1�s�z&HandlerCase.FuzzHashGenerator.generatecCs|j�||�}tt|||��S)z)generate random int w/ gauss distirbution)rZ
normalvariater�r�)rjr�r�ZmuZsigmar�r.r.r/�randintgauss�sz*HandlerCase.FuzzHashGenerator.randintgausscCsX|j}t|�sdS|jp|j}|j}|jdkr4|}nt|d|j�}|�||||d�S)NrPr�r�)rMrrQrirOr<r�rU�rjrMr@r�r�r.r.r/rM�s
z+HandlerCase.FuzzHashGenerator.random_roundscCsJ|j}t|�rd|jvsdS|j}|j}|jp4|d}|�||||d�S)Nr�r r�)rMrrIr�r�r�rUrVr.r.r/rN�sz.HandlerCase.FuzzHashGenerator.random_salt_sizecCsL|j}|j}d|jvs t|d�s$dS|��dkr4dSt|d|�}|�|j�S)Nr�r�r�rb)rrMrIrHr�r�rFr�)rjrrMr.r.r/rO�sz*HandlerCase.FuzzHashGenerator.random_identcCs^|��}|��}|�||�rq q|j}|�dd�r>|�|j�}|�dd�rV|�|j�}||fS)z=generate random password, and non-matching alternate passwordrrX)�random_password�accept_password_pairr�randintrp�password_encoding)rjrAr{rr.r.r/rR�sz2HandlerCase.FuzzHashGenerator.random_password_paircCs�|j}|��dkrtd�S|j}|jo*|j}|p2d}|dksH|��dkr`|�dt|d�dd�}n|�dt|d�d	d
�}t||j	|�}|r�t
|t�r�t|�
d��|kr�|dd
�}q�|S)z*generate random passwords for fuzz testingg-C��6?r}i?Br�r�rX��c�F�rnNr�)rr�rrMr�r�rUr<r�password_alphabetrcrr�rp)rjrrMr�r��sizer�r.r.r/rW�sz-HandlerCase.FuzzHashGenerator.random_passwordcCs||kS)z-verify fuzz pair contains different passwordsr.)rjrAr{r.r.r/rX�sz2HandlerCase.FuzzHashGenerator.accept_password_pairN)r�r�r�r�rr_rZr�rSrTr�r1rUrMrNrOrRrWrXr.r.r.r/r/is"
�		r/c
Cs�|j}|jsB|�t|d��|�t|d��|�|j�|�d��|��}|j|tdd�|j	|�
|�d|d�|���|j
�d}|�|�}|j|tdd�|j	|�
|�d|d�|�td|j|�z|�|�}d	}Wn.t�y
}zd	}|}WYd	}~n
d	}~00|d	u�r4|j|td
d�|�||�n|�|t�|�dt|��|��}|j�rn|�||�n|d	u�r�|�||�|�|�}	|j�r�|�|	|�n|�|	|�|�|d�}
|j�s�|d	u�r�|�|
|�n|�|
|�d	S)z.disable() / .enable() methods�disable�enablerz#disable() must return native stringr�z0identify() didn't recognize disable() result: %rrXzcannot restore original hashNz"enable() must return native stringr�)rMrJr�rHrxr�rar�rwrIr]rrFrZassertRaisesRegexr�rbr�r�ry)rjrMZdisabled_defaultrtZ
disabled_stubr�rA�eZdisabled_default2Zdisabled_stub2Zdisabled_otherr.r.r/�test_disable_and_enablesd
��
���

�

z#HandlerCase.test_disable_and_enable)NF)FNN)N)NN)F)F)F)nr�r�r�r�rMrUr>r?r@rrrrrwr�rrxrr"r=Z_HandlerCase__unittest_skip�propertyr�r�rErGrLrMrTrUr[rHr_rarcrdrerfrkrgrmr�rsrurvr|r}r~r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr	rrrrrrrr#rrrr$r5rDr,r?rKr-rHr�r/rdr�r.r.r�r/r&�s�
�




	






! )	
7#,)
6
2+8<&)34! m&,#&0'
YB


$
r&cs�eZdZdZgZdZdZdZ�fdd�Ze	dd��Z
ed	d
��Zdd�Z
e	�fd
d��Zdd�Zdd�Zdd�Zedd��Zdd�Zdd�Z�ZS)rha�helper used by create_backend_case() which adds additional features
    to test the os_crypt backend.

    * if crypt support is missing, inserts fake crypt support to simulate
      a working safe_crypt, to test passlib's codepath as fully as possible.

    * extra tests to verify non-conformant crypt implementations are handled
      correctly.

    * check that native crypt support is detected correctly for known platforms.
    Tr;Fcs&|j�d�s|��tt|���dS)Nr;)rMrZ�_patch_safe_cryptr�rhr�r�r�r.r/r��szOsCryptMixin.setUpcCs$t|j�}|��t|d�}||fS)z�
        return (handler, backend) pair to use for faking crypt.crypt() support for hash.
        backend will be None if none availabe.
        r;)rQrMrSra)r�rM�alt_backendr.r.r/�_get_safe_crypt_handler_backend�s

z,OsCryptMixin._get_safe_crypt_handler_backendcCs|��dduS)z�
        test if there's a fallback handler to test against if os_crypt can't support
        a specified secret (may be explicitly set to False for some subclasses)
        rN)rhr�r.r.r/�has_os_crypt_fallback�sz"OsCryptMixin.has_os_crypt_fallbackcsZ|��\}}|std��|�����|��fdd�}ddlm}|�|d|�d|_dS)z�if crypt() doesn't support current hash alg, this patches
        safe_crypt() so that it transparently uses another one of the handler's
        backends, so that we can go ahead and test as much of code path
        as possible.
        z,handler has no available alternate backends!cs��||�}|Sr1)rb�rArB�Zalt_handlerr.r/�
crypt_stub�sz2OsCryptMixin._patch_safe_crypt.<locals>.crypt_stubrN�_cryptT)rhr�rWrTr��utilsr��using_patched_crypt)rjrMrgrl�modr.rkr/rf�s
zOsCryptMixin._patch_safe_cryptcsJtt|��|�}ddlm}||jkrF|rFtd�rB|��drBdSdS|S)z|
        make sure os_crypt backend is tested
        when it's known os_crypt will be faked by _patch_safe_crypt()
        r)�	has_cryptrArXNz hash not supported by os crypt())r�rhrfr�rqrer#rh)r�rU�reasonrqr�r.r/rf�sz%OsCryptMixin._get_skip_backend_reasoncs8ddlm}�fdd��|j�_d�_|�|d���S)z�
        patch passlib.utils.safe_crypt() so it returns mock value for duration of test.
        returns function whose .return_value controls what's returned.
        this defaults to None.
        rNcs|dkr��||�S�jSdS)Nr:)�__wrapped__�return_value)rArC��
mock_cryptr.r/rv�sz0OsCryptMixin._use_mock_crypt.<locals>.mock_cryptrm)r�rnrmrsrtr�)rjrpr.rur/�_use_mock_crypt�szOsCryptMixin._use_mock_cryptcsb���d�tjf���������fdd�}|d�dd��|�dd��|�d�dS)	ztest with faulty crypt()rXcs>|�_����jd������jd�����jd��dSr�)rtr�rcr[rHr��Z	exc_typesrBrvrjr.r/r:�sz/OsCryptMixin.test_80_faulty_crypt.<locals>.testz$xr�Nr�r�)rGr�InternalBackendErrorrw)rjr:r.rxr/�test_80_faulty_crypt�sz!OsCryptMixin.test_80_faulty_cryptcCs�|��}d|_|jrJ|�d�}|�d|�}|�||�|�|�d|��nLddlm	}|�
�d}|�||jd�|�||jd|�|�||jd|�dS)ztest per-call crypt() fallbackNrtr)ryrX)rwrtrir[rcr�rIrHrryrGr�)rjrvr�r�Zerr_typerBr.r.r/�test_81_crypt_fallback
s
z#OsCryptMixin.test_81_crypt_fallbackcCs�t|jd�r|�d��|j}|jj}tj}|jD]\}}t�	||�r2q^q2|�d||f��|durx|�d||f��||kr�n*|r�|�
d||f�n|�
d||f�dS)a'
        test platform-specific crypt() support detection

        NOTE: this is mainly just a sanity check to ensure the runtime
              detection is functioning correctly on some known platforms,
              so that we can feel more confident it'll work right on unknown ones.
        rFznot applicable to wrappersz3no data for %r platform (current host support = %r)Nz9varied support on %r platform (current host support = %r)z5expected %r platform would have native support for %rz;did not expect %r platform would have native support for %r)rHrMr�ror��sys�platform�platform_crypt_supportr~rrr")rjZ
using_backendr�r}�patternZexpectedr.r.r/�test_82_crypt_support
s0
����z"OsCryptMixin.test_82_crypt_supportcsP�j}�jst|d�rdSddlm�ddlm��jj�����fdd�}|S)ztest results against OS crypt()rbNr)�crypt)�_safe_crypt_lockcsN��|�sdSt|��}���||�|kWd�S1s@0YdS)zstdlib-cryptrN)�crypt_supports_variantrrj�r�r��encodingrjr.r/�check_cryptS
s


z5OsCryptMixin.fuzz_verifier_crypt.<locals>.check_crypt)rMrorHr�r�r�r/rZ)rjrMr�r.r�r/�fuzz_verifier_cryptE
s	z OsCryptMixin.fuzz_verifier_cryptcCsdS)z~
        fuzzy_verified_crypt() helper --
        used to determine if os crypt() supports a particular hash variant.
        Tr.r^r.r.r/r�^
sz#OsCryptMixin.crypt_supports_variant)r�r�r�r�r~Z_OsCryptMixin__unittest_skiprUror�r�rhrerirfrfrwrzr{r9r�r�r�r�r.r.r�r/rhfs(


/rhc@sReZdZdZdZdZdZdZdd�Zdd�Z	d	d
�Z
dd�ZGd
d�dej
�Z
dS)�UserHandlerMixina(helper for handlers w/ 'user' context kwd; mixin for HandlerCase

    this overrides the HandlerCase test harness methods
    so that a username is automatically inserted to hash/verify
    calls. as well, passing in a pair of strings as the password
    will be interpreted as (secret,user)
    �userTFcCs||j}d}|j||jd�}|jrV|�t|j|�|�t|j||�|�t|j||�n"|�|�|�||�|�||�dS)ztest user context keywordrt�r�N)rMrB�default_user�
requires_userr�r�rbr\)rjrM�passwordrBr.r.r/�test_80_user�
s
zUserHandlerMixin.test_80_usercCsb|j��}|��}|jdt|d�d�}|jrF|�|jd||d�d�n|�|jd||d�d�dS)ztest user case sensitivityrtr�)rYz!user should not be case sensitivezuser should be case sensitiveN)	r�r�r�r[r��user_case_insensitiverIrHr�)rjr�r�rBr.r.r/�test_81_user_case�
s
��z"UserHandlerMixin.test_81_user_casecCsT|��}|jd|dd�}|jd|dd�}|�||�|jd|dd�}|�||�dS)ztest user used as saltrtZadminr��rootN)rdrcr�ry)rjrCr�r�Zh3r.r.r/�test_82_user_salt�
sz"UserHandlerMixin.test_82_user_saltcCs8t|t�r|\}}n|js|S|j}d|vr4||d<|S)zinsert username into kwdsr�)rcr�r�r�)rjrAr`r�r.r.r/rU�
s

z!UserHandlerMixin.populate_contextc@s4eZdZejj��Zejdd�ed�Z	dd�Z
dS)z"UserHandlerMixin.FuzzHashGenerator�random_userr�Z	asdQWE123cCs4|j}|jjs|��dkrdSt||j|�dd��S)Nr'r�r�)rr:r�r�r�
user_alphabetrY)rjrr.r.r/r��
sz.UserHandlerMixin.FuzzHashGenerator.random_userN)r�r�r�r&r/rTrrVrr�r�r.r.r.r/r/�
sr/N)r�r�r�r�r�r�r�Z _UserHandlerMixin__unittest_skipr�r�r�rUr&r/r.r.r.r/r�i
s
r�c@s@eZdZdZdZed�ded�gZGdd�dej�Zdd	�Z	d
S)�EncodingHandlerMixina helper for handlers w/ 'encoding' context kwd; mixin for HandlerCase

    this overrides the HandlerCase test harness methods
    so that an encoding can be inserted to hash/verify
    calls by passing in a pair of strings as the password
    will be interpreted as (secret,encoding)
    Tr:stestu¬ºc@seZdZed�ZdS)z&EncodingHandlerMixin.FuzzHashGeneratoruqwerty1234<>.@*#! ¬N)r�r�r�rr_r.r.r.r/r/�
sr/cCs"t|t�r|\}}|�d|�|S)zinsert encoding into kwdsr�)rcr��
setdefault)rjrAr`r�r.r.r/rU�
s
z%EncodingHandlerMixin.populate_contextN)
r�r�r�r�Z$_EncodingHandlerMixin__unittest_skiprrwr&r/rUr.r.r.r/r��
s
�r�cs:eZdZdZd
�fdd�	Z�fdd�Z�fdd	�Z�ZS)r�z@catch_warnings() wrapper which clears warning registry & filters�always�.*cs4tt|�jfi|��||_|r*t�|�nd|_dSr1)r�r�r��
_reset_filterr~�compile�_reset_registry)rjZreset_filterZreset_registryr`r�r.r/r��
szreset_warnings.__init__cs�tt|���}|jr(t��t�|j�|j}|r�i}|_t	t
j���D]@\}}|dusJ|�
|�sfqJt|dd�}|rJ|��||<|��qJ|S�NZ__warningregistry__)r�r�r�r�r��
resetwarnings�simplefilterr��_orig_registryr�r|�modulesrrrr�r�clear)rjr�r�backupr�rp�regr�r.r/r��
s

zreset_warnings.__enter__cs�|j}|r�|j}ttj���D]b\}}|dus|�|�s:qt|dd�}|rR|��|�	|�}|r|durvt
|d|�q|�|�qtt
|�j|�dSr�)r�r�r�r|r�rrrr�r�rr-rVr�r�r�)rjr�rr�r�rpr�rVr�r.r/r�s
zreset_warnings.__exit__)r�r�r�r.r.r�r/r��
sr�)NN)N)NF)NrXr�)r�r�)jr�Z
__future__rZbinasciirr5�	functoolsrrrr0rr�r�r�r~r(r|r!r2r+rrrrrr	r�r
ZpasslibrrZpasslib.registry�registryZpasslib.tests.backportsr
r4rrrrr�rrrrr	rrrrrrrrrrr r!Zpasslib.utils.decorr"Zpasslib.utils.handlersrnrnrK�__all__Zgoogle.appengineZgoogle�ImportErrorrr0r>ZTICK_RESOLUTIONrCrDrrrr�rBr#rNrRrWr^rarQrhr6rmr$r%r|r�r�r�r�r�r�r9r&rhr�r�r1r�r.r.r.r/�<module>s�0 
	�



 

Fya&

Youez - 2016 - github.com/yon3zu
LinuXploit