ó
    ´æ¹iE¶  ã                   ób  • S r SSKJr  SSKr\R                  " \5      rSSKrSSKJ	r	  SSK
JrJr  SSKJr  SSKJr  SSKJr  SS	KJrJrJr  SS
KJr  SSKJrJrJrJr  SS/r\" 5       r Sr!Sr"Sr#Sr$Sr% " S S\5      r&\'" 5       r(S r)\)" 5       r*S r+\+" 5       r, " S S\&5      r- " S S\&5      r.g)z(passlib.apache - apache password supporté    )Úwith_statementN)Úwarn)ÚexcÚregistry)ÚCryptContext)ÚExpectedStringError)Úhtdigest)Úrender_bytesÚto_bytesÚis_ascii_codec)Údeprecated_method)Ú
join_bytesÚunicodeÚBytesIOÚPY3ÚHtpasswdFileÚHtdigestFileó   :ó   #s   :
	 ÚskippedÚrecordc                   ó  • \ rS rSrSrSrSrSrSrSr	Sr
Sr\S 5       r\S 5       rSSSSS\4S	 jrS
 r\S 5       r\R(                  S 5       r\S 5       rS rSS jrS rS rS rS rS rSS jrS rS rS r S r!S r"S S jr#S r$Sr%g)!Ú_CommonFileé,   z0common framework for HtpasswdFile & HtdigestFileNFc                 óZ   • SU;   a  [        S5      eU " S0 UD6nUR                  U5        U$ )zÆcreate new object from raw string.

:type data: unicode or bytes
:arg data:
    database to load, as single string.

:param \*\*kwds:
    all other keywords are the same as in the class constructor
Úpathz$'path' not accepted by from_string()© )Ú	TypeErrorÚload_string)ÚclsÚdataÚkwdsÚselfs       Ú_/home/gothic/Documentos/geniubs/sat/app/api/venv/lib/python3.13/site-packages/passlib/apache.pyÚfrom_stringÚ_CommonFile.from_stringK   s5   € ð �T‹>ÜÐBÓCÐCÙ‰{�T‰{ˆØ×Ñ˜ÔØˆó    c                 ó8   • U " S0 UD6nUR                  U5        U$ )zËcreate new object from file, without binding object to file.

:type path: str
:arg path:
    local filepath to load from

:param \*\*kwds:
    all other keywords are the same as in the class constructor
r   )Úload)r    r   r"   r#   s       r$   Ú	from_pathÚ_CommonFile.from_path\   s   € ñ ‰{�T‰{ˆØ�	‰	�$ŒØˆr'   Túutf-8c                 ó8  • U(       d  [        S[        SS9  SnSnO[        U5      (       d  [        S5      eXPl        X`l        X@l        Xl        SU l        U(       d  [        S[        SS9  S	nU(       a  U(       d  U R                  5         g 0 U l
        / U l        g )
