U
    Ê¼µb6  ã                   @   sÌ   d Z ddlmZ ddlmZ ddlmZ G dd„ deƒZdd„ Zd	d
„ Zdd„ Z	dd„ Z
d'dd„Zd(dd„Zd)dd„Zd*dd„Zd+dd„Zd,dd„Zdd„ ZeeeedœZed d!d"gƒZd#d$„ Zd%d&„ ZdS )-z3Module containing the validation logic for rfc3986.é   )Ú
exceptions)Úmisc)Únormalizersc                   @   sn   e Zd ZdZedddddddgƒZd	d
„ Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )Ú	Validatora�  Object used to configure validation of all objects in rfc3986.

    .. versionadded:: 1.0

    Example usage::

         >>> from rfc3986 import api, validators
         >>> uri = api.uri_reference('https://github.com/')
         >>> validator = validators.Validator().require_presence_of(
         ...    'scheme', 'host', 'path',
         ... ).allow_schemes(
         ...    'http', 'https',
         ... ).allow_hosts(
         ...    '127.0.0.1', 'github.com',
         ... )
         >>> validator.validate(uri)
         >>> invalid_uri = rfc3986.uri_reference('imap://mail.google.com')
         >>> validator.validate(invalid_uri)
         Traceback (most recent call last):
         ...
         rfc3986.exceptions.MissingComponentError: ('path was required but
         missing', URIReference(scheme=u'imap', authority=u'mail.google.com',
         path=None, query=None, fragment=None), ['path'])

    ÚschemeÚuserinfoÚhostÚportÚpathÚqueryÚfragmentc                 C   sD   t ƒ | _t ƒ | _t ƒ | _d| _ddddddddœ| _| j ¡ | _dS )z#Initialize our default validations.TF)r   r   r   r	   r
   r   r   N)ÚsetÚallowed_schemesÚallowed_hostsÚallowed_portsÚallow_passwordÚrequired_componentsÚcopyÚvalidated_components©Úself© r   ú6/tmp/pip-unpacked-wheel-9bk_1qnx/rfc3986/validators.pyÚ__init__4   s    ù	zValidator.__init__c                 G   s    |D ]}| j  t |¡¡ q| S )a	  Require the scheme to be one of the provided schemes.

        .. versionadded:: 1.0

        :param schemes:
            Schemes, without ``://`` that are allowed.
        :returns:
            The validator instance.
        :rtype:
            Validator
        )r   Úaddr   Znormalize_scheme)r   Úschemesr   r   r   r   Úallow_schemesE   s    zValidator.allow_schemesc                 G   s    |D ]}| j  t |¡¡ q| S )zðRequire the host to be one of the provided hosts.

        .. versionadded:: 1.0

        :param hosts:
            Hosts that are allowed.
        :returns:
            The validator instance.
        :rtype:
            Validator
        )r   r   r   Únormalize_host)r   Úhostsr   r   r   r   Úallow_hostsU   s    zValidator.allow_hostsc                 G   s>   |D ]4}t |dd�}d|  kr(dkrn q| j |¡ q| S )zðRequire the port to be one of the provided ports.

        .. versionadded:: 1.0

        :param ports:
            Ports that are allowed.
        :returns:
            The validator instance.
        :rtype:
            Validator
        é
   ©Úbaseé    éÿÿ  )Úintr   r   )r   Zportsr	   Zport_intr   r   r   Úallow_portse   s
    zValidator.allow_portsc                 C   s
   d| _ | S )z®Allow passwords to be present in the URI.

        .. versionadded:: 1.0

        :returns:
            The validator instance.
        :rtype:
            Validator
        T©r   r   r   r   r   Úallow_use_of_passwordw   s    
zValidator.allow_use_of_passwordc                 C   s
   d| _ | S )z¶Prevent passwords from being included in the URI.

        .. versionadded:: 1.0

        :returns:
            The validator instance.
        :rtype:
            Validator
        Fr'   r   r   r   r   Úforbid_use_of_password„   s    
z Validator.forbid_use_of_passwordc                 G   sJ   dd„ |D ƒ}|D ]}|| j krtd |¡ƒ‚q| j dd„ |D ƒ¡ | S )aA  Check the validity of the components provided.

        This can be specified repeatedly.

        .. versionadded:: 1.1

        :param components:
            Names of components from :attr:`Validator.COMPONENT_NAMES`.
        :returns:
            The validator instance.
        :rtype:
            Validator
        c                 S   s   g | ]}|  ¡ ‘qS r   ©Úlower©Ú.0Úcr   r   r   Ú
