3
(h0                 @   s.  d Z ddlmZ ddl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 ejdZdZdZdZdZdZdZ dZ!de! Z"ej#ej$ 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.G d(d) d)eZ/dS )*z
Cross Site Request Forgery Middleware.

This module provides a middleware that implements protection
against request forgeries from other sites.
    )unicode_literalsN)settings)get_callable)patch_vary_headers)constant_time_compareget_random_string)MiddlewareMixin)
force_text)is_same_domain)zip)urlparsezdjango.requestz%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 or incorrect.z/Referer checking failed - Referer is malformed.zCReferer checking failed - Referer is insecure while host is secure.       c               C   s
   t tjS )z9
    Returns the view to be used for CSRF rejections
    )r   r   ZCSRF_FAILURE_VIEW r   r   :/tmp/pip-install-q3hcpn_q/Django/django/middleware/csrf.py_get_failure_view%   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_string,   s    r   c                sP   t  }t t fdd| D  fdd|D }dj fdd|D }|| S )z
    Given a secret (assumed to be a string of CSRF_ALLOWED_CHARS), generate a
    token by adding a salt and using it to encrypt the secret.
    c             3   s   | ]} j |V  qd S )N)index).0x)charsr   r   	<genexpr>7   s    z&_salt_cipher_secret.<locals>.<genexpr> c             3   s&   | ]\}} || t    V  qd S )N)len)r   r   y)r   r   r   r   8   s    )r   r   r   join)secretsaltpairscipherr   )r   r   _salt_cipher_secret0   s
    &r#   c                s^   | dt  }| t d } t t fdd| D  fdd|D }dj 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 salt), use it to decrypt
    the second half to produce the original secret.
    Nc             3   s   | ]} j |V  qd S )N)r   )r   r   )r   r   r   r   E   s    z'_unsalt_cipher_token.<locals>.<genexpr>r   c             3   s   | ]\}} ||  V  qd S )Nr   )r   r   r   )r   r   r   r   F   s    )r   r   r   r   )tokenr    r!   r   r   )r   r   _unsalt_cipher_token<   s    &r%   c               C   s
   t t S )N)r#   r   r   r   r   r   _get_new_csrf_tokenJ   s    r&   c             C   s@   d| j kr t }t|| j d< nt| j d }d| j d< t|S )a  
    Returns 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.
    CSRF_COOKIETCSRF_COOKIE_USED)METAr   r#   r%   )requestZcsrf_secretr   r   r   	get_tokenN   s    


r+   c             C   s   | j jdt d d| _dS )zj
    Changes the CSRF token in use for a request - should be done on login
    for security purposes.
    T)r(   r'   N)r)   updater&   csrf_cookie_needs_reset)r*   r   r   r   rotate_tokena   s    r.   c             C   s@   t jdt| rt S t| tkr&| S t| tkr:t| S t S )Nz[^a-zA-Z0-9])researchr	   r&   r   CSRF_TOKEN_LENGTHr   r#   )r$   r   r   r   _sanitize_tokenm   s    r2   c             C   s   t t| t|S )N)r   r%   )request_csrf_token
csrf_tokenr   r   r   _compare_salted_tokens~   s    r5   c               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )CsrfViewMiddlewarez
    Middleware that requires a present and correct csrfmiddlewaretoken
    for POST requests that have a CSRF cookie, and sets an outgoing
    CSRF cookie.

    This middleware should be used in conjunction with the csrf_token template
    tag.
    c             C   s
   d|_ d S )NT)csrf_processing_done)selfr*   r   r   r   _accept   s    zCsrfViewMiddleware._acceptc             C   s(   t jd||jd|dd t ||dS )NzForbidden (%s): %si  )status_coder*   )extra)reason)loggerwarningpathr   )r8   r*   r<   r   r   r   _reject   s
    zCsrfViewMiddleware._rejectc                s  t |ddrd S y|jtj }W n tk
r8   d }Y n"X t|}||krPd|_||jd< t |ddrjd S |jdkrt |d
dr| j	|S |j
 rzt|jjdddd  d kr| j|tS t  d j jfkr| j|tS  jdk r| j|tS tjd kr|j }n$tj}|j }|dkr6d||f }ttj}	|	j| t fdd|	D szt j  }
| j||
S |d kr| j|tS d}|jdkry|jjdd}W n tk
r   Y nX |dkr|jjtj d}t|}t!||s| j|t"S | j	|S )Nr7   FTr'   Zcsrf_exemptGETHEADOPTIONSTRACEZ_dont_enforce_csrf_checksZHTTP_REFERERreplace)Zstrings_onlyerrorsr   https44380z%s:%sc             3   s   | ]}t  j|V  qd S )N)r
   netloc)r   host)refererr   r   r      s    z2CsrfViewMiddleware.process_view.<locals>.<genexpr>POSTZcsrfmiddlewaretoken)rA   rB   rC   rD   )rH   rI   )#getattrZCOOKIESr   CSRF_COOKIE_NAMEKeyErrorr2   r-   r)   methodr9   Z	is_securer	   getr@   REASON_NO_REFERERr   schemerJ   REASON_MALFORMED_REFERERREASON_INSECURE_REFERERCSRF_COOKIE_DOMAINget_hostZget_portlistZCSRF_TRUSTED_ORIGINSappendanyREASON_BAD_REFERERgeturlREASON_NO_CSRF_COOKIErM   IOErrorZCSRF_HEADER_NAMEr5   REASON_BAD_TOKEN)r8   r*   callbackcallback_argscallback_kwargsZcookie_tokenr4   Zgood_refererZserver_portZ
good_hostsr<   r3   r   )rL   r   process_view   sh    










zCsrfViewMiddleware.process_viewc          	   C   sl   t |ddst |ddr|S |jjdds.|S |jtj|jd tjtjtjtj	tj
d t|d	 d|_|S )
Nr-   Fcsrf_cookie_setr(   r'   )Zmax_agedomainr?   securehttponlyCookieT)ri   )rN   r)   rR   
set_cookier   rO   ZCSRF_COOKIE_AGErW   ZCSRF_COOKIE_PATHZCSRF_COOKIE_SECUREZCSRF_COOKIE_HTTPONLYr   re   )r8   r*   responser   r   r   process_response  s    

z#CsrfViewMiddleware.process_responseN)__name__
__module____qualname____doc__r9   r@   rd   rl   r   r   r   r   r6      s
   
ur6   )0rp   
__future__r   loggingr/   stringZdjango.confr   Zdjango.urlsr   Zdjango.utils.cacher   Zdjango.utils.cryptor   r   Zdjango.utils.deprecationr   Zdjango.utils.encodingr	   Zdjango.utils.httpr
   Zdjango.utils.six.movesr   Z#django.utils.six.moves.urllib.parser   	getLoggerr=   rS   r\   r^   r`   rU   rV   r   r1   ascii_lettersdigitsr   r   r   r#   r%   r&   r+   r.   r2   r5   r6   r   r   r   r   <module>   sB   
	