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 )zRequire 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 )zRequire 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 )zAllow 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 )zPrevent 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od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





