U
     5iG                     @   s  d Z ddlZddlZddlmZ ddlm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 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 ddlm Z  e!dZ"e dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-de- Z.ej/ej0 Z1dZ2dd  Z3d!d" Z4d#d$ Z5d%d& Z6d'd( Z7d)d* Z8d+d, Z9G d-d. d.e:Z;d/d0 Z<d1d2 Z=G d3d4 d4e:Z>G d5d6 d6eZ?dS )7z
Cross Site Request Forgery Middleware.

This module provides a middleware that implements protection
against request forgeries from other sites.
    N)defaultdicturlparse)settings)DisallowedHostImproperlyConfigured)UnreadablePostError)HttpHeaders)get_callable)patch_vary_headers)constant_time_compareget_random_string)MiddlewareMixin)cached_propertyis_same_domain)log_response)_lazy_re_compilezdjango.security.csrfz[^a-zA-Z0-9]z?Origin checking failed - %s does not match any trusted origins.z%Referer checking failed - no Referer.z@Referer checking failed - %s does not match any trusted origins.zCSRF cookie not set.zCSRF token missing.z/Referer checking failed - Referer is malformed.zCReferer checking failed - Referer is insecure while host is secure.zhas incorrect lengthzhas invalid characters       Z
_csrftokenc                   C   s
   t tjS )z/Return the view to be used for CSRF rejections.)r
   r   ZCSRF_FAILURE_VIEW r   r   :/tmp/pip-unpacked-wheel-gcyiijx6/django/middleware/csrf.py_get_failure_view0   s    r   c                   C   s   t ttdS )N)allowed_chars)r   CSRF_SECRET_LENGTHCSRF_ALLOWED_CHARSr   r   r   r   _get_new_csrf_string5   s    r   c                    sP   t  }t t fdd| D  fdd|D }d fdd|D }|| S )z
    Given a secret (assumed to be a string of CSRF_ALLOWED_CHARS), generate a
    token by adding a mask and applying it to the secret.
    c                 3   s   | ]}  |V  qd S Nindex.0xcharsr   r   	<genexpr>@   s     z&_mask_cipher_secret.<locals>.<genexpr> c                 3   s&   | ]\}} || t    V  qd S r   )lenr!   r"   yr#   r   r   r%   A   s     )r   r   zipjoin)secretmaskpairscipherr   r#   r   _mask_cipher_secret9   s
    &r0   c                    sZ   | dt  }| t d } t t fdd| D  fdd|D }d fdd|D S )z
    Given a token (assumed to be a string of CSRF_ALLOWED_CHARS, of length
    CSRF_TOKEN_LENGTH, and that its first half is a mask), use it to decrypt
    the second half to produce the original secret.
    Nc                 3   s   | ]}  |V  qd S r   r   r    r#   r   r   r%   N   s     z'_unmask_cipher_token.<locals>.<genexpr>r&   c                 3   s   | ]\}} ||  V  qd S r   r   r(   r#   r   r   r%   O   s     )r   r   r*   r+   )tokenr-   r.   r   r#   r   _unmask_cipher_tokenE   s
    &r2   c                 C   s    t  }| jt|dd |S )zDGenerate a new random CSRF_COOKIE value, and add it to request.META.T)CSRF_COOKIECSRF_COOKIE_NEEDS_UPDATE)r   METAupdater0   requestZcsrf_secretr   r   r   _add_new_csrf_cookieR   s    r9   c                 C   s4   d| j kr$t| j d }d| j d< nt| }t|S )a  
    Return the CSRF token required for a POST form. The token is an
    alphanumeric value. A new token is created if one is not already set.

    A side effect of calling this function is to make the csrf_protect
    decorator and the CsrfViewMiddleware add a CSRF cookie and a 'Vary: Cookie'
    header to the outgoing response.  For this reason, you may need to use this
    function lazily, as is done by the csrf context processor.
    r3   Tr4   )r5   r2   r9   r0   r7   r   r   r   	get_token\   s
    

r:   c                 C   s   t |  dS )zi
    Change the CSRF token in use for a request - should be done on login
    for security purposes.
    N)r9   )r8   r   r   r   rotate_tokenq   s    r;   c                   @   s   e Zd Zdd ZdS )InvalidTokenFormatc                 C   s
   || _ d S r   reasonselfr>   r   r   r   __init__z   s    zInvalidTokenFormat.__init__N__name__