Nz„``encoding=None`` is deprecated as of Passlib 1.6, and will cause a ValueError in Passlib 1.8, use ``return_unicode=False`` instead.é   ©Ú
stacklevelr,   Fz'encoding must be 7-bit ascii compatibler   zp``autoload=False`` is deprecated as of Passlib 1.6, and will be removed in Passlib 1.8, use ``new=True`` insteadT)r   ÚDeprecationWarningr   Ú
ValueErrorÚencodingÚreturn_unicodeÚautosaveÚ_pathÚ_mtimer)   Ú_recordsÚ_source)r#   r   ÚnewÚautoloadr5   r3   r4   s          r$   Ú__init__Ú_CommonFile.__init__n   s™   € ö Üð 9ô $°ò3ð ˆHØ"‰NÜ ×)Ñ)ô ÐFÓGÐGØ Œð -ÔØ ŒØŒ
ØˆŒö Üð Pä#°ò3ð ˆCÞžØ�I‰I�KàˆDŒMØˆD�Lr'   c                 ó  • SnU R                   (       a  US-  nU R                  (       a  USU R                  -  -  nU R                  S:w  a  USU R                  -  -  nSU R                  R                  [        U 5      U4-  $ )NÚ z autosave=Truez path=%rr,   z encoding=%rz<%s 0x%0x%s>)r5   r6   r3   Ú	__class__Ú__name__Úid)r#   Útails     r$   Ú__repr__Ú_CommonFile.__repr__‘   sr   € ØˆØ�=�=ØÐ$Ñ$ˆDØ�:�:Ø�J §¡Ñ+Ñ+ˆDØ�=‰=˜GÓ#Ø�N T§]¡]Ñ2Ñ2ˆDØ §¡×!8Ñ!8¼"¸T»(ÀDÐ IÑIÐIr'   c                 ó   • U R                   $ ©N)r6   ©r#   s    r$   r   Ú_CommonFile.path�   s   € à�z‰zÐr'   c                 ó<   • XR                   :w  a  SU l        Xl         g )Nr   )r6   r7   ©r#   Úvalues     r$   r   rI   ¡   s   € à—J‘JÓØˆDŒKØ�
r'   c                 ó   • U R                   $ )z7modify time when last loaded (if bound to a local file))r7   rH   s    r$   ÚmtimeÚ_CommonFile.mtime§   s   € ð �{‰{Ðr'   c                 óô   • U R                   (       d  [        SU -  5      eU R                  (       a8  U R                  [        R                  R                  U R                   5      :X  a  gU R                  5         g)zBReload from ``self.path`` only if file has changed since last loadz%r is not bound to a local fileFT)r6   ÚRuntimeErrorr7   Úosr   Úgetmtimer)   rH   s    r$   Úload_if_changedÚ_CommonFile.load_if_changed¯   sN   € à�z�zÜÐ@À4ÑGÓHÐHØ�;�;˜4Ÿ;™;¬"¯'©'×*:Ñ*:¸4¿:¹:Ó*FÓFØØ�	‰	ŒØr'   c                 óT  • Ub.  [        US5       nSU l        U R                  U5        SSS5        g	U(       d=  [        S[	        U R
                  R                  S9-  [        SS9  U R                  5       $ U R                  (       a_  [        U R                  S5       n[        R                  R                  U R                  5      U l        U R                  U5        SSS5        g	[        SU R
                  R                  -  5      e! , (       d  f       g	= f! , (       d  f       g	= f)
aœ  Load state from local file.
If no path is specified, attempts to load from ``self.path``.

:type path: str
:arg path: local file to load from

:type force: bool
:param force:
    if ``force=False``, only load from ``self.path`` if file
    has changed since last load.

    .. deprecated:: 1.6
        This keyword will be removed in Passlib 1.8;
        Applications should use :meth:`load_if_changed` instead.
NÚrbr   z†%(name)s.load(force=False) is deprecated as of Passlib 1.6,and will be removed in Passlib 1.8; use %(name)s.load_if_changed() instead.)Únamer.   r/   z2%s().path is not set, an explicit path is requiredT)Úopenr7   Ú_load_linesr   Údictr@   rA   r1   rT   r6   rR   r   rS   rQ   )r#   r   ÚforceÚfhs       r$   r)   Ú_CommonFile.load¸   s  € ð  ÑÜ�d˜DÔ! RØ�”Ø× Ñ  Ô$÷ "ð" ö Üð ;ô ˜4Ÿ>™>×2Ñ2Ñ3ñ4ô $°ò	3ð
 ×'Ñ'Ó)Ð)Ø�Z�ZÜ�d—j‘j $Ô'¨2Ü Ÿg™g×.Ñ.¨t¯z©zÓ:�”Ø× Ñ  Ô$÷ (ð ô ÐSØ#Ÿ~™~×6Ñ6ñ 7ó 8ð 8÷ "Ô!ð" ú÷ (Ô'ð ús   �DÂA DÄ
DÄ
D'c                 ór   • [        XR                  S5      nSU l        U R                  [	        U5      5        g)z@Load state from unicode or bytes string, replacing current stater!   r   N)r   r3   r7   rZ   r   )r#   r!   s     r$   r   Ú_CommonFile.load_stringÜ   s+   € ä˜Ÿm™m¨VÓ4ˆØˆŒØ×Ñœ ›Õ'r'   c                 ó  • U R                   n0 n/ nSn[        U5       H§  u  pgUR                  5       nU(       a  UR                  [        5      (       a  XW-  nM<  U" XvS-   5      u  pšX“;   a  [
        R                  SU	-  5        XW-  nMl  U(       a  UR                  [        U45        SnX£U	'   UR                  [        U	45        M©     UR                  5       (       a  UR                  [        U45        X0l        X@l        g)zload from sequence of listsr'   é   z1username occurs multiple times in source file: %rN)Ú_parse_recordÚ	enumerateÚlstripÚ
startswithÚ_BHASHÚlogÚwarningÚappendÚ_SKIPPEDÚ_RECORDÚrstripr8   r9   )r#   ÚlinesÚparseÚrecordsÚsourcer   ÚidxÚlineÚtmpÚkeyrL   s              r$   rZ   Ú_CommonFile._load_linesâ   së   € à×"Ñ"ˆØˆØˆØˆÜ" 5Ö)‰IˆCð —+‘+“-ˆCÞ˜#Ÿ.™.¬×0Ñ0Ø‘�Ùñ ˜t¨¡UÓ+‰JˆCð ‹~Ü—‘ÐOÐRUÑUÔVØ‘�Ùö Ø—‘œx¨Ð1Ô2Ø�ð !�C‰LØ�M‰Mœ7 C˜.Ö)ñ5 *ð: �>‰>×ÑØ�M‰Mœ8 WÐ-Ô.ð  ŒØ�r'   c                 ó   • [        S5      e)z)parse line of file into (key, value) pairú!should be implemented in subclass©ÚNotImplementedError)r#   r   Úlinenos      r$   rc   Ú_CommonFile._parse_record  ó   € ä!Ð"EÓFÐFr'   c                 ó~   • U R                   nX;   nX#U'   U(       d!  U R                  R                  [        U45        U$ )z{
helper for setting record which takes care of inserting source line if needed;

:returns:
    bool if key already present
)r8   r9   rj   rl   )r#   ru   rL   rp   Úexistings        r$   Ú_set_recordÚ_CommonFile._set_record  s9   € ð —-‘-ˆØ‘NˆØ�‰ÞØ�L‰L×Ñ¤¨# Ô/Øˆr'   c                 ól   • U R                   (       a#  U R                  (       a  U R                  5         ggg)z0subclass helper to call save() after any changesN)r5   r6   ÚsaverH   s    r$   Ú	_autosaveÚ_CommonFile._autosave!  s   € à�=�=˜TŸZŸZØ�I‰I�Kð (ˆ=r'   c                 óŽ  • Ub5  [        US5       nUR                  U R                  5       5        SSS5        gU R                  (       aJ  U R	                  U R                  5        [
        R                  R                  U R                  5      U l        g[        SU R                  R                  -  5      e! , (       d  f       g= f)zXSave current state to file.
If no path is specified, attempts to save to ``self.path``.
NÚwbz%%s().path is not set, cannot autosave)rY   Ú
writelinesÚ_iter_linesr6   rƒ   rR   r   rS   r7   rQ   r@   rA   )r#   r   r]   s      r$   rƒ   Ú_CommonFile.save&  s�   € ð ÑÜ�d˜DÔ! RØ—‘˜d×.Ñ.Ó0Ô1÷ "Ð!à�Z�ZØ�I‰I�d—j‘jÔ!ÜŸ'™'×*Ñ*¨4¯:©:Ó6ˆD�KäÐFØ#Ÿ~™~×6Ñ6ñ 7ó 8ð 8÷ "Õ!ús   � B6Â6
Cc                 ó4   • [        U R                  5       5      $ )z)Export current state as a string of bytes)r   r‰   rH   s    r$   Ú	to_stringÚ_CommonFile.to_string4  s   € ä˜$×*Ñ*Ó,Ó-Ð-r'   c              #   ó"  #   • U R                   n [        U5      nU R                   HP  u  p4U[        :X  a  Uv •  M  U[        :X  d   eXA;  a  M(  U R                  XAU   5      v •   UR                  U5        MR      U(       a   SU< 35       eg7f)z#iterator yielding lines of databasez%failed to write all records: missing=N)r8   Úsetr9   rk   rl   Ú_render_recordÚremove)r#   rp   ÚpendingÚactionÚcontents        r$   r‰   Ú_CommonFile._iter_lines@  s�   é € ð —-‘-ˆØÜ˜'“lˆGØ#Ÿ|œ|‰OˆFØœÓ!à”à¤Ó(Ð(Ð(àÓ)ñ Ø×)Ñ)¨'¸7Ñ3CÓDÒDØØ—N‘N 7Ö+ñ  ,ð ö ÑVÊWÐ VÓV�;�wùs   ‚BBc                 ó   • [        S5      e)z,given key/value pair, encode as line of filerx   ry   )r#   ru   rL   s      r$   r�   Ú_CommonFile._render_record[  r}   r'   c                 ó&   • U R                  US5      $ )z)user-specific wrapper for _encode_field()Úuser©Ú_encode_field©r#   r™   s     r$   Ú_encode_userÚ_CommonFile._encode_userb  s   € à×!Ñ! $¨Ó/Ð/r'   c                 ó&   • U R                  US5      $ )z*realm-specific wrapper for _encode_field()Úrealmrš   ©r#   r    s     r$   Ú_encode_realmÚ_CommonFile._encode_realmf  s   € à×!Ñ! %¨Ó1Ð1r'   c                 ó<  • [        U[        5      (       a  UR                  U R                  5      nO [        U[        5      (       d  [        X5      e[        U5      S:”  a  [        U< SU< 35      e[        S U 5       5      (       a  [        U< SU< 35      eU$ )aÓ  convert field to internal representation.

