
vÅÏ^k5  ã               @   s¥  d  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	 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 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 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. Gd( 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.
é    N)Úurlparse)Úsettings)ÚDisallowedHostÚImproperlyConfigured)Úget_callable)Úpatch_vary_headers)Úconstant_time_compareÚget_random_string)ÚMiddlewareMixin)Úis_same_domain)Úlog_responsezdjango.security.csrfz%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.é    é   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   ú8/tmp/pip-build-8lau8j11/django/django/middleware/csrf.pyÚ_get_failure_view$   s    r   c               C   s   t  t d t ƒS)NÚallowed_chars)r	   ÚCSRF_SECRET_LENGTHÚCSRF_ALLOWED_CHARSr   r   r   r   Ú_get_new_csrf_string)   s    r   c                sn   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>4   s    z&_salt_cipher_secret.<locals>.<genexpr>Ú c             3   s-   |  ]# \ } } ˆ  | | t  ˆ  ƒ Vq d  S)N)Úlen)r   r   Úy)r   r   r   r   5   s    )r   r   ÚzipÚjoin)ZsecretÚsaltÚpairsÚcipherr   )r   r   Ú_salt_cipher_secret-   s
    	5"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   B   s    z'_unsalt_cipher_token.<locals>.<genexpr>r   c             3   s#   |  ] \ } } ˆ  | | Vq d  S)Nr   )r   r   r   )r   r   r   r   C   s    )r   r   r   r   )Útokenr    r!   r   )r   r   Ú_unsalt_cipher_token9   s
    5r%   c               C   s   t  t ƒ  ƒ S)N)r#   r   r   r   r   r   Ú_get_new_csrf_tokenF   s    r&   c             C   sX   d |  j  k r. t ƒ  } t | ƒ |  j  d <n t |  j  d ƒ } d |  j  d <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.
    ÚCSRF_COOKIETÚCSRF_COOKIE_USED)ÚMETAr   r#   r%   )ÚrequestZcsrf_secretr   r   r   Ú	get_tokenJ   s    
	r+   c             C   s,   |  j  j d d d t ƒ  i ƒ d |  _ d S)zi
    Change the CSRF token in use for a request - should be done on login
    for security purposes.
    r(   Tr'   N)r)   Úupdater&   Úcsrf_cookie_needs_reset)r*   r   r   r   Úrotate_token]   s    	r.   c             C   sR   t  j d |  ƒ r t ƒ  St |  ƒ t k r/ |  St |  ƒ t k rK t |  ƒ St ƒ  S)Nz[^a-zA-Z0-9])ÚreÚsearchr&   r   ÚCSRF_TOKEN_LENGTHr   r#   )r$   r   r   r   Ú_sanitize_tokeni   s    
r2   c             C   s   t  t |  ƒ t | ƒ ƒ S)N)r   r%   )Úrequest_csrf_tokenÚ
csrf_tokenr   r   r   Ú_compare_salted_tokensz   s    	r5   c               @   sj   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 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  S)NT)Úcsrf_processing_done)Úselfr*   r   r   r   Ú_accept   s    	zCsrfViewMiddleware._acceptc          
   C   s>   t  ƒ  | d | ƒ} t d | | j d | d | d t ƒ| S)NÚreasonzForbidden (%s): %sÚresponser*   Úlogger)r   r   Úpathr<   )r8   r*   r:   r;   r   r   r   Ú_reject”   s    zCsrfViewMiddleware._rejectc             C   s°   t  j rZ y | j j t ƒ SWq¬ t k
 rV t d t  j d  k rH d n d ƒ ‚ Yq¬ XnR y | j t  j	 } Wn t
 k
 r† d  SYn Xt | ƒ } | | k r¨ d | _ | Sd  S)Nz†CSRF_USE_SESSIONS is enabled, but request.session is not set. SessionMiddleware must appear before CsrfViewMiddleware in MIDDLEWARE%s.Z_CLASSESr   T)r   ÚCSRF_USE_SESSIONSÚsessionÚgetÚCSRF_SESSION_KEYÚAttributeErrorr   Z
MIDDLEWAREZCOOKIESÚCSRF_COOKIE_NAMEÚKeyErrorr2   r-   )r8   r*   Zcookie_tokenr4   r   r   r   Ú
_get_tokenž   s    	'		zCsrfViewMiddleware._get_tokenc             C   s    t  j r? | j j t ƒ | j d k rœ | j d | j t <n] | j t  j | j d d t  j d t  j	 d t  j
 d t  j d t  j d t  j ƒt | d	 ƒ d  S)