__module____qualname__rA   r   r   r   r   r<   y   s   r<   c                 C   sB   t | ttfkrttt| r*ttt | tkr>t| S | S r   )	r'   CSRF_TOKEN_LENGTHr   r<   REASON_INCORRECT_LENGTHinvalid_token_chars_researchREASON_INVALID_CHARACTERSr0   )r1   r   r   r   _sanitize_token~   s    
rK   c                 C   s   t t| t|S r   )r   r2   )request_csrf_token
csrf_tokenr   r   r   _does_token_match   s    rN   c                   @   s   e Zd Zdd ZdS )RejectRequestc                 C   s
   || _ d S r   r=   r?   r   r   r   rA      s    zRejectRequest.__init__NrB   r   r   r   r   rO      s   rO   c                   @   s   e Zd ZdZedd Zedd Ze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d Zdd Zdd ZdS )CsrfViewMiddlewarez
    Require a present and correct csrfmiddlewaretoken for POST requests that
    have a CSRF cookie, and set an outgoing CSRF cookie.

    This middleware should be used in conjunction with the {% csrf_token %}
    template tag.
    c                 C   s   dd t jD S )Nc                 S   s   g | ]}t |jd qS *)r   netloclstripr!   originr   r   r   
<listcomp>   s   zACsrfViewMiddleware.csrf_trusted_origins_hosts.<locals>.<listcomp>r   CSRF_TRUSTED_ORIGINSr@   r   r   r   csrf_trusted_origins_hosts   s    z-CsrfViewMiddleware.csrf_trusted_origins_hostsc                 C   s   dd t jD S )Nc                 S   s   h | ]}d |kr|qS rQ   r   rU   r   r   r   	<setcomp>   s   z;CsrfViewMiddleware.allowed_origins_exact.<locals>.<setcomp>rX   rZ   r   r   r   allowed_origins_exact   s    z(CsrfViewMiddleware.allowed_origins_exactc                 C   s:   t t}dd tjD D ]}||j |jd q|S )z
        A mapping of allowed schemes to list of allowed netlocs, where all
        subdomains of the netloc are allowed.
        c                 s   s   | ]}d |krt |V  qdS )rR   Nr   rU   r   r   r   r%      s      z?CsrfViewMiddleware.allowed_origin_subdomains.<locals>.<genexpr>rR   )r   listr   rY   schemeappendrS   rT   )r@   allowed_origin_subdomainsparsedr   r   r   ra      s    z,CsrfViewMiddleware.allowed_origin_subdomainsc                 C   s
   d|_ d S )NT)csrf_processing_done)r@   r8   r   r   r   _accept   s    zCsrfViewMiddleware._acceptc                 C   s(   t  ||d}td||j||td |S )Nr=   zForbidden (%s): %s)responser8   logger)r   r   pathrf   )r@   r8   r>   re   r   r   r   _reject   s      zCsrfViewMiddleware._rejectc                 C   s~   t jr4z|jtW S  tk
r0   tdY qzX nFz|jt j }W n t	k
rZ   Y d S X t
|}||krvd|jd< |S d S )NzCSRF_USE_SESSIONS is enabled, but request.session is not set. SessionMiddleware must appear before CsrfViewMiddleware in MIDDLEWARE.Tr4   )r   CSRF_USE_SESSIONSsessiongetCSRF_SESSION_KEYAttributeErrorr   ZCOOKIESCSRF_COOKIE_NAMEKeyErrorrK   r5   )r@   r8   Zcookie_tokenrM   r   r   r   
_get_token   s    
zCsrfViewMiddleware._get_tokenc              
   C   sj   t jr.|jt|jd krf|jd |jt< n8|jt j|jd t jt j	t j
t jt jt jd t|d d S )Nr3   )Zmax_agedomainrg   securehttponlysamesite)Cookie)r   ri   rj   rk   rl   r5   
set_cookiern   ZCSRF_COOKIE_AGECSRF_COOKIE_DOMAINZCSRF_COOKIE_PATHZCSRF_COOKIE_SECUREZCSRF_COOKIE_HTTPONLYZCSRF_COOKIE_SAMESITEr   r@   r8   re   r   r   r   _set_csrf_cookie   s    z#CsrfViewMiddleware._set_csrf_cookiec                    s   |j d }z| }W n tk
r*   Y n&X d| r:dnd|f }||krPdS || jkr^dS zt|}W n tk
r   Y dS X |j}|j t	 fdd| j
|d	D S )
NHTTP_ORIGINz%s://%shttpshttpTFc                 3   s   | ]}t  |V  qd S r   r   r!   hostZrequest_netlocr   r   r%     s   z6CsrfViewMiddleware._origin_verified.<locals>.<genexpr>r   )r5   get_hostr   	is_securer]   r   
ValueErrorr_   rS   anyra   rk   )r@   r8   Zrequest_originZ	good_hostZgood_originZparsed_originZrequest_schemer   r   r   _origin_verified   s,    