internal representation is always bytes. byte strings are left as-is,
unicode strings encoding using file's default encoding (or ``utf-8``
if no encoding has been specified).

:raises UnicodeEncodeError:
    if unicode value cannot be encoded using default encoding.

:raises ValueError:
    if resulting byte string contains a forbidden character,
    or is too long (>255 bytes).

:returns:
    encoded identifer as bytes
éÿ   z! must be at most 255 characters: c              3   ó2   #   • U  H  o[         ;   v •  M     g 7frG   )Ú_INVALID_FIELD_CHARS)Ú.0Úcs     r$   Ú	<genexpr>Ú,_CommonFile._encode_field.<locals>.<genexpr>‚  s   é € Ð8²%¨QÔ(Ö(²%ùs   ‚z contains invalid characters: )	Ú
isinstancer   Úencoder3   Úbytesr   Úlenr2   Úany)r#   rL   Úparams      r$   r›   Ú_CommonFile._encode_fieldj  s‹   € ô" �eœW×%Ñ%Ø—L‘L §¡Ó/‰EÜ˜E¤5×)Ñ)Ü% eÓ3Ð3Üˆu‹:˜ÓÜÛ#¢Uð,ó -ð -äÑ8±%Ó8×8Ñ8ÜÛ#¢Uð-ó .ð .àˆr'   c                 ó–   • [        U[        5      (       d   S5       eU R                  (       a  UR                  U R                  5      $ U$ )a  decode field from internal representation to format
returns by users() method, etc.

:raises UnicodeDecodeError:
    if unicode value cannot be decoded using default encoding.
    (usually indicates wrong encoding set for file).

:returns:
    field as unicode or bytes, as appropriate.
zexpected value to be bytes)r¬   r®   r4   Údecoder3   rK   s     r$   Ú_decode_fieldÚ_CommonFile._decode_field‡  s>   € ô ˜%¤×'Ñ'ÐEÐ)EÓEÐ'Ø××Ø—<‘< §¡Ó.Ð.àˆLr'   )r7   r6   r8   r9   r5   r3   r4   )NTrG   )Úfield)&rA   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r3   r4   r6   r7   r5   r8   r9   Úclassmethodr%   r*   r   r<   rD   Úpropertyr   ÚsetterrN   rT   r)   r   rZ   rc   r€   r„   rƒ   rŒ   r‰   r�   r�   r¢   r›   rµ   Ú__static_attributes__r   r'   r$   r   r   ,   s  † Ù:ð €Hð €Nð €EØ€Fð €Hð €Hð €Gð
 ñó ðð  ñó ðð" ! e°dÀUØ!°#ô!òFJð ñó ðð 
