Ë
    àU.j”¡  ã                   ó˜  — d Z ddlmZmZmZ ddlZ ej                  e«      Zddl	Z	ddl
Z
ddlmZmZmZ ddlmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZmZmZ dd	lm Z  dd
l!m"Z"m#Z#m$Z$ ddl%m&Z& g d¢Z'eek\  Z(e(rSddl)m*Z*m+Z+  e,e*e+«      s e-de*›�«      ‚e*j\                  s e*j^                  «        ddl0mZ  ejb                  ddg«       edk\  reje                  de«        e3«       Z4d„ Z5e(rddl6m7Z7  G d„ de7«      Z8d„ Z9d„ Z:d-d„Z;edk\  r e;ejx                  «      Z=n*edk\  r e;ej|                  «      Z=n e;ej&                  «      Z=ddl?m@Z@  eAd e@j„                  e=j‡                  d«      ¬ «      j‰                  d«      f¬«      ZE G d!„ d"e3«      ZF G d#„ d$e"eF«      ZGd%ZHd&ZI G d'„ d(eG«      ZJ G d)„ d*eJ«      ZK G d+„ d,eG«      ZLy).ztest passlib.ext.djangoé    )Úabsolute_importÚdivisionÚprint_functionN)ÚappsÚexcÚregistry)Údjango10_contextÚdjango14_contextÚdjango16_context)ÚCryptContext)ÚDJANGO_VERSIONÚMIN_DJANGO_VERSIONÚDjangoTranslatorÚquirks)Ú	iteritemsÚget_method_functionÚu)Úmemoized_property)ÚTestCaseÚ	TEST_MODEÚhandler_derived_from)Úget_handler_case)ÚDjangoBehaviorTestÚExtensionBehaviorTestÚDjangoExtensionTestÚ_ExtensionSupportÚ_ExtensionTest)ÚsettingsÚLazySettingsz2expected django.conf.settings to be LazySettings: )r   zdjango.contrib.contenttypeszdjango.contrib.auth)é   é   z1this release hasn't been tested against Django %rc                  ó    — t        | «      D ]@  \  }}|t        u r"t        t        |«      sŒt	        t        |«       Œ0t        t        ||«       ŒB y)z*helper to update django settings from kwdsN)r   ÚUNSETÚhasattrr   ÚdelattrÚsetattr)ÚkwdsÚkÚvs      ú_C:\xampp\htdocs\tradingbinance\backend\.venv\Lib\site-packages\passlib/tests/test_ext_django.pyÚupdate_settingsr+   N   s;   € ä˜Ž‰ˆˆ!Ø”‰:Ü”x Õ#Üœ !Õ$ä”H˜a Õ#ñ ó    )ÚUserc                   óB   — e Zd ZdZ G d„ d«      Zed„ «       Zd„ Zdd„Zy)	ÚFakeUserz#mock user object for use in testingc                   ó   — e Zd Ze Zy)úFakeUser.MetaN)Ú__name__Ú
__module__Ú__qualname__Ú	app_label© r,   r*   ÚMetar1   _   s   „ Ø ‰Ir,   r7   c                 ó   — g S ©Nr6   ©Úselfs    r*   Úsaved_passwordszFakeUser.saved_passwordsb   s   € àˆIr,   c                 óh   — 	 | j                   d d  | j                   d d …= S # | j                   d d …= w xY wr9   )r<   r:   s    r*   Úpop_saved_passwordszFakeUser.pop_saved_passwordsf   s2   € ð,Ø×+Ñ+©AÐ.à×(Ñ(ªÑ+ø�D×(Ñ(ªÑ+ús   ‚   1Nc                 óN   — | j                   j                  | j                  «       y r9   )r<   ÚappendÚpassword)r;   Úupdate_fieldss     r*   ÚsavezFakeUser.savel   s   € à× Ñ ×'Ñ'¨¯©Õ6r,   r9   )	r2   r3   r4   Ú__doc__r7   r   r<   r>   rC   r6   r,   r*   r/   r/   Z   s-   „ Ù1÷	!ñ 	!ð 
ñ	ó 
ð	ò	,ô	7r,   r/   c                  ó.   ‡— g Šˆfd„} ˆfd„}|| _         | S )Nc                 ó(   •— ‰j                  | «       y r9   )r@   )rA   Ústates    €r*   Úsetterz"create_mock_setter.<locals>.setterr   s   ø€ Ø�‰�XÕr,   c                  ó.   •— 	 ‰ d d  ‰ d d …= S # ‰ d d …= w xY wr9   r6   )rG   s   €r*   Úpopstatez$create_mock_setter.<locals>.popstatet   s   ø€ ð	Ø™�8à’a‘ø�’a‘ús   ƒ �)rJ   )rH   rJ   rG   s     @r*   Úcreate_mock_setterrK   p   s    ø€ Ø€Eôôð
 €F„OØ€Mr,   c                 óš   — | sJ ‚ddl m} 	  |d| ¬«       y# t        $ r*}t        j                  dt        |«      «      rY d}~y‚ d}~ww xY w)	z|
    check whether django hasher is available;
    or if it should be skipped because django lacks third-party library.
    r   ©Úmake_passwordÚ ©ÚhasherTz3Couldn't load '.*?' algorithm .* No module named .*NF)Údjango.contrib.auth.hashersrN   Ú
ValueErrorÚreÚmatchÚstr)ÚnamerN   Úerrs      r*   Úcheck_django_hasher_has_backendrY   }   sI   € ñ
 €Kˆ4Ý9ðÙ�b Õ&ØøÜò Ü�8‰8ÐIÌ3ÈsË8ÔTÜØûðús   Œ
 —	A
 AÁAÁA
