Ë
    àU.jÁ  ã                   óò  — d Z ddl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 	 ddlmZ ej                  de«       dd	lmZmZ dd
lmZ ddlmZ ddlmZmZmZmZ ddlmZ g d¢ZdZ  G d„ d«      Z!dddddœZ"d„ Z#dZ$dZ%dZ& e'dg«      Z(d„ Z) G d„ de*«      Z+ G d„ d e+«      Z,d!Z- G d"„ d#e*«      Z. G d$„ d%e*«      Z/ e*«       Z0 G d&„ d'e*«      Z1y# e$ r ej                  d«       dZY Œ­w xY w)(z?passlib.ext.django.utils - helper functions used by this pluginé    )Úupdate_wrapperÚwrapsN)Úwarn)ÚVERSIONzfound django %r installationzdjango installation not found© )ÚexcÚregistry)ÚCryptContext)ÚPasslibRuntimeWarning)Úget_method_functionÚ	iteritemsÚOrderedDictÚunicode)Úmemoized_property)ÚDJANGO_VERSIONÚMIN_DJANGO_VERSIONÚget_preset_configÚquirks)é   é   c                   ó*   — e Zd Zedk\  Zedk\  Zedk\  Zy)r   ©é   r   N)Ú__name__Ú
__module__Ú__qualname__r   Ú none_causes_check_password_errorÚempty_is_usable_passwordÚinvalid_is_usable_passwordr   ó    úZC:\xampp\htdocs\tradingbinance\backend\.venv\Lib\site-packages\passlib/ext/django/utils.pyr   r   '   s)   „ ð (6¸Ñ'?Ð$ð  .°Ñ7Ðð "0°6Ñ!9Ñr    r   Údjango10_contextÚdjango14_contextÚdjango16_contextÚdjango_context)z
django-1.0z
django-1.4ú
django-1.6zdjango-latestc                 óâ   — | dk(  rt         st        d«      ‚d} | dk(  rt        S 	 t        |    }ddl}t        |j                  |«      j                  «       S # t        $ r t        d| z  «      ‚w xY w)ae  Returns 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
    zdjango-defaultz9can't resolve django-default preset, django not installedr&   úpasslib-defaultzunknown preset config name: %rr   N)	r   Ú
ValueErrorÚPASSLIB_DEFAULTÚ_preset_mapÚKeyErrorÚpasslib.appsÚgetattrÚappsÚ	to_string)ÚnameÚattrÚpasslibs      r!   r   r   ?   s‰   € ð ÐÒÝÜð 4ó 5ð 5àˆØÐ Ò ÜÐðBÜ˜4Ñ ˆó Ü�7—<‘< Ó&×0Ñ0Ó2Ð2øô ò BÜÐ9¸DÑ@ÓAÐAðBús   ¥	A ÁA.a¤  
[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
Úpasslib_Údjango_Úhex_md5c                 ó.   ‡ — t        ‰ «      ˆ fd„«       }|S )z#wrap method object in bare functionc                  ó   •—  ‰| i |¤ŽS ©Nr   )ÚargsÚkwdsÚmethods     €r!   Úwrapperz_wrap_method.<locals>.wrapperŽ   s   ø€ á�tÐ$˜tÑ$Ð$r    )r   )r<   r=   s   ` r!   Ú_wrap_methodr>   Œ   s   ø€ ä
ˆ6ƒ]ó%ó ð%à€Nr    c                   óª   ‡ — e Zd ZdZdZdZdZdZdˆ fd„	Zd„ Z	d„ Z
d„ Zdd„Z ed¬	«      Zed
kD  rej!                  d¬«       d„ Zd„ Zdd„Zdd„Zˆ xZS )ÚDjangoTranslatoraO  
    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).
    Nc                 ó¢   •— t        t        | �
  di |¤Ž |�|| _        t	        j
                  «       | _        t	        j                  «       | _        y )Nr   )	Úsuperr@   Ú__init__ÚcontextÚweakrefÚWeakKeyDictionaryÚ_django_hasher_cacheÚWeakValueDictionaryÚ_passlib_hasher_cache)ÚselfrD   r;   Ú	__class__s      €r!   rC   zDjangoTranslator.__init__¶   sE   ø€ ÜÔ Ñ.Ñ6°Ò6ØÐØ"ˆDŒLä$+×$=Ñ$=Ó$?ˆÔ!Ü%,×%@Ñ%@Ó%BˆÕ"r    c                 óz   — | j                   j                  «        | j                  j                  «        d | _        y r9   )rG   ÚclearrI   Ú_django_unsalted_sha1©rJ   s    r!   Úreset_hasherszDjangoTranslator.reset_hashers¾   s.   € Ø×!Ñ!×'Ñ'Ô)Ø×"Ñ"×(Ñ(Ô*Ø%)ˆÕ"r    c                 ój   — | j                   }|€t        j                  |«      S |j                  |«      S )zM
        resolve passlib hasher by name, using context if available.
        )rD   r	   Úget_crypt_handlerÚhandler)rJ   Úpasslib_namerD   s      r!   Ú_get_passlib_hasherz$DjangoTranslator._get_passlib_hasherÃ   s2   € ð —,‘,ˆØˆ?Ü×-Ñ-¨lÓ;Ð;à—?‘? <Ó0Ð0r    c                 ó8   — | j                  |«      j                  S )zF
        Convert passlib hasher / name to Django hasher name.
        )Úpasslib_to_djangoÚ	algorithm)rJ   rT   s     r!   Úpasslib_to_django_namez'DjangoTranslator.passlib_to_django_nameÑ   s   € ð ×%Ñ% lÓ3×=Ñ=Ð=r    c                 ó  — t        |d«      s| j                  |«      }|r| j                  }	 ||   S t        |dd«      }|r| j                  |«      S t        |«      S # t        $ r Y nw xY w| j	                  |d¬«      x}||<   |S )z¹
        Convert passlib hasher / name to Django hasher.

        :param passlib_hasher:
            passlib hasher / name

        :returns:
            django hasher instance
        r1   F©ÚcachedÚdjango_nameN)ÚhasattrrU   rG   r,   rW   r.   Ú_create_django_hasherÚ_PasslibHasherWrapper)rJ   Úpasslib_hasherr\   ÚcacheÚresultr]   s         r!   rW   z"DjangoTranslator.passlib_to_djangoÚ   sª   € ô �~ vÔ.Ø!×5Ñ5°nÓEˆNñ Ø×-Ñ-ˆEðØ˜^Ñ,Ð,ô ˜n¨m¸TÓBˆÙØ×-Ñ-¨kÓ:Ð:ä(¨Ó8Ð8øô ò Ùðúð ×&Ñ& ~¸eÐ&ÓDðEˆF�U˜>Ñ*àˆMs   ­A Á	A)Á(A)ÚMD5PasswordHasher)Úmd5r   ÚBCryptPasswordHasher)Úbcryptc                 ó  — t         j                  j                  d«      }|�|j                  j                  sddlm} 	  ||«      S |j                  j                  j                  d«      j                  } |«       D ]  }|j                  |k(  sŒ|c S  | j                  j                  |«      }|rd|vrd|z   }dd	lm}   ||«      «       S t        d