‡[�[ñó ðð
 ñó ðòô"òH(ò(òTGòò"ô
8ò.òWò6Gò0ò2ôõ:r'   r   c            	      óž  • S n S H"  n[         R                  " U5      (       d  M   Un   O   [         R                  " S5      (       a  SOS n[        R	                  5         U(       d  [        R                  / SQ5        [        U=(       d    SSU=(       d    U =(       d    SU =(       d    SU=(       d    SSS9nUR                  US   US   S	9  U$ )
N)ÚbcryptÚsha256_cryptrÁ   )Úportable_apache_24Úhost_apache_24Úlinux_apache_24ÚportableÚhostÚapr_md5_cryptrÂ   )rÃ   Úportable_apache_22rÄ   Úhost_apache_22rÅ   Úlinux_apache_22rÃ   rÄ   )rÆ   rÇ   )r   Úhas_os_crypt_supportÚhas_backendÚ_warn_no_bcryptÚclearÚupdater[   )Ú	host_bestrX   rÁ   Údefaultss       r$   Ú_init_default_schemesrÓ   ³  sÐ   € ð €IÛ*ˆÜ×(Ò(¨×.Ó.ØˆIÙñ +ô "×-Ò-¨h×7Ñ7‰X¸T€FÜ×ÑÔÞÜ×Ñò  Gô 	Hô à!×4 _Ø*ð ×= ×=¨oØ ×3 Oð ×0 .Ø&ñ€Hð" ‡O�OØÐ.Ñ/ØÐ&Ñ'ð ñ ð €Or'   c                  óÈ   • / SQn U R                  [        R                  " 5       5        U S S S/-   U -   n[        [	        U 5      UR
                  S9n [        U [        S   SS9$ )N)rÁ   rÂ   Úsha512_cryptÚ	des_cryptrÈ   Ú	ldap_sha1Ú	plaintexté   rÈ   )ru   rÉ   Ú2y)ÚschemesÚdefaultÚbcrypt__ident)Úextendr   Úget_supported_os_crypt_schemesÚsortedr�   Úindexr   Úhtpasswd_defaults)rÛ   Ú	preferreds     r$   Ú_init_htpasswd_contexträ   Þ  sp   € ò€Gð0 ‡N�N”8×:Ò:Ó<Ô=ð ˜˜�˜Ð/Ñ/°'Ñ9€IÜ”S˜“\ y§¡Ñ7€Gô Øô "Ð"6Ñ7ð ñð r'   c                   óº   ^ • \ rS rSrSrSS\4U 4S jjrS rS rS r	S r
\" S	S
SS9S 5       rS rS r\" S	S
SS9S 5       rS rS r\" S	S
SS9S 5       rSrU =r$ )r   i  aÓ  class for reading & writing Htpasswd files.

The class constructor accepts the following arguments:

:type path: filepath
:param path:

    Specifies path to htpasswd file, use to implicitly load from and save to.

    This class has two modes of operation:

    1. It can be "bound" to a local file by passing a ``path`` to the class
       constructor. In this case it will load the contents of the file when
       created, and the :meth:`load` and :meth:`save` methods will automatically
       load from and save to that file if they are called without arguments.

    2. Alternately, it can exist as an independant object, in which case
       :meth:`load` and :meth:`save` will require an explicit path to be
       provided whenever they are called. As well, ``autosave`` behavior
       will not be available.

       This feature is new in Passlib 1.6, and is the default if no
       ``path`` value is provided to the constructor.

    This is also exposed as a readonly instance attribute.

:type new: bool
:param new:

    Normally, if *path* is specified, :class:`HtpasswdFile` will
    immediately load the contents of the file. However, when creating
    a new htpasswd file, applications can set ``new=True`` so that
    the existing file (if any) will not be loaded.

    .. versionadded:: 1.6
        This feature was previously enabled by setting ``autoload=False``.
        That alias has been deprecated, and will be removed in Passlib 1.8

:type autosave: bool
:param autosave:

    Normally, any changes made to an :class:`HtpasswdFile` instance
    will not be saved until :meth:`save` is explicitly called. However,
    if ``autosave=True`` is specified, any changes made will be
    saved to disk immediately (assuming *path* has been set).

    This is also exposed as a writeable instance attribute.

:type encoding: str
:param encoding:

    Optionally specify character encoding used to read/write file
    and hash passwords. Defaults to ``utf-8``, though ``latin-1``
    is the only other commonly encountered encoding.

    This is also exposed as a readonly instance attribute.