c                 óÀ   — t        | d«      r| j                  «       } | j                  d¬«       |€t        rddlm} |j                  }|r| j                  ||¬«       | S )zš
    helper to build django CryptContext config matching expected setup for stock django deploy.
    :param kwds:
    :param sha_rounds:
    :return:
    Úto_dictÚauto)Ú
deprecatedr   )ÚPBKDF2PasswordHasher)Ú"django_pbkdf2_sha1__default_roundsÚ$django_pbkdf2_sha256__default_rounds)r$   r[   ÚupdateÚhas_min_djangorR   r^   Ú
iterations)r'   Ú
sha_roundsr^   s      r*   Ú_modify_django_configre   �   sj   € ô ˆt�YÔà�|‰|‹~ˆð 	‡K�Kàð ô ð Ð�nÝDØ)×4Ñ4ˆ
ñ Ø�‰Ø/9Ø1;ð 	ô 	
ð
 €Kr,   )r!   é   ©rf   é
   )Údjango_pbkdf2_sha256znot a passwordr`   ©Úroundsc                   óD   — e Zd ZdZed„ «       Zd„ Zd	d„Zg d¢Zd
d„Z	d„ Z
y)r   zx
    test support funcs for loading/unloading extension.
    this class is mixed in to various TestCase subclasses.
    c              #   óZ  K  — ddl m}m} ddg}ddg}g d¢}||f|j                  |f||fg}|D ]y  \  }}t	        |«      D ]f  }	|	j                  d«      rŒ|j                  j                  |	t        «      }
|
t        u r|	|vrŒBt        |
«      }
t        |
dd	«      }|sŒ]||	||	|v f–— Œh Œ{ y	­w)
zàhelper to scan for monkeypatches.

        returns tuple containing:
        * object (module or class)
        * attribute of object
        * value of attribute
        * whether it should or should not be patched
        r   )ÚmodelsÚhashersÚcheck_passwordÚset_passwordrN   )rp   rN   Ú
get_hasherÚidentify_hasherÚget_hashersÚ_r3   N)Údjango.contrib.authrn   ro   r-   ÚdirÚ
startswithÚ__dict__Úgetr#   r   Úgetattr)Úclsrn   ro   Ú
user_attrsÚmodel_attrsÚhasher_attrsÚobjsÚobjÚpatchedÚattrÚvalueÚsources               r*   Ú_iter_patch_candidatesz(_ExtensionSupport._iter_patch_candidatesØ   sË   è ø€ ÷ 	8Ø&¨Ð7ˆ
Ø'¨Ð9ˆò'ˆà˜Ð%Ø—‘˜jÐ)Ø˜,Ð'ð
ˆó !‰LˆC�Ü˜Cž�Ø—?‘? 3Ô'ØØŸ™×(Ñ(¨¬uÓ5�ØœE‘> d°'Ñ&9ØÜ+¨EÓ2�Ü  ¨°dÓ;�ÚØ˜t V¨d°g¨oÐ>Ó>ñ !ñ !ùs   ‚BB+ÂB+c           
      óx  — t         j                  j                  d«      }| j                  |xr |j                  j
                  d«       | j                  «       D ]^  \  }}}}|r+| j                  |j                  d«      d|›d|›d|›�«       Œ5| j                  |j                  d«      d|›d|›d|›�«       Œ` y	)
z8
        test that django is in unpatched state
        úpasslib.ext.django.modelszpatch should not be enabledzdjango.contrib.auth.úobj=ú attr=z was not reverted: úpasslib.ú should not have been patched: N)	ÚsysÚmodulesrz   ÚassertFalseÚadapterr‚   r†   Ú
assertTruerx   )r;   Úmodr�   rƒ   r…   r‚   s         r*   Úassert_unpatchedz"_ExtensionSupport.assert_unpatchedý   s¨   € ô
 �k‰k�o‰oÐ9Ó:ˆØ×Ñ˜Ò4 §¡×!4Ñ!4Ð6SÔTð +/×*EÑ*EÖ*GÑ&ˆC��v˜wÙØ—‘ × 1Ñ 1Ð2HÔ Iâ!$¢d©Fð!4õ5ð × Ñ  ×!2Ñ!2°:Ô!>â!$¢d©Fð!4õ5ñ +Hr,   Nc           
      ó  — t         j                  j                  d«      }| j                  |xr |j                  j
                  d«       | j                  «       D ]R  \  }}}}|r| j                  |dk(  d|›d|›d|›�«       Œ)| j                  |j                  d«      d|›d|›d|›�«       ŒT |�Rt        j                  |«      }| j                  |j                  j                  d
¬«      |j                  d
¬«      «       y	y	)zY
        helper to ensure django HAS been patched, and is using specified config
        rˆ   zpatch should have been enabledzpasslib.ext.django.utilsr‰   rŠ   z should have been patched: r‹   rŒ   NT©Úresolve)r�   rŽ   rz   r‘   r�   r‚   r†   r�   rx   r   Ú_norm_sourceÚassertEqualÚpassword_contextr[   )r;   Úcontextr’   r�   rƒ   r…   r‚   s          r*   Úassert_patchedz _ExtensionSupport.assert_patched  sï   € ô
 �k‰k�o‰oÐ9Ó:ˆØ�‰˜Ò3 §¡× 3Ñ 3Ð5UÔVð +/×*EÑ*EÖ*GÑ&ˆC��v˜wÙØ—‘ Ð*DÒ Dâ!$¢d©Fð!4õ5ð × Ñ  ×!2Ñ!2°:Ô!>â!$¢d©Fð!4õ5ð +Hð ÐÜ"×/Ñ/°Ó8ˆGØ×Ñ˜S×1Ñ1×9Ñ9À$Ð9ÓGØ$Ÿ_™_°T˜_Ó:õ<ð r,   )ÚPASSLIB_CONFIGÚPASSLIB_CONTEXTÚPASSLIB_GET_CATEGORYc                 ó  — | j                  «        |r$|j                  d«      xs |j                  d«      }| j                  D ]  }|j                  |t        «       Œ t        di |¤Ž ddl}|r| j                  ¬«       yy)zO
        helper to load extension with specified config & patch django
        rœ   r�   r   N©rš   r6   )Úunload_extensionrz   Ú_config_keysÚ
