o
    5hE                     @   s  d Z ddlmZ ddlZeeZddlZddlm	Z	 ddl
mZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZ dd
lmZ ddlmZmZmZmZ ddgZe Z dZ!dZ"dZ#dZ$dZ%G dd deZ&e' Z(dd Z)e) Z*dd Z+e+ Z,G dd de&Z-G dd de&Z.dS )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                   @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
edd Zedd Zddddd	efd
dZdd Zedd Zejdd Zedd Zdd Zd2ddZdd Zdd Zdd Zdd Zdd  Zd3d!d"Zd#d$ Zd%d& Zd'd( Zd)d* Z d+d, Z!d4d.d/Z"d0d1 Z#dS )5_CommonFilez0common framework for HtpasswdFile & HtdigestFileNFc                 K   s,   d|v rt d| di |}|| |S )zcreate 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()N )	TypeErrorload_string)clsdatakwdsselfr   r   b/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/passlib/apache.pyfrom_stringK   s
   
z_CommonFile.from_stringc                 K   s   | di |}| | |S )zcreate 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
        Nr   )load)r   r   r   r   r   r   r    	from_path\   s   
z_CommonFile.from_pathTutf-8c                 C   s   |st dtdd d}d}nt|std|| _|| _|| _|| _d| _|s0t dtdd d	}|r:|s:| 	  d S i | _
g | _d S )
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autoloadr,   r*   r+   r   r   r    __init__n   s,   
z_CommonFile.__init__c                 C   sT   d}| j r	|d7 }| jr|d| j 7 }| jdkr|d| j 7 }d| jjt| |f S )N z autosave=Truez path=%rr$   z encoding=%rz<%s 0x%0x%s>)r,   r-   r*   	__class____name__id)r   tailr   r   r    __repr__   s   
z_CommonFile.__repr__c                 C      | j S N)r-   r   r   r   r    r      s   z_CommonFile.pathc                 C   s   || j krd| _|| _ d S )Nr   )r-   r.   r   valuer   r   r    r      s   

c                 C   r:   )z7modify time when last loaded (if bound to a local file))r.   r<   r   r   r    mtime   s   z_CommonFile.mtimec                 C   s<   | j s	td|  | jr| jtj| j krdS |   dS )zBReload from ``self.path`` only if file has changed since last loadz%r is not bound to a local fileFT)r-   RuntimeErrorr.   osr   getmtimer"   r<   r   r   r    load_if_changed   s   z_CommonFile.load_if_changedc                 C   s   |dur$t |d}d| _| | W d   d	S 1 sw   Y  d	S |s8tdt| jjd tdd |  S | j	rat | j	d}t
j| j	| _| | W d   d	S 1 sZw   Y  d	S td| jj )
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)openr.   _load_linesr   dictr5   r6   r(   rC   r-   rA   r   rB   r@   )r   r   forcefhr   r   r    r"      s4   

z_CommonFile.loadc                 C   s&   t || jd}d| _| t| dS )z@Load state from unicode or bytes string, replacing current stater   r   N)r
   r*   r.   rG   r   )r   r   r   r   r    r      s   z_CommonFile.load_stringc                 C   s   | j }i }g }d}t|D ]C\}}| }|r|tr!||7 }q|||d \}	}
|	|v r:td|	  ||7 }q|rE|t|f d}|
||	< |t	|	f q|
 r\|t|f || _|| _dS )zload from sequence of lists       z1username occurs multiple times in source file: %rN)_parse_record	enumeratelstrip
startswith_BHASHlogwarningappend_SKIPPED_RECORDrstripr/   r0   )r   linesparserecordssourcer   idxlinetmpkeyr>   r   r   r    rG      s.   
z_CommonFile._load_linesc                 C      t d)z)parse line of file into (key, value) pair!should be implemented in subclassNotImplementedError)r   r   linenor   r   r    rM        z_CommonFile._parse_recordc                 C   s.   | j }||v }|||< |s| jt|f |S )z
        helper for setting record which takes care of inserting source line if needed;

        :returns:
            bool if key already present
        )r/   r0   rT   rV   )r   r_   r>   rZ   existingr   r   r    _set_record  s   z_CommonFile._set_recordc                 C   s    | j r| jr|   dS dS dS )z0subclass helper to call save() after any changesN)r,   r-   saver<   r   r   r    	_autosave!  s   z_CommonFile._autosavec                 C   s|   |dur#t |d}||   W d   dS 1 sw   Y  dS | jr6| | j tj| j| _dS t	d| j
j )zhSave current state to file.
        If no path is specified, attempts to save to ``self.path``.
        Nwbz%%s().path is not set, cannot autosave)rF   