:type default_scheme: str
:param default_scheme:
    Optionally specify default scheme to use when encoding new passwords.

    This can be any of the schemes with builtin Apache support,
    OR natively supported by the host OS's :func:`crypt.crypt` function.

    * Builtin schemes include ``"bcrypt"`` (apache 2.4+), ``"apr_md5_crypt"`,
      and ``"des_crypt"``.

    * Schemes commonly supported by Unix hosts
      include ``"bcrypt"``, ``"sha256_crypt"``, and ``"des_crypt"``.

    In order to not have to sort out what you should use,
    passlib offers a number of aliases, that will resolve
    to the most appropriate scheme based on your needs:

    * ``"portable"``, ``"portable_apache_24"`` -- pick scheme that's portable across hosts
      running apache >= 2.4. **This will be the default as of Passlib 2.0**.

    * ``"portable_apache_22"`` -- pick scheme that's portable across hosts
      running apache >= 2.4. **This is the default up to Passlib 1.9**.

    * ``"host"``, ``"host_apache_24"`` -- pick strongest scheme supported by
       apache >= 2.4 and/or host OS.

    * ``"host_apache_22"`` -- pick strongest scheme supported by
       apache >= 2.2 and/or host OS.

    .. versionadded:: 1.6
        This keyword was previously named ``default``. That alias
        has been deprecated, and will be removed in Passlib 1.8.

    .. versionchanged:: 1.6.3

        Added support for ``"bcrypt"``, ``"sha256_crypt"``, and ``"portable"`` alias.

    .. versionchanged:: 1.7

        Added apache 2.4 semantics, and additional aliases.

:type context: :class:`~passlib.context.CryptContext`
:param context:
    :class:`!CryptContext` instance used to create
    and verify the hashes found in the htpasswd file.
    The default value is a pre-built context which supports all
    of the hashes officially allowed in an htpasswd file.

    This is also exposed as a readonly instance attribute.

    .. warning::

        This option may be used to add support for non-standard hash
        formats to an htpasswd file. However, the resulting file
        will probably not be usable by another application,
        and particularly not by Apache.

:param autoload:
    Set to ``False`` to prevent the constructor from automatically
    loaded the file from disk.

    .. deprecated:: 1.6
        This has been replaced by the *new* keyword.
        Instead of setting ``autoload=False``, you should use
        ``new=True``. Support for this keyword will be removed
        in Passlib 1.8.

:param default:
    Change the default algorithm used to hash new passwords.

    .. deprecated:: 1.6
        This has been renamed to *default_scheme* for clarity.
        Support for this alias will be removed in Passlib 1.8.

Loading & Saving
================
.. automethod:: load
.. automethod:: load_if_changed
.. automethod:: load_string
.. automethod:: save
.. automethod:: to_string

Inspection
================
.. automethod:: users
.. automethod:: check_password
.. automethod:: get_hash

Modification
================
.. automethod:: set_password
.. automethod:: delete

Alternate Constructors
======================
.. automethod:: from_string

Attributes
==========
.. attribute:: path

    Path to local file that will be used as the default
    for all :meth:`load` and :meth:`save` operations.
    May be written to, initialized by the *path* constructor keyword.

.. attribute:: autosave

    Writeable flag indicating whether changes will be automatically
    written to *path*.

Errors
======
:raises ValueError:
    All of the methods in this class will raise a :exc:`ValueError` if
    any user name contains a forbidden character (one of ``:\r\n\t\x00``),
    or is longer than 255 characters.
Nc                 ó,  >• SU;   a   [        S[        SS9  UR                  S5      nU(       aK  U[        ;   a  [        SU-  [        R
                  5        [        R                  X"5      nUR                  US9nX0l	        [        [        U ]2  " U40 UD6  g )NrÜ   z{``default`` is deprecated as of Passlib 1.6, and will be removed in Passlib 1.8, it has been renamed to ``default_scheem``.r.   r/   zPHtpasswdFile: no bcrypt backends available, using fallback for default scheme %r)rÜ   )r   r1   ÚpoprÎ   r   ÚPasslibSecurityWarningrâ   ÚgetÚcopyÚcontextÚsuperr   r<   )r#   r   Údefault_schemerë   r"   r@   s        €r$   r<   ÚHtpasswdFile.__init__Ê  s”   ø€ à˜ÓÜð *ô $°ò3ð "ŸX™X iÓ0ˆNÞØ¤Ó0Üð <Ø>LñMä×/Ñ/ô1ô /×2Ñ2°>ÓRˆNØ—l‘l¨>�lÐ:ˆGØŒÜŒl˜DÒ*¨4Ñ8°4Ó8r'   c                 ó†   • UR                  5       R                  [        5      n[        U5      S:w  a  [	        SU-  5      eU$ )Nr.   z/malformed htpasswd file (error reading line %d)©rm   ÚsplitÚ_BCOLONr¯   r2   )r#   r   r{   Úresults       r$   rc   ÚHtpasswdFile._parse_recordÜ  sA   € à—‘“×&Ñ&¤wÓ/ˆÜˆv‹;˜!ÓÜÐNØ%ñ&ó 'ð 'àˆr'   c                 ó   • [        SX5      $ )Nz%s:%s
©r
   )r#   r™   Úhashs      r$   r�   ÚHtpasswdFile._render_recordä  s   € Ü˜I tÓ2Ð2r'   c                 ób   • U R                    Vs/ s H  oR                  U5      PM     sn$ s  snf )z&
Return list of all users in database
)r8   rµ   rœ   s     r$   ÚusersÚHtpasswdFile.usersë  s)   € ð 6:·]²]ÓC²]¨T×"Ñ" 4Ö(±]ÑCÐCùÒCs   �,c                 óZ   • U R                   R                  U5      nU R                  X5      $ )ac  Set password for user; adds user if needed.

:returns:
    * ``True`` if existing user was updated.
    * ``False`` if user account was added.

.. versionchanged:: 1.6
    This method was previously called ``update``, it was renamed
    to prevent ambiguity with the dictionary method.
    The old alias is deprecated, and will be removed in Passlib 1.8.
)rë   r÷   Úset_hash)r#   r™   Úpasswordr÷   s       r$   Úset_passwordÚHtpasswdFile.set_passwordý  s'   € ð �|‰|× Ñ  Ó*ˆØ�}‰}˜TÓ(Ð(r'   ú1.6ú1.8rÿ   ©Ú
deprecatedÚremovedÚreplacementc                 ó$   • U R                  X5      $ ©zset password for user©rÿ   ©r#   r™   rþ   s      r$   rÐ   ÚHtpasswdFile.update  s   € ð × Ñ  Ó0Ð0r'   c                 ó`   •  U R                   U R                  U5         $ ! [         a     gf = f)zèReturn hash stored for user, or ``None`` if user not found.

.. versionchanged:: 1.6
    This method was previously named ``find``, it was renamed
    for clarity. The old name is deprecated, and will be removed
    in Passlib 1.8.