setdefaultr#   r+   Úpasslib.ext.django.modelsr›   )r;   Úcheckr'   ÚconfigÚkeyÚpasslibs         r*   Úload_extensionz _ExtensionSupport.load_extension/  sv   € ð 	×ÑÔÙØ—X‘XÐ.Ó/ÒN°4·8±8Ð<MÓ3NˆFØ×$Ô$ˆCØ�O‰O˜C¤Õ'ð %äÑ˜$ÒÛ(ÙØ×Ñ¨ÐÕ/ð r,   c                 ó  — t         j                  j                  d«      }|r+|j                  j	                  «        t         j                  d= t        di t        d„ | j                  D «       «      ¤Ž | j                  «        y)z?
        helper to remove patches and unload extension
        rˆ   c              3   ó,   K  — | ]  }|t         f–— Œ y ­wr9   )r#   )Ú.0r§   s     r*   Ú	<genexpr>z5_ExtensionSupport.unload_extension.<locals>.<genexpr>G  s   è ø€ ÐIÑ7H° ¤Uœ|Ñ7Hùs   ‚Nr6   )	r�   rŽ   rz   r�   Úremove_patchr+   Údictr¢   r“   )r;   r’   s     r*   r¡   z"_ExtensionSupport.unload_extension=  s_   € ô
 �k‰k�o‰oÐ9Ó:ˆÙØ�K‰K×$Ñ$Ô&Ü—‘Ð7Ð8äÑJœ$ÑI°t×7HÒ7HÓIÓIÒJà×ÑÕr,   r9   )T)r2   r3   r4   rD   Úclassmethodr†   r“   r›   r¢   r©   r¡   r6   r,   r*   r   r   Ï   s8   „ ñð ñ?ó ð?òH5ó&<ò: Q€Ló0ó r,   r   c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )r   z€
    TestCase mixin which makes sure extension is unloaded before test;
    and make sure it's unloaded after test as well.
    c                 óþ   •— t         t        | �  «        | j                  d«       t        s| j                  d«      ‚t        s| j                  d«      ‚| j                  «        | j                  | j                  «       y )NÚdefaultzDjango not installedzDjango version too old)	Úsuperr   ÚsetUpÚrequire_TEST_MODEr   ÚskipTestrb   r¡   Ú
addCleanup©r;   Ú	__class__s    €r*   rµ   z_ExtensionTest.setUp]  sf   ø€ ÜŒn˜dÑ)Ô+à×Ñ˜yÔ)åØ—-‘-Ð 6Ó7Ð7ÝØ—-‘-Ð 8Ó9Ð9ð 	×ÑÔð 	�‰˜×-Ñ-Õ.r,   )r2   r3   r4   rD   rµ   Ú__classcell__©rº   s   @r*   r   r   T  s   ø„ ñ÷/ð /r,   r   ÚtoomanysecretsÚletmeinc                   óz   — e Zd ZdZdZdZeZed„ «       Z	d„ Z
edfd„Zd„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zy)r   a	  
    tests model to verify it matches django's behavior.

    running this class verifies the tests correctly assert what Django itself does.

    running the ExtensionBehaviorTest subclass below verifies "passlib.ext.django"
    matches what the tests assert.
    zverify django behaviorFc                 ó@   — t        j                  | j                  «      S )z?
        per-test CryptContext() created from .config.
        )r   r—   r¦   r:   s    r*   rš   zDjangoBehaviorTest.contextš  s   € ô
 ×(Ñ(¨¯©Ó5Ð5r,   c                 óÖ   — | j                  |j                  j                  d«      «       | j                  |j	                  «       «       | j                  |j                  «       g «       y)zO
        check that user object is set to 'unusable password' constant
        Ú!N)r‘   rA   rx   r�   Úhas_usable_passwordr˜   r>   )r;   Úusers     r*   Úassert_unusable_passwordz+DjangoBehaviorTest.assert_unusable_password¡  sO   € ð 	�‰˜Ÿ™×0Ñ0°Ó5Ô6Ø×Ñ˜×1Ñ1Ó3Ô4Ø×Ñ˜×1Ñ1Ó3°RÕ8r,   Nc                 ól  — |t         u r9| j                  |j                  d«       | j                  |j                  d«       n| j                  |j                  |«       | j	                  |j                  «       d|j                  ›�«       | j                  |j                  «       |€g «       y|g«       y)zÚ
        check that user object has a usable password hash.
        :param hash: optionally check it has this exact hash
        :param saved: check that mock commit history for user.password matches this list
        rÂ   Nzhash should be usable: )r#   ÚassertNotEqualrA   r˜   r‘   rÃ   r>   )r;   rÄ   ÚhashÚsaveds       r*   Úassert_valid_passwordz(DjangoBehaviorTest.assert_valid_password©  s“   € ð ”5‰=Ø×Ñ §¡¨sÔ3Ø×Ñ §¡¨tÕ4à×Ñ˜TŸ]™]¨DÔ1Ø�‰˜×0Ñ0Ô2Ø7;·}²}ÐFô	Hà×Ñ˜×1Ñ1Ó3Ø$˜}˜õ	;Ø38°'õ	;r,   c                 ó  — | j                   s| j                  d«      ‚| j                  }ddlm} ddlm} | j                  |j                  d¬«      |j                  d¬«      «       ddl	m} | j                  ||«       y)z;
        test extension config is loaded correctly
        zextension not loadedr   )rp   )r™   Tr•   N)