writelines_iter_linesr-   rh   rA   r   rB   r.   r@   r5   r6   )r   r   rJ   r   r   r    rh   &  s   "z_CommonFile.savec                 C   s   t |  S )z)Export current state as a string of bytes)r   rl   r<   r   r   r    	to_string4     z_CommonFile.to_stringc                 c   s~    | j }	 t|}| jD ]&\}}|tkr|V  q|tksJ ||vr#q| ||| V  	 || q	 |r=J d|f dS )z#iterator yielding lines of databaseTz'failed to write all records: missing=%rN)r/   setr0   rU   rV   _render_recordremove)r   rZ   pendingactioncontentr   r   r    rl   @  s   z_CommonFile._iter_linesc                 C   r`   )z,given key/value pair, encode as line of filera   rb   )r   r_   r>   r   r   r    rp   [  re   z_CommonFile._render_recordc                 C      |  |dS )z)user-specific wrapper for _encode_field()user_encode_fieldr   rv   r   r   r    _encode_userb  rn   z_CommonFile._encode_userc                 C   ru   )z*realm-specific wrapper for _encode_field()realmrw   r   r{   r   r   r    _encode_realmf  rn   z_CommonFile._encode_realmfieldc                 C   sn   t |tr|| j}n
t |tst||t|dkr$td||f tdd |D r5td||f |S )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%%s must be at most 255 characters: %rc                 s   s    | ]}|t v V  qd S r;   )_INVALID_FIELD_CHARS).0cr   r   r    	<genexpr>      z,_CommonFile._encode_field.<locals>.<genexpr>z"%s contains invalid characters: %r)	
isinstancer   encoder*   bytesr   lenr)   any)r   r>   paramr   r   r    rx   j  s   


z_CommonFile._encode_fieldc                 C   s(   t |ts	J d| jr|| jS |S )aW  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   r+   decoder*   r=   r   r   r    _decode_field  s   z_CommonFile._decode_field)NTr;   )r~   )$r6   
__module____qualname____doc__r*   r+   r-   r.   r,   r/   r0   classmethodr!   r#   r   r3   r9   propertyr   setterr?   rC   r"   r   rG   rM   rg   ri   rh   rm   rl   rp   rz   r}   rx   r   r   r   r   r    r   ,   sL    


#



	$*

r   c                  C   s   d } dD ]}t |r|}  nqt drdnd }t  |s&tg d t|p*dd|p0| p0d| p3d|p6ddd}|j|d |d d	 |S )
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updaterH   )	host_bestrE   r   defaultsr   r   r    _init_default_schemes  s.   

r   c                  C   sP   g d} |  t  | d d dg |  }tt| |jd} t| td ddS )N)r   r   sha512_crypt	des_cryptr   	ldap_sha1	plaintext   r   )r_   r   2y)schemesdefaultbcrypt__ident)extendr   get_supported_os_crypt_schemessortedro   indexr   htpasswd_defaults)r   	preferredr   r   r    _init_htpasswd_context  s   r   c                       s   e Zd ZdZddef fdd	Zdd Zdd Zd	d
 Zdd Z	e
dddddd Zdd Zdd Ze
dddddd Zdd Zdd Ze
dddddd  Z  ZS )!r   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                    sv   d|v rt dtdd |d}|r*|tv rt d| tj t||}|j|d}|| _	t
t| j|fi | d S )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   r(   popr   r   PasslibSecurityWarningr   getcopycontextsuperr   r3   )r   r   default_schemer   r   r5   r   r    r3     s    
zHtpasswdFile.__init__c                 C   s*   |  t}t|dkrtd| |S )Nr%   z/malformed htpasswd file (error reading line %d)rW   split_BCOLONr   r)   )r   r   rd   resultr   r   r    rM     s   zHtpasswdFile._parse_recordc                 C   s   t d||S )Nz%s:%s
r	   )r   rv   hashr   r   r    rp     s   zHtpasswdFile._render_recordc                    s    fdd j D S )z6
        Return list of all users in database
        c                       g | ]}  |qS r   r   )r   rv   r<   r   r    
<listcomp>      z&HtpasswdFile.users.<locals>.<listcomp>)r/   r<   r   r<   r    users  s   zHtpasswdFile.usersc                 C   s   | j |}| ||S )a  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   rv   passwordr   r   r   r    set_password  s   zHtpasswdFile.set_password1.61.8r   
deprecatedremovedreplacementc                 C      |  ||S zset password for userr   r   rv   r   r   r   r    r        zHtpasswdFile.updatec                 C   s(   z	| j | | W S  ty   Y dS w )a  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)r/   rz   KeyErrorry   r   r   r    get_hash  s
   zHtpasswdFile.get_hashc                 C   s<   t rt|tr|| j}| |}| ||}|   |S )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   r*   rz   rg   ri   )r   rv   r   rf   r   r   r    r     s   
zHtpasswdFile.set_hashr   c                 C   s
   |  |S zreturn hash for userr   ry   r   r   r    find1  s   
zHtpasswdFile.findc                 C   s4   z	| j | |= W n
 ty   Y dS w |   dS )zDelete user's entry.

        :returns:
            * ``True`` if user deleted.
            * ``False`` if user not found.
        FT)r/   rz   r   ri   ry   r   r   r    delete8  s   zHtpasswdFile.deletec                 C   sz   |  |}| j|}|du rdS t|tr|| j}| j||\}}|r;|dur;|| jv s2J || j|< | 	  |S )aM  
        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)