z#CsrfViewMiddleware._origin_verifiedc                    s  |j d  d krttzt  W n tk
rD   ttY nX d j jfkr^tt jdkrptt	t
 fdd| jD rd S tjrtjntj}|d krz| }W q tk
r   tt   Y qX n| }|dkrd||f }t j|stt   d S )NZHTTP_REFERERr&   r{   c                 3   s   | ]}t  j|V  qd S r   )r   rS   r}   Zrefererr   r   r%   (  s   z4CsrfViewMiddleware._check_referer.<locals>.<genexpr>)44380z%s:%s)r5   rk   rO   REASON_NO_REFERERr   r   REASON_MALFORMED_REFERERr_   rS   REASON_INSECURE_REFERERr   r[   r   ri   ZSESSION_COOKIE_DOMAINrw   r   r   REASON_BAD_REFERERgeturlZget_portr   )r@   r8   Zgood_refererZserver_portr   r   r   _check_referer  s:    
z!CsrfViewMiddleware._check_refererc                 C   s0   |dkrt |}d|d}d| d| dS )NPOSTzthe z HTTP headerzCSRF token from  .)r	   Zparse_header_name)r@   r>   token_sourceheader_namer   r   r   _bad_token_messageC  s    
z%CsrfViewMiddleware._bad_token_messagec              
   C   s8  z|  |}W n4 tk
rB } ztd|j dW 5 d }~X Y nX |d krTttd}|jdkrz|jdd}W n tk
r   Y nX |dkrz|j	t
j }W n tk
r   ttY nX t
j}nd}zt|}W n: tk
r } z| |j|}t|W 5 d }~X Y nX t||s4| d|}t|d S )NzCSRF cookie r   r&   r   ZcsrfmiddlewaretokenZ	incorrect)rp   r<   rO   r>   REASON_NO_CSRF_COOKIEmethodr   rk   r   r5   r   ZCSRF_HEADER_NAMEro   REASON_CSRF_TOKEN_MISSINGrK   r   rN   )r@   r8   rM   excrL   r   r>   r   r   r   _check_tokenJ  s6    $
zCsrfViewMiddleware._check_tokenc                 C   sB   z|  |}W n tk
r*   t| Y nX |d k	r>||jd< d S )Nr3   )rp   r<   r9   r5   )r@   r8   rM   r   r   r   process_requestz  s    z"CsrfViewMiddleware.process_requestc              
   C   s  t |ddrd S t |ddr d S |jdkr4| |S t |ddrJ| |S d|jkrv| |s| |t|jd  S nL| rz| | W n4 t	k
r } z| ||j
 W Y S d }~X Y nX z| | W n6 t	k
r } z| ||j
 W Y S d }~X Y nX | |S )Nrc   FZcsrf_exempt)GETHEADOPTIONSTRACEZ_dont_enforce_csrf_checksrz   )getattrr   rd   r5   r   rh   REASON_BAD_ORIGINr   r   rO   r>   r   )r@   r8   callbackcallback_argscallback_kwargsr   r   r   r   process_view  s*    




$$zCsrfViewMiddleware.process_viewc                 C   s&   |j dr"| || d|j d< |S )Nr4   F)r5   rk   ry   rx   r   r   r   process_response  s    
z#CsrfViewMiddleware.process_responseN)rC   rD   rE   __doc__r   r[   r]   ra   rd   rh   rp   ry   r   r   r   r   r   r   r   r   r   r   r   rP      s$   



-0
7rP   )@r   loggingstringcollectionsr   urllib.parser   Zdjango.confr   Zdjango.core.exceptionsr   r   Zdjango.httpr   Zdjango.http.requestr	   Zdjango.urlsr
   Zdjango.utils.cacher   Zdjango.utils.cryptor   r   Zdjango.utils.deprecationr   Zdjango.utils.functionalr   Zdjango.utils.httpr   Zdjango.utils.logr   Zdjango.utils.regex_helperr   	getLoggerrf   rH   r   r   r   r   r   r   r   rG   rJ   r   rF   ascii_lettersdigitsr   rl   r   r   r0   r2   r9   r:   r;   	Exceptionr<   rK   rN   rO   rP   r   r   r   r   <module>   sV   

	