r‚   r·   rš   rR   rp   r¤   r™   r˜   r[   Údjango.contrib.auth.models)r;   Úctxrp   r™   Úcheck_password2s        r*   Útest_extension_configz(DjangoBehaviorTest.test_extension_configÎ  sm   € ð �|Š|Ø—-‘-Ð 6Ó7Ð7à�l‰lˆõ 	?Ý>Ø×ÑÐ)×1Ñ1¸$Ð1Ó?ÀÇÁÐUYÀÓAZÔ[õ 	QØ×Ñ˜¨.Õ9r,   c                 ó€  — | j                   }ddlm} t        «       }|j	                  t
        «       | j                  |j                  «       j                  t
        |j                  «      «       | j                  |«        |t
        «      }| j                  |j                  «       j                  t
        |«      «       y)z1
        test django's default algorithm
        r   rM   N)rš   rR   rN   r/   rq   ÚPASS1r‘   ÚhandlerÚverifyrA   rÊ   )r;   rÍ   rN   rÄ   rÈ   s        r*   Útest_default_algorithmz)DjangoBehaviorTest.test_default_algorithmà  s…   € ð �l‰lˆõ 	>ô ‹zˆØ×Ñœ%Ô Ø�‰˜Ÿ™›×,Ñ,¬U°D·M±MÓBÔCØ×"Ñ" 4Ô(ñ
 œUÓ#ˆØ�‰˜Ÿ™›×,Ñ,¬U°DÓ9Õ:r,   c                 ó˜  — | j                   }ddlm}m}m}m} t        «       }|j                  d«       |j                  }| j                  |j                  «       j                  d|«      «       | j                  ||«       | j                  |j                  d«      «       | j                  ||«       | j                   |d|«      «       y)zB
        test how methods handle empty string as password
        r   ©rp   rN   Úis_password_usablers   rO   N)rš   rR   rp   rN   r×   rs   r/   rq   rA   r‘   rÒ   rÓ   rÊ   )r;   rÍ   rp   rN   r×   rs   rÄ   rÈ   s           r*   Útest_empty_passwordz&DjangoBehaviorTest.test_empty_password÷  s¤   € ð �l‰lˆ÷	
ó 	
ô ‹zˆØ×Ñ˜"ÔØ�}‰}ˆØ�‰˜Ÿ™›×,Ñ,¨R°Ó6Ô7Ø×"Ñ" 4¨Ô.ð 	�‰˜×+Ñ+¨BÓ/Ô0Ø×"Ñ" 4¨Ô.ð 	�‰™ r¨4Ó0Õ1r,   c                 óD  — ddl m}m}m}m} t        «       }|j                  «        | j                  |«       t        «       }|j                  d«       | j                  |«       | j                  |j                  d«      «       | j                  |j                  d«      «       | j                  |j                  d«      «       | j                  |j                  t        «      «       | j                  |j                  t        «      «       | j                  |«       | j                   |d«      j                  d«      «       | j                   |t        d«      «       | j                   ||j                  «      «       | j                  t         ||j                  «       y)zA
        test how methods handle 'unusable flag' in hash
        r   rÖ   NÚNonerO   rÂ   )rR   rp   rN   r×   rs   r/   Úset_unusable_passwordrÅ   rq   r�   rÑ   ÚWRONG1r‘   rx   rA   ÚassertRaisesrS   ©r;   rp   rN   r×   rs   rÄ   s         r*   Útest_unusable_flagz%DjangoBehaviorTest.test_unusable_flag  sF  € ÷
	
ó 	
ô ‹zˆØ×"Ñ"Ô$Ø×%Ñ% dÔ+ô ‹zˆØ×Ñ˜$ÔØ×%Ñ% dÔ+ð 	×Ñ˜×,Ñ,¨TÓ2Ô3Ø×Ñ˜×,Ñ,¨VÓ4Ô5Ø×Ñ˜×,Ñ,¨RÓ0Ô1Ø×Ñ˜×,Ñ,¬UÓ3Ô4Ø×Ñ˜×,Ñ,¬VÓ4Ô5Ø×%Ñ% dÔ+ð 	�‰™ dÓ+×6Ñ6°sÓ;Ô<ð 	×Ñ™¬¨sÓ3Ô4ð 	×ÑÑ+¨D¯M©MÓ:Ô;Ø×Ñœ* o°t·}±}ÕEr,   c                 ó.  — | j                   }ddlm}m}m}m} t        «       }d|_        t        j                  r(|s&| j                  t        |j                  t        «       n$| j                  |j                  t        «      «       | j                  |j                  «       t        j                   «       t        j                  r|s| j                  t        |t        d«       n| j                   |t        d«      «       | j                  t        |d«       y)z<
        test how methods handle None as hash value
        r   rÖ   N)r‚   rR   rp   rN   r×   rs   r/   rA   r   Ú none_causes_check_password_errorrÝ   Ú	TypeErrorrÑ   r�   r˜   rÃ   Úempty_is_usable_password)r;   r‚   rp   rN   r×   rs   rÄ   s          r*   Útest_none_hash_valuez'DjangoBehaviorTest.test_none_hash_valueA  sÏ   € ð —,‘,ˆ÷	
