5Xc@sdZddlmZmZddlZejeZddlZddl Z ddl m Z y$ddl m ZejdeWn$ek rejdfZnXddlmZmZdd lmZdd lmZdd lmZmZmZmZdd lmZd dddgZddfZ idd6dd6dd6dd6Z!dZ"dZ#dZ$dZ%e&dgZ'd Z(d!e)fd"YZ*d#e*fd$YZ+d%Z,d&e)fd'YZ-d(e)fd)YZ.e)Z/d*e)fd+YZ0dS(,s?passlib.ext.django.utils - helper functions used by this plugini(tupdate_wrappertwrapsN(twarn(tVERSIONsfound django %r installationsdjango installation not found(texctregistry(t CryptContext(tPasslibRuntimeWarning(tget_method_functiont iteritemst OrderedDicttunicode(tmemoized_propertytDJANGO_VERSIONtMIN_DJANGO_VERSIONtget_preset_configtget_django_hasheriitdjango10_contexts django-1.0tdjango14_contexts django-1.4tdjango16_contexts django-1.6tdjango_contexts django-latestcCs|dkr*ts!tdnd}n|dkr:tSyt|}Wn!tk rktd|nXddl}t|j|jS(seReturns configuration string for one of the preset strings supported by the ``PASSLIB_CONFIG`` setting. Currently supported presets: * ``"passlib-default"`` - default config used by this release of passlib. * ``"django-default"`` - config matching currently installed django version. * ``"django-latest"`` - config matching newest django version (currently same as ``"django-1.6"``). * ``"django-1.0"`` - config used by stock Django 1.0 - 1.3 installs * ``"django-1.4"`` - config used by stock Django 1.4 installs * ``"django-1.6"`` - config used by stock Django 1.6 installs sdjango-defaults9can't resolve django-default preset, django not installeds django-1.6spasslib-defaultsunknown preset config name: %riN( R t ValueErrortPASSLIB_DEFAULTt _preset_maptKeyErrort passlib.appstgetattrtappst to_string(tnametattrtpasslib((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR/s     s [passlib] ; list of schemes supported by configuration ; currently all django 1.6, 1.4, and 1.0 hashes, ; and three common modular crypt format hashes. schemes = django_pbkdf2_sha256, django_pbkdf2_sha1, django_bcrypt, django_bcrypt_sha256, django_salted_sha1, django_salted_md5, django_des_crypt, hex_md5, sha512_crypt, bcrypt, phpass ; default scheme to use for new hashes default = django_pbkdf2_sha256 ; hashes using these schemes will automatically be re-hashed ; when the user logs in (currently all django 1.0 hashes) deprecated = django_pbkdf2_sha1, django_salted_sha1, django_salted_md5, django_des_crypt, hex_md5 ; sets some common options, including minimum rounds for two primary hashes. ; if a hash has less than this number of rounds, it will be re-hashed. sha512_crypt__min_rounds = 80000 django_pbkdf2_sha256__min_rounds = 10000 ; set somewhat stronger iteration counts for ``User.is_staff`` staff__sha512_crypt__default_rounds = 100000 staff__django_pbkdf2_sha256__default_rounds = 12500 ; and even stronger ones for ``User.is_superuser`` superuser__sha512_crypt__default_rounds = 120000 superuser__django_pbkdf2_sha256__default_rounds = 15000 tpasslib_tdjango_thex_md5cstfd}|S(s#wrap method object in bare functioncs ||S(N((targstkwds(tmethod(s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytwrapper~s(R(R%R&((R%s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt _wrap_method|stDjangoTranslatorcBseZdZd Zd Zd Zd Zd dZdZ dZ dZ e dZ eddZdZd Ze d Ze d ZRS( sO Object which helps translate passlib hasher objects / names to and from django hasher objects / names. These methods are wrapped in a class so that results can be cached, but with the ability to have independant caches, since django hasher names may / may not correspond to the same instance (or even class). cKsPtt|j||dk r.||_ntj|_tj|_ dS(N( tsuperR(t__init__tNonetcontexttweakreftWeakKeyDictionaryt_django_hasher_cachetWeakValueDictionaryt_passlib_hasher_cache(tselfR,R$((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR*s   cCs'|jj|jjd|_dS(N(R/tclearR1R+t_django_unsalted_sha1(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt reset_hasherss  cCs3|j}|dkr"tj|S|j|SdS(sM resolve passlib hasher by name, using context if available. N(R,R+Rtget_crypt_handlerthandler(R2t passlib_nameR,((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt_get_passlib_hashers   cCs|j|jS(sF Convert passlib hasher / name to Django hasher name. (tpasslib_to_djangot algorithm(R2R8((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytpasslib_to_django_namescCst|ds!|j|}n|rq|j}y ||SWntk rOnX|j|dt}||<|St|dd}|r|j|St |SdS(s Convert passlib hasher / name to Django hasher. :param passlib_hasher: passlib hasher / name :returns: django hasher instance Rtcachedt django_nameN( thasattrR9R/RR:tFalseRR+t_create_django_hashert_PasslibHasherWrapper(R2tpasslib_hasherR=tcachetresultR>((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR:s     tmd5tMD5PasswordHashercCstjjd}|d ks+|jj rEddlm}||S|jjj dj }x$|D]}|j |krg|SqgW|j j|}|rd|krd|}nddl m}||Std|d S( sf helper to create new django hasher by name. wraps underlying django methods. spasslib.ext.django.modelsi(t get_hashers'django.contrib.auth.hashers:get_hasherst.sdjango.contrib.auth.hashers.(t import_stringsunknown hasher: %rN(tsystmodulestgetR+tadaptertpatchedtdjango.contrib.auth.hashersRHt_managertgetorigt __wrapped__R;t_builtin_django_hasherstdjango.utils.module_loadingRJR(R2R>tmoduleRHt get_hashersthashertpathRJ((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRAs    cCs|j|jS(sF Convert Django hasher / name to Passlib hasher name. (tdjango_to_passlibR(R2R>((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytdjango_to_passlib_namesc Cst|dr1t|tr%|jS|j}n|r|j}y ||SWntk r_nX|j|dt}||<|S|j t r|t t }|j |S|dkr|j }|d krtdn|jS|dkrd}n|j }|d kr*dtjD}n|jdt}x*|D]"}t|d d |krC|SqCWtd |fd S( s Convert Django hasher / name to Passlib hasher / name. If present, CryptContext will be checked instead of main registry. :param django_name: Django hasher class or algorithm name. "default" allowed if context provided. :raises ValueError: if can't resolve hasher. :returns: passlib hasher or name R;R=tdefaults)can't determine default scheme w/ contextt unsalted_sha1tsha1css9|]/}|jts$|tkrtj|VqdS(N(t startswithtDJANGO_COMPAT_PREFIXt_other_django_hashesRR6(t.0R8((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pys SstresolveR>s/can't translate django name to passlib name: %rN(R?t isinstanceRBtpasslib_handlerR;R1RRZR@R_tPASSLIB_WRAPPER_PREFIXtlenR9R,R+t TypeErrorR7Rtlist_crypt_handlerstschemestTrueRR( R2R>R=RDRER8R,t candidatesR7((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRZs@              cCst|dr|S|j|d|}|dkr|jdkr|sV|j|S|j}|dkr|j|}|_n|S|j|d|S(sH Take in a django algorithm name, return django hasher. R;R=R]tdjango_salted_sha1N(R?RZRRAR4R+R:(R2R>R=RCRE((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytresolve_django_hasherjs    N(t__name__t __module__t__doc__R+R,R/R4R1R*R5R9R<RkR:tdictRTRAR[RZRn(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR(s       !  UtDjangoContextAdapterc BseZdZdZdZdZdZeZ e Z dddZ dZ dZddZdZdddZdddZd Zd Zd Zd Zd ZedZdZeddedefeddedefeddfeddfeddfeddfeddfeddfeddfeddfeddfg ZdZdZdZdZRS( sC Object which tries to adapt a Passlib CryptContext object, using a Django-hasher compatible API. When installed in django, :mod:`!passlib.ext.django` will create an instance of this class, and then monkeypatch the appropriate methods into :mod:`!django.contrib.auth` and other appropriate places. cKstjtd|_|dkr.t}ntt|jd|||rnt |sbt ||_ nddl m }||j|_ddlm}|jjdrtj|}n||_ddlm}||_tjtd}td ||_dS( Ns.DjangoContextAdapterR,i(t lru_cache(t make_passwordspasslib.(tis_password_usables.DjangoContextAdapter._managertlog(tloggingt getLoggerRoRwR+RR)RsR*tcallabletAssertionErrortget_user_categorytdjango.utils.lru_cacheRtRWRPRuRpR_t _PatchManagertpeek_unpatched_funct_orig_make_passwordRvRQ(R2R,R|R$RtRuRvtmlog((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR*s"     cCs4ddlm}|ddtt|jdS(sH Wrapper to manually reset django's hasher lookup cache i(R5tsettingtPASSWORD_HASHERSN(RPR5R)Rs(R2R5((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR5s cCs5|j}g|jjdtD]}||^qS(sq Passlib replacement for get_hashers() -- Return list of available django hasher classes Rc(R:R,RjRk(R2R:RX((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRWs R\cCs |j|S(s^ Passlib replacement for get_hasher() -- Return django hasher by name (Rn(R2R;((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRHscCsV|jj|dtdt}|jdkrI|jdrI|jdS|j|S(sl Passlib replacement for identify_hasher() -- Identify django hasher based on hash. RctrequiredRmssha1$$R](R,tidentifyRkRR_RHR:(R2tencodedR7((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytidentify_hashers cCs|dkr|jdS|j|}d|jkr:n?|jdr^|jdd}n|ry|jd|}n|j|S(s9 Passlib replacement for make_password() tsaltt unsalted_tN(R+RRZt setting_kwdsR_tusingthash(R2tpasswordRRXRC((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRus  cCs|dks|j| r tS|j}|j||}|oD|sK|S|dkrs|j|d|s|Sn8|j|}|j|r|j|d| r|S|||S(s: Passlib replacement for check_password() R\tsecretN(R+RvR@R,tverifyt needs_updateRZR(R2RRtsettert preferredR,tcorrectRX((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytcheck_passwords    cCs|dkrtS|j}|j|s,tS|j|}|jj||d|\}}|r|dk r||_|jn|S(s? Passlib replacement for User.check_password() tcategoryN(R+R@RRvR|R,tverify_and_updatetsave(R2tuserRRtcattoktnew_hash((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytuser_check_passwordEs    cCsG|dkr|jn*|j|}|jj|d||_dS(s= Passlib replacement for User.set_password() RN(R+tset_unusable_passwordR|R,RR(R2RRR((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytuser_set_passwordWs  cCs"|jr dS|jrdSdSdS(s Helper for hashing passwords per-user -- figure out the CryptContext category for specified Django user object. .. note:: This may be overridden via PASSLIB_GET_CATEGORY django setting t superusertstaffN(t is_superusertis_staffR+(R2R((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR|as   sdjango.contrib.auth.hasherssdjango.contrib.auth.modelss:Usersdjango.contrib.auth.formss.check_passwordRR%s .set_passwordRt:RRuRWRHRcCs|j}|jr#|jdtSttkrEtdtfn|jd|j}x|j D]}t |dkr|if7}n|\}}}|j d r||7}nt ||}|j drt|}n|j||qeW|jt|_|jdtS( sI Install monkeypatch to replace django hasher framework. s3monkeypatching already applied, refusing to reapplys(passlib.ext.django requires django >= %ss#preparing to monkeypatch django ...iRt,R%s"... finished monkeypatching django(RR(RwROtwarningR@R Rt RuntimeErrortdebugRQtpatch_locationsRgtendswithRRMR'tpatchR5Rk(R2Rwtmanagertrecordttargettsourcetoptstvalue((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt install_patchs.          cCs|j}|j}|jrl|jd|jdt|jjit|_|j |jdtS|j r|j d|j|jji|j |jdtS|jdtS(s Remove monkeypatch from django hasher framework. As precaution in case there are lingering refs to context, context object will be wiped. .. warning:: This may cause problems if any other Django modules have imported their own copies of the patched functions, though the patched code has been designed to throw an error as soon as possible in this case. s!removing django monkeypatching...tunpatch_conflictss*...finished removing django monkeypatchings-reverting partial monkeypatching of django...sdjango not monkeypatched( RwRQRORt unpatch_allRkR,tloadR@R5tisactiveR(R2RwR((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt remove_patchs&             cCso|j|jr;y|jWq^|jq^Xn#|jrTtjdn|jtjddS(sD Load configuration from django, and install patch. s.didn't expect monkeypatching would be applied!spasslib.ext.django loadedN(t_load_settingstenabledRRRORwterrorR(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt load_models      cCsddlm}t}t|d|}||krLt|d|}n||krad}n|d krtdtd}n0t|tt t fst j |ddnt|d d }|rt | rt j |d d n|dkr t|_d S|jjd d t|trFd |krFt|}n|rX||_n|jjdd |jj||jd S(s- Update settings from django i(tsettingstPASSLIB_CONFIGtPASSLIB_CONTEXTspasslib-defaults}setting PASSLIB_CONFIG=None is deprecated, and support will be removed in Passlib 1.8, use PASSLIB_CONFIG='disabled' instead.tdisableds str or dicttPASSLIB_GET_CATEGORYRzNRs t get_category(t django.confRtobjectRR+RtDeprecationWarningRdR tbytesRrRtExpectedTypeErrorRzR@Rt__dict__tpoptstrRR|R,RR5(R2Rt_UNSETtconfigR((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRs6         N( RoRpRqR+R,RRvRQRkRR@ROR*R5RWRHRRuRRRR|t HASHERS_PATHt MODELS_PATHtUSER_CLASS_PATHt FORMS_PATHRrRRRRR(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRssH!   *             * ' s--!!!generate-new-salt!!!--t ProxyPropertycBs2eZdZdZdZdZdZRS(s%helper that proxies another attributecCs ||_dS(N(R(R2R((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR*<scCs%|dkr|}nt||jS(N(R+RR(R2tobjtcls((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt__get__?s  cCst||j|dS(N(tsetattrR(R2RR((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt__set__DscCst||jdS(N(tdelattrR(R2R((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt __delete__Gs(RoRpRqR*RRR(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR9s    RBcBseZdZd ZdZdZedZedZedZ edZ dZ dZ d d d d Z d Zd ZRS( s adapter which which wraps a :cls:`passlib.ifc.PasswordHash` class, and provides an interface compatible with the Django hasher API. :param passlib_handler: passlib hash handler (e.g. :cls:`passlib.hash.sha256_crypt`. cCs~t|ddr+td|jfn|jrJtd|jn||_|jrz|j|_t d|_ ndS(NR>sHhandlers that reflect an official django hasher shouldn't be wrapped: %rs%can't wrap disabled-hash handlers: %rtrounds( RR+RRt is_disabledRet _has_roundstdefault_roundsRRt iterations(R2Re((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR*bs    cCs d|jS(Ns!(Re(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt__repr__vscCsd|jjjS(NsPasslib_%s_PasswordHasher(ReRttitle(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRo}scCsd|jjkS(NR(ReR(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRscCs;tdd}|jr7d|jjkr7d|d django keywords tchecksumRtpbkdf2RR(RrRReR(R2tout((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt_translate_kwdss cCst|jjS(N(RfReR(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR;scCstS(N(t_GEN_SALT_SIGNAL(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRscCs|jj||S(N(ReR(R2RR((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRscCsi}|dk r+|tkr+||d to have , stores originalspatching resource: %rsmodifying resource: %rs4overridding resource another library has patched: %rcs||S(N((R#R$(twrappedt wrapped_by(s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR&sN(RR{RRRRwRRRRRzRRt_patched_original_valueR(R2RYRtwraptcurrentRRR&((RRs</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR|s,     cCs|jS(N(R(RR((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRscsEfd}trA}d||dS|S(sBfunction decorator which patches function of same name in csRrNdkrdnd}|p1|j}j||dn|S(NRRIR (RoR(tfunctsepRY(tenableRtparentR2R (s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytbuilders N(RzR+(R2RRR R RR ((R RRR2R s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt monkeypatchs  cCsy|j|\}}Wntk r+dSX|j|}|jjd||j||s|rztd|tqtd|t|j|=dSn|j|||j|=dS(Nsunpatching resource: %rs2reverting resource another library has patched: %rs6not reverting resource another library has patched: %r( RRRRwRRRRR(R2RYRRRR ((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytunpatchs    cKs.x't|jD]}|j||qWdS(N(tlistRR(R2R$R((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRsN(RoRpRqR+R*Rt__bool__t __nonzero__Rt staticmethodRRRRMRRR@RRRt classmethodRRkRRR(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR~-s             (1Rqt functoolsRRRxRyRoRwRKR-twarningsRtdjangoRR Rt ImportErrorRRRtpasslib.contextRt passlib.excRtpasslib.utils.compatRR R R tpasslib.utils.decorR t__all__RRRRRfR`tsetRaR'RR(RsRRRBRR~(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytsT      "    =