<listcomp>Ÿ   s     z/Validator.check_validity_of.<locals>.<listcomp>ú"{}" is not a valid componentc                 S   s   i | ]
}|d “qS ©Tr   ©r-   Ú	componentr   r   r   Ú
<dictcomp>¦   s      z/Validator.check_validity_of.<locals>.<dictcomp>)ÚCOMPONENT_NAMESÚ
ValueErrorÚformatr   Úupdate©r   Ú
componentsr3   r   r   r   Úcheck_validity_of‘   s    
ÿÿzValidator.check_validity_ofc                 G   sJ   dd„ |D ƒ}|D ]}|| j krtd |¡ƒ‚q| j dd„ |D ƒ¡ | S )a3  Require the components provided.

        This can be specified repeatedly.

        .. versionadded:: 1.0

        :param components:
            Names of components from :attr:`Validator.COMPONENT_NAMES`.
        :returns:
            The validator instance.
        :rtype:
            Validator
        c                 S   s   g | ]}|  ¡ ‘qS r   r*   r,   r   r   r   r/   ¸   s     z1Validator.require_presence_of.<locals>.<listcomp>r0   c                 S   s   i | ]
}|d “qS r1   r   r2   r   r   r   r4   ¿   s      z1Validator.require_presence_of.<locals>.<dictcomp>)r5   r6   r7   r   r8   r9   r   r   r   Úrequire_presence_ofª   s    
ÿÿzValidator.require_presence_ofc                 C   s€   | j st|ƒ dd„ | j ¡ D ƒ}dd„ | j ¡ D ƒ}|rDt||ƒ |rRt||ƒ t| j|dƒ t| j	|dƒ t| j
|dƒ dS )aƒ  Check a URI for conditions specified on this validator.

        .. versionadded:: 1.0

        :param uri:
            Parsed URI to validate.
        :type uri:
            rfc3986.uri.URIReference
        :raises MissingComponentError:
            When a required component is missing.
        :raises UnpermittedComponentError:
            When a component is not one of those allowed.
        :raises PasswordForbidden:
            When a password is present in the userinfo component but is
            not permitted by configuration.
        :raises InvalidComponentsError:
            When a component was found to be invalid.
        c                 S   s   g | ]\}}|r|‘qS r   r   ©r-   r3   Úrequiredr   r   r   r/   Ù   s   þz&Validator.validate.<locals>.<listcomp>c                 S   s   g | ]\}}|r|‘qS r   r   r=   r   r   r   r/   Þ   s   þr   r   r	   N)r   Úcheck_passwordr   Úitemsr   Ú ensure_required_components_existÚensure_components_are_validÚensure_one_ofr   r   r   )r   Úurir   r   r   r   r   ÚvalidateÃ   s    þþ

zValidator.validateN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	frozensetr5   r   r   r   r&   r(   r)   r;   r<   rE   r   r   r   r   r      s   ÿr   c                 C   s8   | j }|sdS | dd¡}t|ƒdkr*dS t | ¡‚dS )z4Assert that there is no password present in the uri.Nú:r   )r   ÚsplitÚlenr   ZPasswordForbidden)rD   r   Úcredentialsr   r   r   r?   í   s    r?   c                 C   s0   t ||ƒ}|dk	r,| r,|| kr,t ||| ¡‚dS )z=Assert that the uri's attribute is one of the allowed values.N)Úgetattrr   ZUnpermittedComponentError)Zallowed_valuesrD   Ú	attributeÚvaluer   r   r   rC   ø   s    
ýrC   c                    s.   t ‡ fdd„|D ƒƒ}|r*tjˆ f|žŽ ‚dS )z;Assert that all required components are present in the URI.c                    s   g | ]}t ˆ |ƒd kr|‘qS )N)rO   r2   ©rD   r   r   r/     s   þz4ensure_required_components_exist.<locals>.<listcomp>N)Úsortedr   ZMissingComponentError)rD   r   Zmissing_componentsr   rR   r   rA     s    
þÿrA   c                 C   s(   |r| dk	o|  | ¡S | dkp&|  | ¡S )a  Determine if a value is valid based on the provided matcher.

    :param str value:
        Value to validate.
    :param matcher:
        Compiled regular expression to use to validate the value.
    :param require:
        Whether or not the value is required.
    N)Úmatch)rQ   ÚmatcherÚrequirer   r   r   Úis_valid  s    