|z  «      ‚# t        $ r%}t        |«      j                  d«      s‚ Y d}~Œpd}~ww xY w)zf
        helper to create new django hasher by name.
        wraps underlying django methods.
        zpasslib.ext.django.modelsNr   )Ú
get_hasherz"Unknown password hashing algorithmz'django.contrib.auth.hashers:get_hashersÚ.zdjango.contrib.auth.hashers.)Úimport_stringzunknown hasher: %r)ÚsysÚmodulesÚgetÚadapterÚpatchedÚdjango.contrib.auth.hashersri   r)   ÚstrÚ
startswithÚ_managerÚgetorigÚ__wrapped__rX   Ú_builtin_django_hashersÚdjango.utils.module_loadingrk   )	rJ   r]   Úmoduleri   ÚerrÚget_hashersÚhasherÚpathrk   s	            r!   r_   z&DjangoTranslator._create_django_hasher  sû   € ô —‘—‘Ð!<Ó=ˆØˆ> §¡×!7Ò!7Ý>ðÙ! +Ó.Ð.ð !Ÿ.™.×1Ñ1×9Ñ9Ð:cÓd×pÑpˆKÙ%ž-�Ø×#Ñ# {Ó2Ø!’Mð (ð ×+Ñ+×/Ñ/°Ó<ˆÙØ˜$‰Ø5¸Ñ<�ÝAØ&‘= Ó&Ó(Ð(äÐ-°Ñ;Ó<Ð<øô+ ò Ü˜3“x×*Ñ*Ð+OÔPØô Qûðús   ¿C Ã	D
Ã%DÄD
c                 ó8   — | j                  |«      j                  S )zF
        Convert Django hasher / name to Passlib hasher name.
        )Údjango_to_passlibr1   )rJ   r]   s     r!   Údjango_to_passlib_namez'DjangoTranslator.django_to_passlib_name+  s   € ð ×%Ñ% kÓ2×7Ñ7Ð7r    c                 óˆ  — t        |d«      r(t        |t        «      r|j                  S |j                  }|r| j
                  }	 ||   S |j                  t        «      r#|t        t        «      d }| j                  |«      S |dk(  r)| j                  }|€t        d«      ‚|j                  «       S |dk(  rd}| j                  }|€d	„ t        j                   «       D «       }n|j#                  d
¬«      }|D ]  }t%        |dd«      |k(  sŒ|c S  t'        d|›�«      ‚# t        $ r Y nw xY w| j                  |d¬«      x}||<   |S )aŽ  
        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
        rX   Fr[   NÚdefaultz)can't determine default scheme w/ contextÚunsalted_sha1Úsha1c              3   ó€   K  — | ]6  }|j                  t        «      s|t        v rt        j                  |«      –— Œ8 y ­wr9   )rs   ÚDJANGO_COMPAT_PREFIXÚ_other_django_hashesr	   rR   )Ú.0rT   s     r!   Ú	<genexpr>z5DjangoTranslator.django_to_passlib.<locals>.<genexpr>n  s;   è ø€ ð á$B�LØ×*Ñ*Ô+?Ô@ØÔ#7Ñ7ô ×*Ñ*¨<×8Ù$Bùs   ‚<>T©Úresolver]   z-can't translate django name to passlib name: )r^   Ú