rz   r/   r   r   r   r   r*   r   verify_and_updateri   )r   rv   r   r   oknew_hashr   r   r    check_passwordF  s   


zHtpasswdFile.check_passwordr   c                 C   r   zverify password for userr   r   r   r   r    verifye  r   zHtpasswdFile.verify)r6   r   r   r   htpasswd_contextr3   rM   rp   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r    r     s0     9

c                       s   e Zd ZdZdZd+ fdd	Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zd,ddZdefddZedddddd Zd,ddZdefddZeddddd d! Zd,d"d#Zd$d% Zdefd&d'Zeddd(dd)d* Z  ZS )-r   a  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                    s"   || _ tt| j|fi | d S r;   )default_realmr   r   r3   )r   r   r   r   r   r   r    r3     s   zHtdigestFile.__init__c                 C   s<   |  t}t|dkrtd| |\}}}||f|fS )Nr   z/malformed htdigest file (error reading line %d)r   )r   r   rd   r   rv   r{   r   r   r   r    rM     s   
zHtdigestFile._parse_recordc                 C   s   |\}}t d|||S )Nz	%s:%s:%s
r   )r   r_   r   rv   r{   r   r   r    rp     s   zHtdigestFile._render_recordc                 C   s"   |d u r| j }|d u rtd|S )NzGyou must specify a realm explicitly, or set the default_realm attribute)r   r   r|   r   r   r    _require_realm  s
   zHtdigestFile._require_realmc                 C   s   |  |}| |dS )Nr{   )r   rx   r|   r   r   r    r}     s   
zHtdigestFile._encode_realmc                 C   s   |  || |fS r;   )rz   r}   r   rv   r{   r   r   r    _encode_key#  s   zHtdigestFile._encode_keyc                    s&   t dd  jD } fdd|D S )z%Return list of all realms in databasec                 s   s    | ]}|d  V  qdS )rL   Nr   r   r_   r   r   r    r   ,  r   z&HtdigestFile.realms.<locals>.<genexpr>c                    r   r   r   )r   r{   r<   r   r    r   -  r   z'HtdigestFile.realms.<locals>.<listcomp>)ro   r/   )r   realmsr   r<   r    r   *  s   zHtdigestFile.realmsc                    s        fddjD S )zReturn list of all users in specified realm.

        * uses ``self.default_realm`` if no realm explicitly provided.
        * returns empty list if realm not found.
        c                    s&   g | ]}|d   kr |d qS )rL   r   r   r   r{   r   r   r    r   6  s    z&HtdigestFile.users.<locals>.<listcomp>)r}   r/   r|   r   r   r    r   /  s   
zHtdigestFile.usersc                 C   s>   |t u r	d|}}| |}tj|||| jd}| |||S )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r*   )_UNSETr   r   r   r*   r   r   rv   r{   r   r   r   r   r    r   Q  s
   

zHtdigestFile.set_passwordr   r   r   r   c                 C      |  |||S r   r   r   rv   r{   r   r   r   r    r   d     zHtdigestFile.updatec                 C   s8   |  ||}| j|}|du rdS tr|| j}|S )a  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)r   r/   r   r   r   r*   )r   rv   r{   r_   r   r   r   r    r   j  s   zHtdigestFile.get_hashc                 C   sP   |t u r	d|}}trt|tr|| j}| ||}| ||}|   |S )a  
        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)	r   r   r   r   r   r*   r   rg   ri   )r   rv   r{   r   r_   rf   r   r   r    r   }  s   
zHtdigestFile.set_hashr   c                 C   r   r   r   r   r   r   r    r     r   zHtdigestFile.findc                 C   s:   |  ||}z| j|= W n
 ty   Y dS w |   dS )zDelete 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)r   r/   r   ri   )r   rv   r{   r_   r   r   r    r     s   	zHtdigestFile.deletec                    sB   |    | j} fdd|D }|D ]}||= q|   t|S )zDelete all users for specified realm.

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

        :returns: number of users deleted (0 if realm not found)
        c                    s   g | ]
}|d   kr|qS )rL   r   r   r{   r   r    r     s    z-HtdigestFile.delete_realm.<locals>.<listcomp>)r}   r/   ri   r   )r   r{   rZ   keysr_   r   r   r    delete_realm  s   
zHtdigestFile.delete_realmc                 C   sX   |t u r	d|}}| |}| |}| j||f}|du r!dS tj||||| jdS )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.
        Nr   )r   rz   r}   r/   r   r   r   r*   r   r   r   r    r     s   


zHtdigestFile.check_passwordr   c                 C   r   r   r   r   r   r   r    r     r   zHtdigestFile.verify)NNr;   )r6   r   r   r   r   r3   rM   rp   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r  s<     
"



)/r   
__future__r   logging	getLoggerr6   rR   rA   warningsr   passlibr   r   passlib.contextr   passlib.excr   passlib.hashr   passlib.utilsr	   r
   r   passlib.utils.decorr   passlib.utils.compatr   r   r   r   __all__objectr   r   rQ   r   rU   rV   r   ro   r   r   r   r   r   r   r   r   r   r   r    <module>   sD       )-  c