ó 	
ô ‹zˆØˆŒÜ×2Ò2¹7à×Ñœi¨×)<Ñ)<¼eÕDà×Ñ˜T×0Ñ0´Ó7Ô8à×Ñ˜×1Ñ1Ó3Ü×8Ñ8ô	:ô ×2Ò2¹7Ø×Ñœi¨¼ÀÕEà×Ñ™^¬E°4Ó8Ô9ð 	×Ñœ) _°dÕ;r,   c                 óÀ  — ddl m}m}m}m} t        «       }d|_        | j                  |j                  t        «      «       | j                  |j                  d«       | j                  |j                  «       g «       | j                  |j                  «       t        j                  «       | j                   |t        d«      «       | j                  t        |d«       y)zD
        test how methods handle empty string as hash value
        r   rÖ   rO   N)rR   rp   rN   r×   rs   r/   rA   r�   rÑ   r˜   r>   rÃ   r   rã   rÝ   rS   rÞ   s         r*   Útest_empty_hash_valuez(DjangoBehaviorTest.test_empty_hash_valuej  s°   € ÷
	
ó 	
ô ‹zˆØˆŒØ×Ñ˜×,Ñ,¬UÓ3Ô4ð 	×Ñ˜Ÿ™¨Ô+Ø×Ñ˜×1Ñ1Ó3°RÔ8ð 	×Ñ˜×1Ñ1Ó3´V×5TÑ5TÔUð 	×Ñ™¬¨rÓ2Ô3ð 	×Ñœ* o°rÕ:r,   c                 ó‚   — dD ].  }| j                  |¬«      5  | j                  |«       ddd«       Œ0 y# 1 sw Y   Œ;xY w)z>
        test how methods handle invalid hash values.
        )z$789$foo)rÈ   N)ÚsubTestÚ_do_test_invalid_hash_value)r;   rÈ   s     r*   Útest_invalid_hash_valuesz+DjangoBehaviorTest.test_invalid_hash_values�  s=   € ó
ˆDð —‘ 4�Õ(Ø×0Ñ0°Ô6÷ )Ð(ñ
÷ )Ð(ús   ˜5µ>	c                 óÀ  — ddl m}m}m}m} t        «       }||_        | j                  |j                  t        «      «       | j                  |j                  |«       | j                  |j                  «       g «       | j                  |j                  «       t        j                  «       | j                   |t        |«      «       | j                  t        ||«       y )Nr   rÖ   )rR   rp   rN   r×   rs   r/   rA   r�   rÑ   r˜   r>   rÃ   r   Úinvalid_is_usable_passwordrÝ   rS   )r;   rÈ   rp   rN   r×   rs   rÄ   s          r*   ré   z.DjangoBehaviorTest._do_test_invalid_hash_value™  s°   € ÷	
ó 	
ô ‹zˆØˆŒØ×Ñ˜×,Ñ,¬UÓ3Ô4ð 	×Ñ˜Ÿ™¨Ô-Ø×Ñ˜×1Ñ1Ó3°RÔ8ð 	×Ñ˜×1Ñ1Ó3´V×5VÑ5VÔWð 	×Ñ™¬¨tÓ4Ô5ð 	×Ñœ* o°tÕ<r,   c                 ó²   — | j                   j                  «       D ].  }| j                  |¬«      5  | j                  |«       ddd«       Œ0 y# 1 sw Y   Œ;xY w)z�
        run a bunch of subtests for each hasher available in the default django setup
        (as determined by reading self.context)
        )ÚschemeN)rš   Úschemesrè   Ú_do_test_available_scheme)r;   rî   s     r*   Útest_available_schemesz)DjangoBehaviorTest.test_available_schemes¼  sF   € ð
 —l‘l×*Ñ*Ö,ˆFØ—‘ V�Õ,Ø×.Ñ.¨vÔ6÷ -Ð,ñ -ß,Ð,ús   °AÁA	c                 ó²  — | j                  «       }| j                  }| j                  }t        «       }ddlm}m}m}m}	 |j                  |«      }
|j                  d||
«       |j                  |«      j                  }|r||j                  «       k7  sJ ‚	 t        |«      }t#        |
|j                  «      sJ ‚|
j$                  r| j!                  d«      ‚|sFt'        |
j(                  «      s1|dv s
J d|z  «       ‚|j+                  d|«       | j!                  d	«      ‚	 t,        |   \  }}d}t3        «       }||_        | j7                  |j                  d«      «       | j7                  |j                  |«      «       | j9                  ||«       | j;                  |j                  |«      «       |}|r�| j=                  |j4                  |«       | j7                  |
j?                  |j4                  «      «       | j;                  |j                  «       jA                  ||j4                  «      «       | j9                  ||j4                  ¬«       n| j9                  ||«       tC        d¬«      rytE        «       jG                  |«      } |||¬«      }| j;                  |
jA                  ||«      «       | j;                   ||||¬«      «       | jI                  |jK                  «       |r|gng «       | j7                   ||||¬«      «       | jI                  |jK                  «       g «       | j;                   ||«      «       tE        «       jM                   |	|«      jN                  «      }| jI                  ||«       y# t        j                  $ r | j!                  d«      ‚w xY w# t.        $ r%  |d
«      j0                  }	  |«       \  }}|rnŒY �Œªw xY w)z‹
        helper to test how specific hasher behaves.
        :param scheme: *passlib* name of hasher (e.g. "django_pbkdf2_sha256")
        r   rÖ   ztesting scheme: %r => %rzbackend not availablezskip disabled hasher)Údjango_bcryptÚdjango_bcrypt_sha256Údjango_argon2z+%r scheme should always have active backendz3skipping scheme %r due to missing django dependencyzskip due to missing dependencyrµ   ÚdontletmeinN)rÉ   r³   )ÚmaxrP   )rH   )(Ú	getLoggerrš   r‚   rK   rR   rp   rN   r×   rs   rÒ   Údebugr]   Údefault_schemer   r   ÚMissingBackendErrorr·   r   Úis_disabledrY   Údjango_nameÚwarningÚsample_hashesÚKeyErrorÚget_sample_hashr/   rA   r�   rÊ   r‘   rÇ   ÚidentifyrÓ   r   r   Úpasslib_to_django_namer˜   rJ   Údjango_to_passlib_nameÚ	algorithm)r;   rî   ÚlogrÍ   r‚   rH   rp   rN   r×   rs   rÒ   r]   ÚtestcaseÚsecretrÈ   r  ÚotherrÄ   Úneeds_updateÚalgÚhash2rW   s                         r*   rð   z,DjangoBehaviorTest._do_test_available_schemeÅ  sr  € ð
 �n‰nÓˆØ�l‰lˆØ—,‘,ˆÜ#Ó%ˆ÷	