isinstancer`   Úpasslib_handlerrX   rI   r,   r   rs   ÚPASSLIB_WRAPPER_PREFIXÚlenrU   rD   Ú	TypeErrorrS   r	   Úlist_crypt_handlersÚschemesr.   r)   )	rJ   r]   r\   rb   rc   rT   rD   Ú
candidatesrS   s	            r!   r   z"DjangoTranslator.django_to_passlib1  sx  € ô  �; Ô,ô ˜+Ô'<Ô=Ø"×2Ñ2Ð2ð &×/Ñ/ˆKñ Ø×.Ñ.ˆEðØ˜[Ñ)Ð)ð ×!Ñ!Ô"8Ô9Ø&¤sÔ+AÓ'BÐ'CÐDˆLØ×+Ñ+¨LÓ9Ð9ð ˜)Ò#Ø—l‘lˆGØˆÜÐ KÓLÐLØ—?‘?Ó$Ð$ð
 ˜/Ò)Ø ˆKð
 —,‘,ˆØˆ?ñä$,×$@Ñ$@Ô$Bó‰Jð !Ÿ™°˜Ó6ˆJÛ!ˆGÜ�w ¨tÓ4¸ÓCØ’ð "õ Ù%ð(ó )ð 	)øôa ò Ùðúð ×&Ñ& {¸5Ð&ÓAðBˆF�U˜;Ñ'àˆMs   ÁD Ä	D'Ä&D'c                 ó  — t        |d«      r|S | j                  ||¬«      }|dk(  rJ|j                  dk(  r;|s| j                  |«      S | j                  }|€| j                  |«      x}| _        |S | j                  ||¬«      S )zH
        Take in a django algorithm name, return django hasher.
        rX   r[   rƒ   Údjango_salted_sha1)r^   r   r1   r_   rN   rW   )rJ   r]   r\   ra   rc   s        r!   Úresolve_django_hasherz&DjangoTranslator.resolve_django_hasher†  s�   € ô
 �; Ô,ØÐð ×/Ñ/°ÀFÐ/ÓKˆð ˜/Ò)¨n×.AÑ.AÐEYÒ.YÙØ×1Ñ1°+Ó>Ð>Ø×/Ñ/ˆFØˆ~Ø6:×6PÑ6PÐQ\Ó6]Ð]�˜Ô3ØˆMð ×%Ñ% n¸VÐ%ÓDÐDr    r9   ©T)r   r   r   Ú__doc__rD   rG   rN   rI   rC   rP   rU   rY   rW   Údictrw   r   Úupdater_   r€   r   r–   Ú__classcell__©rK   s   @r!   r@   r@   –   sŒ   ø„ ñð €Gð  Ðð !Ðð !ÐõCò*ò
1ò>ó9ñ@ #ØôÐð ˜Òð 	 ×&Ñ&Ø)ð 	'ô 	
ò =òL8óO)÷jEr    r@   c                   óR  ‡ — e Zd ZdZdZdZdZdZdZdZ	d"ˆ fd„	Z
ˆ fd„Zd„ Zd#d„Zd	„ Zd$d
„Zd$d„Zd„ Zd„ Zd„ ZdZdZedz   ZdZedz   d ed¬«      fedz   d ed¬«      fedz   dfedz   dfedz   dfedz   dfedz   dfedz   dfedz   dfedz   dfedz   dfgZd„ Zd„ Zd „ Zd!„ Zˆ xZS )%ÚDjangoContextAdapteraC  
    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.
    NTFc                 ó  •— t        j                  t        dz   «      | _        |€
t	        «       }t        t        | �  d
d|i|¤Ž |rt        |«      sJ ‚|| _	        	 ddl
m}   |«       | j                  «      | _        ddlm} |j"                  j%                  d«      rt&        j)                  |«      }|| _        ddlm} || _        t        j                  t        dz   «      }t'        |¬	«      | _        y # t        $ r	 ddlm} Y Œ¥w xY w)Nz.DjangoContextAdapterrD   r   )Ú	lru_cache)Úmake_passwordzpasslib.)Úis_password_usablez.DjangoContextAdapter._manager)Úlogr   )ÚloggingÚ	getLoggerr   r£   r
   rB   rž   rC   ÚcallableÚget_user_categoryÚ	functoolsr    ÚImportErrorÚdjango.utils.lru_cacher{   rq   r¡   r   rs   Ú_PatchManagerÚpeek_unpatched_funcÚ_orig_make_passwordr¢   rt   )	rJ   rD   r§   r;   r    r¡   r¢   ÚmlogrK   s	           €r!   rC   zDjangoContextAdapter.__init__Î  s÷   ø€ ô ×$Ñ$¤XÐ0GÑ%GÓHˆŒð ˆ?Ü"“nˆGÜÔ" DÑ2ÑK¸7ÐKÀdÒKñ ÜÐ-Ô.Ð.Ð.Ø%6ˆDÔ"ð	9Ý+ð '™9›; t×'7Ñ'7Ó8ˆÔõ 	>Ø×#Ñ#×.Ñ.¨zÔ:Ü)×=Ñ=¸mÓLˆMØ#0ˆÔ õ 	CØ"4ˆÔô × Ñ ¤Ð,LÑ!LÓMˆÜ%¨$Ô/ˆ�øô! ò 	9ß8ð	9ús   ÁC5 Ã5DÄDc                 óH   •— ddl m}  |d¬«       t        t        | �  «        y)zH
        Wrapper to manually reset django's hasher lookup cache
        r   )rP   ÚPASSWORD_HASHERS)ÚsettingN)rq   rP   rB   rž   )rJ   rP   rK   s     €r!   rP   z"DjangoContextAdapter.reset_hashersò  s!   ø€ õ
 	>ÙÐ0Õ1ô 	Ô" DÑ7Õ9r    c                 ó„   — | j                   }| j                  j                  d¬«      D �cg c]
  } ||«      ‘Œ c}S c c}w )zq
        Passlib replacement for get_hashers() --
        Return list of available django hasher classes
        TrŠ   )rW   rD   r’   )rJ   rW   r|   s      r!   r{   z DjangoContextAdapter.get_hashers  sP   € ð
 !×2Ñ2Ðà"Ÿl™l×2Ñ2¸4Ð2Ô@óBÙ@�Fñ " &Õ)Ø@ñBð 	Bùò Bs   «=c                 ó$   — | j                  |«      S )z^
        Passlib replacement for get_hasher() --
        Return django hasher by name
        )r–   )rJ   rX   s     r!   ri   zDjangoContextAdapter.get_hasher  s   € ð
 ×)Ñ)¨)Ó4Ð4r    c                 óÂ   — | j                   j                  |dd¬«      }|j                  dk(  r"|j                  d«      r| j	                  d«      S | j                  |«      S )zl
        Passlib replacement for identify_hasher() --
        Identify django hasher based on hash.
        T)r‹   Úrequiredr•   zsha1$$rƒ   )rD   Úidentifyr1   rs   ri   rW   )rJ   ÚencodedrS   s      r!   Úidentify_hasherz$DjangoContextAdapter.identify_hasher  s[   € ð
 —,‘,×'Ñ'¨¸ÈÐ'ÓMˆØ�<‰<Ð/Ò/°G×4FÑ4FÀxÔ4Pð —?‘? ?Ó3Ð3Ø×%Ñ% gÓ.Ð.r    c                 óú   — |€| j                  d«      S | j                  |«      }d|j                  vrn8|j                  d«      r|j	                  d¬«      }n|r|j	                  |¬«      }|j                  |«      S )z9
        Passlib replacement for make_password()
        NÚsaltÚ	unsalted_Ú )rº   )r­   r   Úsetting_kwdsrs   ÚusingÚhash)rJ   Úpasswordrº   r|   ra   s        r!   r¡   z"DjangoContextAdapter.make_password#  sŠ   € ð ÐØ×+Ñ+¨DÓ1Ð1ð ×/Ñ/°Ó7ˆØ˜×4Ñ4Ñ4àØ×Ñ˜{Ô+ð ,×1Ñ1°rÐ1Ó:‰NÙð ,×1Ñ1°tÐ1Ó<ˆNØ×"Ñ" 8Ó,Ð,r    c                 ó\  — |�| j                  |«      sy| j                  }	 |j                  ||«      }|r|s|S |dk(  r|j                  ||¬«      s9|S | j                  |«      }|j                  |«      r|j                  ||¬«      s|S  ||«       |S # t        j                  $ r Y yw xY w)z:
        Passlib replacement for check_password()
        Fr‚   )Úsecret)r¢   rD   Úverifyr   ÚUnknownHashErrorÚneeds_updater   r¶   )rJ   rÀ   r·   ÚsetterÚ	preferredrD   Úcorrectr|   s           r!   Úcheck_passwordz#DjangoContextAdapter.check_password:  sË   € ð Ð 4×#:Ñ#:¸7Ô#CØð —,‘,ˆð	Ø—n‘n X¨wÓ7ˆGñ ™FØˆNð ˜	Ò!Ø×'Ñ'¨¸Ð'ÔAØ�ð ×+Ñ+¨IÓ6ˆFØ—‘ Ô(Ø×+Ñ+¨G¸HÐ+ÔEð �ñ 	ˆxÔØˆøô; ×#Ñ#ò 	ñ ð	ús   ¢B ÂB+Â*B+c                 ó  — |€y|j                   }| j                  |«      sy| j                  |«      }	 | j                  j	                  |||¬«      \  }}|r|�||_         |j                  «        |S # t
        j                  $ r Y yw xY w)z?
        Passlib replacement for User.check_password()
        F©Úcategory)rÀ   r¢   r§   rD   Úverify_and_updater   rÄ   Úsave)rJ   ÚuserrÀ   r¿   ÚcatÚokÚnew_hashs          r!   Úuser_check_passwordz(DjangoContextAdapter.user_check_passwordl  s—   € ð ÐØØ�}‰}ˆØ×&Ñ& tÔ,ØØ×$Ñ$ TÓ*ˆð	ØŸ<™<×9Ñ9¸(ÀDÐSVÐ9ÓW‰LˆB�ñ
 �(Ð&à$ˆDŒMØ�I‰IŒKØˆ	øô ×#Ñ#ò 	ñ ð	ús   ´!A2 Á2BÂBc                 ó�   — |€|j                  «        y| j                  |«      }| j                  j                  ||¬«      |_        y)z=
        Passlib replacement for User.set_password()
        NrË   )Úset_unusable_passwordr§   rD   r¿   rÀ   )rJ   rÏ   rÀ   rÐ   s       r!   Úuser_set_passwordz&DjangoContextAdapter.user_set_password‚  sA   € ð ÐØ×&Ñ&Õ(à×(Ñ(¨Ó.ˆCØ ŸL™L×-Ñ-¨hÀÐ-ÓEˆD�Mr    c                 ó8   — |j                   ry|j                  ryy)zæ
        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
        Ú	superuserÚstaffN)Úis_superuserÚis_staff)rJ   rÏ   s     r!   r§   z&DjangoContextAdapter.get_user_categoryŒ  s   € ð ×ÒØØ�]Š]Øàr    zdjango.contrib.auth.hasherszdjango.contrib.auth.modelsz:Userzdjango.contrib.auth.formsz.check_passwordrÓ   )r<   z.set_passwordrÖ   Ú:rÉ   r¡   r{   ri   r¸   c                 ó  — | j                   }| j                  r|j                  d«       yt        t        k  rt        dt        ›�«      ‚|j                  d«       | j                  }| j                  D ]l  }t        |«      dk(  r|i fz  }|\  }}}|j                  d«      r||z  }t        | |«      }|j                  d«      rt        |«      }|j                  ||«       Œn | j                  «        d| _        |j                  d	«       y)
zI
        Install monkeypatch to replace django hasher framework.
        z3monkeypatching already applied, refusing to reapplyFz&passlib.ext.django requires django >= z#preparing to monkeypatch django ...r   )rÜ   Ú,r<   Tz"... finished monkeypatching django)r£   rp   Úwarningr   r   ÚRuntimeErrorÚdebugrt   Úpatch_locationsr�   Úendswithr.   rn   r>   ÚpatchrP   )rJ   r£   ÚmanagerÚrecordÚtargetÚsourceÚoptsÚvalues           r!   Úinstall_patchz"DjangoContextAdapter.install_patchÀ  s   € ð
 �h‰hˆØ�<Š<Ø�K‰KÐMÔNØô Ô.Ò.ÝÝ 2ð 5ó 6ð 6ð 	�	‰	Ð7Ô8ð —-‘-ˆØ×*Ô*ˆFÜ�6‹{˜aÒØ˜2˜%‘�Ø#)Ñ ˆF�F˜DØ�‰˜zÔ*Ø˜&Ñ �Ü˜D &Ó)ˆEØ�x‰x˜Ô!ô % UÓ+�Ø�M‰M˜& %Õ(ð +ð 	×ÑÔð ˆŒØ�	‰	Ð6Ô7Ør    c                 ó  — | j                   }| j                  }| j                  rg|j                  d«       |j	                  d¬«       | j
                  j                  i «       d| _        | j                  «        |j                  d«       y|j                  «       r^|j                  d«       |j	                  «        | j
                  j                  i «       | j                  «        |j                  d«       y|j                  d«       y)a¼  
        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.
        z!removing django monkeypatching...T)Úunpatch_conflictsFz*...finished removing django monkeypatchingz-reverting partial monkeypatching of django...zdjango not monkeypatched)
r£   rt   rp   rá   Úunpatch_allrD   ÚloadrP   Úisactiverß   )rJ   r£   rå   s      r!   Úremove_patchz!DjangoContextAdapter.remove_patchê  sÓ   € ð �h‰hˆØ—-‘-ˆà�<Š<Ø�I‰IÐ9Ô:Ø×Ñ°$ÐÔ7Ø�L‰L×Ñ˜bÔ!Ø ˆDŒLØ×ÑÔ Ø�I‰IÐBÔCØà×ÑÔØ�K‰KÐGÔHØ×ÑÔ!Ø�L‰L×Ñ˜bÔ!Ø×ÑÔ Ø�I‰IÐBÔCØà�	‰	Ð,Ô-Ør    c                 ó  — | j                  «        | j                  r	 | j                  «        n1| j                  rt
        j                  d«       | j                  «        t
        j                  d«       y#  | j                  «        ‚ xY w)zD
        Load configuration from django, and install patch.
        z.didn't expect monkeypatching would be applied!zpasslib.ext.django loadedN)Ú_load_settingsÚenabledrë   rñ   rp   r£   Úerrorrá   rO   s    r!   Ú
load_modelzDjangoContextAdapter.load_model  sm   € ð 	×ÑÔØ�<Š<ðØ×"Ñ"Õ$ð �|Š|Ü—	‘	ÐJÔKØ×ÑÔÜ�	‰	Ð-Õ.øðà×!Ñ!Ô#Øús   žA6 Á6B	c                 óŽ  — ddl m} t        «       }t        |d|«      }||u rt        |d|«      }||u rd}|€t	        dt
        «       d}n2t        |t        t        t        f«      st        j                  |d	d«      ‚t        |d
d«      }|r"t        |«      st        j                  |dd
«      ‚|dk(  rd| _        y| j                  j                  dd«       t        |t         «      rd|vrt#        |«      }|r|| _        n| j                  j                  dd«       | j&                  j)                  |«       | j+                  «        y)z-
        Update settings from django
        r   )ÚsettingsÚPASSLIB_CONFIGÚPASSLIB_CONTEXTr(   Nz}setting PASSLIB_CONFIG=None is deprecated, and support will be removed in Passlib 1.8, use PASSLIB_CONFIG='disabled' instead.Údisabledzstr or dictÚPASSLIB_GET_CATEGORYr¦   Frô   Ú
Úget_category)Údjango.confrø   Úobjectr.   r   ÚDeprecationWarningrŒ   r   Úbytesr™   r   ÚExpectedTypeErrorr¦   rô   Ú__dict__Úpoprr   r   r§   rD   rï   rP   )rJ   rø   Ú_UNSETÚconfigrþ   s        r!   ró   z#DjangoContextAdapter._load_settings#  s?  € õ 	)ô “ˆÜ˜Ð#3°VÓ<ˆØ�VÑä˜XÐ'8¸&ÓAˆFØ�VÑØ&ˆFØˆ>Üð :ô $ô%ð  ‰FÜ˜F¤W¬e´TÐ$:Ô;Ü×'Ñ'¨°Ð?OÓPÐPô ˜xÐ)?ÀÓFˆÙ¤¨Ô 6Ü×'Ñ'¨°jÐBXÓYÐYð �ZÒØ ˆDŒLØà�M‰M×Ñ˜i¨Ô.ô �fœcÔ" t°6Ñ'9Ü& vÓ.ˆFñ Ø%1ˆDÕ"à�M‰M×Ñ˜n¨dÔ3ð 	�‰×Ñ˜&Ô!Ø×ÑÕr    )NN)r‚   )Nr‚   )r   r   r   r˜   rD   r­   r¢   rt   rô   rp   rC   rP   r{   ri   r¸   r¡   rÉ   rÓ   rÖ   r§   ÚHASHERS_PATHÚMODELS_PATHÚUSER_CLASS_PATHÚ
FORMS_PATHr™   râ   rë   rñ   rö   ró   r›   rœ   s   @r!   rž   rž   «  sM  ø„ ñð €Gð Ðð Ðð €Hð €Gð €Gõ
"0ôH	:ò Bó5ò/ó"-ó.,òdò,Fòð$ 1€LØ.€KØ! GÑ+€OØ,€Jð 
Ð,Ñ	,Ð.CÁTÐQUÔEVÐWØ	˜?Ñ	*Ð,?ÁÈTÔARÐSð
 
˜Ñ	Ð-Ð.Ø	˜Ñ	˜_Ð-Ø	˜Ñ	˜]Ð+Ø	˜Ñ	˜\Ð*Ø	˜Ñ	Ð.Ð/ð
 
�sÑ	Ð,Ð-Ø	�sÑ	˜OÐ,Ø	�cÑ	˜<Ð(Ø	�cÑ	Ð,Ð-ð1€Oò8(òT!òN/ö$6r    rž   z--!!!generate-new-salt!!!--c                   ó(   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zy)ÚProxyPropertyz%helper that proxies another attributec                 ó   — || _         y r9   )r2   )rJ   r2   s     r!   rC   zProxyProperty.__init__g  s	   € Øˆ�	r    c                 ó6   — |€|}t        || j                  «      S r9   )r.   r2   )rJ   ÚobjÚclss      r!   Ú__get__zProxyProperty.__get__j  s   € Øˆ;ØˆCÜ�s˜DŸI™IÓ&Ð&r    c                 ó2   — t        || j                  |«       y r9   )Úsetattrr2   )rJ   r  rê   s      r!   Ú__set__zProxyProperty.__set__o  s   € Ü��T—Y‘Y Õ&r    c                 ó0   — t        || j                  «       y r9   )Údelattrr2   )rJ   r  s     r!   Ú
__delete__zProxyProperty.__delete__r  s   € Ü��T—Y‘YÕr    N)r   r   r   r˜   rC   r  r  r  r   r    r!   r  r  d  s   „ Ù/òò'ò
'ó r    r  c                   ó€   — e Zd ZdZdZd„ Zd„ Zed„ «       Z ed„ «       Zed„ «       Z	ed„ «       Z
d	„ Zd
„ Zdd„Zd„ Zd„ Zy)r`   zó
    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`.
    Nc                 ó   — t        |dd «      rt        d|j                  ›�«      ‚|j                  rt        d|j                  z  «      ‚|| _        | j
                  r"|j                  | _        t        d«      | _	        y y )Nr]   zFhandlers that reflect an official django hasher shouldn't be wrapped: z%can't wrap disabled-hash handlers: %rÚrounds)
r.   r)   r1   Úis_disabledr�   Ú_has_roundsÚdefault_roundsr  r  Ú
iterations)rJ   r�   s     r!   rC   z_PasslibHasherWrapper.__init__�  sƒ   € ä�? M°4Ô8Ýà-×2Ò2ð5ó 6ð 6ð ×&Ò&äÐDØ-×2Ñ2ñ4ó 5ð 5à.ˆÔð ×ÒØ)×8Ñ8ˆDŒKÜ+¨HÓ5ˆD�Oð r    c                 ó    — d| j                   z  S )Nz!<PasslibHasherWrapper handler=%r>)r�   rO   s    r!   Ú__repr__z_PasslibHasherWrapper.__repr__¡  s   € Ø2°T×5IÑ5IÑIÐIr    c                 óP   — d| j                   j                  j                  «       z  S )NzPasslib_%s_PasswordHasher)r�   r1   ÚtitlerO   s    r!   r   z_PasslibHasherWrapper.__name__¨  s"   € à*¨T×-AÑ-A×-FÑ-F×-LÑ-LÓ-NÑNÐNr    c                 ó2   — d| j                   j                  v S )Nr  )r�   r½   rO   s    r!   r  z!_PasslibHasherWrapper._has_rounds¬  s   € à˜4×/Ñ/×<Ñ<Ð<Ð<r    c                 óp   — t        d¬«      }| j                  rd| j                  j                  v rd|d<   |S )zy
        internal helper for safe_summary() --
        used to translate passlib hash options -> django keywords
        r¿   )ÚchecksumÚpbkdf2r  r  )r™   r  r�   r1   )rJ   Úouts     r!   Ú_translate_kwdsz%_PasslibHasherWrapper._translate_kwds°  s8   € ô ˜FÔ#ˆØ×Ò ¨D×,@Ñ,@×,EÑ,EÑ EØ(ˆC�‰MØˆ
r    c                 ó<   — t         | j                  j                  z   S r9   )rŽ   r�   r1   rO   s    r!   rX   z_PasslibHasherWrapper.algorithm¿  s   € ä%¨×(<Ñ(<×(AÑ(AÑAÐAr    c                 ó   — t         S r9   )Ú_GEN_SALT_SIGNALrO   s    r!   rº   z_PasslibHasherWrapper.saltÆ  s
   € ô  Ðr    c                 ó:   — | j                   j                  ||«      S r9   )r�   rÃ   )rJ   rÀ   r·   s      r!   rÃ   z_PasslibHasherWrapper.verifyÌ  s   € Ø×#Ñ#×*Ñ*¨8°WÓ=Ð=r    c                 ó  — i }|�|t         k7  r||d<   | j                  r |�||d<   n4|�||d<   n,| j                  |d<   n|€|�t        d| j                  z  «       | j
                  }|r |j                  di |¤Ž}|j                  |«      S )Nrº   r  z0%s.hash(): 'rounds' and 'iterations' are ignoredr   )r,  r  r  r   r   r�   r¾   r¿   )rJ   rÀ   rº   r  r  r;   rS   s          r!   Úencodez_PasslibHasherWrapper.encodeÏ  sŸ   € ØˆØÐ Ô(8Ò 8ØˆD�‰LØ×ÒØÐ!Ø!'��X’ØÐ'Ø!+��X’à!%§¡��X’ØÐ :Ð#9ÜÐCÀdÇmÁmÑSÔTØ×&Ñ&ˆÙØ#�g—m‘mÑ+ dÑ+ˆGØ�|‰|˜HÓ%Ð%r    c                 ó@  — ddl m} ddlm} | j                  } |d«      |j
                  fg}t        |d«      r[|j                  ||¬«      }t        |«      D ]:  \  }}| j                  j                  ||«      }|j                   ||«      |f«       Œ< t        |«      S )Nr   )Ú	mask_hash)Úugettext_nooprX   Ú	parsehash)Úsanitize)rq   r1  Údjango.utils.translationr2  r�   r1   r^   r3  r   r)  rn   Úappendr   )	rJ   r·   r1  Ú_rS   Úitemsr;   Úkeyrê   s	            r!   Úsafe_summaryz"_PasslibHasherWrapper.safe_summaryá  s˜   € Ý9Ý?Ø×&Ñ&ˆñ ˆ{‹^˜WŸ\™\Ð*ð
ˆô
 �7˜KÔ(Ø×$Ñ$ W°yÐ$ÓAˆDÜ'¨žo‘
��UØ×*Ñ*×.Ñ.¨s°CÓ8�Ø—‘™a ›f e˜_Õ-ð .ô ˜5Ó!Ð!r    c                 ó¢   — | j                   rC| j                  j                  | j                  | j                  ¬«      }|j	                  |«      ryy)N)Ú
min_roundsÚ
max_roundsTF)r  r�   r¾   r  rÅ   )rJ   r·   Úsubclss      r!   Úmust_updatez!_PasslibHasherWrapper.must_updateñ  sI   € ð ×Òð ×)Ñ)×/Ñ/¸4¿;¹;ÐSW×S^ÑS^Ð/Ó_ˆFØ×"Ñ" 7Ô+ØØr    )NNN)r   r   r   r˜   r�   rC   r!  r   r  r)  rX   rº   rÃ   r/  r:  r?  r   r    r!   r`   r`   v  s†   „ ñð €Oò6ò(Jð ñOó ðOð ñ=ó ð=ð ñó ðð ñBó ðBò ò>ó&ò$"ó 
r    r`   c                   ó’   — e Zd ZdZdd„Zd„ ZexZZd„ Ze	d„ «       Z
efd„Zdd„Zdd	„Zdd
„Zd„ Zdd„Zed„ «       Zdd„Zdd„Zd„ Zy)r«   z4helper to manage monkeypatches and run sanity checksNc                 ó\   — |xs t        j                  t        dz   «      | _        i | _        y )Nz._PatchManager)r¤   r¥   r   r£   Ú_state)rJ   r£   s     r!   rC   z_PatchManager.__init__b  s(   € ð ÒHœ'×+Ñ+¬HÐ7GÑ,GÓHˆŒØˆ�r    c                 ó,   — t        | j                  «      S r9   )ÚboolrB  rO   s    r!   rð   z_PatchManager.isactiveh  s   € Ü�D—K‘KÓ Ð r    c                 ó¤   — |j                  d«      \  }}t        ||gd¬«      }d|v r&|j                  dd«      \  }}t        ||«      }d|v rŒ&||fS )z8retrieve obj and final attribute name from resource pathrÜ   r   )ÚfromlistÚlevelrj   r   )ÚsplitÚ
__import__r.   )rJ   r}   r1   r2   r  Úheads         r!   Ú_import_pathz_PatchManager._import_patho  s_   € à—Z‘Z “_‰
ˆˆdÜ˜¨¨°aÔ8ˆØ�T‰kØŸ
™
 3¨Ó*‰:ˆ4�Ü˜˜dÓ#ˆ3ð �TŠkð �DˆyÐr    c                 ó0   — t        | «      t        |«      k(  S )zAcheck if two values are the same (stripping method wrappers, etc))r   )ÚleftÚrights     r!   Ú_is_same_valuez_PatchManager._is_same_valuex  s   € ô # 4Ó(Ô,?ÀÓ,FÑFÐFr    c                 óD   — | j                  |«      \  }}t        |||«      S r9   )rK  r.   )rJ   r9  r‚   r  r2   s        r!   Ú	_get_pathz_PatchManager._get_path€  s%   € Ø×%Ñ% cÓ*‰	ˆˆTÜ�s˜D 'Ó*Ð*r    c                 ó&   — | j                  ||«      S )zreturn current value for path)rQ  )rJ   r}   r‚   s      r!   rn   z_PatchManager.get„  s   € à�~‰~˜d GÓ,Ð,r    c                 ó€   — 	 | j                   |   \  }}|t        u r|S |S # t        $ r | j                  |«      }Y Œ(w xY w)z*return original (unpatched) value for path)rB  r,   rQ  r  )rJ   r}   r‚   rê   r7  s        r!   ru   z_PatchManager.getorigˆ  sK   € ð	)Ø—k‘k $Ñ'‰HˆE�1ð  ¤6™/ˆwÐ4¨uÐ4øô ò 	)Ø—N‘N 4Ó(ŠEð	)ús   ‚   =¼=c                 óÒ   — | j                   }t        | j                  «      D ]C  \  }\  }} || j                  |«      |«      rŒ"d|z  }|rt	        |«      ‚t        |t        «       ŒE y)z:run sanity check on all keys, issue warning if out of syncz(another library has patched resource: %rN)rO  r   rB  rQ  rà   r   r   )rJ   ÚstrictÚsamer}   ÚorigÚexpectedÚmsgs          r!   Ú	check_allz_PatchManager.check_all�  sc   € à×"Ñ"ˆÜ&/°·±Ö&<Ñ"ˆDÑ"�4˜Ù�D—N‘N 4Ó(¨(Ô3ØØ<¸tÑCˆCÙÜ" 3Ó'Ð'ä�SÔ/Õ0ñ '=r    c                 óŠ   — | j                  |«      \  }}|t        u rt        ||«      rt        ||«       y y t	        |||«       y r9   )rK  r  r^   r  r  )rJ   r}   rê   r  r2   s        r!   Ú	_set_pathz_PatchManager._set_pathŸ  sD   € Ø×%Ñ% dÓ+‰	ˆˆTØ”F‰?Ü�s˜DÔ!Ü˜˜TÕ"ð "ô �C˜˜uÕ%r    c                 ó  ‡‡	— |t         k7  sJ ‚| j                  |«      }	 | j                  |   \  }}| j                  j	                  d|«       | j                  ||«      st        d|z  t        «       	 |r%t        |«      sJ ‚|Š|Š	ˆˆ	fd„}t        ||«       |}t        |«      r|t        |«      _        | j                  ||«       ||f| j                  |<   y# t        $ r! | j                  j	                  d|«       |}Y Œ�w xY w)zBmonkeypatch object+attr at <path> to have <value>, stores originalzmodifying resource: %rz4overridding resource another library has patched: %rzpatching resource: %rc                  ó   •—  ‰‰g| ¢­i |¤ŽS r9   r   )r:   r;   ÚwrappedÚ