Nr'   Zmax_ageÚdomainr=   ÚsecureÚhttponlyZsamesiteÚCookie)zCookie)r   r?   r@   rA   rB   r)   Ú
set_cookierD   ZCSRF_COOKIE_AGEÚCSRF_COOKIE_DOMAINZCSRF_COOKIE_PATHZCSRF_COOKIE_SECUREZCSRF_COOKIE_HTTPONLYZCSRF_COOKIE_SAMESITEr   )r8   r*   r;   r   r   r   Ú
_set_tokenµ   s    						
zCsrfViewMiddleware._set_tokenc             C   s,   |  j  | ƒ } | d  k	 r( | | j d <d  S)Nr'   )rF   r)   )r8   r*   r4   r   r   r   Úprocess_requestÇ   s    z"CsrfViewMiddleware.process_requestc                s’  t  | d d ƒ r d  St  | d d ƒ r, d  S| j d k r…t  | d d ƒ rZ |  j | ƒ S| j ƒ  rÅ| j j d	 ƒ ‰  ˆ  d  k r” |  j | t ƒ St ˆ  ƒ ‰  d
 ˆ  j	 ˆ  j
 f k rÈ |  j | t ƒ Sˆ  j	 d k rç |  j | t ƒ St j rù t j n t j } | d  k	 r9| j ƒ  } | d k r^d | | f } n% y | j ƒ  } Wn t k
 r]Yn Xt t j ƒ } | d  k	 r†| j | ƒ t ‡  f d d †  | Dƒ ƒ sÅt ˆ  j ƒ  } |  j | | ƒ S| j j d ƒ }	 |	 d  k ró|  j | t ƒ Sd
 }
 | j d k r6y | j j d d
 ƒ }
 Wn t k
 r5Yn X|
 d
 k rZ| j j t j d
 ƒ }
 t |
 ƒ }
 t |
 |	 ƒ s…|  j | t  ƒ S|  j | ƒ S)Nr7   FZcsrf_exemptÚGETÚHEADÚOPTIONSÚTRACEZ_dont_enforce_csrf_checksZHTTP_REFERERr   Ú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>r'   ÚPOSTZcsrfmiddlewaretoken)zGETzHEADzOPTIONSzTRACE)rT   z80)!ÚgetattrÚmethodr9   Z	is_securer)   rA   r>   ÚREASON_NO_REFERERr   ÚschemerV   ÚREASON_MALFORMED_REFERERÚREASON_INSECURE_REFERERr   r?   ZSESSION_COOKIE_DOMAINrL   Zget_portÚget_hostr   ÚlistZCSRF_TRUSTED_ORIGINSÚappendÚanyÚREASON_BAD_REFERERÚgeturlÚREASON_NO_CSRF_COOKIErY   ÚOSErrorZCSRF_HEADER_NAMEr2   r5   ÚREASON_BAD_TOKEN)r8   r*   ÚcallbackÚcallback_argsÚcallback_kwargsZgood_refererZserver_portZ
good_hostsr:   r4   r3   r   )rX   r   Úprocess_viewÍ   s^    	zCsrfViewMiddleware.process_viewc             C   s^   t  | d d ƒ s( t  | d d ƒ r( | S| j j d d ƒ sA | S|  j | | ƒ d | _ | S)Nr-   FÚcsrf_cookie_setr(   T)rZ   r)   rA   rM   rm   )r8   r*   r;   r   r   r   Úprocess_response:  s    	z#CsrfViewMiddleware.process_responseN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r9   r>   rF   rM   rN   rl   rn   r   r   r   r   r6   ƒ   s   
mr6   )0rr   Úloggingr/   ÚstringÚurllib.parser   Zdjango.confr   Zdjango.core.exceptionsr   r   Zdjango.urlsr   Zdjango.utils.cacher   Zdjango.utils.cryptor   r	   Zdjango.utils.deprecationr
   Zdjango.utils.httpr   Zdjango.utils.logr   Ú	getLoggerr<   r\   rd   rf   rh   r^   r_   r   r1   Úascii_lettersÚdigitsr   rB   r   r   r#   r%   r&   r+   r.   r2   r5   r6   r   r   r   r   Ú<module>   sB   
	