V;Xc@`s,dZddlmZmZmZddlZejeZddl Z ddl m Z m Z mZddlmZmZmZddlmZddlmZmZmZddlmZmZmZdd lmZdd lm Z m!Z!m"Z"dd l#m$Z$m%Z%d d dgZ&eekZ'e'rddl(m)Z)m*Z*e+e)e* rhe,de)fne)j- re)j.nddl/m Z e j0ddgne1Z2dZ3e'rddl4m5Z5de5fdYZ6ndZ7eddfkre j8j9Z:dZ;n?eddfkrCe jj9Z:dZ;ne jj9Z:dZ;e:j<dd d!e;d"e;dd#l=m>Z>e?d$d%e>j@d&e:jAd"jBd%fZCde1fd'YZDd(e eDfd)YZEd eEfd*YZFd eFfd+YZGd,eEfd-YZHdS(.stest passlib.ext.djangoi(tabsolute_importtdivisiontprint_functionN(tappstexctregistry(tdjango10_contexttdjango14_contexttdjango16_context(t CryptContext(tDJANGO_VERSIONtMIN_DJANGO_VERSIONtDjangoTranslator(t iteritemstget_method_functiontu(tmemoized_property(tTestCaset TEST_MODEthandler_derived_from(tget_handler_casetconditionally_available_hashestDjangoBehaviorTesttExtensionBehaviorTestt_ExtensionSupport(tsettingst LazySettingss4expected django.conf.settings to be LazySettings: %r(Rsdjango.contrib.contenttypessdjango.contrib.authcK`s_xXt|D]J\}}|tkrGtt|rWtt|qWq tt||q WdS(s*helper to update django settings from kwdsN(R tUNSETthasattrRtdelattrtsetattr(tkwdstktv((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytupdate_settingsEs  (tUsertFakeUsercB`sEeZdZdddYZedZdZddZRS(s#mock user object for use in testingtMetacB`seZeZRS((t__name__t __module__t app_label(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyR%VscC`sgS(N((tself((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytsaved_passwordsYscC`sz |jSWd|j2XdS(N(R*(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytpop_saved_passwords]s cC`s|jj|jdS(N(R*tappendtpassword(R)t update_fields((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytsavecs(N( R&R't__doc__R%RR*R+tNoneR/(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyR$Qs  c`s1gfd}fd}||_|S(Nc`sj|dS(N(R,(R-(tstate(sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytsetterisc`sz SWd2XdS(N(((R2(sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytpopstateks (R4(R3R4((R2sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytcreate_mock_settergs  ii i0ui i]i Nt deprecatedtautot"django_pbkdf2_sha1__default_roundst$django_pbkdf2_sha256__default_rounds(tdjango_pbkdf2_sha256R:snot a passwordtroundscB`sVeZdZedZdZd dZdddgZe dZ dZ RS( s-support funcs for loading/unloading extensionc c`sddlm}m}ddg}ddg}dddddg}||f|j|f||fg}x|D]\}}xt|D]} | jd rqn|jj| t} | tkr| |krqnt | } t | d d } | r|| | | |kfVqqWqnWd S( shelper 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 i(tmodelsthasherstcheck_passwordt set_passwordt make_passwordt get_hashertidentify_hashert get_hasherst_R'N( tdjango.contrib.authR<R=R#tdirt startswitht__dict__tgetRRtgetattrR1( tclsR<R=t user_attrst model_attrst hasher_attrstobjstobjtpatchedtattrtvaluetsource((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyt_iter_patch_candidatess&        cC`stjjd}|j|o'|jjdxu|jD]g\}}}}|r||j|jdd|||fq;|j|jdd|||fq;WdS(s&test that django is in unpatched statespasslib.ext.django.modelsspatch should not be enabledsdjango.contrib.auth.s#obj=%r attr=%r was not reverted: %rspasslib.s/obj=%r attr=%r should not have been patched: %rN( tsystmodulesRIt assertFalsetadapterRQRUt assertTrueRG(R)tmodRPRRRTRQ((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytassert_unpatchedscC`stjjd}|j|o'|jjdxr|jD]d\}}}}|ry|j|dkd|||fq;|j|jdd|||fq;W|dk rt j |}|j |j jdt|jdtndS( sGhelper to ensure django HAS been patched, and is using specified configspasslib.ext.django.modelsspatch should have been enabledspasslib.ext.django.utilss+obj=%r attr=%r should have been patched: %rspasslib.s/obj=%r attr=%r should not have been patched: %rtresolveN(RVRWRIRZRYRQRURXRGR1R t _norm_sourcet assertEqualtpassword_contexttto_dicttTrue(R)tcontextR[RPRRRTRQ((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytassert_patcheds tPASSLIB_CONFIGtPASSLIB_CONTEXTtPASSLIB_GET_CATEGORYcK`s|j|r1|jdp+|jd}nx!|jD]}|j|tq;Wt|ddl}|r|jd|ndS(s=helper to load extension with specified config & patch djangoReRfiNRc(tunload_extensionRIt _config_keyst setdefaultRR"tpasslib.ext.django.modelsRd(R)tcheckRtconfigtkeytpasslib((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytload_extensions !  cC`s]tjjd}|r2|jjtjd=nttd|jD|jdS(s-helper to remove patches and unload extensionspasslib.ext.django.modelscs`s|]}|tfVqdS(N(R(t.0Rn((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pys sN( RVRWRIRYt remove_patchR"tdictRiR\(R)R[((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRhs   N( R&R'R0t classmethodRUR\R1RdRiRbRpRh(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRs$   t_ExtensionTestcB`seZdZRS(cC`sntt|j|jdts8|jdntsP|jdn|j|j|jdS(NtdefaultsDjango not installedsDjango version too old( tsuperRutsetUptrequire_TEST_MODER tskipTestthas_min_djangoRht addCleanup(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRxs  (R&R'Rx(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRuscB`sPeZdZdZeZeZedZ dZ e ddZ dZRS(s2tests model to verify it matches django's behaviorsverify django behaviorcC`stj|jS(N(R R^Rm(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRc&scC`sF|j|jjd|j|j|j|jgdS(s=check that user object is set to 'unusable password' constantt!N(RZR-RGRXthas_usable_passwordR_R+(R)tuser((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytassert_unusable_password*scC`s|tkr5|j|jd|j|jdn|j|j||j|jd|jf|j|j|dkrgn|gdS(scheck that user object has a usuable 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}shash should be usable: %rN(RtassertNotEqualR-R1R_RZR~R+(R)Rthashtsaved((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytassert_valid_password0s cC`s|j|j}}|j}t}d}d}ddlm}m}m} m} |rddl m } |j | j dt |j dt ddlm} |j | |nt} | j||j|jj|| j|j| ||}|j|jj||t} | jd| j}|j|jjd||j| ||j| jd|j| ||j|d|t} | j|j| t} | jd|j| |j| jd|j| jd |j| jd|j| j||j| j||j| |j|djd |j||d |j| | j|jt| | jt} d| _|j| j||j| j|j||d|jt| dxdD]}t} || _|j| j||j | j||j | jg|j| j|j||||jt| |q5Wx5|j D]'}|j|}|j|j!}| s||j"kst#yt$|}Wn)t%j&k rZ|t'kst#qnXt(||jsst#|j)rqnt*j+|s|dkst#d|qnyt,|\}}WnFt-k r|dj.}x't r |\}}|rPqqWnXd}t} || _|j| jd|j| j||j| ||j| j||}|r|j/| j||j|j0| j|j|jj|| j|j| d| jn|j| |t1ddrqnt2j3|}||d|}|j|j|||j|||d||j |j4|r|gng|j|||d||j |j4g|j| |t2j5| |j6}|j ||qWdS(stest hashing interface this function is run against both the actual django code, to verify the assumptions of the unittests are correct; and run against the passlib extension, to verify it matches those assumptions. ttoomanysecretstletmeini(R>R@tis_password_usableRB(R`R](R>tR1R}s$789$foot django_bcrypttdjango_bcrypt_sha256t django_argon2s+%r scheme should always have active backendRxt dontletmeinRtmaxRvthasherR3N(Rs$789$foo(RRR(7RQRmRcR5tdjango.contrib.auth.hashersR>R@RRBRkR`R_RaRbtdjango.contrib.auth.modelsR$R?RZthandlertverifyR-Rtset_unusable_passwordRR1RXRGt assertRaisest ValueErrorR~t TypeErrorR+tschemesR6tdefault_schemetAssertionErrorRRtMissingBackendErrorRRt is_disabledRt has_backendt sample_hashestKeyErrortget_sample_hashRtidentifyRR tpasslib_to_django_nameR4tdjango_to_passlib_namet algorithm(R)RQRmtctxR3tPASS1tWRONG1R>R@RRBR`tcheck_password2RRtschemeRR6ttestcasetsecretRtothert needs_updatetalgthash2tname((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyt test_configAs  "  "                        "% N(R&R'R0tdescriptionPrefixtFalseRQt stock_configRmtpropertyRcRRR1RR(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRs cB`s8eZdZdZeZeddddZdZRS(s6test model to verify passlib.ext.django conforms to itsverify extension behaviorRs sha256_crypt,md5_crypt,des_cryptR6t des_cryptcC`s*tt|j|jd|jdS(NRe(RwRRxRpRm(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRxPs( R&R'R0RRbRQRsRmRx(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRGs tDjangoExtensionTestcB`s\eZdZdZdZdZdZdZdZdZ dZ d Z RS( s&test the ``passlib.ext.django`` pluginspasslib.ext.django pluginc C`s|jdddt|j|jd|jdddtWdQX|j|jdddt|jdt|j|jdddt|jdt|jdS( s.test set_django_password_context patch/unpatchRetdisabledRls!PASSLIB_CONFIG=None is deprecatedNs django-1.0Rcs django-1.4( RpRR\tassertWarningListR1RdRRhR(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_00_patch_control[s   cC`sd}|jd|ddljjj}ddlm}d}|jj}||j_|j d|j j WdQX||j_|j }||_ |j d|j j WdQX||_ dS( s(test detection of foreign monkeypatchings[passlib] schemes=des_crypt ReiN(RYcS`sdS(N((((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytdummyss/another library has patched.*User\.set_passwords2another library has patched.*models:check_password( RpRtcontribtauthR<RkRYR#R?Rt_managert check_allR>(R)RmR<RYRtorig((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_01_overwrite_detectionus      cC`srddlm}tj}tdkr>|jt|dn|d}|j||j|d}|j||j ddl m }|d}|j |j d |jd }|j|jd ||j|jd ||j|jd ||jd ddd}|j |d|j |j|idd6tdd6dd6tdd6dS(s'test Hasher-compatible handler wrappersi(R=ii thex_md5R(t sha256_cryptRtpasslib_sha256_crypttstubtxxxxtabcdiR;isK$5$rounds=1234$abcdabcdabcdabcd$v2RWkZQzctPdejyRqmmTDQpZN6wTh7.RUy9zF2LftT6Rsabcdab**********tsalts+v2RWkZ*************************************RN(ii tabcdabcdabcdabcd(RER=R tpasslib_to_djangoR RRtassertIsInstancetUnsaltedMD5PasswordHashertBCryptPasswordHashert passlib.hashRR_RtencodeRZRRXt safe_summaryR(R)R=RRRtencoded((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_02_handler_wrappers,       c C`sZ|jd|jdddtWdQX|j|jdddt|jdS(stest PASSLIB_CONFIG='disabled's!PASSLIB_CONFIG=None is deprecatedReRlNR(RRpR1RR\(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_11_config_disableds  cC`ss|jdddtt}|j||jdddt|jt|jdddt|jtdS(stest PASSLIB_CONFIG=''Rfsdjango-defaultRlRes django-1.0s django-1.4N(RpRRRdRR(R)R((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_12_config_presetss  cC`sddlm}tj|}|j|j||jdddt|j||jd|dt|j|dS(s$test PASSLIB_CONFIG default behaviori(tPASSLIB_DEFAULTRfspasslib-defaultRlN(tpasslib.ext.django.utilsRR t from_stringRpRdR(R)RRv((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_13_config_defaultss   cC`sZtdddt|jttd|jtdddt|jttddS(stest PASSLIB_CONFIG type checksRfi{Respasslib.ext.django.modelssmissing-presetN(R"RRRt __import__RhR(R)((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_14_config_invalids  c `stddgdddddd}d d lmfd }|jd ||j|d|j|d td|j|dtdd}|jd|d||j|d|j|ddd|j|ddd|j|dddd}|jd|d||j|d|j|ddd|j|ddd td|j|dddtd|jt|jd|dddS(s#test PASSLIB_GET_CATEGORY parameterRRtsha256_crypt__default_roundsit#staff__sha256_crypt__default_roundsit'superuser__sha256_crypt__default_roundsi i(Rc`s,t|}|jdj|jjS(s;helper to take in user opts, return rounds used in passwordR(R$R?RR-R;(RR(R(sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytruns  Retis_stafft is_superusercS`s |jp dS(N(t first_nameR1(R((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyt get_categorysRfRgRRtstafft superusercS`sdS(N(R1(R((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRstxN(RsRRRpR_RbRR(R)RmRR((RsA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyttest_21_category_settings6    ( R&R'R0RRRRRRRRR(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pyRTs   )  (IR0t __future__RRRtloggingt getLoggerR&tlogRVRoRt_appsRRt passlib.appsRRRtpasslib.contextR RR R R tpasslib.utils.compatR RRtpasslib.utils.decorRtpasslib.tests.utilsRRRtpasslib.tests.test_handlersRRt__all__R{t django.confRRt isinstancet RuntimeErrort configuredt configuret django.appstpopulatetobjectRR"RR#R$R5tdjango110_contextRaRt stock_roundstupdateRR:RstusingRIRRRRuRRR(((sA/usr/lib/python2.7/site-packages/passlib/tests/test_ext_django.pytsj             r-