ó 	
ð —+‘+˜fÓ%ˆØ�	‰	Ð,¨f°gÔ>Ø—[‘[ Ó(×3Ñ3ˆ
Ù ¨3×+=Ñ+=Ó+?Ò!?Ð?Ð?ð	9Ü'¨Ó/ˆHô $ G¨X×-=Ñ-=Ô>Ð>Ð>Ø×ÒØ—-‘-Ð 6Ó7Ð7ñ
 Ô>¸w×?RÑ?RÔSØÐWÑWð GØ=ÀÑFóGÐWà�K‰KÐMÈvÔVØ—-‘-Ð @ÓAÐAð	Ü(¨Ñ0‰LˆF�Dð ˆô ‹zˆØˆŒð 	×Ñ˜×,Ñ,¨TÓ2Ô3à×Ñ˜×,Ñ,¨UÓ3Ô4Ø×"Ñ" 4¨Ô.ð 	�‰˜×+Ñ+¨FÓ3Ô4ð "ˆÙØ×Ñ §¡¨tÔ4Ø×Ñ˜W×-Ñ-¨d¯m©mÓ<Ô=Ø�O‰O˜CŸK™K›M×0Ñ0°¸¿¹ÓGÔHØ×&Ñ& t°4·=±=Ð&ÕAà×&Ñ& t¨TÔ2ô ˜Õ#Øô
 Ó ×7Ñ7¸Ó?ˆÙ˜f¨SÔ1ˆØ�‰˜Ÿ™ v¨uÓ5Ô6ð 	�‰™ v¨t¸FÔCÔDØ×Ñ˜Ÿ™Ó*¹¨V©HÈ"ÔMð 	×Ñ™¨¨t¸FÔCÔDØ×Ñ˜Ÿ™Ó*¨BÔ/ð 	�‰Ñ*¨4Ó0Ô1ÜÓ!×8Ñ8¹ÈÓ9N×9XÑ9XÓYˆØ×Ñ˜˜vÕ&øôs ×&Ñ&ò 	9Ø—-‘-Ð 7Ó8Ð8ð	9ûô$ ò 	Ù& wÓ/×?Ñ?ˆOØÙ.Ó0‘�˜ÙØð ò ð	ús   ÂN  ÄN( Î %N%Î(*OÏO)r2   r3   r4   rD   ÚdescriptionPrefixr‚   Ústock_configr¦   r   rš   rÅ   r#   rÊ   rÏ   rÔ   rØ   rß   rä   ræ   rê   ré   rñ   rð   r6   r,   r*   r   r   z  s|   „ ñð 1Ðð €Gð €Fð ñ6ó ð6ò9ð 05¸Dó ;òJ:ò$;ò. 2òD&FòP'<òR#;òJ7ò!=òF7ót'r,   r   c                   ó:   ‡ — e Zd ZdZdZ edd¬«      Zˆ fd„Zˆ xZS )r   z`
    test that "passlib.ext.django" conforms to behavioral assertions in DjangoBehaviorTest
    zverify extension behaviorz sha256_crypt,md5_crypt,des_cryptÚ	des_crypt)rï   r]   c                 óp   •— t         t        | �  «        | j                  | j                  ¬«       d| _        y )N©rœ   T)r´   r   rµ   r©   r¦   r‚   r¹   s    €r*   rµ   zExtensionBehaviorTest.setUpN  s/   ø€ ÜÔ# TÑ0Ô2ð 	×Ñ¨4¯;©;ÐÔ7Øˆ�r,   )	r2   r3   r4   rD   r  r¯   r¦   rµ   r»   r¼   s   @r*   r   r   C  s*   ø„ ñð 4ÐáØ6Ø"ô€F÷
ð r,   r   c                   óD   — e Zd ZdZdZd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zy)r   z0
    test the ``passlib.ext.django`` plugin
    zpasslib.ext.django pluginc                 óÀ  — | j                  dd¬«       | j                  «        | j                  d«      5  | j                  dd¬«       ddd«       | j                  «        | j                  dd¬«       | j                  t        ¬«       | j                  «        | j                  dd¬«       | j                  t        ¬«       | j                  «        y# 1 sw Y   ŒŒxY w)	z.test set_django_password_context patch/unpatchÚdisabledF©rœ   r¥   ú!PASSLIB_CONFIG=None is deprecatedNú
django-1.0r    ú
django-1.4)r©   r“   ÚassertWarningListr›   r	   r¡   r
   r:   s    r*   Útest_00_patch_controlz)DjangoExtensionTest.test_00_patch_controlg  sÍ   € ð 	×Ñ¨:¸UÐÔCØ×ÑÔð ×#Ñ#Ð$GÕHØ×Ñ¨t¸5ÐÔA÷ Ià×ÑÔð 	×Ñ¨<¸uÐÔEØ×ÑÔ$4ÐÔ5ð 	×ÑÔð 	×Ñ¨<¸uÐÔEØ×ÑÔ$4ÐÔ5ð 	×ÑÕ÷! IÐHús   µCÃCc                 ó  — d}| j                  |¬«       ddlmc mc m} ddlm} d„ }|j                  j                  }||j                  _        | j                  d«      5  |j                  j                  «        ddd«       ||j                  _        |j                  }||_        | j                  d«      5  |j                  j                  «        ddd«       ||_        y# 1 sw Y   ŒixY w# 1 sw Y   ||_        yxY w)	z(test detection of foreign monkeypatchingz[passlib]