N)r8   r�   ÚKeyErrorrœ   s     r$   Úget_hashÚHtpasswdFile.get_hash  s3   € ð	Ø—=‘= ×!2Ñ!2°4Ó!8Ñ9Ð9øÜó 	Ùð	ús   ‚   
-¬-c                 óà   • [         (       a0  [        U[        5      (       a  UR                  U R                  5      nU R                  U5      nU R                  X5      nU R                  5         U$ )z³
semi-private helper which allows writing a hash directly;
adds user if needed.

.. warning::
    does not (currently) do any validation of the hash string

.. versionadded:: 1.7
)r   r¬   Ústrr­   r3   r�   r€   r„   )r#   r™   r÷   r   s       r$   rý   ÚHtpasswdFile.set_hash  sV   € ÷ Š3”:˜d¤C×(Ñ(Ø—;‘;˜tŸ}™}Ó-ˆDØ× Ñ  Ó&ˆØ×#Ñ# DÓ/ˆØ�‰ÔØˆr'   r  c                 ó$   • U R                  U5      $ ©zreturn hash for user©r  rœ   s     r$   ÚfindÚHtpasswdFile.find1  s   € ð �}‰}˜TÓ"Ð"r'   c                 ó~   •  U R                   U R                  U5      	 U R                  5         g! [         a     gf = f)zcDelete user's entry.

:returns:
    * ``True`` if user deleted.
    * ``False`` if user not found.
FT)r8   r�   r  r„   rœ   s     r$   ÚdeleteÚHtpasswdFile.delete8  sA   € ð	Ø—‘˜d×/Ñ/°Ó5Ð6ð 	�‰ÔØøô ó 	Ùð	ús   ‚/ ¯
<»<c                 ór  • U R                  U5      nU R                  R                  U5      nUc  g[        U[        5      (       a  UR                  U R                  5      nU R                  R                  X#5      u  pEU(       a2  Ub/  XR                  ;   d   eXPR                  U'   U R                  5         U$ )aõ  
Verify password for specified user.
If algorithm marked as deprecated by CryptContext, will automatically be re-hashed.

:returns:
    * ``None`` if user not found.
    * ``False`` if user found, but password does not match.
    * ``True`` if user found and password matches.

.. versionchanged:: 1.6
    This method was previously called ``verify``, it was renamed
    to prevent ambiguity with the :class:`!CryptContext` method.
    The old alias is deprecated, and will be removed in Passlib 1.8.
N)
r�   r8   ré   r¬   r   r­   r3   rë   Úverify_and_updater„   )r#   r™   rþ   r÷   ÚokÚnew_hashs         r$   Úcheck_passwordÚHtpasswdFile.check_passwordF  sš   € ð × Ñ  Ó&ˆØ�}‰}× Ñ  Ó&ˆØ‰<ØÜ�h¤×(Ñ(ð  —‘ t§}¡}Ó5ˆHØ—|‘|×5Ñ5°hÓE‰ˆÞ�(Ñ&àŸ=™=Ó(Ð(Ð(Ø"*�M‰M˜$ÑØ�N‰NÔØˆ	r'   r  c                 ó$   • U R                  X5      $ ©zverify password for user©r  r
  s      r$   ÚverifyÚHtpasswdFile.verifye  s   € ð ×"Ñ" 4Ó2Ð2r'   )rë   )rA   r¸   r¹   rº   r»   Úhtpasswd_contextr<   rc   r�   rú   rÿ   r   rÐ   r  rý   r  r  r  r$  r¿   Ú__classcell__©r@   s   @r$   r   r     s¢   ø† ñmðp !°Ð?O÷ 9ò$ò3òDò$)ñ  %°Ø#1ñ3ñ1ó3ð1òòñ$  %°Ø#-ñ/ñ#ó/ð#ò
òñ>  %°Ø#3ñ5ñ3ó5ö3r'   c                   óú   ^ • \ rS rSrSrSrSU 4S jjrS rS rS r	S r
S	 rS
 rSS jrS\4S jr\" SSSS9S 5       rSS jrS\4S jr\" SSSS9S 5       rSS jrS rS\4S jr\" SSSS9S 5       rSrU =r$ )r   ir  aN  class for reading & writing Htdigest files.

The class constructor accepts the following arguments:

:type path: filepath
:param path:

    Specifies path to htdigest file, use to implicitly load from and save to.

    This class has two modes of operation:

    1. It can be "bound" to a local file by passing a ``path`` to the class
       constructor. In this case it will load the contents of the file when
       created, and the :meth:`load` and :meth:`save` methods will automatically
       load from and save to that file if they are called without arguments.

    2. Alternately, it can exist as an independant object, in which case
       :meth:`load` and :meth:`save` will require an explicit path to be
       provided whenever they are called. As well, ``autosave`` behavior
       will not be available.

       This feature is new in Passlib 1.6, and is the default if no
       ``path`` value is provided to the constructor.

    This is also exposed as a readonly instance attribute.

:type default_realm: str
:param default_realm:

    If ``default_realm`` is set, all the :class:`HtdigestFile`
    methods that require a realm will use this value if one is not
    provided explicitly. If unset, they will raise an error stating
    that an explicit realm is required.

    This is also exposed as a writeable instance attribute.

    .. versionadded:: 1.6

:type new: bool
:param new:

    Normally, if *path* is specified, :class:`HtdigestFile` will
    immediately load the contents of the file. However, when creating
    a new htpasswd file, applications can set ``new=True`` so that
    the existing file (if any) will not be loaded.

    .. versionadded:: 1.6
        This feature was previously enabled by setting ``autoload=False``.
        That alias has been deprecated, and will be removed in Passlib 1.8

:type autosave: bool
:param autosave:

    Normally, any changes made to an :class:`HtdigestFile` instance
    will not be saved until :meth:`save` is explicitly called. However,
    if ``autosave=True`` is specified, any changes made will be
    saved to disk immediately (assuming *path* has been set).

    This is also exposed as a writeable instance attribute.

:type encoding: str
:param encoding:

    Optionally specify character encoding used to read/write file
    and hash passwords. Defaults to ``utf-8``, though ``latin-1``
    is the only other commonly encountered encoding.

    This is also exposed as a readonly instance attribute.

:param autoload:
    Set to ``False`` to prevent the constructor from automatically
    loaded the file from disk.

    .. deprecated:: 1.6
        This has been replaced by the *new* keyword.
        Instead of setting ``autoload=False``, you should use
        ``new=True``. Support for this keyword will be removed
        in Passlib 1.8.

Loading & Saving
================
.. automethod:: load
.. automethod:: load_if_changed
.. automethod:: load_string
.. automethod:: save
.. automethod:: to_string

Inspection
==========
.. automethod:: realms
.. automethod:: users
.. automethod:: check_password(user[, realm], password)
.. automethod:: get_hash

Modification
============
.. automethod:: set_password(user[, realm], password)
.. automethod:: delete
.. automethod:: delete_realm

Alternate Constructors
======================
.. automethod:: from_string

Attributes
==========
.. attribute:: default_realm

    The default realm that will be used if one is not provided
    to methods that require it. By default this is ``None``,
    in which case an explicit realm must be provided for every
    method call. Can be written to.

.. attribute:: path

    Path to local file that will be used as the default
    for all :meth:`load` and :meth:`save` operations.
    May be written to, initialized by the *path* constructor keyword.

.. attribute:: autosave

    Writeable flag indicating whether changes will be automatically
    written to *path*.

Errors
======
:raises ValueError:
    All of the methods in this class will raise a :exc:`ValueError` if
    any user name or realm contains a forbidden character (one of ``:\r\n\t\x00``),
    or is longer than 255 characters.
Nc                 ó<   >• X l         [        [        U ]  " U40 UD6  g rG   )Údefault_realmrì   r   r<   )r#   r   r+  r"   r@   s       €r$   r<   ÚHtdigestFile.__init__  s   ø€ Ø*ÔÜŒl˜DÒ*¨4Ñ8°4Ó8r'   c                 ó–   • UR                  5       R                  [        5      n[        U5      S:w  a  [	        SU-  5      eUu  pEnXE4U4$ )NrÙ   z/malformed htdigest file (error reading line %d)rð   )r#   r   r{   ró   r™   r    r÷   s          r$   rc   ÚHtdigestFile._parse_record  sS   € Ø—‘“×&Ñ&¤wÓ/ˆÜˆv‹;˜!ÓÜÐNØ%ñ&ó 'ð 'à"Ñˆ�TØˆ}˜dÐ"Ð"r'   c                 ó$   • Uu  p4[        SX4U5      $ )Nz	%s:%s:%s
rö   )r#   ru   r÷   r™   r    s        r$   r�   ÚHtdigestFile._render_record  s   € Ø‰ˆÜ˜L¨$°tÓ<Ð<r'   c                 ó@   • Uc  U R                   nUc  [        S5      eU$ )NzGyou must specify a realm explicitly, or set the default_realm attribute)r+  r   r¡   s     r$   Ú_require_realmÚHtdigestFile._require_realm  s1   € Ø‰=Ø×&Ñ&ˆEØ‰}Üð !Eó Fð Fàˆr'   c                 óH   • U R                  U5      nU R                  US5      $ )Nr    )r2  r›   r¡   s     r$   r¢   ÚHtdigestFile._encode_realm  s%   € Ø×#Ñ# EÓ*ˆØ×!Ñ! %¨Ó1Ð1r'   c                 óF   • U R                  U5      U R                  U5      4$ rG   )r�   r¢   ©r#   r™   r    s      r$   Ú_encode_keyÚHtdigestFile._encode_key#  s#   € Ø× Ñ  Ó&¨×(:Ñ(:¸5Ó(AÐAÐAr'   c                 ó†   • [        S U R                   5       5      nU Vs/ s H  o R                  U5      PM     sn$ s  snf )z%Return list of all realms in databasec              3   ó*   #   • U  H	  oS    v •  M     g7f)rb   Nr   )r¨   ru   s     r$   rª   Ú&HtdigestFile.realms.<locals>.<genexpr>,  s   é € Ð5¢} ˜–V¢}ùs   ‚)r�   r8   rµ   )r#   Úrealmsr    s      r$   r=  ÚHtdigestFile.realms*  s7   € äÑ5 t§}¢}Ó5Ó5ˆÙ7=Ó>²v¨e×"Ñ" 5Ö)±vÑ>Ð>ùÒ>s   ¡>c                 ó¢   • U R                  U5      nU R                   Vs/ s H"  nUS   U:X  d  M  U R                  US   5      PM$     sn$ s  snf )z–Return list of all users in specified realm.

* uses ``self.default_realm`` if no realm explicitly provided.
* returns empty list if realm not found.
rb   r   )r¢   r8   rµ   )r#   r    ru   s      r$   rú   ÚHtdigestFile.users/  sW   € ð ×"Ñ" 5Ó)ˆØ6:·m²mó $²m¨sØ�q‘6˜U‘?ó +�×"Ñ" 3 q¡6Ö*±mñ $ð 	$ùò $s
    A±Ac                 óž   • U[         L a  SUp2U R                  U5      n[        R                  " X1X R                  S9nU R                  XU5      $ )a_  Set password for user; adds user & realm if needed.

If ``self.default_realm`` has been set, this may be called
with the syntax ``set_password(user, password)``,
otherwise it must be called with all three arguments:
``set_password(user, realm, password)``.

:returns:
    * ``True`` if existing user was updated
    * ``False`` if user account added.
N©r3   )Ú_UNSETr2  r	   r÷   r3   rý   ©r#   r™   r    rþ   r÷   s        r$   rÿ   ÚHtdigestFile.set_passwordQ  sH   € ð ”vÒà" E�8Ø×#Ñ# EÓ*ˆÜ�}Š}˜X¨U¿]¹]ÑKˆØ�}‰}˜T¨$Ó/Ð/r'   r  r  rÿ   r  c                 ó&   • U R                  XU5      $ r  r	  ©r#   r™   r    rþ   s       r$   rÐ   ÚHtdigestFile.updated  s   € ð × Ñ  ¨hÓ7Ð7r'   c                 ó²   • U R                  X5      nU R                  R                  U5      nUc  g[        (       a  UR	                  U R
                  5      nU$ )aX  Return :class:`~passlib.hash.htdigest` hash stored for user.

