o
    g'                     @   s  d dl 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	 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 d dlmZ d dlmZ d dlmZ dZeeZdddZd ddZ	d!ddZG dd deZG dd dZG dd deZdd Z dS )"    N)urlparse)	Blueprint)current_app)g)request)session)BadData)SignatureExpired)URLSafeTimedSerializer)
BadRequest)ValidationError)CSRF)generate_csrfvalidate_csrfCSRFProtectc                 C   s   t | dtjdd} t |dddd}|tvrWt| dd}|tvr+tt	d	
 t|< z	|t| }W n tyP   tt	d	
 t|< |t| }Y nw tt|| t|S )
a  Generate a CSRF token. The token is cached for a request, so multiple
    calls to this function will generate the same token.

    During testing, it might be useful to access the signed token in
    ``g.csrf_token`` and the raw token in ``session['csrf_token']``.

    :param secret_key: Used to securely sign the token. Default is
        ``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
    :param token_key: Key where token is stored in session for comparison.
        Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.
    WTF_CSRF_SECRET_KEY%A secret key is required to use CSRF.messageWTF_CSRF_FIELD_NAME
csrf_token%A field name is required to use CSRF.wtf-csrf-tokensalt@   )_get_configr   
secret_keyr   r
   r   hashlibsha1osurandom	hexdigestdumps	TypeErrorsetattrget)r   	token_key
field_namestoken r+   [/var/www/html/portale_awareness/portale-venv/lib/python3.10/site-packages/flask_wtf/csrf.pyr      s0   
r   c              
   C   s   t |dtjdd}t |dddd}t |ddd	d
}| std|tvr'tdt|dd}z	|j| |d}W n! tyG } ztd|d}~w tyW } ztd|d}~ww t	
t| |sdtddS )a  Check if the given data is a valid CSRF token. This compares the given
    signed token to the one stored in the session.

    :param data: The signed CSRF token to be checked.
    :param secret_key: Used to securely sign the token. Default is
        ``WTF_CSRF_SECRET_KEY`` or ``SECRET_KEY``.
    :param time_limit: Number of seconds that the token is valid. Default is
        ``WTF_CSRF_TIME_LIMIT`` or 3600 seconds (60 minutes).
    :param token_key: Key where token is stored in session for comparison.
        Default is ``WTF_CSRF_FIELD_NAME`` or ``'csrf_token'``.

    :raises ValidationError: Contains the reason that validation failed.

    .. versionchanged:: 0.14
        Raises ``ValidationError`` with a specific error message rather than
        returning ``True`` or ``False``.
    r   r   r   r   r   r   WTF_CSRF_TIME_LIMIT  F)requiredzThe CSRF token is missing.z"The CSRF session token is missing.r   r   )max_agezThe CSRF token has expired.NzThe CSRF token is invalid.zThe CSRF tokens do not match.)r   r   r   r   r   r
   loadsr	   r   hmaccompare_digest)datar   
time_limitr'   r(   r)   r*   er+   r+   r,   r   B   s<   

r   TCSRF is not configured.c                 C   s.   | du rt j||} |r| du rt|| S )a  Find config value based on provided value, Flask config, and default
    value.

    :param value: already provided config value
    :param config_name: Flask ``config`` key
    :param default: default value if not provided or configured
    :param required: whether the value must not be ``None``
    :param message: error message if required config is not found
    :raises KeyError: if required config is not found
    N)r   configr&   RuntimeError)valueconfig_namedefaultr/   r   r+   r+   r,   r   v   s
   r   c                       s,   e Zd Z fddZdd Zdd Z  ZS )_FlaskFormCSRFc                    s   |j | _ t |S N)metasuper
setup_form)selfform	__class__r+   r,   rA      s   z_FlaskFormCSRF.setup_formc                 C   s   t | jj| jjdS )N)r   r'   )r   r?   csrf_secretcsrf_field_name)rB   csrf_token_fieldr+   r+   r,   generate_csrf_token   s   z"_FlaskFormCSRF.generate_csrf_tokenc              
   C   s^   t ddrd S zt|j| jj| jj| jj W d S  ty. } z	t	