schemes=des_crypt
r  r   N)r�   c                   ó   — y r9   r6   r6   r,   r*   Údummyz>DjangoExtensionTest.test_01_overwrite_detection.<locals>.dummyŽ  s   € Ør,   z/another library has patched.*User\.set_passwordz2another library has patched.*models:check_password)r©   rÌ   ÚcontribÚauthrn   r¤   r�   r-   rq   r  Ú_managerÚ	check_allrp   )r;   r¦   rn   r�   r  Úorigs         r*   Útest_01_overwrite_detectionz/DjangoExtensionTest.test_01_overwrite_detection�  s×   € ð 2ˆØ×Ñ¨6ÐÔ2÷ 	4Ó3Ý5ò	ð �{‰{×'Ñ'ˆØ#(ˆ�‰Ô Ø×#Ñ#Ð$UÕVØ×Ñ×&Ñ&Ô(÷ Wà#'ˆ�‰Ô ð ×$Ñ$ˆØ %ˆÔØ×#Ñ#Ð$XÕYØ×Ñ×&Ñ&Ô(÷ Zà $ˆÕ÷ WÐVú÷ Zà $ˆÕús   Á"C%Â:C1Ã%C.Ã1Dc           	      ó0  — ddl m} t        «       j                  }t        dkD  r| j                  t        |d«       n$ |d«      }| j                  ||j                  «        |d«      }| j                  ||j                  «       ddl
m}  |d«      }| j                  |j                  d«       |j                  d	«      }| j                  |j!                  d	|«      «       | j                  |j!                  d	|«      «       | j#                  |j!                  d
|«      «       |j                  d	dd¬«      }| j                  |d«       | j                  |j%                  |«      dt'        d«      dt'        d«      dœ«       | j                  t(        |d«       y)z'test Hasher-compatible handler wrappersr   )ro   rg   Úhex_md5ró   ©Úsha256_cryptr(  Úpasslib_sha256_cryptÚstubÚxxxxÚabcdabcdabcdabcdiÒ  rj   zK$5$rounds=1234$abcdabcdabcdabcd$v2RWkZQzctPdejyRqmmTDQpZN6wTh7.RUy9zF2LftT6zabcdab**********z+v2RWkZ*************************************)r  Úsaltrk   rÈ   Údoes_not_existN)rv   ro   r   Úpasslib_to_djangor   rÝ   rS   ÚassertIsInstanceÚUnsaltedMD5PasswordHasherÚBCryptPasswordHasherÚpasslib.hashr(  r˜   r  Úencoder‘   rÓ   r�   Úsafe_summaryr   r   )r;   ro   r/  rQ   r(  Úencodeds         r*   Útest_02_handler_wrapperz+DjangoExtensionTest.test_02_handler_wrapperŸ  sm  € å/ä,Ó.×@Ñ@Ðô ˜GÒ#Ø×ÑœjÐ*;¸YÕGá& yÓ1ˆFØ×!Ñ! &¨'×*KÑ*KÔLñ
 # ?Ó3ˆØ×Ñ˜f g×&BÑ&BÔCõ 	.Ù" >Ó2ˆØ×Ñ˜×)Ñ)Ð+AÔBð —-‘- Ó'ˆØ�‰˜×+Ñ+¨F°GÓ<Ô=Ø�‰˜Ÿ™ f¨gÓ6Ô7Ø×Ñ˜Ÿ™ v¨wÓ7Ô8ð —-‘- ¨¸�-Ó>ˆØ×Ñ˜ð #Pô 	Qà×Ñ˜×,Ñ,¨WÓ5Ø(ÜÐ)Ó*ØÜÐDÓEñô	ð 	×Ñœ(Ð$5Ð7GÕHr,   c                 óÜ   — | j                  d«      5  | j                  dd¬«       ddd«       | j                  «        | j                  dd¬«       | j                  «        y# 1 sw Y   Œ=xY w)ztest PASSLIB_CONFIG='disabled'r  NFr  r  )r  r©   r“   r:   s    r*   Útest_11_config_disabledz+DjangoExtensionTest.test_11_config_disabledÏ  sc   € ð ×#Ñ#Ð$GÕHØ×Ñ¨t¸5ÐÔA÷ Ià×ÑÔð 	×Ñ¨:¸UÐÔCØ×ÑÕ÷ IÐHús   ’A"Á"A+c                 óø   — | j                  dd¬«       t        }| j                  |«       | j                  dd¬«       | j                  t        «       | j                  dd¬«       | j                  t        «       y)ztest PASSLIB_CONFIG='<preset>'zdjango-defaultF©r�   r¥   r  r  r  N)r©   r   r›   r	   r
   )r;   rÍ   s     r*   Útest_12_config_presetsz*DjangoExtensionTest.test_12_config_presetsÚ  so   € ð 	×ÑÐ,<ÀEÐÔJÜˆØ×Ñ˜CÔ à×Ñ¨<¸uÐÔEØ×ÑÔ,Ô-à×Ñ¨<¸uÐÔEØ×ÑÔ,Õ-r,   c                 ó  — ddl m} t        j                  |«      }| j	                  «        | j                  |«       | j	                  dd¬«       | j                  |«       | j	                  |d¬«       | j                  |«       y)z$test PASSLIB_CONFIG default behaviorr   )ÚPASSLIB_DEFAULTzpasslib-defaultFr;  N)Úpasslib.ext.django.utilsr>  r   Úfrom_stringr©   r›   )r;   r>  r³   s      r*   Útest_13_config_defaultsz+DjangoExtensionTest.test_13_config_defaultsç  sx   € õ 	=Ü×*Ñ*¨?Ó;ˆØ×ÑÔØ×Ñ˜OÔ,ð 	×ÑÐ,=ÀUÐÔKØ×Ñ˜OÔ,ð 	×Ñ¨OÀ5ÐÔIØ×Ñ˜OÕ,r,   c                 óÔ   — t        dt        ¬«       | j                  t        t        d«       | j                  «        t        dt        ¬«       | j                  t        t        d«       y)ztest PASSLIB_CONFIG type checksé{   )r�   rœ   rˆ   zmissing-preset)rœ   r�   N)r+   r#   rÝ   râ   Ú
