__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
�

�M�g�@���SrSSKJr SSKJr SSKrSSKJrJr SSK	r	SSK
r
\
R"\5r
SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKJrJr SSKJrJr SSKrSSKJr SS	KJr SS
KJr SSK J!r! SSK"J#r$J%r%J&r&J'r'J(r( SSK)J*r*J+r+J,r,J-r.J/r/J0r0J1r1J2r2J3r3J4r4 SS
KJ5r5J6r6J7r7J8r8J9r9J:r: SSK;J<r< SSK=J>s J?r@ /SQrASSKBrCSrDSrFSrG\G"\35rH/SQrI\IR�\R�R�SS5R�5R�55rOS6SjrPSrQS7SjrRSrSS8SjrTSrUSrVSrW\R�S5rYS rZS!r[S"r\S#r]S$r^S%r_S9S&jr`S:S'jra"S(S)\$5r#S*S/rbS+rc"S,S-\#5rd"S.S/\d5re"S0S1\d5rf"S2S3\d5rg"S4S5\R�5rig!\Ea SrDGNf=f);zhelpers 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�HandlerCaseTFc�.�[RRU5n[RRU5U:XaS[R"S5 [R
"US5 [RRU5U:XaMRgg)zensure file's mtime has changed皙�����?N)�os�path�getmtime�time�sleep�utime)r+�lasts  �5/usr/lib/python3/dist-packages/passlib/tests/utils.py�ensure_mtime_changedr2;sa���7�7���D�!�D�
�'�'�
�
�4�
 �D�
(��
�
�3��
����t��
�'�'�
�
�4�
 �D�
(�c�N^^�U4Sjm[U4Sj[S555$)Nc�B>�T"5=pX:XaT"5nX:XaMX-
$�N�)�start�cur�timers  �r1�sample�%_get_timer_resolution.<locals>.sampleEs(����g����l��'�C��l��y�r3c3�2># �UHnT"5v� M g7fr6r7)�.0�_r;s  �r1�	<genexpr>�(_get_timer_resolution.<locals>.<genexpr>Js����*��A�v�x�x��s��)�min�range)r:r;s`@r1�_get_timer_resolutionrEDs����
�*��q��*�*�*r3)�quick�default�full�PASSLIB_TEST_MODErGc��U(a[[RU5:agU(a[[RU5:�agg)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)rC�maxs  r1r$r$Ts7��&�z�K�-�-�c�2�2��
�z�K�-�-�c�2�2��r3c��[US5(agSUR;=(d [U[R5$)z'check if handler supports 'relaxed' kwd�orig_prefixF�relaxed)�hasattr�setting_kwds�
issubclass�uh�GenericHandler��handlers r1�has_relaxed_settingrYpsA���w�
�&�&����,�,�,�N�
�7�;=�;L�;L�1N�Nr3c�:�[U5nU"USS9R$)z'get effective rounds value from handlerT)�rounds�use_defaults)�unwrap_handlerr[)rXr[s  r1�get_effective_roundsr^|s���W�%�G��&�t�4�;�;�;r3c���UR5nURS5 UR5U:HURU5 $![a gf=f!URU5 f=f)z*check if backend is the default for sourceFrG)�get_backendr
�set_backend)rX�backend�origs   r1�is_default_backendrd�sl����"�"�$��"����I�&��"�"�$��/����D�!��
�����	���D�!�s�A�#A�
A�A�A+c#��# �UcUR5nURnU(aURU5S-OSnX4SH&nXQ:wdM
URU5(dM"Uv� M( g7f)zs
iterate over alternate backends available to handler.

.. warning::
    not thread-safe due to has_backend() call
N�r)r`�backendsrM�has_backend)rX�current�fallbackrg�idxrbs      r1�iter_alt_backendsrl�se������%�%�'�����H�'/�(�.�.��
!�!�
#�Q�C��D�>����'�"5�"5�g�">�">��M�"�s�AA.�
A.�%	A.c�,�[U0UD6HnUs $ gr6)rl)�args�kwdsrbs   r1�get_alt_backendrp�s��$�d�3�d�3����4�r3c�f�[US5(aURn[US5(aMU$)z5return original handler, removing any wrapper objects�wrapped)rRrrrWs r1r]r]�s,��
�'�9�
%�
%��/�/���'�9�
%�
%��Nr3c�.�X:Xag[U[R5(a#U(aX:XagURnU(aMg[U[5(a*[U[R5(a[X5$[SU<35e)z?
test if <handler> was derived from <base> via <base.using()>.
TFz#don't know how to inspect handler: )�
isinstancerU�
PrefixWrapper�
_derived_from�typerT�MinimalHandler�NotImplementedError)rX�bases  r1�handler_derived_fromr{�sy�����	�G�R�-�-�	.�	.������+�+�G�	�g�
�	�G�T�	"�	"�z�'�2�;L�;L�'M�'M��'�(�(�!�W�"V�W�Wr3c#�^# �[U[5(aD[U[R5(a%UR
mU4SjnXlSv� TUlg[U[R5(a#[UR5 Sv� SSS5 gSv� g!TUlf=f!,(df   g=f7f)z�
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.
c�z>�URnURUlT"U/UQ70UD6X0l$!X0lf=fr6)r[�
min_rounds)�selfrnror[rrs    �r1�wrapper�&patch_calc_min_rounds.<locals>.wrapper�s9����[�[�F�
%�"�o�o����t�3�d�3�d�3�$���f��s�2�:N)	rtrwrTrU�	HasRounds�_calc_checksumru�patch_calc_min_roundsrr)rXr�rrs  @r1r�r��s������'�4� � �Z�����%F�%F��(�(��	%�")��	-��%,�G�"�	�G�R�-�-�	.�	.�
"�7�?�?�
3��4�
3�	���
&-�G�"��
3�
3�s6�A
C�B$�<C�B0�C�$	B-�-C�0
B>�:Cc��[U[5(aURS5n[US5nUR	U5 SSS5 g!,(df   g=f)zset file to specified bytes�utf-8�wbN)rtr �encode�open�write)r+�content�fhs   r1r%r%�sA���'�7�#�#��.�.��)��	
�d�D�	�R�
�����
�	�	�s�A�
Ac�p�[US5nUR5sSSS5 $!,(df   g=f)zread file as bytes�rbN)r��read)r+r�s  r1r&r&�s#��	
�d�D�	�R��w�w�y�
�	�	�s�'�
5c���[U[5(dU$[(aURS5$UR	S5$![
a UR	S5s$f=f)z*convert native string to non-native stringr��latin-1)rt�strr	r��decode�UnicodeDecodeError��sources r1�tonnr��sZ���f�c�"�"��
�	���}�}�W�%�%�	,��=�=��)�)��!�	,��=�=��+�+�	,�s�A�A$�#A$c�D�[[R"SSU55$)zH
helper for represent byte strings in hex.

usage: ``hb("deadbeef23")``
z\s�)r�re�subr�s r1�hbr��s���R�V�V�E�2�v�.�/�/r3c�"�X:aU$X:�aU$U$r6r7)�value�lower�uppers   r1�limitr��s���}���	�����Lr3c�d�[5n[5U-
U:a[5U-
U:aMgg)zAbecause time.sleep() doesn't even have 10ms accuracy on some OSesN�r)�delayr8s  r1�
quicksleepr�s*���F�E�
�&��,��
���&��,��
r3c���SSKJn SSKJn U"X=(d SS9nSn[	5U-n[UR
X755n	[	5U:�aX�-[U"US554$US-nME)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�)�setuprf�
)�timeitr��mathr�rrC�repeat�int)
�funcr��maxtime�bestofr�r�r:�number�end�deltas
          r1�	time_callr�	sn�����$�k�r�*�E�
�F�
�&�7�
�C�
��E�L�L��0�1���6�S�=��<��S���_�!5�5�5��"���	r3c�^^�UU4SjnU$)z4
decorator run test method w/ multiple fixed seeds.
c�6>^�[T5UUU4Sj5nU$)Nc�>�[R"T5n[T5HnURS5US'T"U0UD6 M! g)N� �seed)�random�Randomr�getrandbits)rnrorr?�countr��master_seeds    ���r1r��6run_with_fixed_seeds.<locals>.builder.<locals>.wrapper s>����-�-��,�C��E�]��"���r�2��V���d�#�d�#�#r3)r)r�r�r�r�s` ��r1�builder�%run_with_fixed_seeds.<locals>.builders ���	�t��	$�
�	$�
�r3r7)r�r�r�s`` r1�run_with_fixed_seedsr�s�����Nr3c�^�\rSrSrSrSrU4Sjr\S5r\S5r	Sr
SrU4SjrS	r
SrS
rSU4SjjrSr\=rrSS
jr"SS\R,5rS SjrSSjrSrSrSrSrSr\R@"5r!Sr"Sr#S!Sjr$\%"\&S5r'\(RRU4Sj5r*Sr+Sr,S"Sjr-Sr.Sr/U=r0$)#ri-a6passlib-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
Nc�>�[[U]5nURnU(aU<SU=(d [	U5<3nU$)z;wrap shortDescription() method to prepend descriptionPrefix�: )�superr�shortDescription�descriptionPrefixr�)r�desc�prefix�	__class__s   �r1r��TestCase.shortDescriptionBs;����X�t�5�7���'�'���%�t�'8�s�4�y�'8�9�D��r3c�j�URnURS5=(d [USU-S5$)Nr?z_%s__unittest_skipF)�__name__�
startswith�getattr)�cls�names  r1�__unittest_skip__�TestCase.__unittest_skip__Ns7���|�|�����s�#�@��s�0�4�7��?�	@r3c�$�UR(+$r6)r��r�s r1�__test__�TestCase.__test__Us���(�(�(�(r3Tc�x>�[[U]5 UR5 UR	[
SS5 g)N�ENABLE_DEBUG_ONLY_REPRT)r�r�setUp�
setUpWarnings�	patchAttrr�rr�s �r1r��TestCase.setUpds-���
�h��#�%��������s�4�d�;r3c��UR(a{[5nUR5 URUR5 [
R"SS5 [
R"SS5 [
R"SS5 gg)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)r�ctxs  r1r��TestCase.setUpWarningsjsf���!�!� �"�C��M�M�O��O�O�C�L�L�)�
�#�#�H�.m�n��#�#�H�.W�X��#�#�H�.a�b�"r3c��UR(aBU(a;UR5RS5(aUR5<SU<3$U=(d U$)N�:� )�longMessage�rstrip�endswith)r�msg�stds   r1�_formatMessage�TestCase._formatMessage�s>�������
�
��(=�(=�c�(B�(B�!�j�j�l�C�0�0��:�#�r3c��>�URSS5nUc[[U]"US/UQ70UD6$U"U0UD6nSU<SU<3nUR	URXX55e!UanUsSnA$SnAff=f)N�__msg__zfunction returned z, expected it to raise )�popr�r�assertRaises�failureExceptionr�)
r�	_exc_type�	_callablernror��result�errr�r�s
         �r1r��TestCase.assertRaises�s�����h�h�y�$�'������4�5�i��E�7;�E�?C�E�
E�	���-��-�F�BH�AJ�L���#�#�D�$7�$7��$A�B�B��	�	��J��	�s�A#�#A5�)A0�*A5�0A5c��[S5e)Nz%this alias is deprecated by unittest2)�AssertionError)r�a�ks   r1�assertEquals�TestCase.assertEquals�s���D�E�Er3c	��[US5(aUn	URnOSn	U(aUR[U5X85 U(aUR	[U5X(5 U(aURXU5 U(dU(a�U	(d[
S5eU	Rn
U
RS5(dU
RS5(aU
SSn
U(aURX�U5 U(aUR	X�U5 U(a/U	(d[
S5eURU	RXx5 gg)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)
rR�message�assertEqualr��assertRegex�assertIsInstance�	TypeError�filenamer��lineno)r�warning�
message_rer
r�filename_rerrr��wmsg�reals           r1�
assertWarning�TestCase.assertWarning�s���7�J�'�'��D��o�o�G��D�����S��\�7�8�����S��\�:�;���!�!�'�S�9��{���!:�;�;��=�=�D��}�}�V�$�$��
�
�f�(=�(=��C�R�y���� � ���5��� � ��C�8����!:�;�;����T�[�[�&�6�	r3c�8^�\rSrSrSrU4SjrSrSrSrU=r	$)�TestCase._AssertWarningListi�z'context manager for assertWarningList()c�>�XlX l[[RU5UlUR
R
SS9 g)NT��record)�caseror�r�_AssertWarningList�_AssertWarningList__super�__init__)rrror�s   �r1r �$TestCase._AssertWarningList.__init__�s6����I��I� ��!<�!<�d�C�D�L��L�L�!�!��!�.r3c�B�URR5Ulgr6)rr�r��rs r1r��%TestCase._AssertWarningList.__enter__�s���|�|�-�-�/�D�Hr3c��URR"U6 USc2URR"UR40UR
D6 gg�Nr)rr�r�assertWarningListr�ro)r�exc_infos  r1r��$TestCase._AssertWarningList.__exit__�sB���L�L�!�!�8�,���{�"��	�	�+�+�D�H�H�B��	�	�B�#r3)�__superrror��
r��
__module__�__qualname__�__firstlineno__�__doc__r r�r��__static_attributes__�
__classcell__�r�s@r1rr�s���5�	/�	0�	C�	Cr3rc��UcUceURXUS9$Uce[U[[45(dU/n[	U5H�upE[U[
5(a
[
US9nOT[U[5(a[U[5(a
[
US9nO [U[5(d[S5eXnUR"U4SU0UD6 M� [U5[U5:XagS[U5[U5URU5U4-nURUR!X755e![a  MXf=f)zBcheck that warning list (e.g. from catch_warnings) matches patternN)r�r�)r�rz#entry must be str, warning, or dictr�z0expected %d warnings, found %d: wlist=%s desc=%r)rrt�list�tuple�	enumerater��dictrwrT�Warningr�
IndexErrorr�len�_formatWarningListr�r�)r�wlistr�r�rk�entry�datar�s        r1r'�TestCase.assertWarningList�sE���<��$�$�$��*�*�4��*�E�E������$��e��-�-��6�D�#�D�/�J�C��%��%�%���.���E�4�(�(�Z��w�-G�-G��e�,����t�,�,�� E�F�F�
��z��
���t�6��6��6�*��5�z�S��Y�&��@��T��C��J��(?�(?��(F��M�N���#�#�D�$7�$7��$A�B�B���
��
�s�E�
E�Ec�D�Uc/nUR"X/UQ70UD6 USS2	g)zD[deprecated] assertWarningList() variant that clears list afterwardsN)r')rr=r�rnros     r1�consumeWarningList�TestCase.consumeWarningLists+���<��D����u�:�T�:�T�:��!�Hr3c�8�Sn[US5(aNSUR<SUR<3nUR(aUSUR<3-
nURn[U5nSUR<SUR<S[U5<U<S	3$)
Nr�r
z
 filename=z lineno=z line=�<�.z	 message=�>)	rRrr�liner
rwr,r�r�)rr>�tailr�s    r1�_formatWarning�TestCase._formatWarningsp�����5�)�$�$�/4�~�~�u�|�|�L�D��z�z��e�j�j�2�2���M�M�E��5�k��),������+.�u�:�t�=�	=r3c�@^�SSRU4SjU55-$)Nz[%s]�, c3�F># �UHnTRU5v� M g7fr6)rJ)r>r>rs  �r1r@�.TestCase._formatWarningList.<locals>.<genexpr>s����!P�%��$�"5�"5�e�"<�"<�%�s�!)�join)rr=s` r1r<�TestCase._formatWarningLists�����	�	�!P�%�!P�P�P�Pr3c�R�SSKJn U(dSSKJn URSU-5eg)z,helper to skip test if stringprep is missingr)�
stringprep)�_stringprep_missing_reasonz%not available - stringprep module is N)�
passlib.utilsrSrT�skipTest)rrSrTs   r1�require_stringprep�TestCase.require_stringpreps,��,��@��-�-� G� :�!;�<�
<�r3c�L�[U5(dURSU-5eg)z8skip test for all PASSLIB_TEST_MODE values below <level>zrequires >= %r test modeN)r$rV)r�levels  r1�require_TEST_MODE�TestCase.require_TEST_MODE!s'�������-�-� :�U� B�C�C� r3c�<�[(aURS5$g)z'skip test if writeable FS not availablez.GAE doesn't offer read/write filesystem accessN)�GAErVr#s r1�require_writeable_filesystem�%TestCase.require_writeable_filesystem&s���3��=�=�!Q�R�R�r3c��URnU(a	X;aX1$UR URnU(aX;a
X1sSSS5 $U(d0=o0lU=(d [RnUc�[	[
RRS5=(d< [
RRS5=(d [R"S55=n[l[RSU5 [U5nSR[U5URUR UR"U/5n[$R&"UR)S55R+5n[	USSS5n[,R."U5=o�U'UsSSS5 $!,(df   g=f)	a�
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
N�RANDOM_TEST_SEED�PYTHONHASHSEEDr�zusing RANDOM_TEST_SEED=%d�
r��)�
_random_cache�_random_global_lockr�_random_global_seedr�r*�environ�get�sys_rngr�r��inforwrPr�r,r��_testMethodName�hashlib�sha256r��	hexdigestr�r�)	rr�r��cache�global_seedr�r��digestr�s	         r1�	getRandom�TestCase.getRandom9sd��2�"�"���T�]��;��
�
%�
%��&�&�E�����{�&�
%��-/�/��*��>�(�">�">�K��"���
�
���'9�:�0��
�
���'7�8�0��+�+�B�/�1�1��h�:�
���4�k�B��t�*�C��Y�Y��K� 0�#�.�.�#�,�,� $� 4� 4�d� <�=�F��^�^�F�M�M�'�$:�;�E�E�G�F��v�c�r�{�B�'�D�#)�-�-��"5�5�E�$�K��=&�
%�
%�s�F5�EF5�5
G�subTestc
/��># �SSjnUR5nU"U0UD6nUR(a[[U]"U0UD6nO
[5nU UR
SU5 Sv� SSS5 UR
SU5 g![a UR
SU5 N9[a6nURSU[U5R[U55 eSnAff=f!,(df   N�=f7f)z\
wrapper/backport for .subTest() which also traps SkipTest errors.
(see source for details)
Nc��U(aSU-OSnU(a,USSRSUR555--
nUR5=(d S$)Nz[%s] r�z(%s)r�c3�># �UHnS[U5-v� M g7f)z%s=%rN)r6)r>�items  r1r@�:TestCase.subTest.<locals>._render_title.<locals>.<genexpr>�s���(Z�>�4��5��;�)>�>�s�z	<subtest>)rP�items�strip)�_msg�params�outs   r1�
_render_title�'TestCase.subTest.<locals>._render_title�sG��%)�7�T�>�r�C���v����(Z�6�<�<�>�(Z� Z�Z�Z���9�9�;�-�+�-r3zrunning subtest: %szsubtest skipped: %szsubtest failed: %s: %s: %rzsubtest passed: %sr6)
�	getLogger�has_real_subtestr�rrvr"rlr�	Exceptionrrwr�r�)	rrnror��test_log�titler�r�r�s	        �r1rv�TestCase.subTest|s�����*	.��>�>�#���t�,�t�,��� � ���$�/��>��>�C��-�C���M�M�/��7�

���	�
�
�*�E�2���
��
�
�3�U�;���
�� � �!=�u�d�3�i�FX�FX�Z]�^a�Zb�c���	
���S�sH�AC7�C&�'B�+C7�C#�"C&�$	C#�-1C�C#�#C&�&
C4�0C7c�^�UR5 [R"U0UD6up4[R"U5 UR
mTc /=mUlU4SjnUR
U5 TRU5 U$)z1create temp file that's cleaned up at end of testc�>�TH?n[RRU5(dM)[R"U5 MA TSS2	gr6)r*r+�exists�remove)r+�queues �r1�cleaner� TestCase.mktemp.<locals>.cleaner�s4���!�D��w�w�~�~�d�+�+��	�	�$��"��!�Hr3)r_�tempfile�mkstempr*�close�
_mktemp_queuer��append)rrnro�fdr+r�r�s      @r1�mktemp�TestCase.mktemp�sr����)�)�+��#�#�T�2�T�2���
������"�"���=�)+�+�E�D�&�
�

�O�O�G�$�
���T���r3c�^^�[TT5nUR[TTU5 U(a[	UW5n[U5"U5 [TTU5 g![a# U(aeUU4SjnURU5 N^f=f)z=monkeypatch object value, restoring original value on cleanupc�@>�[TT5 g![a gf=fr6)�delattr�AttributeError)�attr�objs��r1�cleanup�#TestCase.patchAttr.<locals>.cleanup�s$�����C��&��%����s��
�N)r�r��setattrr�rr)rr�r�r��require_existing�wraprcr�s ``     r1r��TestCase.patchAttr�sy���	6��3��%�D�
�O�O�G�S�$��5���E�4�(�E��$�K�����T�5�!���	%���
�

�O�O�G�$�	%�s�A�*B�Bc���[U5nURS-[USUR5-nURnU(aUS-U-n[
R"U5$)z)
return logger named after current test.
rFr-)rwr,r�r�rm�loggingr�)rr�r+r�s    r1r��TestCase.getLogger�sZ���4�j���~�~��#�g�c�>�3�<�<�&P�P���#�#����#�:��$�D�� � ��&�&r3)r�rfr6)NNNNNNN)NNN)rGN)TF)1r�r,r-r.r/r�r�r#r�r��_TestCase__unittest_skipr�r�r�r�r�r�r�assertNotEquals�assertRegexMatchesrr��catch_warningsrr'rBrJr<rWr[r_�	threading�LockrgrhrfrtrR�	_TestCaser��
contextlib�contextmanagerrvr�r�r�r�r0r1r2s@r1rr-s5����$����@��@��)��)�
�O���<�c�,�K��C�"F�+7�7�O�(�7;�&*�8<�$(�!%�.7�`C�X�4�4�C� C�8�
=�Q�<�D�
S�$�.�.�*�����M�;�B�y�)�4�����33��33�p�M��""�(
'�
'r3r�anyc��SUlU$)a
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_backend)r�s r1�doesnt_require_backendr��s��$(�D� ��Kr3c�^�\rSrSrSrSrSr/r/r/r	/r
/r/SQr\
"S5\
"S5S/rSrSrSrSr\S	5rS
r\S5r\S5rS
rS_SjrSrSrSrS`SjrSaSjr Sr!Sr"Sr#SbSjr$Sr%\S5r&\S5r'Sr(Sr)U4Sjr*Sr+Sr,Sr-ScS jr.S!r/S"r0S#r1S$r2S%r3S&r4\S'5r5S(r6S)r7S*r8Sr9S+r:S,r;\S-5r<S.r=S/r>S0r?S1r@S2rAS3rBU4S4jrCS5rDS6rES7rFS8rGS9rHS:rIS;rJS<rKS=rLS>rMS?rNS@rOSArPSBrQSCrRSDrSSErTSFrUSGrVSHrWSIrXSJrYSKrZSLr[SMr\SNr]SOr^/r_SPr`SQraSRrbSSrcScSTjrdSUre\SV5rf\SW5rgSXrhScSYjriSZrj"S[S\\k5rlS]rmS^rnU=ro$)dr'i�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))�	des_crypt�
6f8c114b58f2c)�	md5_cryptz"$1$dOHYPKoP$tnxS1T8Q6VVn3kpV8cN6o.)�sha512_cryptzx$6$rounds=123456$asaltof16chars..$BtCwjqMJGx5hrJhZywWvt0RLE8uZ4oPwcelCjmw2kSYu.Ec6ycULevoBK25fs2xXgMNrCzIMVcgEJAstJeonj1�testu€¥$s€¥$Fc�<�S[URSS5;agg)N�os_cryptrgr7�)r�rXr�s r1�forbidden_characters� HandlerCase.forbidden_charactersZs�������j�"�=�=��r3Tc��URnURn[US5(aUSUR5<S3-
nU$)Nr`� (�	 backend))rXr�rRr`)rrXr�s   r1r��HandlerCase.descriptionPrefixgs<���,�,���|�|���7�M�*�*��w�':�':�'<�>�>�D��r3c#�# �URH
upX4v� M URHup1nX4v� M
 URHupAnX4v� M
 g7f)z*iterate through known (secret, hash) pairsN)�known_correct_hashes�known_correct_configs�known_alternate_hashes)r��secret�hash�config�alts     r1�iter_known_hashes�HandlerCase.iter_known_hashesvs[��� �4�4�L�F��,��5�$'�$=�$=� �F�D��,��%>�!$�!;�!;��C���,��"<�s�AAc�r�[UR55nUR5RU5$)z#test random sample secret/hash pair)r5r�rt�choice)r�knowns  r1�get_sample_hash�HandlerCase.get_sample_hash�s-���T�+�+�-�.���~�~��&�&�u�-�-r3c�V�URX5nURUSL=(d USLSU<35 URR(dU(a*U(dgU(d
SU<SU<3nUR	U5eU(agU(d
SU<SU<3nUR	U5e)z>helper to check verify() outcome, honoring is_disabled_handlerTFz%verify() returned non-boolean value: Nz)verify incorrectly returned True: secret=�, hash=zverify failed: secret=)�	do_verify�
assertTruerX�is_disabledr�)rr�r�r��negater�s      r1�check_verify�HandlerCase.check_verify�s�������-������$��9�&�E�/��EK�M�	O��<�<�#�#�v������&���'�'��,�,����=C�T�J���'�'��,�,r3c�@�URU[U<SU<35 g)Nz#() failed to return native string: )r
r�)rr��	func_names   r1�check_returned_native_str�%HandlerCase.check_returned_native_str�s�����f�c�9B�F�L�	Nr3c��URnSUR;amSU;afURnURn[	SS9(a[SU5US'gSn[
USS5S:XaXE-nOUSU--n[SX45US'ggg)	z0subclassable method to populate default settingsr[rF�rNrB�rounds_costN�log2rf)rXrSr~�default_roundsr$rNr�)rrorX�mn�df�factors      r1�populate_settings�HandlerCase.populate_settings�s����,�,���w�+�+�+���0D��#�#�B��'�'�B��W�%�!$�Q����X�����7�M�4�8�F�B��L�B��A�v�I�&�B�!$�Q����X��1E�+r3c��U$)z?subclassable method allowing 'secret' to be encode context kwdsr7)rr�ros   r1�populate_context�HandlerCase.populate_context�s���
r3c���URU5 Uc0nURX5nU(an/nU(a$UR"S0UD6 UR"S5 UR	U5 U=(d UR
R"U40UD6sSSS5 $U=(d UR
R"S0UD6R"U40UD6$!,(df   g=f)z3call handler's hash() method with specified optionsNz"passing settings to.*is deprecatedr7)	r�r��updater�r'rX�encrypt�usingr�)rr��use_encryptrX�context�settingsr�s       r1�
do_encrypt�HandlerCase.do_encrypt�s������x�(��?��G��&�&�v�7����H�����*��*���� D�E��'�'��1��/�4�<�<�8�8��K�7�K�2�1��+�t�|�|�2�2�>�X�>�C�C�F�V�g�V�V�	2�1�s�-&C�
C!c�p�URX5nU=(d URR"X40UD6$)zcall handler's verify method)r�rX�verify)rr�r�rXros     r1r��HandlerCase.do_verify�s1���&�&�v�4���'�4�<�<�/�/��E��E�Er3c�8�URRU5$)zcall handler's identify method)rX�identify�rr�s  r1�do_identify�HandlerCase.do_identify�s���|�|�$�$�T�*�*r3c�\�URU5 URR"S0UD6$)z6call handler's genconfig method with specified optionsr7)r�rX�	genconfig)rros  r1�do_genconfig�HandlerCase.do_genconfig�s(�����t�$��|�|�%�%�-��-�-r3c�^�URX5nURR"X40UD6$)z4call handler's genhash method with specified options)r�rX�genhash)rr�r�ros    r1�
do_genhash�HandlerCase.do_genhash�s,���&�&�v�4���|�|�#�#�F�;�d�;�;r3c���U=(d URR"S0UD6nUc0nURSU5n[U5 UR"U40UD6sSSS5 $!,(df   g=f)z~
return sample hash for handler, w/o caring if digest is valid
(uses some monkeypatching to minimize digest calculation cost)
Nr�r7)rXr�r�r�r�)rrXr�r�r�s     r1�do_stub_encrypt�HandlerCase.do_stub_encrypt�sa��
�*�d�l�l�1�1�=�H�=���?��G��&�&�r�7�3��
"�7�
+��<�<��2�'�2�,�
+�
+�s�A%�%
A3zbackend not availablec��URn[X!5(d[S5(dgURU5(agUR$)zi
helper for create_backend_case() --
returns reason to skip backend, or None if backend should be tested
rHz$only default backend is being testedN)rXrdr$rh�_BACKEND_NOT_AVAILABLE)r�rbrXs   r1�_get_skip_backend_reason�$HandlerCase._get_skip_backend_reason�sE���+�+��!�'�3�3�I�f�<M�<M�9����w�'�'���)�)�)r3c�@�URnURn[US5(dS5eXR;dSU<35eU4nUS:Xa
U[4-
n[U<SU<S3U[
U<SU<S3UURU5URS	95nU$)
Nrgz0handler must support uh.HasManyBackends protocolzunknown backend: r�r?�_testr�r�)r�rb�_skip_backend_reasonr,)	rXr�rRrg�OsCryptMixinrwr8r	r,)r�rbrXr��bases�subclss      r1�create_backend_case�HandlerCase.create_backend_cases����+�+���|�|���w�
�+�+�_�-_�_�+��*�*�*�N�W�,N�N�*�����j� ��l�_�$�E�� �'�*���7;�W�"E��%(�%A�%A�'�%J��>�>�	
�	
���
r3c�R�[XRS5n[USS5(+$)zM
check if current test method decorated with doesnt_require_backend() helper
Nr�F)r�rm)r�meths  r1�_test_requires_backend�"HandlerCase._test_requires_backends)���t�1�1�4�8���4�!:�E�B�B�Br3c�F>�UR5nU(a,UR(aURUR5e[[U]5 URnURnU(aX[US5(d[S5eURURUR55 URU5 SSKJn UR%USUR'S55 g![RRa U(aeNQf=f)Nraz)handler doesn't support multiple backendsr)�handlersrzsalt generator)rr
rVr�r'r�rXrbrR�RuntimeErrorr�rar`rUrr
rUrr�rt)r�test_requires_backendrXrbrr�s     �r1r��HandlerCase.setUp$s����!%� ;� ;� =�� �T�%>�%>��-�-�� 9� 9�:�:�
�k�4�&�(�
�,�,���,�,����7�M�2�2�"�#N�O�O�
����� 3� 3�W�5H�5H�5J�K��#�#�G�,�	+����x�����7G�(H�I���6�6�-�-�
�(��)�
�s�;C7�7&D �D c��^�URmU4SjnU"S5nURUS5 URU[S5 URUR	5U:HS5 UR[
R"SU5SU<35 U"S5nURUS	LS
5 URU[S5 U"S5nURUS	LS
5 URU[S5 g	)zvalidate required attributesc�>�[TUS5$r6)r�)r�rXs �r1�ga�3HandlerCase.test_01_required_attributes.<locals>.gaHs����7�D�$�/�/r3r�zname not defined:zname must be native strzname not lower-case:z^[a-z0-9_]+$z$name must be alphanum + underscore: rSNzsetting_kwds must be defined:zsetting_kwds must be a tuple:�context_kwdszcontext_kwds must be defined:zcontext_kwds must be a tuple:)rXr�r
r�r�r��matchr6)rrr�r�r�rXs     @r1�test_01_required_attributes�'HandlerCase.test_01_required_attributesEs�����,�,��	0��&�z������1�2����d�C�)B�C�����
�
���,�.D�E���������6�DH�J�	L��n�%�������,�.M�N����h��/N�O�
�^�$������t�+�-L�M����g�u�.M�Nr3c��UR5nURUS5 URSU5nURUS5 URSU5 UR	URU5SU<35 g)z�test basic config-string workflow

this tests that genconfig() returns the expected types,
and that identify() and genhash() handle the result correctly.
r��stubrr�z2identify() failed to identify genconfig() output: N)r�r�rr�r�r�)rr�r�s   r1�test_02_config_workflow�#HandlerCase.test_02_config_workflowesw���"�"�$���&�&�v�{�;������0���&�&�v�y�9�	
���r�6�"�	
����(�(��0�
�
�	r3c��URnUR5nURX!5 URURUR5 g)ztest basic using() workflowN)rXr��assertIsNotrr�)rrXrs   r1�test_02_using_workflow�"HandlerCase.test_02_using_workflow�s<���,�,�����������)�������g�l�l�3r3c
�6�SnURGH�nURX1S9nURUS5 URX45 URX$SS9 UR	X45nURUS5 UR
R(a0UR(aURXTSU<SU<S	U<35 OURXTS
U<SU<S	U<35 UR	X$5nURUS5 UR
R(a4UR(d#URXTSU<SU<SU<S	U<35 O"URXTS
U<SU<SU<S	U<35 URURU55 GM� g)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.
r%)r�r�T)r�rz-genhash() failed to salt result hash: secret=� hash=�	: result=z+genhash() failed to reproduce hash: secret=z4genhash() failed to reproduce disabled-hash: secret=z other_secret=z"genhash() duplicated hash: secret=z wrong_secret=N)�stock_passwordsr�r�r�rrXr��disabled_contains_salt�assertNotEqualrr�r�)r�
use_16_legacy�wrong_secretr�r��others      r1�test_03_hash_workflow�!HandlerCase.test_03_hash_workflow�sf�����*�*�F�
�_�_�V�_�G�F��*�*�6�6�:�

���f�-����l�4��@�
�O�O�F�3�E��*�*�5�)�<��|�|�'�'�D�,G�,G��#�#�E�6�%+�V�U�4<�=�� � ���"(�&�%�19�:��O�O�L�9�E��*�*�5�)�<��|�|�'�'��0K�0K�� � ���"(�&�,��1G�H��#�#�E�6�"(�&�,��4G�H�
�O�O�D�,�,�V�4�5�[+r3c�"�URSS9 g)zEtest hash-string workflow with legacy .encrypt() & .genhash() methodsT)r2N)r5r#s r1�test_03_legacy_hash_workflow�(HandlerCase.test_03_legacy_hash_workflow�s���"�"��"�6r3c�.�UR[S55nURUS5 URS[U55 UR[S5[U55 UR	S[U55nURUS5 UR
R(a#UR(aURX!5 OURX!5 UR	[S5[U55nURUS5 UR
R(a#UR(aURX!5 OURX!5 URUR[U555 g)z#test hashes can be unicode or bytesr%r�rN)r�r�r�r�rrXr�r0r1rr�r�)rr�r4s   r1�test_04_hash_types�HandlerCase.test_04_hash_types�s%������f��.���&�&�v�v�6�	
���&�$�v�,�/�	
���$�v�,��V��5������V��5���&�&�u�i�8��<�<�#�#��(C�(C�����.����U�+�����V��d�6�l�;���&�&�u�i�8��<�<�#�#��(C�(C�����.����U�+�	
����(�(��f��6�7r3c�@�URn[US5(dURS5eURURUR55 URH�nURU[5 URU[SU<35 URU5nUSLa3UR	U5 URUR5U5 M}USLa#UR[URU5 M�[SU<SU<35e g)	ztest multi-backend supportrazhandler only has one backendzinvalid backend name: TFzhas_backend(z) returned invalid value: N)rXrRrVr�rar`rgr
r��assertNotIn�RESERVED_BACKEND_NAMESrhrr�r
r)rrXrb�rets    r1�test_05_backends�HandlerCase.test_05_backends�s���,�,���w�
�.�.��-�-� >�?�?�	
����+�+�W�-@�-@�-B�C��'�'�G�

�!�!�'�3�/����W�&<�;B�D�
F��%�%�g�.�C��d�{��#�#�G�,�� � ��!4�!4�!6��@�����!�!�"5�w�7J�7J�")�+� �/6��!=�>�>�5(r3c�Z�SURR;aURS5eg)N�saltzhandler doesn't have salt)rXrSrVr#s r1�require_salt�HandlerCase.require_salt!s)������2�2�2��-�-� ;�<�<�3r3c�z�UR5 [UR5(dURS5eg)Nz!handler doesn't provide salt info)rErrXrVr#s r1�require_salt_info�HandlerCase.require_salt_info%s2�������T�\�\�*�*��-�-� C�D�D�+r3c�@�UR5 URnURnURSLnU(aURS:aU"S5eURS:aU"S5eU(a"URUR:�aU"S5eUR
UR:aU"S5eU(a"UR
UR:�aU"S5eS	UR;a:U(aUR
UR:a[UR<S
35 UR(aIUR(dU"S5eURHnXBR;dMU"SU<S
35e gUR(dU"S5eg)z!validate optional salt attributesNrfzmax_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_sizezR: hash handler supports range of salt sizes, but doesn't offer 'salt_size' settingz$default_salt_chars must not be emptyz1default_salt_chars must be subset of salt_chars: z not in salt_charsz;default_salt_chars MUST be specified if salt_chars is empty)rHr�rX�
max_salt_size�
min_salt_size�default_salt_sizerSrr��
salt_chars�default_salt_chars)rrr��mx_set�cs     r1� test_10_optional_salt_attributes�,HandlerCase.test_10_optional_salt_attributes*sq����� ��.�.���l�l���#�#�4�/���c�'�'�!�+� �!>�?�?����q� � �!>�?�?��c�'�'�#�*;�*;�;� �!K�L�L�� � �3�#4�#4�4� �!M�N�N��c�+�+�c�.?�.?�?� �!M�N�N�
�c�.�.�.��#�BW�BW�Z]�Zk�Zk�Bk��?B�x�x�J�
K��>�>��)�)�$�%K�L�L��+�+���N�N�*�(�tu�)w�x�x�,��)�)�$�%b�c�c�*r3c���URn[U5(dSUR-5eSSKJn [URU"[UR5S5-5$)z%calculate number of salt bits in hashzneed explicit bit-size for rr��)	rXrr�r�r�r�rNr;rP)rrXr�s   r1�	salt_bits�HandlerCase.salt_bitsSsa���,�,���W�%�%�S�'D�w�|�|�'S�S�%���7�,�,��s�7�5�5�6��:�;�<�	<r3c�^^�TR5 [SSTR-
5mUU4SjnU"TR5 U"U4Sj5 g)z4test hash() / genconfig() creates new salt each timerfrec�|>�U"5n[T5HnU"5nX:wdM g TRST4-5e)Nz.failed to find different salt after %d samples)rr�)r��value1r?�value2�samplesrs    ��r1�sampler�0HandlerCase.test_11_unique_salt.<locals>.samplerisO����V�F��G�_������#��%��'�'�)5�8?�z�)B�C�
Cr3c�&>�TRS5$�Nr%)r�r#s�r1�<lambda>�1HandlerCase.test_11_unique_salt.<locals>.<lambda>rs�������/r3N)rErNrWr�)rr^r]s` @r1�test_11_unique_salt�HandlerCase.test_11_unique_salt_sE��������a��$�.�.�0�1��	C�	��!�!�"��/�0r3c�N�UR5 URnURSSnURnX#-nUR	US9 URSUS9 US:�a"UR
[URUSSS9 UR
[UR
SUS-
S9 g)z.test hash() / genconfig() honors min_salt_sizerrf�rDr%�rKNr	)rHrXrOrMr�r�r��
ValueError)rrX�	salt_char�min_size�s1s     r1�test_12_min_salt_size�!HandlerCase.test_12_min_salt_sizets������ ��,�,���&�&�q��+�	��(�(��
�
!�����r��"�����(��3�
�a�<����j�$�*;�*;�#%�c�r�7�
�
,�	
���*�d�o�o�v�$,�Q�J�	�	0r3c��UR5 URnURnURSSnUbUS:�aFUS-nUR	US9nUR	XC-S9nURXV5 UR	SS9 gX2-nUR	US9nUR	US9 XC-nUR
[URUS9 UR
[URUS-S9 [U5(a?[R"SS	9 UR	USS
9nSSS5 URWU5 URU:a$UR	USSS9nURX�5 gg!,(df   NU=f)z.test hash() / genconfig() honors max_salt_sizerrfNiirgrhTr)rDrQr	)
rHrXrLrOrr1r�rirYr�r�rrM)	rrX�max_sizerjrl�c1�c2�s2�c3s	         r1�test_13_max_salt_size�!HandlerCase.test_13_max_salt_size�s������ ��,�,���(�(���&�&�q��+�	���x�7�3�
�T�!�B��%�%�2�%�.�B��%�%�2�>�%�:�B�����'�� � �4� �0��%�B��%�%�2�%�.�B�� � �8� �4�
��B����j�$�*>�*>�R��H����j�$�*>�*>�(�UV�,��W�
#�7�+�+��,�,�D�9��-�-�2�t�-�D�B�:�� � ��R�(�
�$�$�x�/��)�)�r�#�2�w�)�7���#�#�B�+�0�:�9�s�E2�2
Fc�V�UR(aSSKJn URU5nU$)zprepare generated saltr)�bcrypt64)�fuzz_salts_need_bcrypt_repair�passlib.utils.binaryrx�
repair_unused)rrDrxs   r1�prepare_salt�HandlerCase.prepare_salt�s#���-�-�5��)�)�$�/�D��r3c	��UR5 URnURnURnURn[U[5n[XB=(d S5H=n[U5U:a[Xc5nURU5nURUS9 M? [S5nU(aURS5n[US5nUH1n	X�;dM
UR[ URX�-SU	<S3S9 M3 g	)
ztest hash() honors salt_charsr�rguÿr�rfzinvalid salt char r�)rDr�N)rHrXrLrMrOrt�bytesrr;rr|rrr�rNr�ri)
rrX�mxr��cs�rawrDr��chunkrRs
          r1�test_14_salt_chars�HandlerCase.test_14_salt_chars�s������ ��,�,��
�
"�
"��
�
"�
"��
�
�
����U�#���"�h�B�'�D��4�y�2�~�$�T�.���$�$�T�*�D�� � �d� �+�	(��:�����]�]�9�-�F��B��
���A��{��!�!�*�d�.B�.B���EF�*H�"�J�r3c�R�[URSS5(a[$[$)z)hack to determine salt keyword's datatype�_salt_is_bytesF)r�rXrr r#s r1�	salt_type�HandlerCase.salt_type�s"���4�<�<�!1�5�9�9��L��Nr3c���UR5 URn[URSS5=(d Sn"SS[5nUR[URSU"5S9 U[La,UR[URS[S5U-S9 U[Ld9[(a	U[Ld$UR[URSS	U-S9 g
g
g
)ztest non-string salt valuesrMr�c��\rSrSrSrg)�+HandlerCase.test_15_salt_type.<locals>.fakei�r7N)r�r,r-r.r0r7r3r1�faker��s��r3r�r%rg�x�xN)rEr�r�rX�objectr�rr�r rrr!)rr�rKr�s    r1�test_15_salt_type�HandlerCase.test_15_salt_type�s��������N�N�	��D�L�L�/�1�=�B��	�	�6�	����)�T�_�_�f�4�6��J��G�#����i����&�q��v�PY�GY��Z��U�"�s�s�y�G�/C����i����&�t�i�GW��X�0D�"r3c��UR5 URnURnURnURnUR[URSS9 UR[/5 URSSS9nSSS5 URWRU5 U(apUR[URUS-S9 UR[/5 URUS-SS9nSSS5 URURU5 X#:wa�URUS-S9nURURUS-5 URURU5 URUS-S9nURURUS-5 URURU5 X#:XaUnOUS-nUR[U5S9nURURU5 UR[UR[U5S-S9 URUS	9nURURU5 g!,(df   GN�=f!,(df   GNt=f)
z$Handler.using() -- default_salt_sizer	)rNT)rNrQNrfrV�xxxrh)rHrXrMrLrNr�rir�r'rrr�)rrXr�r�r��temp�refs       r1�test_using_salt_size� HandlerCase.test_using_salt_sizes%����� ��,�,��
�
"�
"��
�
"�
"��
�
&�
&��	
���*�g�m�m�r��J�
�
#�
#�%7�$8�
9��=�=�2�t�=�D�D�:�����/�/��4�����j�'�-�-�2�a�4��P��'�'�);�(<�=��}�}�r�!�t�T�}�J��>����T�3�3�R�8��8��=�=�2�a�4�=�8�D����T�3�3�R��T�:����W�6�6��;��=�=�2�a�4�=�8�D����T�3�3�R��T�:����W�6�6��;��8��C��q�&�C��}�}�s�3�x�}�8������/�/��5�	
���*�g�m�m�s�3�x�RW�GW��X��}�}�s�}�+������/�/��5�E:�
9��>�=�s�6I�*I+�
I(�+
I:c�Z�[UR5(dURS5eg)Nzhandler lacks rounds attributes)rrXrVr#s r1�require_rounds_info�HandlerCase.require_rounds_info7s&���t�|�|�,�,��-�-� A�B�B�-r3c��UR5 URnURnURcU"S5eURS:aU"S5eURS:aU"S5eURUR:�aU"S5eUR
bDUR
UR:aU"S5eUR
UR:�aU"S	5eUR[;aU"S
UR<35eg)z#validate optional rounds attributesNzmax_rounds not specifiedrfzmax_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_roundszunknown rounds cost constant: )r�rXr��
max_roundsr~r�r�r)rr�rs   r1�"test_20_optional_rounds_attributes�.HandlerCase.test_20_optional_rounds_attributes;s���� � �"��l�l���.�.���>�>�!� �!;�<�<��>�>�A�� �!:�;�;��>�>�A�� �!:�;�;��>�>�C�N�N�*� �!C�D�D����)��!�!�C�N�N�2�$�%K�L�L��!�!�C�N�N�2�$�%K�L�L��?�?�"4�4� �s���!X�Y�Y�5r3c��UR5 URnURnURUS9 UR	SUS9 UR[URUS-
S9 UR[URSUS-
S9 g)z+test hash() / genconfig() honors min_rounds�r[r%rfN)r�rXr~r�r�r�ri)rrXr~s   r1�test_21_min_rounds�HandlerCase.test_21_min_roundsYs���� � �"��,�,���'�'�
�	
�����,�����z��2�	
���*�d�&7�&7�
�1���M����*�d�o�o�v�j�QR�l��Sr3c�(�UR5 URnURnUbEUR[UR
US-S9 UR[URSUS-S9 UcURSS9 gURUS9 g)z+test hash() / genconfig() honors max_roundsNrfr�r%i���)r�rXr�r�rir�r�r)rrXr�s   r1�test_21b_max_rounds�HandlerCase.test_21b_max_roundsis���� � �"��,�,���'�'�
��!����j�$�*;�*;�J�q�L��Q����j�$�/�/�6�*�UV�,��W���� � �
� �6�� � �
� �3r3c�&>^
�UR5 URnURS:Xa'Um
UR5n[	UU
4Sj5UlURnURnURnU=(d SU-S-nXT:XaUS-
nX%-S-nU=(d SU-S-nURS:XaUS-nUS-nUS-nSnOSnUR/5 URUUUS9n	SSS5 UW	XeXx4$!,(df   N=f)zE
setup test helpers for testing handler.using()'s rounds parameters.
�
bsdi_cryptc� >�[TU]5$r6)r��_generate_rounds)r�r��orig_handlers ��r1rb�9HandlerCase._create_using_rounds_helper.<locals>.<lambda>�s���u�\�SV�?h�?jr3i'rVrf)�min_desired_rounds�max_desired_roundsr�N)
r�rXr�r��classmethodr�r~r�r�r')rrX�orig_min_rounds�orig_max_rounds�orig_default_rounds�medium�small�large�adjrr�r�s          @�r1�_create_using_rounds_helper�'HandlerCase._create_using_rounds_helpers(���	
� � �"��,�,���<�<�<�'�"�L��m�m�o�G�'2�3j�'k�G�$�"�,�,��!�,�,��%�4�4��"�*�d�o�=�!�C���(��a�K�F� �)�a�/��!�)�T�V�3��9���<�<�<�'��Q�J�E��a�K�F��Q�J�E��C��C��
#�
#�B�
'��]�]�#(�#(�%�#��F�(����u�9�9�(�
'�s�"D�
Dc���UR5 URnURnURnURnUR5uppgp�UR
URU5 UR
URU5 UR
URS5 UR
URS5 UR
URU5 UR
URU5 UR
URU5 UR
URU5 UR
URU5 UR
URU5 g)z0
HasRounds.using() -- sanity check test harness
N)	r�rXr~r�r�r�rr�r�)
rrXr�r�r�rr�r�r�r�s
          r1�test_has_rounds_using_harness�)HandlerCase.test_has_rounds_using_harness�s1��
	
� � �"��,�,��!�,�,��!�,�,��%�4�4��59�5U�5U�5W�2����	
����+�+�_�=�����+�+�_�=�����3�3�T�:�����3�3�T�:�����/�/�1D�E�	
����*�*�O�<�����*�*�O�<�����.�.��7�����2�2�E�:�����2�2�E�:r3c��UR5upp4pVURnURnURn	US:�anUR	[
URXv-
S9 UR[/5 UR
Xv-
SS9n
SSS5 URW
RU5 U(anUR	[
URX�-S9 UR[/5 UR
X�-SS9n
SSS5 URW
RU5 UR/5 UR
X6-
S9n
SSS5 URW
RX6-
5 UR
USU--S9n
URU
RUSU--5 UR/5 UR
XV-S9n
SSS5 URU
RXV-5 UR[X#U-5X6-5 UR[X#5U5 UR/5 UR[X#U-
5X6-
5 SSS5 UR
US9n
URU
RU5 UR
[U5S9n
URU
RU5 UR	[
UR[U5S-S9 g!,(df   GNi=f!,(df   GN=f!,(df   GN�=f!,(df   GNc=f!,(df   N�=f)	z6
HasRounds.using() -- min_rounds / min_desired_rounds
r�r�T)r�rQNrV�r~r�)
r�r~r�r�r�rir�r'rrr�r^r�)rrXrr�r�r�r�r�r�r�r�s           r1�"test_has_rounds_using_w_min_rounds�.HandlerCase.test_has_rounds_using_w_min_rounds�s���
6:�5U�5U�5W�2����!�,�,��!�,�,��%�4�4���Q�����j�'�-�-�O�La��b��'�'�);�(<�=��}�}��8M�W[�}�\��>����T�4�4�o�F�����j�'�-�-�O�La��b��'�'�);�(<�=��}�}��8M�W[�}�\��>����T�4�4�o�F��
#�
#�B�
'��<�<�5�;�<�?�D�(�����0�0�%�+�>��|�|�u�q�3�w��|�?������0�0�%�!�c�'�/�B��
#�
#�B�
'��<�<�5�;�<�?�D�(�����0�0�%�+�>�	
���-�f�c�k�B�E�K�P����-�f�<�e�D�
�
#�
#�B�
'����1�&�#�+�F���T�(��}�}��}�.������0�0�%�8��}�}��E�
�}�3������0�0�%�8�	
���*�g�m�m��E�
�U�@R��S�S>�=��>�=��
(�
'��(�
'��(�
'�s<�6K+�+K=�3L�3L!�7!L3�+
K:�=
L�
L�!
L0�3
Mc��UR5upp4pVURnURnUS:�anUR[UR
Xv-
S9 UR
[/5 URXv-
SS9n	SSS5 URW	RU5 U(anUR[UR
X�-S9 UR
[/5 URX�-SS9n	SSS5 URW	RU5 UR
[/5 URX6-
S9n	SSS5 URW	RU5 UR[UR
XF-XF-
S9 URUSU--
S9n	URU	RUSU--
5 UR
/5 URXV-S9n	SSS5 URU	RXV-5 UR[X%U-
5XV-
5 UR[X%5U5 UR
/5 UR[X%U-5XV-5 SSS5 URUS	9n	URU	RU5 UR[U5S9n	URU	RU5 UR[UR
[U5S
-S9 g!,(df   GN�=f!,(df   GN-=f!,(df   GN�=f!,(df   GNc=f!,(df   N�=f)z6
HasRounds.using() -- max_rounds / max_desired_rounds
r)r�T)r�rQN�r�r�rVr��r�r�)r�r~r�r�rir�r'rrr�rr�r^r�)
rrXrr�r�r�r�r�r�r�s
          r1�$test_has_rounds_replace_w_max_rounds�0HandlerCase.test_has_rounds_replace_w_max_rounds�s���
6:�5U�5U�5W�2����!�,�,��!�,�,���Q�����j�'�-�-�O�La��b��'�'�);�(<�=��}�}��8M�W[�}�\��>����T�4�4�o�F�����j�'�-�-�O�La��b��'�'�);�(<�=��}�}��8M�W[�}�\��>����T�4�4�o�F��
#�
#�%9�$:�
;��<�<�5�;�<�?�D�<�����0�0�%�8�	
���*�f�l�l�-3�Z�-3�Z�	�	9�
�|�|�u�q�3�w��|�?������0�0�%�!�c�'�/�B��
#�
#�B�
'��<�<�5�;�<�?�D�(�����0�0�%�+�>�	
���-�f�c�k�B�E�K�P����-�f�<�e�D�
�
#�
#�B�
'����1�&�#�+�F���T�(��}�}��}�.������0�0�%�8��}�}��E�
�}�;������0�0�%�8�	
���*�g�m�m��E�
�UZ�HZ��[�]>�=��>�=��
<�
;��(�
'��(�
'�s<�*L�L�,L*�L<�!M�
L�
L'�*
L9�<
M�
Mc���UR5upp4pVURnURXF-S9nURURXF-5 URXF-
S9nURURXF-
5 UR[URX6-
S9 U(a!UR[URXV-S9 UR[U5U5 UR[X$U-5XF-5 UR[U5S9nURURU5 UR[UR[U5S-S9 g)z%
HasRounds.using() -- default_rounds
r�r�)r�r�N)	r�r�r�rr�r�rir^r��	rrXrr�r�r�r�r�r�s	         r1�&test_has_rounds_using_w_default_rounds�2HandlerCase.test_has_rounds_using_w_default_rounds8s>��
6:�5U�5U�5W�2����!�,�,��
�|�|�v�z�|�2������,�,�f�j�9��|�|�v�z�|�2������,�,�f�j�9�	
���*�f�l�l�5�9��M�����j�&�,�,�u�y��Q�	
���-�f�5�v�>����-�f�S�j�A�6�:�N��}�}�C��K�}�8������,�,�f�5�	
���*�g�m�m�C��K�RW�DW��Xr3c��UR5upp4pVURnURXF-S9nURURXF-5 URUR
XF-5 URURXF-5 URUS-X6-XEU-
S9nURURX6-5 URUR
U5 URURXV-
5 g)z
HasRounds.using() -- rounds
r�rf)r[r~r�r�N)r�r�r�rr�r�r�r�s	         r1�test_has_rounds_using_w_rounds�*HandlerCase.test_has_rounds_using_w_rounds^s���
6:�5U�5U�5W�2����!�,�,���|�|�6�:�|�.������0�0�&�*�=�����,�,�f�j�9�����0�0�&�*�=��|�|�6�!�8��	�+1�C�i��I������0�0�%�)�<�����,�,�f�5�����0�0�%�)�<r3c�^�UR5unmp#pEU4SjnURU"S5S5 URU"S5S5 URU"S5S5 URU"S5S5 URU"S5S5 UR[US5 UR[US5 g	)
z*
HasRounds.using() -- vary_rounds parsing
c�6>�TRUS9R$)N��vary_rounds)r�r�)r�rs �r1�parse�FHandlerCase.test_has_rounds_using_w_vary_rounds_parsing.<locals>.parsezs����<�<�E�<�2�>�>�>r3r)z0.1z10%���1000g��������g�������?N)r�rr�ri)rrXr�r�r�r�r�rs       @r1�+test_has_rounds_using_w_vary_rounds_parsing�7HandlerCase.test_has_rounds_using_w_vary_rounds_parsingss����
6:�5U�5U�5W�2�����	?�	
����s��S�)�����u��s�+�	
����u��s�+�	
����t��d�+�����v���-�	
���*�e�T�2����*�e�S�1r3c	�J^^	^
�TR5unm
p#pESm	U	UU
4SjnU"SX35 U"SX35 U"XSU-
X5-5 U"S[X#S-
5[XCS-55 URS:XaU"SX35 U"SX35 U"S	X5-
U5 gT	"T
R	S	S
95upxTRU[X#S-55 TR
U[X#S-55 TRU[XCS
-55 TR
U[XCS-55 g)z-
HasRounds.using() -- vary_rounds generation
c�l^�[U4Sj[S555n[U5[U54$)Nc3�:># �UHn[T5v� M g7fr6)r^)r>r?r�s  �r1r@�jHandlerCase.test_has_rounds_using_w_vary_rounds_generation.<locals>.get_effective_range.<locals>.<genexpr>�s����G�,�Q�+�C�0�0�,�s�r�)�setrrCrN)r��seens` r1�get_effective_range�WHandlerCase.test_has_rounds_using_w_vary_rounds_generation.<locals>.get_effective_range�s*����G�&��,�G�G�D��t�9�c�$�i�'�'r3c�>�TRUS9nT"U5upETRXAS5 TRXRS5 g)Nr�z"vary_rounds had wrong lower limit:z"vary_rounds had wrong upper limit:)r�r)	r�r�r�r��
seen_lower�
seen_upperr�rrs	      ���r1�assert_rounds_range�WHandlerCase.test_has_rounds_using_w_vary_rounds_generation.<locals>.assert_rounds_range�sB����<�<�K�<�8�D�%8��%>�"�J����Z�0T�U����Z�0T�Ur3rz0%�2r�z1%z49%z50%r���?g�������?g333333�?g�?N)r�rNrCr�r��assertGreaterEqual�assertLessEqual)rrXr�r�r�r�r�r�r�r�rs`        @@r1�.test_has_rounds_using_w_vary_rounds_generation�:HandlerCase.test_has_rounds_using_w_vary_rounds_generation�s���6:�5U�5U�5W�2�����	(�	V�	�A�v�.��D�&�1�	�C�#��v�|�<��B��E�B�;� 7��U�R�K�9P�Q����&�(���f�5���v�6���v�|�V�<�/�v�|�|��|�/N�O�L�E��#�#�E�3�u�s�l�+C�D�� � ���E�C�<�(@�A��#�#�E�3�u�s�l�+C�D�� � ���E�C�<�(@�Ar3c�2�UR5upp4pVURUS-US-
S9nURX#S9nURX$S9n	URX%S9n
URUR	U55 URUR	U	55 URUR	U
55 URUR	U55 URUR	U	55 URUR	U
55 g)z6
HasRounds.using() -- desired_rounds + needs_update()
rVr�r�N)r�r�r�assertFalse�needs_updater�)rrXrr�r�r�r�r��
small_hash�medium_hash�
large_hashs           r1�&test_has_rounds_using_and_needs_update�2HandlerCase.test_has_rounds_using_and_needs_update�s��6:�5U�5U�5W�2�����|�|�u�Q�w�5�QR�7�|�S���)�)�&�)�?�
��*�*�6�*�A���)�)�&�)�?�
�	
����,�,�Z�8�9�����,�,�[�9�:�����,�,�Z�8�9�	
����)�)�*�5�6�����*�*�;�7�8�����)�)�*�5�6r3c��URn[U[5(a[U[R
5(dUR
S5eg)Nz)handler doesn't derive from HasManyIdents)rXrtrwrTrU�
HasManyIdentsrV)rrXs  r1�require_many_idents�HandlerCase.require_many_idents�s@���,�,���'�4�(�(�
�7�B�DT�DT�0U�0U��-�-� K�L�L�1Vr3c��URnUR5 URSUR;5 URHnURU[S5 M UR[UR5S:�S5 URUR[S5 URURUR;S5 UR(an[UR5HUup4URU[S5 URU[S5 URXAR;S	U<35 MW UnUR5SnURU5nUS	U"SSUR0UD6 UR"[U40UD6 U"SS
S0UD6 UR"[U4SS0UD6 g
)z$validate HasManyIdents configuration�identz!cls.ident_values must be unicode:rfz'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:z8cls.ident_aliases must map to cls.ident_values members: r\T�xXxNr7)rXr�r�rS�ident_valuesr
r r;�
default_ident�
ident_aliasesrr��	parsehashr�rri)rr�r��aliasr�rXr�ros        r1�test_30_HasManyIdents�!HandlerCase.test_30_HasManyIdents�s����l�l��� � �"�	
����3�#3�#3�3�4��%�%�E��!�!�%��"E�
G�&�	
����C�,�,�-�a�/�A�	C�	
���c�/�/��B�	D�����)�)�S�-=�-=�=�S�	U���� )�#�*;�*;� <����%�%�e�W�&O�Q��%�%�e�W�&Q�S�����)9�)9� 9�`e� g�i�!=����#�#�%�a�(��� � ��&����M�	�0�c�'�'�0�4�0�	
���)�W�5��5�	�*�T�*�T�*�	
���*�g�C�U�C�d�Cr3c���UR5 URnURnURH
nX2:wdM
 O [	SU<SUR<35eSnUR5nUR
URU5 URUS9nUR
URU5 UR
URU5 UR
U"U5U5 UR
U"U5U5 UR[UR
SS9 URUS9nUR
URU5 UR
URU5 UR[UR
X3S9 UR(aQURR5H2upgURUS9nUR
URUSU-S	9 M4 g
g
)z=HasManyIdents.using() -- 'default_ident' and 'ident' keywordsz*expected to find alternate ident: default=z values=c�8�[U5nU"SS9R$)NT)r\)r]r�r�s r1�effective_ident�?HandlerCase.test_has_many_idents_using.<locals>.effective_idents�� ��%�C��D�)�/�/�/r3)r�r�)r�)r�r�z	alias %r:�r�N)r�rXr�r�rr�rr�rirr�r|)rrX�
orig_ident�	alt_identrrr�r�s        r1�test_has_many_idents_using�&HandlerCase.test_has_many_idents_usings���� � �"��,�,���*�*�
� �-�-�I��&��.�!�",�g�.B�.B�"D�E�
E�	0�
���������-�-�z�:����Y��7������-�-�y�9�����.�.�
�;�	
�����0�)�<������1�:�>�	
���*�g�m�m�5��I����Y��/������-�-�y�9�����.�.�
�;�	
���)�W�]�]�)��]�� � � '� 5� 5� ;� ;� =��� ���U��3��� � ��!5�!5�u�+�PU�BU� �V�!>�!r3c�`^�URmTRcURSTR5 gTR(dURTR5 STR;aURTR5 gU4SjnURU"S5TR5 URU"S5S5 URU"S5S5 URU"S5S5 URU"S5S5 UR[US5 g)	z8
validate 'truncate_error' setting & related attributes
N�truncate_errorc�6>�TRUS9R$)N�r)r�r)r��hashers �r1�parse_value�<HandlerCase.test_truncate_error_setting.<locals>.parse_valueSs����<�<�u�<�5�D�D�Dr3T�trueF�falser�)rX�
truncate_sizer>rSrr��truncate_verify_rejectr�rr�ri)rrrs  @r1�test_truncate_error_setting�'HandlerCase.test_truncate_error_setting;s�����������'����-�v�/B�/B�C��
�$�$����V�:�:�;��6�#6�#6�6��O�O�F�1�1�2��	E�����T�*�F�,A�,A�B�����T�*�D�1�����V�,�d�3�����U�+�U�3�����W�-�u�5����*�k�5�9r3c�n�URnURb-URURS5 URS5eSnSnUR	U5nUR
(+nUR
URX$5USS9 USSU-nURURXd5S	5 g)
z?
test no password size limits enforced (if truncate_size=None)
Nrfztruncate_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 secretrr	z full password not used in digest)	rXrr�rVr�r�rr�r�)rrr�r�r��verify_success�
alt_secrets       r1�test_secret_wo_truncate_size�(HandlerCase.test_secret_wo_truncate_size\s���
�������+��#�#�F�$8�$8�!�<��-�-� 6�7�7�)�������v�&��$�/�/�/���������5�~�=�	�	?��C�R�[�3�&�
�������
�9�;�	=r3c	�X�URnURnU(dURS5e[RnSUR
;a/UR
SS9nUR
SS9n[RnOUR(aSnUnOUnSnSnSn[XbS	-5nUSS
n	USS
U-n
U	SS
U-nUR(+nU=(a UR(+n
U(d	U(deXE4HrnURX�S9nURURX�US9U5 URURX�US9S5 URURX�US9U
5 Mt U(aqURX�S9nURURUUUS9U5 URURU
UUS9U5 UR!URU	UUS95 U(a7UR#X0RX�S9nURUR$U5 gg)
zA
test password size limits raise truncate_error (if appropriate)
ztruncate_size not setrFr
TNztoo many secretsr�rfr	rWz truncate_size value is too large)rXrrVr�PasswordSizeErrorrSr��PasswordTruncateErrorrrr�rr�rr�r�r�r�rp)rrXr�size_error_type�
without_error�
with_errorrzr��long_secret�short_secret�alt_long_secret�alt_short_secret�short_verify_success�long_verify_success�cand_hasher�
short_hash�	long_hashr�s                  r1�test_secret_w_truncate_size�'HandlerCase.test_secret_w_truncate_size|s����,�,���-�-�
���-�-� 7�8�8��/�/���w�3�3�3�#�M�M��M�?�M� ���d��;�J�!�7�7�O�
�
#�
#� �M� �J�$�M��J�"����#�D��/�:��"�3�B�'��%�c�r�*�S�0��'���,�s�2��$+�#6�#6�6��2�A�")�"@�"@�@�	��
�*�*�)�6�K������K�J�
���T�^�^�L�3>�,�@�1�
3�
���T�^�^�,<�4>�,�@�?�
A�
���T�^�^�K�4?�,�A�0�
2�%7�4������K�I�
���T�^�^�K��4A�,�C�1�
3�
���T�^�^�O�Y�4A�,�C�1�
3�
�O�O�D�N�N�<��3@�+�B�
C���#�#�O�_�_�$/�$�E�C����S�\�\�=�9�r3c���URSLnURS;nSnSnURU5nU(a=URR(d"UR	URXE5S5 O!UR
URXE5S5 URU5nU(a=URR(d"UR	URX65S5 O!UR
URX65S5 URXE5nU(d,URR(a$UR(dURXeS5 g	URXeS5 g	)
ztest password case sensitivityT)Tzverify-onlyr��TESTz%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�rXr�r�r�r�rr0rr1)r�hash_insensitive�verify_insensitiver�r��h1�h2s       r1�test_61_secret_case_sensitive�)HandlerCase.test_61_secret_case_sensitive�s8���7�7�4�?��!�9�9�>M�M������
�_�_�U�
#���d�l�l�&>�&>��O�O�D�N�N�5�5�C�
E�
���T�^�^�E�6�@�
B��_�_�U�
#���d�l�l�&>�&>��O�O�D�N�N�5�5�C�
E�
���T�^�^�E�6�@�
B��_�_�U�
'������ 8� 8��A\�A\����R�E�
G�
���� D�
Fr3c��UR5SnUR[URS5 UR[URSU5 UR[UR
SU5 UR[URS5 UR[URSU5 UR[UR
SU5 g)z&test non-string passwords are rejectedrfN)r�r�rr�rr�r�s  r1�test_62_secret_border�!HandlerCase.test_62_secret_border	s����#�#�%�a�(��	
���)�T�_�_�d�;����)�T�_�_�d�D�A����)�T�^�^�T�4�@�	
���)�T�_�_�a�8����)�T�_�_�a��>����)�T�^�^�Q��=r3c�2�SSKJn SSKJn SSU--nUR	5SnURXRX45nURURU5 URXRU5 URXRX45 g)z"test MAX_PASSWORD_SIZE is enforcedr)r)�MAX_PASSWORD_SIZErFrfN)�passlib.excrrUr:r�r�rrrpr�r�)rrr:r�r�r�s      r1�test_63_large_secret� HandlerCase.test_63_large_secret	s���1�3���+�+�,���#�#�%�a�(����� 1�?�?�F�Q��������'8�9����+�_�_�f�E����+�^�^�V�Jr3c�(�URnU(dURS5e[S5n[U[5(aSSKJn U"U5nURS5nUH)nUR[URX$-U-5 M+ g)z1test forbidden characters not allowed in passwordznone listedr%r)�iter_byte_chars�asciiN)r�rVrrtr�passlib.utils.compatr?r�r�rir�)r�charsrzr?rRs     r1�test_64_forbidden_chars�#HandlerCase.test_64_forbidden_chars)	sv���)�)����-�-�
�.�.���y���e�U�#�#�<�#�E�*�E��;�;�w�'�D��A����j�$�/�/�4�8�d�?�K�r3c�F�URU05n[U5(+$r6)r�r�rr�s  r1�is_secret_8bit�HandlerCase.is_secret_8bit9	s"���&�&�v�r�2�� ��(�(�(r3c��[(a8URS:Xa([U[5(aUR	S5 gg![
a gf=f)z\
check if we're expecting potential verify failure due to crypt.crypt() encoding limitation
r�r�TF)r	rbrtrr�r�rFs  r1�expect_os_crypt_failure�#HandlerCase.expect_os_crypt_failure=	sJ���3�4�<�<�:�-�*�V�U�2K�2K�
��
�
�g�&���&�
��
�s�A�
A�Ac���URUR=(d URS5 SnUR5H�up#UR	U5(aSnURURU5SU<35 UR
U5nURX#SU<SU<35 URX#5nURU[SU<35 URR(aUR(aM�URXSSU<SU<S	U<35 M� U(d[!S
UR"-5 gg![a
 U(deGM!f=f)ztest known hasheszOtest must set at least one of 'known_correct_hashes' or 'known_correct_configs'FTz$identify() failed to identify hash: z&verify() of known hash failed: secret=r��*genhash() failed to return native string: z1genhash() failed to reproduce known hash: secret=r.z%s: no 8-bit secrets testedN)r�r�r�r�rGr�rJr�rr
r�rXr�r0rr
rr�)r�saw8bitr�r�rJr�s      r1�test_70_hashes�HandlerCase.test_70_hashesH	sK��	
����1�1�O�T�5O�5O�5�	6�
�� �2�2�4�L�F��"�"�6�*�*���
�O�O�D�,�,�T�2�<@�B�
D�'+�&B�&B�6�&J�#�
��!�!�&�$�:@�$�1H�I�����6���%�%�f�c�FL�N�P��<�<�+�+��0K�0K��� � ����T�6�1+�,�-5�>��.����?�@���'�
�.��/�
�s�A2E
�
E
�
E$�#E$c
���UR(dURS5eURH�upnURURU5SU<35 UR	X!SU<SU<35 URX!5nUR
U[SU<35 URR(aUR(aM�URXCSU<SU<SU<SU<35 M� g	)
ztest known alternate hasheszno alternate hashes providedz.identify() failed to identify alternate hash: z0verify() of known alternate hash failed: secret=r�rMz;genhash() failed to normalize known alternate hash: secret=z, alt=r.N)r�rVr�r�r�rr
r�rXr�r0r)rr�r�r�r�s     r1�test_71_alternates�HandlerCase.test_71_alternatest	s����*�*��-�-� >�?�?�!%�!<�!<��C��
�O�O�D�,�,�T�2���
�

���f�c�>D�c�,K�
L��_�_�V�1�F��!�!�&�#�BH�J�
L��|�|�'�'�D�,G�,G�����V�T�%�s�D�&�-:�
;�#"=r3c
��URR(d-URURS5 UR	S5eUR(dUR	S5eUR
(a[R"S[S9 URH�upnURURU5SU<35 UR[URX!SU<3S9 URX!5nURU[ S	U<35 UR#XCS
U<SU<SU<S
U<35 M� g)ztest known config stringsz&handler should not have config stringszhash has no settingszno config strings providedr�r4z3identify() failed to identify known config string: z)verify() failed to reject config string: �r�rMz=genhash() failed to reproduce known hash from config: secret=z	, config=r�r.N)rXrSr�r�rV�filter_config_warningsr�r�rr�r�r�rir�rr
r�r)rr�r�r�r�s     r1�test_72_configs�HandlerCase.test_72_configs�	s���|�|�(�(����T�7�7�D�
F��-�-� 6�7�7��)�)��-�-� <�=�=��&�&��#�#�H�7I�J�$(�$>�$>� �F�D�
�O�O�D�,�,�V�4���
�

���j�$�.�.�&�&���
�
�
�_�_�V�4�F��!�!�&�#�BH�J�
L����V�T�%�v�t�V�-=�
>�!%?r3c	�L�UR(dURS5eURHrnURURU5SU<35 UR	[
URSUSU<3S9 UR	[
URSUSU<3S9 Mt g)z)test known unidentifiably-mangled stringszno unidentified hashes providedz=identify() incorrectly identified known unidentifiable hash: r%z8verify() failed to throw error for unidentifiable hash: rUz9genhash() failed to throw error for unidentifiable hash: N)�known_unidentified_hashesrVr�r�r�rir�rr�s  r1�test_73_unidentified� HandlerCase.test_73_unidentified�	s����-�-��-�-� A�B�B��2�2�D�
���T�-�-�d�3�"�%�
&�

���j�$�.�.�&�$�"�%�
�
&�

���j�$�/�/�6�4�"�%�
�
&�3r3c	�L�UR(dURS5eURHrnURURU5SU<35 UR	[
URSUSU<3S9 UR	[
URSUSU<3S9 Mt g)z-test known identifiable-but-malformed stringszno malformed hashes providedz4identify() failed to identify known malformed hash: r%z3verify() failed to throw error for malformed hash: rUz4genhash() failed to throw error for malformed hash: N)�known_malformed_hashesrVr�r�r�rir�rr�s  r1�test_74_malformed�HandlerCase.test_74_malformed�	s����*�*��-�-� >�?�?��/�/�D�
�O�O�D�,�,�T�2�"�%�
&�

���j�$�.�.�&�$�"�%�
�
&�

���j�$�/�/�6�4�"�%�
�
&�0r3c��UR(aURS5eUR(dURS5eURGHupXRR:XafURUR
U5SU<35 URSU5 URSU5nURU[SU<35 M�URUR
U5SU<SU<35 UR[URSUSU<SU<3S	9 UR[URSUS
U<SU<3S	9 GM g)ztest known foreign hashes�not applicablezno foreign hashes providedz*identify() failed to identify known hash: r%rMz4identify() incorrectly identified hash belonging to r�z5verify() failed to throw error for hash belonging to rUz6genhash() failed to throw error for hash belonging to N)�accepts_all_hashesrV�known_other_hashesrXr�r�r�r�rr
r�r�r�ri)rr�r�r�s    r1�test_75_foreign�HandlerCase.test_75_foreign�	s.���"�"��-�-� 0�1�1��&�&��-�-� <�=�=��1�1�J�D�
�|�|�(�(�(����� 0� 0�� 6�FJ�L�N����v�t�,������6���%�%�f�c�FL�N�P�
� � ��!1�!1�$�!7� $�d�,�-�
�!�!�*�d�n�n�f�d�-1�4�:�"�;�
�!�!�*�d�o�o�v�t�-1�4�9�"�:�92r3c	��UR[URS5 UR[URSS5 UR[URSS5 UR[URS5 UR[URSS5 UR[URSS5 [S5S4H�nUR(aXURURU55 URSU5 UR	SU5nURUS5 MlURURU5S5 UR[URSUSS	9 UR[URSUS
S	9 M� URS5 URS5 g)
z#test non-string hashes are rejectedNr%rfr�r3rz,identify() incorrectly identified empty hashz$verify() failed to reject empty hashrUz%genhash() failed to reject empty hashu€¥$uabc‘)r�rr�r�rrrcr�r�r�ri)rr�r�s   r1�test_76_hash_border�HandlerCase.test_76_hash_border
s���
	
���)�T�%5�%5�t�<����)�T�^�^�V�T�B�	
���)�T�_�_�f�d�C�
	
���)�T�%5�%5�q�9����)�T�^�^�V�Q�?����)�T�_�_�f�a�@�
�r�U�C�L�D��&�&����� 0� 0�� 6�7����v�t�,������6���.�.�v�y�A�� � ��!1�!1�$�!7�B�D��!�!�*�d�n�n�f�d�B�"�D��!�!�*�d�o�o�v�t�C�"�E�!�&	
���0�1�����'r3c�P�[URS5(d[S5eg)Nr�zparsehash() not implemented)rRrXrr#s r1�require_parsehash�HandlerCase.require_parsehash2
s$���t�|�|�[�1�1��8�9�9�2r3c�\�UR5 URnURS5nURU5nUR	U[
5 URUSS9nUR
5nURSS5 URXE5 URUSS9nUR
5n[(a[R"SS	[S
9 SH9nX�;dM
URXhXx5 URXh5 XhXx'M; URXg5 g)z
parsehash()
r%F)�checksumrnNT)�sanitizer�z(.*unequal comparison failed to convert.*r4)rDrn)rkrXr�r�r
r8�copyr�rr!r�r��UnicodeWarningr1�assert_is_masked)	rrXr�r��result2�correct2�result3�correct3�keys	         r1�test_70_parsehash�HandlerCase.test_70_parsehash6
s��	
��� ��,�,�����v�&���"�"�4�(�����f�d�+�
�#�#�D�5�#�9���;�;�=�����Z��&�����+�
�#�#�D�4�#�8���;�;�=���3�
�#�#�H�.X�-;�
=�'�C��~��#�#�G�L�(�-�@��%�%�g�l�3� '���
�	(�
	
����+r3c��UcgURU[5 [U5S:aUOUSSn[U5[S/5:XagUR	SU-5e)zA
check value properly masked by :func:`passlib.utils.mask_value`
Nr���*Tzvalue not masked: %r)r
r r;r��fail)rr�r�s   r1rr�HandlerCase.assert_is_masked]
s_���=�����e�W�-��5�z�A�~�e�5���9���s�8�s�C�5�z�!���i�i�.��6�7�7r3c��UR5 URnU(dURS5eURH5up#URR	U5nURXCSU-5 M7 g)z
parsehash() -- known outputs
zno samples presentzhash=%r:N)rk�known_parsehash_resultsrVrXr�r)rr]r��correctr�s     r1�test_71_parsehash_results�%HandlerCase.test_71_parsehash_resultsk
sk��	
��� ��.�.����-�-� 4�5�5�"�9�9�M�D��\�\�+�+�D�1�F����V�j�4�.?�@�:r3c
�v^�URR(aURS5eSSKJn UR
nUS::aURS5eUR
US9nSmU(a [R"5RnOSnURUS9nURX5n[RS	URXS[U5S
R!U4SjU555 U"5nX�-n	Sn
U"5U	::GaUR#5nUSnUS
n
USnUSnU(aX�S'UR$"U40UD6nUH�nT"U5nU"UU40UD6nUS:XaMUSLdUSLdeU(d!UR'SU<SU<SU<SU<35eUR)5S:dMgU"U
U40UD6nU(dMzUS:wdM�UR'SU<SU
<SU<SU<SU<3
5e U
S-
n
U"5U	::aGM[RSURXR"5U-
U
5 g)a�fuzz 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)
rbrr��disabled by test mode��threadedc�b�UR=(d URR5S$r&)r/r��
splitlines)�vs r1�vname�-HandlerCase.test_77_fuzz_input.<locals>.vname�
s#���I�I�+����7�7�9�!�<�<r3z	fuzz test)r�z.%s: %s: started; max_time=%r verifiers=%d (%s)rMc3�4># �UH
nT"U5v� M g7fr6r7)r>r�r�s  �r1r@�1HandlerCase.test_77_fuzz_input.<locals>.<genexpr>�
s����8�i��E�!�H�H�i�s�r�r4r�r�rTFzfailed to verify against z verifier: secret=z config=r-r)z(was able to verify wrong password using z: wrong_secret=z
 real_secret=rfz!%s: %s: done; elapsed=%r count=%rN)rXr�rVrUr�
max_fuzz_time�get_fuzz_verifiersr��current_threadr�rt�FuzzHashGeneratorr��debugr�r;rP�generater�r�r�)rr�r�max_time�	verifiers�thread_namer�	generatorr8�stopr��optsr�r4r�r�r�r�r�r�r�s                    @r1�test_77_fuzz_input�HandlerCase.test_77_fuzz_input|
sC���*�<�<�#�#��-�-� 0�1�1�	'��%�%���q�=��-�-� 7�8�8��+�+�X�+�>�	�	=��#�2�2�4�9�9�K�%�K��n�n�+�n�.���*�*�4�5�	�	�	�	�B��(�(�+��Y���)�)�8�i�8�8�	:����������f��n��%�%�'�D��(�^�F���M�E��J�'�H��y�/�C��&)��#��?�?�6�6�X�6�D�
$���V�}�����4��4���V�#����~��5��8�8���/�/�15�v�x��1O�P�P�
�:�:�<�"�$�#�E�4�7�3�7�F��v�&�F�"2�"�3�3�37����RV�5X�Y�Y�$�$
�Q�J�E�E�f��n�H	�	�	�5��(�(�+�t�v��~�u�	Nr3c��^^^	^
^�TRS5 SSKm
TRR(aTR	S5eTR
nUS:dTRS::aTR	S5eT
R"5m	S/mUU	U4SjmUU
U4Sjn[U5Vs/sH
o2"U5PM nnTRU-S	-nSnUHQnURU5 UR5(dM+[RS
URU5 US-
nMS TS(aTRSTSU4-5eU(aTRSXa4-5egs snf)
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)
rHrNrbrfr�c�>�TRSS9 g![a g T TS==S-
ss'SSS5 e!,(df   e=f=f)NTr�rrf)r�r)�failed�failed_lockrs���r1r��3HandlerCase.test_78_fuzz_threading.<locals>.wrapper�
sM���
��'�'��'�6���
��
� ��1�I��N�I�!��!�[��s"��
A
�A
�9�	A
�
A	�A
c��>�[T5nSXRURTR4-nTR"TUS9nURS5 UR
5 U$)NzFuzz-Thread-%d ('%s:%s.%s'))�targetr�T)rwr,r�rm�Thread�	setDaemonr8)�nr�r��threadrr�r�s    ���r1�launch�2HandlerCase.test_78_fuzz_threading.<locals>.launch�
s`����t�*�C�0�A�~�~�s�|�|�48�4H�4H�4J�J�D��%�%�W�4�@�F����T�"��L�L�N��Mr3r{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[r�rXr�rV�fuzz_thread_countr�r�rrP�is_aliver��errorr�r})r�thread_countr�r��threads�timeout�stalledr�r�r�r�r�s`       @@@@r1�test_78_fuzz_threading�"HandlerCase.test_78_fuzz_threading�
si���	
���v�&���<�<�#�#��-�-� 0�1�1��-�-���!��t�1�1�Q�6��-�-� 7�8�8� �n�n�&�����
	�	�'-�\�&:�;�&:��6�!�9�&:��;��$�$�|�3�a�7�����F��K�K�� ��?�?�$�$���I�I�5�v�{�{�G�L��q�L�G�
��!�9��)�)�4�7=�a�y�,�6O�P�Q�
Q���)�)�4�7>�6M�N�O�
O���#<s�+E)c��[[RRS5=(d S5nU(aU$[	SS9(ag[	SS9(agg)z'amount of time to spend on fuzz testing�PASSLIB_TEST_FUZZ_TIMErrFr�rGrf�)�floatr*rirjr$�rr�s  r1r��HandlerCase.max_fuzz_timesB���b�j�j�n�n�%=�>�C�!�D����L�
�7�
#��
�9�
%��r3c��[[RRS5=(d S5nU(aU$[	SS9(agg)z+number of threads for threaded fuzz testing�PASSLIB_TEST_FUZZ_THREADSrrFr�r�)r�r*rirjr$r�s  r1r��HandlerCase.fuzz_thread_count$s7���B�J�J�N�N�#>�?�D�1�E����L�
�7�
#��r3)�fuzz_verifier_defaultc�D^�URm/nURH)n[X5"5nUcMURU5 M+ [	TS5(aF[S5(a6U(d/U4Sjn[
T5HnURU"U55 M U$)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``.
rgrHc�F>^�UU4SjnST-S-UlTS-UlU$)Nc�>�TR5nTRT5 TRX5TRU5 $!TRU5 f=fr6)r`rar�)r�r��orig_backendrbrXs   ��r1r��;HandlerCase.get_fuzz_verifiers.<locals>.maker.<locals>.funcMsM���#*�#6�#6�#8�L�:��+�+�G�4�&�~�~�f�;��+�+�L�9���+�+�L�9�s�!A�A�check_�_backend�-backend)r�r/)rbr�rXs` �r1�maker�-HandlerCase.get_fuzz_verifiers.<locals>.makerLs,���:�!)�7� 2�Z� ?��
�&��3����r3)rX�fuzz_verifiersr�r�rRr$rl)rr�r��method_namer�r�rbrXs       @r1r��HandlerCase.get_fuzz_verifiers8s�����,�,���	� �.�.�K��4�-�/�D���� � ��&�/��7�J�'�'�I�f�,=�,=�h�

�-�W�5��� � ��w��0�6��r3c�p^�U4SjnTR(aTRS-UlU$SUlU$)Nc�*>�TR"X40UD6$r6)r�)r�r�r�rs   �r1�
check_default�8HandlerCase.fuzz_verifier_default.<locals>.check_default^s����>�>�&�6�#�6�6r3r�r)rbr/)rr�s` r1r��!HandlerCase.fuzz_verifier_default\s8���	7��<�<�$(�L�L�:�$=�M�!���%+�M�!��r3c�v�\rSrSrSr\"S5rSr\"SSSS9r	0r
S	rS
rSr
SrS
rSrSrSrSrSrg)�HandlerCase.FuzzHashGeneratoriiz�
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<>.@*#! áəБℓr��
random_rounds�random_salt_size�random_ident)r[rKr�c�>�XlURUlX lgr6)r�rXr)rr�rs   r1r �&HandlerCase.FuzzHashGenerator.__init__�s���I��<�<�D�L��Hr3c�^�U4SjnTR5up#[UUU"TR5U"TR5S9$)z|
generate random password and options for fuzz testing.
:returns:
    `(secret, other_secret, settings_kwds, context_kwds)`
c�r>�0nUR5Hup#[TU5"5nUcMXAU'M! U$r6)r|r�)�mapr�rwrr�rs     �r1�gendict�7HandlerCase.FuzzHashGenerator.generate.<locals>.gendict�s=�����!$����I�C�#�D�$�/�1�E��(�#(�C��"-��
r3)r�r4r�r�)�random_password_pairr8�settings_map�context_map)rr�r�r4s`   r1r��&HandlerCase.FuzzHashGenerator.generate�sH���
�!�5�5�7�M�F��v�#�!(��):�):�!;� '��(8�(8� 9��
r3c�b�URRX45n[[XQU55$)z)generate random int w/ gauss distirbution)r�
normalvariater�r�)rr�r��mu�sigmar�s      r1�randintgauss�*HandlerCase.FuzzHashGenerator.randintgauss�s(���H�H�*�*�2�5�E��u�U�5�1�2�2r3c��URn[U5(dgUR=(d URnURnURS:XaUnO[US-UR5nURX4X"S-5$)Nr�rVr�)rXrr�r~r�rCr�r��rrXrGr�r�s     r1r��+HandlerCase.FuzzHashGenerator.random_rounds�sz���l�l�G�"�7�+�+���,�,�B��0B�0B�G��&�&�E��"�"�f�,����G�A�I�w�'9�'9�:���$�$�U�7�B�J�G�Gr3c���URn[U5(aSUR;dgURnURnUR
=(d US-nUR
X4X"S-5$)NrKr{r�)rXrrSrNrMrLr�r�s     r1r��.HandlerCase.FuzzHashGenerator.random_salt_size�sg���l�l�G�!�'�*�*�{�g�>R�>R�/R���/�/�G��)�)�E��)�)�6�W�Q�Y�E��$�$�U�7�B�J�G�Gr3c���URnURnSUR;d[US5(dgUR	5S:ag[USU5nUR
UR5$)Nr�r�r�rr)rrXrSrRr�r�r�r�)rrrXs   r1r��*HandlerCase.FuzzHashGenerator.random_ident�se���(�(�C��l�l�G��g�2�2�2�'�'�>�:Z�:Z���z�z�|�b� ���g�y�'�:�G��:�:�g�2�2�3�3r3c�\�UR5nUR5nURX5(aOM)URnURSS5(aUR	UR
5nURSS5(aUR	UR
5nX4$)z=generate random password, and non-matching alternate passwordrrf)�random_password�accept_password_pairr�randintr��password_encoding)rr�r4rs    r1r��2HandlerCase.FuzzHashGenerator.random_password_pair�s����)�)�+�F���,�,�.���,�,�V�;�;����(�(�C��{�{�1�Q������t�'=�'=�>���{�{�1�Q������T�%;�%;�<���=� r3c�`�URnUR5S:a[S5$URnUR=(a UR
nU=(d SnUS:dUR5S:aUR
S[US5SS5nOUR
S[US5S	S
5n[XRU5nU(aX[U[5(aC[URS55U:�a%USS
n[URS55U:�aM%U$)z*generate random passwords for fuzz testingg-C��6?r�i?Br�r�rf��c�F�r�Nr	)rr�rrXrrr�rCr�password_alphabetrtr r;r�)rrrXrrp�sizer�s       r1r��-HandlerCase.FuzzHashGenerator.random_password�s���(�(�C��z�z�|�e�#���u���l�l�G�#�2�2�L�w�7L�7L�M�$�.��H��"�}��
�
��r� 1��(�(��C��"�,=�r�2�F���(�(��S��2�->��B�G�� ��%;�%;�T�B�F���F�G�!<�!<��&�-�-��0�1�M�A�#�C�R�[�F��&�-�-��0�1�M�A��Mr3c�
�X:g$)z-verify fuzz pair contains different passwordsr7)rr�r4s   r1r��2HandlerCase.FuzzHashGenerator.accept_password_pair�s
���?�"r3)rXrr�N)r�r,r-r.r/rr�r�r8r�r�r r�r�r�r�r�r�r�r�r0r7r3r1r�r�isg��	��N�O��$��
�?�&8�"0�2��
��	�
	�.	3�
	H�	H�		4�	!�	�<	#r3r�c��URnUR(dbUR[US55 UR[US55 URUR5 URS5eUR
5nURU[SS9 URURU5SU-S9 UR5RUR5SnUR
U5nURU[SS9 URURU5SU-S9 UR[SUR U5 UR!U5nS	nUc'URU[S
S9 UR#XS5 O1URU[5 UR%S[U55 UR
5nUR(aUR'X�5 OUcUR#X�5 UR
U5n	UR(aUR'X�5 OUR#X�5 UR
US-5n
UR(dUcUR'X�5 g	UR#X�5 g	![anS	nUnS	nAGNGS	nAff=f)z.disable() / .enable() methods�disable�enablerbz#disable() must return native stringrz0identify() didn't recognize disable() result: %rrfzcannot restore original hashNz"enable() must return native stringr�)rXr�r�rRr0rVr�r
r�r�r�rtr�rd�assertRaisesRegexrir�rrr1)rrX�disabled_defaultr%�
disabled_stubr�r��e�disabled_default2�disabled_stub2�disabled_others           r1�test_disable_and_enable�#HandlerCase.test_disable_and_enables���
�,�,���"�"����W�W�i�8�9����W�W�h�7�8����T�8�8�9��-�-� 0�1�1�#�?�?�,�����.��"G�	�	I�����(�(�)9�:�N�Rb�c�	�	e��~�~��&�&�t�'>�'>�?��B������-�
����m�S�"G�	�	I�����(�(��7�N�R_�`�	�	b�	
���z�+I�&�~�~�/?�	A�	��^�^�M�2�F��E�
�=��!�!�&�#�&J�
"�
L����V�*�
�!�!�%��4����;�S��Z�H�$�O�O�-���&�&���� 1�D�
�]����.�A�!����.���&�&�����>�
���^�;�!������6���&�&�%�-�����>�
���^�;��W�	��F��E��	�s�J$�$
J=�.J8�8J=r7�NF)FNNr6�NN)F)pr�r,r-r.r/rXrbr�r�r�rZr^rdrr/r/rcr0rVr#r��_HandlerCase__unittest_skip�propertyr�r�r�r�r�r�r�r�r�r�r�r�rrrr	rr
rr�r"r&r*r5r8r;rArErHrSrWrdrmruryr|r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrr+r4r7r<rCrGrJrOrRrWr[r_rerhr�rkrxrrr�r�r�r�r�r�r�r�r�r�rr0r1r2s@r1r'r'�s����2�G��G����� ��!#�� ��
��	
�&�	�	�/�� ��O�$����#��#�������O�
��������.�-�&N�0�&�
W�$F�
+�.�
<�

3�$5���
*��
*�����, ��C�J�BO�@'�R4�56�n7�!8�F'>�X=�E�
'd�R�	<��	<�1�*0�43,�l%*�!��J�6����Y�(-6�dC�Z�<T� 4�,):�V;�46T�p:\�x$Y�L=�*2�2'B�R7�4M�
/D�f/W�h:�B=�@h:�Z$F�L>�	K�L� )�	�*A�X;�2!>�F&�*&�*$:�L)(�`!��:�%,�N8�A�"WN�r<O�D�
��
�����"0�N�"�H�T#�F�T#�|V<�V<r3r'c�^�\rSrSrSr/rSrSrSrU4Sjr	\
S5r\S5r
S	r\
U4S
j5rSrSrS
r\S5rSrSrSrU=r$)rifa�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�Fc�>�URS:XdeURRS5(dUR5 [[
U]5 g)Nr�)rbrXrh�_patch_safe_cryptr�rr�r�s �r1r��OsCryptMixin.setUp�sC����|�|�z�)�)�)��|�|�'�'�
�3�3��"�"�$�
�l�D�'�)r3c�j�[UR5nUR5 [US5nX4$)zy
return (handler, backend) pair to use for faking crypt.crypt() support for hash.
backend will be None if none availabe.
r�)r]rXr`rp)r�rX�alt_backends   r1�_get_safe_crypt_handler_backend�,OsCryptMixin._get_safe_crypt_handler_backend�s7��!����-��	����&�g�z�:���#�#r3c�,�UR5SSL$)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)rr#s r1�has_os_crypt_fallback�"OsCryptMixin.has_os_crypt_fallback�s���3�3�5�a�8��D�Dr3c��^�UR5upU(d[S5eUR5mTRU5 U4SjnSSKJn UR
USU5 SUlg)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!c�X>�TRX5n[U[5(deU$r6)rrtr�)r�r��alt_handlers  �r1�
crypt_stub�2OsCryptMixin._patch_safe_crypt.<locals>.crypt_stub�s+����&�&�v�4�D��d�C�(�(�(�(��Kr3rN�_cryptT)rrr�rarU�utilsr��using_patched_crypt)rrXrr�modrs     @r1r�OsCryptMixin._patch_safe_crypt�sb��� $�C�C�E���� �!O�P�P��m�m�o������,�	�
	$����s�H�j�1�#'�� r3c��>�US:Xde[[U]U5nSSKJn X R
:Xa1U(a*[
S5(aUR5S(aggU$)zd
make sure os_crypt backend is tested
when it's known os_crypt will be faked by _patch_safe_crypt()
r�r)�	has_cryptrHrfNz hash not supported by os crypt())r�rr	rUr"rr$r)r�rb�reasonr"r�s    �r1r	�%OsCryptMixin._get_skip_backend_reason�s]����*�$�$�$��|�S�B�7�K��+��/�/�/�I��� � �S�%H�%H�%J�1�%M��9��
r3c�v^�SSKJn U4SjmURTlSTlURUST5 T$)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.
rNc�J>�US:XaTRX5$TR$)Nr�)�__wrapped__�return_value)r�r��
mock_crypts  �r1r)�0OsCryptMixin._use_mock_crypt.<locals>.mock_crypt�s(������!�-�-�f�=�=�!�.�.�.r3r)rUrrr'r(r�)rrr)s  @r1�_use_mock_crypt�OsCryptMixin._use_mock_crypt�s9���	$�	/�"%���
��"&�
�����s�H�j�1��r3c��^^^^�TR5Sm[R4mTR5mUUUU4SjnU"STSS-5 U"TSS5 U"TS-5 g)ztest with faulty crypt()rfc��>�UTlTRTTRST5 TRTTRS5 TRTTRST5 gra)r(r�rr�r�)r��	exc_typesr�r)rs ����r1r��/OsCryptMixin.test_80_faulty_crypt.<locals>.test�sS���',�J�#����i����&�$�G����i����&�A����i������Fr3z$xrVNr	r�)r�r�InternalBackendErrorr+)rr�r/r�r)s` @@@r1�test_80_faulty_crypt�!OsCryptMixin.test_80_faulty_crypt�sk����#�#�%�a�(���-�-�/�	��)�)�+�
�	G�	G�	
�T�D���H�_���T�#�2�Y���T�C�Z�r3c���UR5nSUlUR(aVURS5nUR	SU5nURX25 UR
URSU55 gSSKJ	n UR5SnURX@RS5 URX@RSU5 URX@RSU5 g)ztest per-call crypt() fallbackNr%r)r1rf)r+r(rr�rrr�r�r;r1r�r�)rr)r2r3�err_typer�s      r1�test_81_crypt_fallback�#OsCryptMixin.test_81_crypt_fallback
s����)�)�+�
�"&�
���%�%�����(�B������,�B����R�$��O�O�D�N�N�6�2�6�7�
E��'�'�)�!�,�D����h����@����h�����F����h�����Er3c��[URS5(aURS5eUR(+nURRn[
RnURH"upE[R"XC5(dM" O URSU<SU<S35eUcURSU<SU<S35eXQ:XagU(aURSU<S	U<35 gURS
U<S	U<35 g)z�
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.
rPznot applicable to wrapperszno data for z" platform (current host support = �)Nzvaried support on z	expected z( platform would have native support for zdid not expect )rRrXrVrr��sys�platform�platform_crypt_supportr�r!r})r�
using_backendr�r;�pattern�expecteds      r1�test_82_crypt_support�"OsCryptMixin.test_82_crypt_support
s����4�<�<��/�/��-�-� <�=�=�!�4�4�4�
��|�|� � ���<�<��!%�!<�!<��G��x�x��*�*��"=��-�-�!)�=�!:�;�
;�
���-�-�!)�=�!:�;�
;��$��
��I�I���'�
(�
�I�I���'�
(r3c��^^^^�TRnTR(d[US5(agSSKJm SSKJm TRRmUUUU4SjnU$![a	 SSKJm N9f=f)ztest results against OS crypt()rrNr)�crypt)�_safe_crypt_lockc�>�TRU5(dg[UT5nT T"X5U:HsSSS5 $!,(df   g=f)zstdlib-cryptrN)�crypt_supports_variantr)r�r�rDrC�encodingrs  ����r1�check_crypt�5OsCryptMixin.fuzz_verifier_crypt.<locals>.check_cryptV
s?����.�.�t�4�4��"�6�8�4�F�!��V�*�d�2�"�!�!�s	�<�
A
)
rXrrRrC�ImportError�legacycryptrUrDr�r�)rrXrHrDrCrGs`  @@@r1�fuzz_verifier_crypt� OsCryptMixin.fuzz_verifier_cryptE
sj���
�,�,���#�#�w�w�	�'B�'B��	*�#�	3��)�)�;�;��	3�	3�����	*�)�	*�s�A"�"A5�4A5c��g)zf
fuzzy_verified_crypt() helper --
used to determine if os crypt() supports a particular hash variant.
Tr7r�s  r1rF�#OsCryptMixin.crypt_supports_varianta
s��
r3)r)r�r,r-r.r/r<�_OsCryptMixin__unittest_skiprbrr�r�rrrrr	r+r2r6r�r@rLrFr0r1r2s@r1rrfs����
�" ��
�O��G� ��
*��
$��
$��E��E�(�0����0�,�$F�*�)(��)(�^�8�r3rc�j�\rSrSrSrSrSrSrSrSr	Sr
SrS	r"S
S\
R5rSrg
)�UserHandlerMixinil
ahelper 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)
�userTFc��URnSnURX RS9nUR(adUR	[
URU5 UR	[
URX#5 UR	[
URX#5 gURU5 UR
X#5 URX#5 g)ztest user context keywordr%�rSN)rXr��default_user�
requires_userr�rrr�)rrX�passwordr�s    r1�test_80_user�UserHandlerMixin.test_80_user�
s����,�,�����|�|�H�+<�+<�|�=��������i����x�@����i����(�I����i�����H�
�L�L��"��O�O�H�+��N�N�8�*r3c�*�URR5nUR5nURS[	US9S9nUR
(a!UR
URSX2S9S5 gURURSX2S9S5 g)ztest user case sensitivityr%rU)r�z!user should not be case sensitivezuser should be case sensitiveN)	rVr�r�r�r8�user_case_insensitiver�r�r�)rr�r�r�s    r1�test_81_user_case�"UserHandlerMixin.test_81_user_case�
s����!�!�'�'�)�����
�����v�t��/?��@���%�%��O�O�D�N�N�6�4�N�D�?�
A�
���T�^�^�F�D�^�E�<�
>r3c���UR5nURSUSS9nURSUSS9nURX25 URSUSS9nURXB5 g)ztest user used as saltr%�adminrU�rootN)rrrr1)rr�r2r3�h3s     r1�test_82_user_salt�"UserHandlerMixin.test_82_user_salt�
sh���%�%�'��
�_�_�V�V�'�_�
:��
�_�_�V�V�'�_�
:������ �
�_�_�V�V�&�_�
9�����B�#r3c��[U[5(aUupOUR(dU$URnSU;aX2S'U$)zinsert username into kwdsrS)rtr6rWrV)rr�rorSs    r1r��!UserHandlerMixin.populate_context�
sE���f�e�$�$�!�L�F�D��#�#��M��$�$�D������L��
r3c��\rSrSr\R
RR5r\RSS9 \	"S5r
SrSrg)�"UserHandlerMixin.FuzzHashGeneratori�
�random_userrU�	asdQWE123c���URnURR(dUR5S:ag[	XR
UR
SS55$)Nr)rVr�)rr�rWr�r�
user_alphabetr�)rrs  r1ri�.UserHandlerMixin.FuzzHashGenerator.random_user�
sF���(�(�C��9�9�*�*�s�z�z�|�b�/@���c�#5�#5�s�{�{�1�R�7H�I�Ir3r7N)
r�r,r-r.r'r�r�rpr�rrlrir0r7r3r1r�rh�
s<��!�3�3�?�?�D�D�F�����
��.��+��
�	Jr3r�r7N)r�r,r-r.r/rVrWr\� _UserHandlerMixin__unittest_skiprYr]rcr�r'r�r0r7r3r1rRrRl
sH����L��M�!��
�O�
+� 
>�$�
�J�K�9�9�Jr3rRc�n�\rSrSrSrSr\"S5S\"S5/r"SS\R5r	S	r
S
rg)�EncodingHandlerMixini�
a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�$�\rSrSr\"S5rSrg)�&EncodingHandlerMixin.FuzzHashGeneratori�
uqwerty1234<>.@*#! ¬r7N)r�r,r-r.rr�r0r7r3r1r�rr�
s���8�9�r3r�c�\�[U[5(aUupURSU5 U$)zinsert encoding into kwdsrG)rtr6�
setdefault)rr�rorGs    r1r��%EncodingHandlerMixin.populate_context�
s*���f�e�$�$�%��F��O�O�J��1��
r3r7N)r�r,r-r.r/�$_EncodingHandlerMixin__unittest_skiprr/r'r�r�r0r7r3r1rprp�
s@����O�
	
�&�	��	�.���O�:�K�9�9�:�r3rpc�H^�\rSrSrSrSU4SjjrU4SjrU4SjrSrU=r	$)r�i�
z@catch_warnings() wrapper which clears warning registry & filtersc�>�[[U]
"S0UD6 XlU(a[R
"U5UlgSUlg)Nr7)r�r�r �
_reset_filterr��compile�_reset_registry)r�reset_filter�reset_registryror�s    �r1r �reset_warnings.__init__�
s6���
�n�d�,�4�t�4�)��=K�r�z�z�.�9���QU��r3c��>�[[U]5nUR(a5[R
"5 [R"UR5 URnU(a�0=o0l[[RR55HXupEUbURU5(dM [USS5nU(dM6UR5X4'UR!5 MZ U$�N�__warningregistry__)r�r�r�ryr��
resetwarnings�simplefilterr{�_orig_registryr5r:�modulesr|r!r�rp�clear)rr@r>�backupr�r�regr�s       �r1r��reset_warnings.__enter__�
s�����N�D�3�5������"�"�$��!�!�$�"4�"4�5��&�&���+-�-�F�(�!�#�+�+�"3�"3�"5�6�	���;�g�m�m�D�&9�&9���c�#8�$�?���3�#&�8�8�:�F�L��I�I�K�
7��
r3c�>�URnU(a�URn[[RR55H�upEUbUR
U5(dM [USS5nU(aUR5 URU5nU(dM^Uc[USU5 MpURU5 M� [[U]:"U6 gr�)r{r�r5r:r�r|r!r�r�rjr�r�r�r�r�)	rr(r>r�r�rr�rcr�s	        �r1r��reset_warnings.__exit__s�����&�&����(�(�F�!�#�+�+�"3�"3�"5�6�	���;�g�m�m�D�&9�&9���c�#8�$�?����I�I�K��z�z�$�'���4��{���%:�D�A��
�
�4�(�7�	�n�d�,�h�7r3)r�ryr{)�alwaysz.*r+r2s@r1r�r��
s���J�V�
�.8�8r3r�r	r6r)Nrfr�)�l�F"*�!)jr/�
__future__r�binasciirr��	functoolsrrrnr�r�r�r�r�r�r*r:r�r�r-r;rrrAr	r
r�r�passlibrr
�passlib.registry�registry�passlib.tests.backportsrr�rrrrrUrrrrrkrrrrrrrrrr r!r"�passlib.utils.decorr#�passlib.utils.handlersrrrU�__all__�google.appengine�googler^rJr2rE�TICK_RESOLUTIONrLrMrirjr}r�rKr$rYr^rdrlrpr]r{r�r�r%r&r�r�r�r�r�r�r?r�r'rrRrpr�r�r7r3r1�<module>r�s���#�&���$���g�'�'��1��
�	�	�
����@�,����+�#�]�]�5�5�5�Q�P�-�#�#��� ���C��+�(��-��
+��
�
�
�r�z�z�~�~�.A�.7� 9�9>������J�
��8
N�<�

"�
��
�X�(������@��

,�0��
��$�$y'�y�y'�F ��+��	�^%<�(�^%<�NK@�;�@�L[J�{�[J�B�;��L18�X�,�,�18��{m��
�C��s�G�G�G

Filemanager

Name Type Size Permission Actions
__init__.cpython-313.pyc File 181 B 0644
__main__.cpython-313.pyc File 329 B 0644
_test_bad_register.cpython-313.pyc File 965 B 0644
backports.cpython-313.pyc File 1.57 KB 0644
test_apache.cpython-313.pyc File 39.23 KB 0644
test_apps.cpython-313.pyc File 7 KB 0644
test_context.cpython-313.pyc File 72.82 KB 0644
test_context_deprecated.cpython-313.pyc File 30.41 KB 0644
test_crypto_builtin_md4.cpython-313.pyc File 6.92 KB 0644
test_crypto_des.cpython-313.pyc File 7.09 KB 0644
test_crypto_digest.cpython-313.pyc File 18.36 KB 0644
test_crypto_scrypt.cpython-313.pyc File 26.38 KB 0644
test_ext_django.cpython-313.pyc File 36.14 KB 0644
test_ext_django_source.cpython-313.pyc File 8.11 KB 0644
test_handlers.cpython-313.pyc File 54.12 KB 0644
test_handlers_argon2.cpython-313.pyc File 20.17 KB 0644
test_handlers_bcrypt.cpython-313.pyc File 25.88 KB 0644
test_handlers_cisco.cpython-313.pyc File 10.54 KB 0644
test_handlers_django.cpython-313.pyc File 16.59 KB 0644
test_handlers_pbkdf2.cpython-313.pyc File 18.31 KB 0644
test_handlers_scrypt.cpython-313.pyc File 3.7 KB 0644
test_hosts.cpython-313.pyc File 3.98 KB 0644
test_pwd.cpython-313.pyc File 8.13 KB 0644
test_registry.cpython-313.pyc File 11.15 KB 0644
test_totp.cpython-313.pyc File 61.07 KB 0644
test_utils.cpython-313.pyc File 48.64 KB 0644
test_utils_handlers.cpython-313.pyc File 43.05 KB 0644
test_utils_md4.cpython-313.pyc File 1.59 KB 0644
test_utils_pbkdf2.cpython-313.pyc File 11.64 KB 0644
test_win32.cpython-313.pyc File 2.14 KB 0644
tox_support.cpython-313.pyc File 3.29 KB 0644
utils.cpython-313.pyc File 139.67 KB 0644
Filemanager