* uses ``self.default_realm`` if no realm explicitly provided.
* returns ``None`` if user or realm not found.

.. versionchanged:: 1.6
    This method was previously named ``find``, it was renamed
    for clarity. The old name is deprecated, and will be removed
    in Passlib 1.8.
N)r8  r8   ré   r   r´   r3   )r#   r™   r    ru   r÷   s        r$   r  ÚHtdigestFile.get_hashj  sL   € ð ×Ñ˜tÓ+ˆØ�}‰}× Ñ  Ó%ˆØ‰<ØßŠ3Ø—;‘;˜tŸ}™}Ó-ˆDØˆr'   c                 óø   • U[         L a  SUp2[        (       a0  [        U[        5      (       a  UR	                  U R
                  5      nU R                  X5      nU R                  XC5      nU R                  5         U$ )ax  
semi-private helper which allows writing a hash directly;
adds user & realm if needed.

If ``self.default_realm`` has been set, this may be called
with the syntax ``set_hash(user, hash)``,
otherwise it must be called with all three arguments:
``set_hash(user, realm, hash)``.

.. warning::
    does not (currently) do any validation of the hash string

.. versionadded:: 1.7
N)	rC  r   r¬   r  r­   r3   r8  r€   r„   )r#   r™   r    r÷   ru   r   s         r$   rý   ÚHtdigestFile.set_hash}  sd   € ð ”6Š>à �4çŠ3”:˜d¤C×(Ñ(Ø—;‘;˜tŸ}™}Ó-ˆDØ×Ñ˜tÓ+ˆØ×#Ñ# CÓ.ˆØ�‰ÔØˆr'   r  c                 ó$   • U R                  X5      $ r  r  r7  s      r$   r  ÚHtdigestFile.find—  s   € ð �}‰}˜TÓ)Ð)r'   c                 ó‚   • U R                  X5      n U R                  U	 U R                  5         g! [         a     gf = f)z¹Delete user's entry for specified realm.