|jd   d }~ww )N
csrf_validFr   )r   r&   r   r4   r?   rF   csrf_time_limitrG   r   loggerinfoargs)rB   rC   fieldr6   r+   r+   r,   validate_csrf_token   s   
z"_FlaskFormCSRF.validate_csrf_token)__name__
__module____qualname__rA   rI   rP   __classcell__r+   r+   rD   r,   r=      s    r=   c                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )r   a[  Enable CSRF protection globally for a Flask app.

    ::

        app = Flask(__name__)
        csrf = CSRFProtect(app)

    Checks the ``csrf_token`` field sent with forms, or the ``X-CSRFToken``
    header sent with JavaScript requests. Render the token in templates using
    ``{{ csrf_token() }}``.

    See the :ref:`csrf` documentation.
    Nc                 C   s&   t  | _t  | _|r| | d S d S r>   )set_exempt_views_exempt_blueprintsinit_app)rB   appr+   r+   r,   __init__   s
   zCSRFProtect.__init__c                    s    j d<  jdd  jdd t jdg d jd<  jdd  jd	d
dg  jdd  jdd t jjd<  dd   j	 fdd}d S )NcsrfWTF_CSRF_ENABLEDTWTF_CSRF_CHECK_DEFAULTWTF_CSRF_METHODS)POSTPUTPATCHDELETEr   r   WTF_CSRF_HEADERSzX-CSRFTokenzX-CSRF-Tokenr-   r.   WTF_CSRF_SSL_STRICTc                   S   s   dt iS )Nr   )r   r+   r+   r+   r,   <lambda>   s    z&CSRFProtect.init_app.<locals>.<lambda>c                     s    j d sd S  j d sd S tj j d vrd S tjsd S  jtjjv r)d S  jtj} | j	 d| j
 }|jv r@d S   d S )Nr\   r]   r^   .)r8   r   methodendpoint
blueprintsr&   	blueprintrW   view_functionsrR   rQ   rV   protect)viewdestrY   rB   r+   r,   csrf_protect   s   


z*CSRFProtect.init_app.<locals>.csrf_protect)

extensionsr8   
setdefaultrU   r&   r   	jinja_envglobalscontext_processorbefore_request)rB   rY   rp   r+   ro   r,   rX      s   

zCSRFProtect.init_appc                 C   sv   t jd }tj|}|r|S tjD ]}||r$tj| }|r$|  S qt jd D ]}tj|}|r8|  S q*d S )Nr   rc   )r   r8   r   rC   r&   endswithheaders)rB   r(   
base_tokenkeyr   header_namer+   r+   r,   _get_csrf_token   s    



zCSRFProtect._get_csrf_tokenc              
   C   s   t jtjd vr
d S zt|   W n" ty4 } zt|j	d  | 
|j	d  W Y d }~nd }~ww t jrWtjd rWt jsE| 
d dt j d}tt j|sW| 
d dt_d S )	Nr^   r   rd   zThe referrer header is missing.zhttps:///z%The referrer does not match the host.T)r   rg   r   r8   r   r|   r   rL   rM   rN   _error_response	is_securereferrerhostsame_originr   rJ   )rB   r6   good_referrerr+   r+   r,   rl      s    


zCSRFProtect.protectc                 C   sL   t |tr| j| |S t |tr|}n	d|j|jf}| j| |S )a  Mark a view or blueprint to be excluded from CSRF protection.

        ::

            @app.route('/some-view', methods=['POST'])
            @csrf.exempt
            def some_view():
                ...

        ::

            bp = Blueprint(...)
            csrf.exempt(bp)

        rf   )	
isinstancer   rW   addstrjoinrR   rQ   rV   )rB   rm   view_locationr+   r+   r,   exempt  s   

zCSRFProtect.exemptc                 C   s   t |r>   )	CSRFError)rB   reasonr+   r+   r,   r~   2  s   zCSRFProtect._error_responser>   )
rQ   rR   rS   __doc__rZ   rX   r|   rl   r   r~   r+   r+   r+   r,   r      s    
)r   c                   @   s   e Zd ZdZdZdS )r   zRaise if the client sends invalid CSRF data with the request.

    Generates a 400 Bad Request response with the failure reason by default.
    Customize the response by registering a handler with
    :meth:`flask.Flask.errorhandler`.
    zCSRF validation failed.N)rQ   rR   rS   r   descriptionr+   r+   r+   r,   r   6  s    r   c                 C   s4   t | }t |}|j|jko|j|jko|j|jkS r>   )r   schemehostnameport)current_uricompare_uricurrentcomparer+   r+   r,   r   A  s   

r   )NN)NNN)NTr7   )!r   r2   loggingr    urllib.parser   flaskr   r   r   r   r   itsdangerousr   r	   r
   werkzeug.exceptionsr   wtformsr   wtforms.csrf.corer   __all__	getLoggerrQ   rL   r   r   r   r=   r   r   r   r+   r+   r+   r,   <module>   s6    


+5
 