+
    i<                        R t ^ RIHt ^ RIt]P                  ! ]4      t^ RIt^ RIt^ RI	H
t
 ^ RIHt ^ RIHt ^ RIHtHtHtHt ^ RIHtHt ^ RIHtHtHt ]! R	4      tR
 t ! R R]4      t ! R R]4      t ! R R]]4      t ! R R]]4      t  ! R R]]4      t! ! R R]]4      t" ! R R]]4      t#]! ]
PH                  PK                  4       R4       ! R R]]4      4       t&]! ]
PH                  PK                  4       R4       ! R R]]4      4       t'^ RI(H)t) ]! ]
PT                  PK                  4       R4       ! R  R!]]4      4       t+R# )"zFpasslib.tests.test_handlers_django - tests for passlib hash algorithms)with_statementN)hash)repeat_string)u)TestCaseHandlerCase
skipUnlessSkipTest)	UPASS_USDUPASS_TABLE)DJANGO_VERSIONMIN_DJANGO_VERSIONcheck_django_hasher_has_backendu   lètmeinc                 2    R P                  R V  4       4      # ).c              3   8   "   T F  p\        V4      x  K  	  R # 5iN)str).0es   & `/var/www/html/photoedit/myenv/lib/python3.14/site-packages/passlib/tests/test_handlers_django.py	<genexpr>vstr.<locals>.<genexpr>   s     ,GqCFFGs   )join)versions   &r   vstrr      s    88,G,,,    c                   n   a  ] tR t^t o RtRt]tRtR t	]
P                  R	,           tR tR tR tRtV tR# )
_DjangoHelperz]
mixin for HandlerCase subclasses that are testing a hasher
which is also present in django.
TNc                   \         V P                  8  d,   V P                  R \        V P                  4      ,          4      hV P                  '       dA   \         V P                  8  d,   V P                  R\        V P                  4      ,          4      hV P
                  P                  p\        V4      '       g   V P                  RV,          4      hR# )zDjango >= %s not installedzDjango <= %s not installedzdjango hasher %r not availableT)r   min_django_versionskipTestr   max_django_versionhandlerdjango_namer   )selfnames   & r   _require_django_support%_DjangoHelper._require_django_support0   s    D333-- <tDD[D[?\ \]]"""~8O8O'O-- <tDD[D[?\ \]] ||''.t44-- @4 GHHr   c                j   a a  S P                  4        ^ RIHo TT 3R lpT#   \         d     R # i ; i)Ncheck_passwordc                   < SP                   P                  R8X  d,   VP                  ! R4      '       d   VP                  ! RR4      p\	        V \
        4      '       d   V P                  R4      p S! W4      # )zdjango/check_passworddjango_bcryptzbcrypt$$2y$z$$2y$z$$2a$utf-8)r#   r&   