if realm is not specified, uses ``self.default_realm``.

:returns:
    * ``True`` if user deleted,
    * ``False`` if user not found in realm.
FT)r8  r8   r  r„   )r#   r™   r    ru   s       r$   r  ÚHtdigestFile.deletež  sH   € ð ×Ñ˜tÓ+ˆð	Ø—‘˜cÐ"ð 	�‰ÔØøô ó 	Ùð	ús   “1 ±
>½>c                 óÊ   • U R                  U5      nU R                  nU Vs/ s H  o3S   U:X  d  M  UPM     nnU H  nX#	 M     U R                  5         [        U5      $ s  snf )z™Delete all users for specified realm.

if realm is not specified, uses ``self.default_realm``.

:returns: number of users deleted (0 if realm not found)
rb   )r¢   r8   r„   r¯   )r#   r    rp   ru   Úkeyss        r$   Údelete_realmÚHtdigestFile.delete_realm¯  sa   € ð ×"Ñ" 5Ó)ˆØ—-‘-ˆÙ&Ó:šw˜¨a©&°E©/—™wˆÐ:ÛˆCØ’ñ à�‰ÔÜ�4‹yÐùò	 ;s
   ¢A ²A c                 óÞ   • U[         L a  SUp2U R                  U5      nU R                  U5      nU R                  R	                  X45      nUc  g[
        R                  " X4XU R                  S9$ )a‚  Verify password for specified user + realm.

If ``self.default_realm`` has been set, this may be called
with the syntax ``check_password(user, password)``,
otherwise it must be called with all three arguments:
``check_password(user, realm, password)``.

:returns:
    * ``None`` if user or realm not found.
    * ``False`` if user found, but password does not match.
    * ``True`` if user found and password matches.

.. versionchanged:: 1.6
    This method was previously called ``verify``, it was renamed
    to prevent ambiguity with the :class:`!CryptContext` method.
    The old alias is deprecated, and will be removed in Passlib 1.8.
NrB  )rC  r�   r¢   r8   ré   r	   r$  r3   rD  s        r$   r  ÚHtdigestFile.check_password¾  sm   € ð$ ”vÒà" E�8Ø× Ñ  Ó&ˆØ×"Ñ" 5Ó)ˆØ�}‰}× Ñ  $ Ó.ˆØ‰<ØÜ�Š˜x¨tØ(,¯©ñ7ð 	7r'   r  c                 ó&   • U R                  XU5      $ r"  r#  rG  s       r$   r$  ÚHtdigestFile.verifyÛ  s   € ð ×"Ñ" 4°Ó9Ð9r'   )r+  )NNrG   )rA   r¸   r¹   rº   r»   r+  r<   rc   r�   r2  r¢   r8  r=  rú   rC  rÿ   r   rÐ   r  rý   r  r  rS  r  r$  r¿   r'  r(  s   @r$   r   r   r  sÎ   ø† ñBð^ €M÷
9ò#ò=òò2òBò?ô
$ðD (,°fô 0ñ&  %°Ø#1ñ3ñ8ó3ð8ôð& $(¨fô ñ4  %°Ø#-ñ/ñ*ó/ð*ô
ò"ð *.¸ô 7ñ:  %°Ø#3ñ5ñ:ó5ö:r'   )/r»   Ú
__future__r   ÚloggingÚ	getLoggerrA   rh   rR   Úwarningsr   Úpasslibr   r   Úpasslib.contextr   Úpasslib.excr   Úpasslib.hashr	   Úpasslib.utilsr
   r   r   Úpasslib.utils.decorr   Úpasslib.utils.compatr   r   r   r   Ú__all__ÚobjectrC  rò   rg   r§   rk   rl   r   r�   rÎ   rÓ   râ   rä   r&  r   r   r   r'   r$   Ú<module>rf     sÏ   ðÙ .õ
 &ã �g×'Ò'¨Ó1�Û 	Ý ÷ "Ý (Ý +Ý !ß @Ñ @Ý 1ß BÓ Bð Øð€ñ 
‹€à
€Ø	€ð &Ð ð €Ø
€ô
j�&ô jñJ “%€ò&ñR *Ó+Ð ò*ñZ *Ó+Ð ôX3�;ô X3ôBm:�;õ m:r'   