ó ï5Xc@sdZddlmZmZddlZejeƒZddlZddl Z ddl m Z y$ddl m ZejdeƒWn$ek r©ejdƒfZnXddlmZmZdd lmZdd lmZdd lmZmZmZmZdd lmZd dddgZddfZ idd6dd6dd6dd6Z!d„Z"dZ#dZ$dZ%e&dgƒZ'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!tdƒ‚nd}n|dkr:tSyt|}Wn!tk rktd|ƒ‚nXddl}t|j|ƒjƒS(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: %riÿÿÿÿN( 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_md5cstˆƒ‡fd†ƒ}|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|stDjangoTranslatorcBs’eZdZd Zd Zd Zd Zd d„Zd„Z d„Z d„Z e d„Z eddƒZd„Zd „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ƒ|jjƒd|_dS(N(R/tclearR1R+t_django_unsalted_sha1(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt reset_hashers®s  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_hasher³s   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_nameÁscCs¤t|dƒs!|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     tmd5tMD5PasswordHashercCsætjjdƒ}|d ks+|jj rEddlm}||ƒS|jjj dƒj }x$|ƒD]}|j |krg|SqgW|j j|ƒ}|rÒd|krµd|}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.pyRAîs    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 Cs€t|dƒr1t|tƒr%|jS|j}n|r|j}y ||SWntk r_nX|j|dtƒ}||<|S|j t ƒr­|t t ƒ}|j |ƒS|dkrç|j }|d krÝtdƒ‚n|jƒS|dkrüd}n|j }|d kr*d„tjƒDƒ}n|jdtƒ}x*|D]"}t|d d ƒ|krC|SqCWtd |fƒ‚d 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|]/}|jtƒs$|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@              cCs›t|dƒr|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 BsŽeZdZdZdZdZdZeZ e Z ddd„Z d„Z d„Zdd„Zd„Zddd„Zddd„Zd „Zd „Zd „Zd Zd ZedZdZeddedeƒfeddedeƒfeddfeddfeddfeddfeddfeddfeddfeddfeddfg Zd„Zd„Zd„Zd„ZRS( 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|||r\||_ nddl m }|ƒ|j ƒ|_ ddl m}|jjdƒrµtj|ƒ}n||_ddl m}||_tjtdƒ}td |ƒ|_dS( Ns.DjangoContextAdapterR,iÿÿÿÿ(t lru_cache(t make_passwordspasslib.(tis_password_usables.DjangoContextAdapter._managertlog(tloggingt getLoggerRoRwR+RR)RsR*tget_user_categorytdjango.utils.lru_cacheRtRWRPRuRpR_t _PatchManagertpeek_unpatched_funct_orig_make_passwordRvRQ(R2R,RzR$RtRuRvtmlog((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR*²s      cCs4ddlm}|ddƒtt|ƒjƒdS(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.pyR5Ós cCs5|j}g|jjdtƒD]}||ƒ^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.pyRWãs 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.pyRHìscCsV|jj|dtdtƒ}|jdkrI|jdƒrI|jdƒS|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_hasherós cCs†|dkr|jdƒS|j|ƒ}d|jkr:n?|jdƒr^|jddƒ}n|ry|jd|ƒ}n|j|ƒS(s9 Passlib replacement for make_password() tsaltt unsalted_tN(R+R~RZt setting_kwdsR_tusingthash(R2tpasswordR†RXRC((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ƒ(R2RŒR„tsettert 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„||_|jƒn|S(s? Passlib replacement for User.check_password() tcategoryN(R+R@RŒRvRzR,tverify_and_updatetsave(R2tuserRŒR‹tcattoktnew_hash((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytuser_check_passwordEs    cCsG|dkr|jƒn*|j|ƒ}|jj|d|ƒ|_dS(s= Passlib replacement for User.set_password() R”N(R+tset_unusable_passwordRzR,R‹RŒ(R2R—RŒR˜((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.pyRzas   sdjango.contrib.auth.hasherssdjango.contrib.auth.modelss:Usersdjango.contrib.auth.formss.check_passwordR›R%s .set_passwordRt:R“RuRWRHR…cCs|j}|jr#|jdƒtSttkrEtdtfƒ‚n|jdƒ|j}x›|j D]}t |ƒdkr|if7}n|\}}}|j d ƒr¸||7}nt ||ƒ}|j dƒråt|ƒ}n|j||ƒqeW|jƒt|_|jdƒtS( sI Install monkeypatch to replace django hasher framework. s3monkeypatching already applied, refusing to reapplys(passlib.ext.django requires django >= %ss#preparing to monkeypatch django ...iR¢t,R%s"... finished monkeypatching django(R¢R£(RwROtwarningR@R Rt RuntimeErrortdebugRQtpatch_locationsRgtendswithRRMR'tpatchR5Rk(R2Rwtmanagertrecordttargettsourcetoptstvalue((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt install_patch•s.          cCsË|j}|j}|jrl|jdƒ|jdtƒ|jjiƒt|_|j ƒ|jdƒtS|j ƒrº|j dƒ|jƒ|jjiƒ|j ƒ|jdƒtS|jdƒtS(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( RwRQROR¦t unpatch_allRkR,tloadR@R5tisactiveR¤(R2RwRª((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt remove_patch¿s&             cCso|jƒ|jr;y|jƒWq^|jƒ‚q^Xn#|jrTtjdƒn|jƒtjdƒdS(sD Load configuration from django, and install patch. s.didn't expect monkeypatching would be applied!spasslib.ext.django loadedN(t_load_settingstenabledR°RµRORwterrorR¦(R2((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt load_modelæs      cCs‰ddlm}tƒ}t|d|ƒ}||krLt|d|ƒ}n||krad}n|d krƒtdtƒd}n0t|tt t fƒs³t j |ddƒ‚nt|d d ƒ}|rðt |ƒ rðt j |d d ƒ‚n|dkr t|_d S|jjd d ƒt|tƒrFd |krFt|ƒ}n|rX||_n|jjdd ƒ|jj|ƒ|jƒd 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_CATEGORYtcallableNR·s t get_category(t django.confRºtobjectRR+RtDeprecationWarningRdR tbytesRrRtExpectedTypeErrorR¿R@R·t__dict__tpoptstrRRzR,R³R5(R2Rºt_UNSETtconfigRÀ((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR¶øs6         N( RoRpRqR+R,R~RvRQRkR·R@ROR*R5RWRHR…RuR“R›RRzt HASHERS_PATHt MODELS_PATHtUSER_CLASS_PATHt FORMS_PATHRrR§R°RµR¹R¶(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRssH!   *             * ' s--!!!generate-new-salt!!!--t ProxyPropertycBs2eZdZd„Zd„Zd„Zd„ZRS(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||jƒS(N(R+RR(R2tobjtcls((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt__get__?s  cCst||j|ƒdS(N(tsetattrR(R2RÐR¯((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt__set__DscCst||jƒdS(N(tdelattrR(R2RÐ((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt __delete__Gs(RoRpRqR*RÒRÔRÖ(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRÏ9s    RBcBs˜eZdZd Zd„Zd„Zed„ƒZed„ƒZed„ƒZ ed„ƒZ d„Z d„Z 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|ddƒr+td|jfƒ‚n|jrJtd|jƒ‚n||_|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_roundsR×RÏt 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|jjjƒS(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.pyRÙscCs;tddƒ}|jr7d|jjkr7d|d django keywords tchecksumR‹tpbkdf2RÛR×(RrRÙReR(R2tout((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt_translate_kwds…s 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.pyR†›scCs|jj||ƒS(N(ReRŽ(R2RŒR„((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyRŽ¡scCsÐi}|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( RýRòRRwR¦RüRRRR¿Rt_patched_original_valueR(R2RYR¯twraptcurrentRRR&((RRs</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR©|s(     cCs|jS(N(R(RÑR¯((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR}˜scsE‡‡‡‡‡fd†}tˆƒrAˆ}d‰||ƒdS|S(sBfunction decorator which patches function of same name in csRˆrNdˆkrdnd}ˆ|ˆp1|j}ˆj||dˆƒn|S(NR¢RIR(RoR©(tfunctsepRY(tenableRtparentR2R(s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytbuilder£s N(R¿R+(R2R RR RRR ((R RR R2Rs</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyt monkeypatch¡s  cCsºy|j|\}}Wntk r+dSX|j|ƒ}|jjd|ƒ|j||ƒsœ|rztd|tƒqœtd|tƒ|j|=dSn|j||ƒ|j|=dS(Nsunpatching resource: %rs2reverting resource another library has patched: %rs6not reverting resource another library has patched: %r( RòRRýRwR¦RüRRR(R2RYR±RRR ((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytunpatch´s    cKs.x't|jƒD]}|j||qWdS(N(tlistRòR(R2R$Rì((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR²ÇsN(RoRpRqR+R*R´t__bool__t __nonzero__Rùt staticmethodRüRÉRýRMRRR@RRR©t classmethodR}RkRRR²(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pyR|-s             (1Rqt functoolsRRRxRyRoRwRKR-twarningsRtdjangoRR R¦t ImportErrorRRRtpasslib.contextRt passlib.excRtpasslib.utils.compatRR R R tpasslib.utils.decorR t__all__RRRRRfR`tsetRaR'RÂR(RsRâRÏRBRÉR|(((s</usr/lib/python2.7/site-packages/passlib/ext/django/utils.pytsT      "    = ÿ ÿ©à