startswithreplace
isinstancebytesdecode)secretr   r+   r%   s   &&r   verify_django9_DjangoHelper.fuzz_verifier_django.<locals>.verify_djangoI   sY    ||  O38V8V||GW5&%((w/!&//r   )r'   r	   django.contrib.auth.hashersr+   )r%   r5   r+   s   f @r   fuzz_verifier_django"_DjangoHelper.fuzz_verifier_djangoB   s:    	((* 	?	0   		s   # 22c           	         V P                  4        ^ RIHp V P                  '       g   Q hV P	                  4        FO  w  r#V P                  V! W#4      RV: RV: R24       V P                  V! RV,           V4      RV: RV: R24       KQ  	  R# )	z:run known correct hashes through Django's check_password()r*   zsecret=z hash=z failed to verifyxzmangled secret=z incorrect verifiedN)r'   r7   r+   known_correct_hashesiter_known_hashes
assertTrueassertFalse)r%   r+   r4   r   s   &   r   test_90_django_reference&_DjangoHelper.test_90_django_referenceR   s~    $$& 	?((((( 224LFOON68#T+, ^C&L$?#T+,	 5r   c                Z   V P                  4        ^ RIHp ^ RIHp V P
                  P                  pV! 4       V P                  ^,          ,           pV P                  W P                  4       4      pV! 4       V8  d   VP                  4       w  rgV'       g   K(  \        V\        4      '       d   VP                  R4      pV! WcR7      pV P                  V P                  V4      4       V P                  V P!                  Wh4      4       V P#                  V P!                  Wx4      4       K  R# )z/test against output of Django's make_password())tick)make_passwordr.   )hasherN)r'   passlib.utilsrC   r7   rD   r#   r$   max_fuzz_timeFuzzHashGenerator	getRandomrandom_password_pairr1   r2   r3   r>   do_identify	do_verifyr?   )	r%   rC   rD   r&   end	generatorr4   otherr   s	   &        r   test_91_django_generation'_DjangoHelper.test_91_django_generationa   s    $$& 	'=||''ft))!++**41AB	fsl%::<MF&%((w/ 5DOOD,,T23OODNN689T^^E89 r    )r8   )__name__
__module____qualname____firstlineno____doc___DjangoHelper__unittest_skipr   r    r"   r'   r   fuzz_verifiersextra_fuzz_verifiersr8   r@   rP   __static_attributes____classdictcell____classdict__s   @r   r   r      sR      O ,  '55 9  ,: :r   r   c                   J    ] tR t^vtRt]P                  tRtRR]	R3.t
R.tRtR# )	django_disabled_testztest django_disabledT!rR   N)passwordra   ) ra   )z!9wa845vn7098ythaehasldkfjrb   ra   )rS   rT   rU   rV   rW   r   django_disabledr#   disabled_contains_saltr   r<   known_alternate_hashesr[   rR   r   r   r`   r`   v   s;    ""G! 		c	 	8r   r`   c                   t    ] tR t^tRt]P                  tR	tR
RR]	R3]
R3]! R4      R3R.tR.tR.t. ROtRtR# )django_des_crypt_testztest django_des_cryptzcrypt$c2e86$c2hN1Bxd6ZiWszcrypt$0.aQs$0.wB.TT0Czvlou   hellÖzcrypt$sa$saykDgk3BPZ9E
sha1$aa$bbrR   N   	   )rb   crypt$c2$c2M87q...WWcU)rb   zcrypt$c2e86$c2M87q...WWcU)passwordignoremezcrypt$c2.AZ$c2M87q...WWcU)fooz!crypt$MNVY.9ajgdvDQ$MNVY.9ajgdvDQ)zcrypt$$c2M87q...WWcUrb   rm   )zcrypt$c2$c2M87qzcrypt$f$c2M87q...WWcUzcrypt$ffe86$c2M87q...WWcU)rS   rT   rU   rV   rW   r   django_des_cryptr#   r"   r
   r   r   r<   rf   known_unidentified_hashesknown_malformed_hashesr[   rR   r   r   rh   rh      sr    ##G 	799 
/0	12	
<23 	5$ 	G 	!	r   rh   c                       ] tR t^tRt]P                  tR
tRR]	R3]
R3.tR.tR.t ! R R]P                  4      tRtR	# )django_salted_md5_testztest django_salted_md5z*md5$c2e86$92105508419a81a6babfaecf876a2fa0z*md5$d9eb8$01495b32852bffb27cf5d4394fe7a54cri   	md5$aa$bbc                   &   a  ] tR t^t o R tRtV tR# )(django_salted_md5_test.FuzzHashGeneratorc                    V P                   pVP                  pVP                  ^ 8X  g   Q h^pVP                  ;'       g
    V^,          pV P	                  W4W"R,          4      # )    g      ?)r#   default_salt_sizemin_salt_sizemax_salt_sizerandintgauss)r%   r#   defaultloweruppers   &    r   random_salt_size9django_salted_md5_test.FuzzHashGenerator.random_salt_size   s_    
 llG//G((A---E))66WQYE$$U7BJGGr   rR   N)rS   rT   rU   rV   r   r[   r\   r]   s   @r   rH   rw      s     
	H 
	Hr   rH   rR   Nrj   )rb   z.md5$123abcdef$c8272612932975ee80e8a35995708e80)testz1md5$3OpqnFAHW5CT$54b29300675271049a1ebae07b395e20)rS   rT   rU   rV   rW   r   django_salted_md5r#   r"   r
   r   r<   rq   rr   r   rH   r[   rR   r   r   rt   rt      sr     $$G 	J 	F 
DE	DE
 	! 	
HK99 H Hr   rt   c                   p    ] tR t^tRt]P                  tRtR	R
]	R3]
R3R.tR.tR.t]P                  tRtR# )django_salted_sha1_testztest django_salted_sha1z3sha1$c2e86$0f75c5d7fbd100d587c127ef0b693cde611b4adaz3sha1$6d853$ef13a4d8fb57aed0cb573fe9c82e28dc7fd372d4ru   zsha1$c2e86$0f75rR   Nrj   )rb   z7sha1$123abcdef$e4a1877b0e35c47329e7ed7e58014276168a37ba)r   z:sha1$bcwHF9Hy8lxS$6b4cfa0651b43161c6f1471ce9523acf1f751ba3)
MyPasswordz3sha1$54123$893cf12e134c3c215f3a76bd50d13f92404a54d3)rS   rT   rU   rV   rW   r   django_salted_sha1r#   r"   r
   r   r<   rq   rr   rt   rH   r[   rR   r   r   r   r      sl    !%%G 	O 	O 
MN	MN 	O  	! 	 /@@r   r   c                   >    ] tR t^tRt]P                  tR]R3.t	Rt
R# )django_pbkdf2_sha256_testztest django_pbkdf2_sha256zMpbkdf2_sha256$10000$bEwAfNrH1TlQ$OgYUblFNUX1B8GfMqaCYUK/iHyO0pa7STTDdaEJBuY0=rR   N)not a passwordzMpbkdf2_sha256$10000$kjVJaVz6qsnJ$5yPHw3rwJGECpUf70daLGhOrQ5+AMxIJdz1c3bqK1Rs=)rS   rT   rU   rV   rW   r   django_pbkdf2_sha256r#   r   r<   r[   rR   r   r   r   r      s*    #''G	Z		X	Zr   r   c                   >    ] tR tRtRt]P                  tR]R3.t	Rt
R# )django_pbkdf2_sha1_testi  ztest django_pbkdf2_sha1z;pbkdf2_sha1$10000$KZKWwvqb8BfL$rw5pWsxJEU4JrZAQhHTCO+u0f5Y=rR   N)r   z;pbkdf2_sha1$10000$wz5B6WkasRoF$atJmJ1o+XfJxKq1+Nu1f1i57Z5I=)rS   rT   rU   rV   rW   r   django_pbkdf2_sha1r#   r   r<   r[   rR   r   r   r   r     s*    !%%G	H		F	Hr   r   zno bcrypt backends availablec                      a a ] tR tRt oRt]P                  tR	tRt	R
R]
R3.tV 3R lt ! R R]P                  4      tRtVtV ;t# )django_bcrypt_testi  test django_bcryptTzCbcrypt$$2a$05$Z17AXnnlpzddNUvnC6cZNOSwMA/8oNiKnHTHTwLlBijfucQQlHjaGc                R   < VP                  R ^4       \        \        V `  V4       R# roundsN)
setdefaultsuperr   populate_settingsr%   kwds	__class__s   &&r   r   $django_bcrypt_test.populate_settings*  s!    !$ $9$?r   c                   ,   a  ] tR tRt o R tR tRtV tR# )$django_bcrypt_test.FuzzHashGeneratori/  c                *    V P                  ^^^^4      #    r}   r%   s   &r   random_rounds2django_bcrypt_test.FuzzHashGenerator.random_rounds1      $$Q1a00r   c                    R # r   rR   r   s   &r   random_ident1django_bcrypt_test.FuzzHashGenerator.random_ident5       r   rR   NrS   rT   rU   rV   r   r   r[   r\   r]   s   @r   rH   r   /       	1	 	r   rH   rR   )   ry   )rc   zCbcrypt$$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.)abcdefghijklmnopqrstuvwxyzzCbcrypt$$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq)rS   rT   rU   rV   rW   r   r-   r#   r"   fuzz_salts_need_bcrypt_repairr   r<   r   r   rH   r[   r\   __classcell__r   r^   s   @@r   r   r     s\       G$(! 	T	T	U	W
@
	K99 	 	r   r   c            	          a a ] tR tRt oRt]P                  tRtRt	R]