__import__r¡   rS   r:   s    r*   Útest_14_config_invalidz*DjangoExtensionTest.test_14_config_invalid÷  sI   € ä¨¼EÕBØ×Ñœ)¤ZÐ1LÔMà×ÑÔÜÐ'7ÌÕOØ×Ñœ*¤jÐ2MÕNr,   c                 ó  ‡— t        dgddd¬«      }ddlmŠ ˆfd„}| j                  |¬	«       | j	                   |«       d«       | j	                   |d
¬«      d«       | j	                   |d
¬«      d«       d„ }| j                  ||¬«       | j	                   |«       d«       | j	                   |d¬«      d«       | j	                   |d¬«      d«       | j	                   |d¬«      d«       d„ }| j                  ||¬«       | j	                   |«       d«       | j	                   |d¬«      d«       | j	                   |dd
¬«      d«       | j	                   |dd
¬«      d«       | j                  t        | j                  |d¬«       y)z#test PASSLIB_GET_CATEGORY parameterr(  iè  iÐ  i¸  )rï   Úsha256_crypt__default_roundsÚ#staff__sha256_crypt__default_roundsÚ'superuser__sha256_crypt__default_roundsr   r'  c                  ó†   •— t        di | ¤Ž}|j                  d«       ‰j                  |j                  «      j                  S )z;helper to take in user opts, return rounds used in passwordr*  r6   )r/   rq   r@  rA   rk   )r'   rÄ   r(  s     €r*   Úrunz9DjangoExtensionTest.test_21_category_setting.<locals>.run  s9   ø€ äÑ#˜dÑ#ˆDØ×Ñ˜fÔ%Ø×+Ñ+¨D¯M©MÓ:×AÑAÐAr,   r  T)Úis_staff)Úis_superuserc                 ó"   — | j                   xs d S r9   ©Ú
first_name©rÄ   s    r*   Úget_categoryzBDjangoExtensionTest.test_21_category_setting.<locals>.get_category  s   € Ø—?‘?Ò* dÐ*r,   )r�   rž   r	  rO  ÚstaffÚ	superuserc                  ó   — y r9   r6   rQ  s    r*   rR  zBDjangoExtensionTest.test_21_category_setting.<locals>.get_category%  s   € Ør,   )rP  rL  )rP  rM  ÚxN)r¯   r3  r(  r©   r˜   rÝ   râ   )r;   r¦   rK  rR  r(  s       @r*   Útest_21_category_settingz,DjangoExtensionTest.test_21_category_setting  s|  ø€ ô Ø%Ð&Ø+/Ø26Ø6:ô	ˆõ 	.ô	Bð 	×Ñ¨6ÐÔ2Ø×Ñ™› Ô%Ø×Ñ™ dÔ+¨TÔ2Ø×Ñ™¨$Ô/°Ô6ò	+à×Ñ¨FØ1=ð 	ô 	?à×Ñ™› Ô%Ø×Ñ™¨Ô0°$Ô7Ø×Ñ™¨Ô0°$Ô7Ø×Ñ™¨Ô4°dÔ;ò	à×Ñ¨FØ1=ð 	ô 	?à×Ñ™› Ô%Ø×Ñ™¨Ô0°$Ô7Ø×Ñ™¨¸$Ô?ÀÔFØ×Ñ™¨À$ÔGÈÔNð 	×Ñœ) T×%8Ñ%8È&Ø/2ð 	õ 	4r,   N)r2   r3   r4   rD   r  r  r$  r7  r9  r<  rA  rE  rW  r6   r,   r*   r   r   Y  s:   „ ñð 4Ðò ò4%ò<+Iò`	 ò.ò-ò Oó-4r,   r   r9   )MrD   Ú
__future__r   r   r   Úloggingrø   r2   r  r�   rT   r¨   r   Ú_appsr   r   Úpasslib.appsr	   r
   r   Úpasslib.contextr   r?  r   r   r   r   Úpasslib.utils.compatr   r   r   Úpasslib.utils.decorr   Úpasslib.tests.utilsr   r   r   Úpasslib.tests.test_handlersr   Ú__all__rb   Údjango.confr   r   Ú
isinstanceÚRuntimeErrorÚ
configuredÚ	configureÚdjango.appsÚpopulateÚinfoÚobjectr#   r+   rÌ   r-   r/   rK   rY   re   Údjango21_contextr  Údjango110_contextr3  ri   r¯   Úusingrz   rÈ   rÿ   r   r   rÑ   rÜ   r   r   r   r6   r,   r*   Ú<module>rn     sï  ðÙ ÷
 AÑ @Û Ð'�g×'Ñ'¨Ó1�Û 
Û 	÷ 1Ñ 0ß MÑ MÝ (÷ó ÷ CÑ BÝ 1ç IÑ IÝ 8ò€ð  Ð#5Ñ5€ñ ÷ 3á�h Ô-ò ÑU]Ð_Ó`Ð`ð ×ÒØˆ×ÑÔõ !Ø€D‡M�MÐ0Ð2GÐHÔIð �VÒØ‡H�HÐ@À.ÔQñ 	‹€ò$ñ Ý/ô7�4ô 7ò,
òó&ðR �VÒÙ(¨×)?Ñ)?Ó@�LØ�wÒÙ(¨×)@Ñ)@ÓA�Lñ )¨×)?Ñ)?Ó@€Lõ
 .ÙØ*ð -!Ð,@ß ™5¨×(8Ñ(8Ð9_Ó(`ô-bç™4Ð 0Ó1ð3ô€ôz ˜ô z ôJ/�XÐ0ô /ðD 	€Ø	€ô'˜ô 'ôRÐ.ô ô,W4˜.õ W4r,   