wrapped_bys     €€r!   r=   z$_PatchManager.patch.<locals>.wrapper¹  s   ø€ Ù! 'Ð9¨DÒ9°DÑ9Ð9r    N)r  rQ  rB  r£   rá   rO  r   r   r,   r¦   r   r   Ú_patched_original_valuer\  )
rJ   r}   rê   ÚwrapÚcurrentrW  rX  r=   r_  r`  s
           @@r!   rä   z_PatchManager.patch§  sú   ù€ àœŠÐˆØ—.‘. Ó&ˆð		4Ø!Ÿ[™[¨Ñ.‰NˆD�(ð
 �H‰H�N‰NÐ3°TÔ:Ø×&Ñ& w°Ô9ÜÐKØñÜ2õ4áÜ˜E”?Ð"�?ØˆGØˆJõ:ä˜7 EÔ*ØˆEÜ�EŒ?àAEÔ Ó&Ô>Ø�‰�t˜UÔ#Ø! 5˜Mˆ�‰�DÒøô) ò 	Ø�H‰H�N‰NÐ2°DÔ9ØŠDð	ús    C Ã'DÄDc                 ó   — |j                   S r9   )ra  )r  rê   s     r!   r¬   z!_PatchManager.peek_unpatched_funcÃ  s   € à×,Ñ,Ð,r    c                 óR   ‡ ‡‡‡‡— ˆˆˆˆ ˆfd„}t        ‰«      r‰}dŠ ||«       y|S )zBfunction decorator which patches function of same name in <parent>c                 óp   •— ‰r2d‰v rdnd}‰|z   ‰xs | j                   z   }‰j                  || ‰¬«       | S )NrÜ   rj   )rb  )r   rä   )ÚfuncÚsepr}   Úenabler1   ÚparentrJ   rb  s      €€€€€r!   Úbuilderz*_PatchManager.monkeypatch.<locals>.builderÎ  sA   ø€ ÙØ  F™]‘c°�Ø ‘| tÒ'<¨t¯}©}Ñ=�Ø—
‘
˜4 ¨D�
Ô1ØˆKr    N)r¦   )rJ   rj  r1   ri  rb  rk  rg  s   `````  r!   Úmonkeypatchz_PatchManager.monkeypatchÌ  s/   ü€ ÷	ð 	ô �DŒ>àˆDØˆDÙ�DŒMØØˆr    c                 ór  — 	 | j                   |   \  }}| j                  |«      }| j                  j	                  d|«       | j                  ||«      s7|rt        d|z  t        «       n!t        d|z  t        «       | j                   |= y | j                  ||«       | j                   |= y # t        $ r Y y w xY w)Nzunpatching resource: %rz2reverting resource another library has patched: %rz6not reverting resource another library has patched: %r)	rB  r,   rQ  r£   rá   rO  r   r   r\  )rJ   r}   rí   rW  rX  rc  s         r!   Úunpatchz_PatchManager.unpatchß  sº   € ð	Ø!Ÿ[™[¨Ñ.‰NˆD�(ð —.‘. Ó&ˆØ�‰�‰Ð0°$Ô7Ø×"Ñ" 7¨HÔ5Ù ÜÐIØñÜ2õ4ô ÐMØñÜ2ô4à—K‘K Ð%ØØ�‰�t˜TÔ"Ø�K‰K˜Ñøô ò 	Ùð	ús   ‚B* Â*	B6Â5B6c                 ó^   — t        | j                  «      D ]  } | j                  |fi |¤Ž Œ y r9   )ÚlistrB  rn  )rJ   r;   r9  s      r!   rî   z_PatchManager.unpatch_allò  s(   € Ü˜Ÿ™Ö$ˆCØˆD�L‰L˜Ñ% Ó%ñ %r    r9   )F)NTFr—   )r   r   r   r˜   rC   rð   Ú__bool__Ú__nonzero__rK  ÚstaticmethodrO  r  rQ  rn   ru   rZ  r\  rä   Úclassmethodr¬   rl  rn  rî   r   r    r!   r«   r«   X  s|   „ Ù>óò!ð
 &Ð%€Hˆ{òð ñGó ðGð &,ó +ó-ó5ó
1ò&ó*ð8 ñ-ó ð-óó&ó&&r    r«   )2r˜   r¨   r   r   r¤   r¥   r   r£   rl   rE   Úwarningsr   Údjangor   r   rá   r©   r3   r   r	   Úpasslib.contextr
   Úpasslib.excr   Úpasslib.utils.compatr   r   r   r   Úpasslib.utils.decorr   Ú__all__r   r   r+   r   r*   rŽ   r†   Úsetr‡   r>   r   r@   rž   r,  r  r`   r  r«   r   r    r!   Ú<module>r}     s4  ðÙ E÷
 ,Û Ð'�g×'Ñ'¨Ó1�Û 
Û Ý ðÝ0Ø‡I�IÐ,¨nÔ=÷
 "Ý (Ý -ß UÓ UÝ 1ò€ð Ð ÷
:ñ 
:ð$ %Ø$Ø$Ø%ñ	€ò3ð: €ðN $Ð ð !Ð ñ ˜I˜;Ó'Ð òôLE�vô LEôjnÐ+ô nðn 1Ð ô �Fô  ô$E˜Fô Eñ@ 
‹€ô\&�Fõ \&øðS" ò Ø‡I�IÐ-Ô.Ø‚Nðús   °C ÃC6Ã5C6