R3]R3]! R^H4      R3]! R^H4      R	,           R
3]! R^H4      R,           R3.tR.tV 3R lt ! R R]P"                  4      tRtVtV ;t# )django_bcrypt_sha256_testi:  ztest django_bcrypt_sha256NTzJbcrypt_sha256$$2a$08$NDjSAIcas.EcoxCRiArvT.MkNiPYVhrsrnJsRkLueZOoV1bsQqlmCzJbcrypt_sha256$$2a$06$kCXUnRFQptGg491siDKNTu8RxjBGSjALHRuvhPYNFsa4Ea5d9M48uabc123zJbcrypt_sha256$$2a$06$Tg/oYyZTyAf.Nb3qSgN61OySmyXA8FoY4PjGizjE1QSDfuL5MXNniqwrzJbcrypt_sha256$$2a$06$Tg/oYyZTyAf.Nb3qSgN61Ocy0BEz1RK6xslSNi8PlaLX2pe7x/KQGxyzzJbcrypt_sha256$$2a$06$Tg/oYyZTyAf.Nb3qSgN61OvY2zoRVUa2Pugv2ExVOUT2YmhvxUFUazMbcrypt_sha256$xyz$2a$06$/3OeRpbOf8/l6nPPRdZPp.nRiyYqPobEZGdNRBWihQhiFDh1ws1tuc                R   < VP                  R ^4       \        \        V `  V4       R# r   )r   r   r   r   r   s   &&r   r   +django_bcrypt_sha256_test.populate_settings\  s!    !$'@Fr   c                   ,   a  ] tR tRt o R tR tRtV tR# )+django_bcrypt_sha256_test.FuzzHashGeneratoria  c                *    V P                  ^^^^4      # r   r   r   s   &r   r   9django_bcrypt_sha256_test.FuzzHashGenerator.random_roundsc  r   r   c                    R # r   rR   r   s   &r   r   8django_bcrypt_sha256_test.FuzzHashGenerator.random_identg  r   r   rR   Nr   r]   s   @r   rH   r   a  r   r   rH   rR   )rc   zJbcrypt_sha256$$2a$06$/3OeRpbOf8/l6nPPRdZPp.nRiyYqPobEZGdNRBWihQhiFDh1ws1tu)rS   rT   rU   rV   rW   r   django_bcrypt_sha256r#   forbidden_charactersr   UPASS_LETMEINr   r   r<   known_malformed_hashersr   r   rH   r[   r\   r   r   s   @@r   r   r   :  s     #''G$(!	Z	X	Z	X	Z 
x	#X	Z	x	#E	)X	Z	x	#E	)X	Z!, 	XG
	K99 	 	r   r   )_base_argon2_testzno argon2 backends availablec                      a a ] tR tRt oRt]P                  tR