rW   NFc                 C   s(   t | tj|ƒ}|r$|dk	r$t||ƒS |S )an  Determine if the authority string is valid.

    :param str authority:
        The authority to validate.
    :param str host:
        (optional) The host portion of the authority to validate.
    :param bool require:
        (optional) Specify if authority must not be None.
    :returns:
        ``True`` if valid, ``False`` otherwise
    :rtype:
        bool
    N)rW   r   ZSUBAUTHORITY_MATCHERÚhost_is_valid)Ú	authorityr   rV   Ú	validatedr   r   r   Úauthority_is_valid!  s    
r[   c                 C   sZ   t | tj|ƒ}|r.| dk	r.tj | ¡r.t| ƒS |rV| dk	rVtj | ¡rVtj | ¡dk	S |S )a  Determine if the host string is valid.

    :param str host:
        The host to validate.
    :param bool require:
        (optional) Specify if host must not be None.
    :returns:
        ``True`` if valid, ``False`` otherwise
    :rtype:
        bool
    N)rW   r   ZHOST_MATCHERZIPv4_MATCHERrT   Úvalid_ipv4_host_addressZIPv6_MATCHERZIPv6_NO_RFC4007_MATCHER)r   rV   rZ   r   r   r   rX   5  s    rX   c                 C   s   t | tj|ƒS )a+  Determine if the scheme is valid.

    :param str scheme:
        The scheme string to validate.
    :param bool require:
        (optional) Set to ``True`` to require the presence of a scheme.
    :returns:
        ``True`` if the scheme is valid. ``False`` otherwise.
    :rtype:
        bool
    )rW   r   ZSCHEME_MATCHER)r   rV   r   r   r   Úscheme_is_validI  s    r]   c                 C   s   t | tj|ƒS )a+  Determine if the path component is valid.

    :param str path:
        The path string to validate.
    :param bool require:
        (optional) Set to ``True`` to require the presence of a path.
    :returns:
        ``True`` if the path is valid. ``False`` otherwise.
    :rtype:
        bool
    )rW   r   ZPATH_MATCHER)r
   rV   r   r   r   Úpath_is_validX  s    r^   c                 C   s   t | tj|ƒS )a0  Determine if the query component is valid.

    :param str query:
        The query string to validate.
    :param bool require:
        (optional) Set to ``True`` to require the presence of a query.
    :returns:
        ``True`` if the query is valid. ``False`` otherwise.
    :rtype:
        bool
    )rW   r   ZQUERY_MATCHER)r   rV   r   r   r   Úquery_is_validg  s    r_   c                 C   s   t | tj|ƒS )a?  Determine if the fragment component is valid.

    :param str fragment:
        The fragment string to validate.
    :param bool require:
        (optional) Set to ``True`` to require the presence of a fragment.
    :returns:
        ``True`` if the fragment is valid. ``False`` otherwise.
    :rtype:
        bool
    )rW   r   ZFRAGMENT_MATCHER)r   rV   r   r   r   Úfragment_is_validv  s    r`   c                 C   s   t dd„ |  d¡D ƒƒS )z4Determine if the given host is a valid IPv4 address.c                 S   s,   g | ]$}d t |dd�  ko"dkn  ‘qS )r#   r    r!   éÿ   )r%   )r-   Úbyter   r   r   r/   ‰  s     z+valid_ipv4_host_address.<locals>.<listcomp>Ú.)ÚallrL   )r   r   r   r   r\   …  s    r\   )r   r
   r   r   r   r   r	   c                 C   s†   z|   ¡ }W n tjk
r$   Y dS X |dkr:t|d ƒS |dkrFdS zt|d ƒ}W n tk
rl   Y dS X d|  ko€dkS   S )z4Determine if the userinfo, host, and port are valid.Fr   r	   Tr#   r$   )Zauthority_infor   ZInvalidAuthorityrX   r%   Ú	TypeError)rD   r3   Zsubauthority_dictr	   r   r   r   Úsubauthority_component_is_valid–  s    rf   c                 C   sh   t g ƒ}|D ]B}|tkr.t| |ƒs| |¡ qt| }|t| |ƒƒs| |¡ q|rdtj| f|žŽ ‚dS )z0Assert that all components are valid in the URI.N)r   Ú_SUBAUTHORITY_VALIDATORSrf   r   Ú_COMPONENT_VALIDATORSrO   r   ZInvalidComponentsError)rD   r   Zinvalid_componentsr3   Z	validatorr   r   r   rB   ®  s    

rB   )NF)F)F)F)F)F)rI   Ú r   r   r   Úobjectr   r?   rC   rA   rW   r[   rX   r]   r^   r_   r`   r\   rh   r   rg   rf   rB   r   r   r   r   Ú<module>   s0    Y





ü