U
    QV‚g¨  ã                   @   sZ   d dl mZ d dlmZ d dlmZ ddlmZ G dd„ dƒZdd	„ Z	G d
d„ deƒZ
dS )é    )Úurlparse)Úsettings)Úis_same_domainé   )ÚAsyncWebsocketConsumerc                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚOriginValidatorze
    Validates that the incoming connection has an Origin header that
    is in an allowed list.
    c                 C   s   || _ || _d S ©N)ÚapplicationÚallowed_origins)Úselfr	   r
   © r   ú?/tmp/pip-unpacked-wheel-lkk2pq7o/channels/security/websocket.pyÚ__init__   s    zOriginValidator.__init__c              	   Ã   s˜   |d dkrt dƒ‚d }| dg ¡D ]8\}}|dkr$zt| d¡ƒ}W q$ tk
rZ   Y q$X q$|  |¡r||  |||¡I d H S tƒ }||||ƒI d H S d S )NÚtypeZ	websocketz<You cannot use OriginValidator on a non-WebSocket connectionÚheaderss   originÚlatin1)Ú
ValueErrorÚgetr   ÚdecodeÚUnicodeDecodeErrorÚvalid_originr	   ÚWebsocketDenier)r   ZscopeZreceiveÚsendÚparsed_originÚheader_nameÚheader_valueZdenierr   r   r   Ú__call__   s    ÿ
zOriginValidator.__call__c                 C   s    |dkrd| j krdS |  |¡S )z¼
        Checks parsed origin is None.

        Pass control to the validate_origin function.

        Returns ``True`` if validation function was successful, ``False`` otherwise.
        NÚ*F)r
   Úvalidate_origin©r   r   r   r   r   r   +   s    	zOriginValidator.valid_originc                    s   t ‡ ‡fdd„ˆjD ƒƒS )aÖ  
        Validate the given origin for this site.

        Check than the origin looks valid and matches the origin pattern in
        specified list ``allowed_origins``. Any pattern begins with a scheme.
        After the scheme there must be a domain. Any domain beginning with a
        period corresponds to the domain and all its subdomains (for example,
        ``http://.example.com``). After the domain there must be a port,
        but it can be omitted. ``*`` matches anything and anything
        else must match exactly.

        Note. This function assumes that the given origin has a schema, domain
        and port, but port is optional.

        Returns ``True`` for a valid host, ``False`` otherwise.
        c                 3   s"   | ]}|d kpˆ  ˆ |¡V  qdS )r   N)Úmatch_allowed_origin)Ú.0Úpattern©r   r   r   r   Ú	<genexpr>I   s   ÿz2OriginValidator.validate_origin.<locals>.<genexpr>)Úanyr
   r   r   r#   r   r   8   s    þzOriginValidator.validate_originc                 C   sˆ   |dkrdS t | ¡ ƒ}|jdkr&dS |jsJt d| ƒjp<|}t|j|ƒS |  |¡}|  |¡}|j|jkr„||kr„t|j|jƒr„dS dS )aü  
        Returns ``True`` if the origin is either an exact match or a match
        to the wildcard pattern. Compares scheme, domain, port of origin and pattern.

        Any pattern can be begins with a scheme. After the scheme must be a domain,
        or just domain without scheme.
        Any domain beginning with a period corresponds to the domain and all
        its subdomains (for example, ``.example.com`` ``example.com``
        and any subdomain). Also with scheme (for example, ``http://.example.com``
        ``http://exapmple.com``). After the domain there must be a port,
        but it can be omitted.

        Note. This function assumes that the given origin is either None, a
        schema-domain-port string, or just a domain string
        NFz//T)r   ÚlowerÚhostnameÚschemer   Úget_origin_port)r   r   r"   Zparsed_patternZpattern_hostnameÚorigin_portZpattern_portr   r   r   r    N   s$    



ÿþýz$OriginValidator.match_allowed_originc                 C   sH   |j dk	r|j S |jdks$|jdkr(dS |jdks<|jdkr@dS dS dS )zq
        Returns the origin.port or port for this schema by default.
        Otherwise, it returns None.
        NÚhttpÚwséP   ÚhttpsÚwssi»  )Úportr(   )r   Úoriginr   r   r   r)   u   s    
zOriginValidator.get_origin_portN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r    r)   r   r   r   r   r   	   s   'r   c                 C   s$   t j}t jr|sdddg}t| |ƒS )zi
    Factory function which returns an OriginValidator configured to use
    settings.ALLOWED_HOSTS.
    Ú	localhostz	127.0.0.1z[::1])r   ZALLOWED_HOSTSÚDEBUGr   )r	   Zallowed_hostsr   r   r   ÚAllowedHostsOriginValidatorˆ   s    

r8   c                   @   s   e Zd ZdZdd„ ZdS )r   z=
    Simple application which denies all requests to it.
    c                 Ã   s   |   ¡ I d H  d S r   )Úclose)r   r   r   r   Úconnect˜   s    zWebsocketDenier.connectN)r2   r3   r4   r5   r:   r   r   r   r   r   “   s   r   N)Úurllib.parser   Zdjango.confr   Zdjango.http.requestr   Zgeneric.websocketr   r   r8   r   r   r   r   r   Ú<module>   s   