U
     5øiéG  ã                   @   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 )Nz„CSRF_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 ƒƒrŒd S tjr˜tjntj}|d krÚz| ¡ }W qö tk
rÖ   ttˆ  ¡  ƒ‚Y qöX n| ¡ }|dkröd||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rŠz|j dd¡}W n tk
rˆ   Y nX |dkrÈz|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| ¡ rÂz|  |¡ 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   

	