R]R3.t	V 3R lt
RR ltR t ! R R]P                  4      tR	tVtV ;t# )django_argon2_testin  r   zIargon2$argon2i$v=19$m=512,t=2,p=2$V25jN1l4UUJZWkR1$MxpA1BD2Gh7+D79gaAw6sQc                Z   < \         \        V `  4        \        P                  ! R R4       R# )ignorez.*Using argon2pure backend.*N)r   r   setUpWarningswarningsfilterwarnings)r%   r   s   &r   r    django_argon2_test.setUpWarnings  s"     $57*HIr   c                    T;'       g    V P                   P                  ! R/ VB pVP                  R R7      p V P                  V n        V P                  '       g   Q hVP                  V P                  4       4      # )T)use_defaultsrR   )r#   usingwrapped_stub_checksumchecksum
_wrap_hash	to_string)r%   r#   settingss   &&,r   do_stub_encrypt"django_argon2_test.do_stub_encrypt  sf     **dll11=H=D1++}}}}!!$.."233r   c                $    V P                  R 4      h)z!legacy 1.6 workflow not supported)r!   r   s   &r   test_03_legacy_hash_workflow/django_argon2_test.test_03_legacy_hash_workflow  s    mm?@@r   c                   ,   a  ] tR tRt o R tR tRtV tR# )$django_argon2_test.FuzzHashGeneratori  c                    R # )IrR   r   s   &r   random_type0django_argon2_test.FuzzHashGenerator.random_type  s    r   c                *    V P                  ^^^^4      # )rk   r   r   s   &r   r   2django_argon2_test.FuzzHashGenerator.random_rounds  r   r   rR   N)rS   rT   rU   rV   r   r   r[   r\   r]   s   @r   rH   r     s     		1 	1r   rH   )r   )rb   zDargon2$argon2i$v=19$m=256,t=1,p=1$c29tZXNhbHQ$AJFIsNZTMKTAewB4+ETN1A)rb   zDargon2$argon2i$v=19$m=380,t=2,p=2$c29tZXNhbHQ$SrssP8n7m/12VWPM8dvNrwr   )rS   rT   rU   rV   rW   r   django_argon2r#   r   r<   r   r   r   r   rH   r[   r\   r   r   s   @@r   r   r   n  s[       G 	] 	] 
cd	J4A1-?? 1 1r   r   ),rW   
__future__r   logging	getLoggerrS   logrer   passlibr   rF   r   passlib.utils.compatr   passlib.tests.utilsr   r   r   r	   passlib.tests.test_handlersr
   r   passlib.tests.test_ext_djangor   r   r   r   r   r   r`   rh   rt   r   r   r   bcrypthas_backendr   r   "passlib.tests.test_handlers_argon2r   argon2r   rR   r   r   <module>r      sZ   L & g''1 	   ' " K K >$ $ ,-U:H U:n; "'K 'R&H[- &HPAk= A@] k=  DKK##%'EF#m # G#J DKK##%'EF/] / G/b ADKK##%'EF*1m *1 G*1r   