
    wdf.                     \   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mZm	Z	m
Z
mZ d dlmZ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mZ dZ ej        e          ZddZ ddZ!	 	 ddZ" G d de          Z# G d de$          Z% G d de%          Z& G d de          Z'd Z(dS )    N)wraps)	Blueprintcurrent_appgrequestsession)BadDataSignatureExpiredURLSafeTimedSerializer)
BadRequest)safe_str_cmp)ValidationError)CSRF   )FlaskWTFDeprecationWarningstring_typesurlparse)generate_csrfvalidate_csrfCSRFProtectc                    t          | dt          j        d          } t          |ddd          }|t          vrt	          | d          }|t
          vr@t          j        t          j	        d	                    
                                t
          |<   	 |                    t
          |                   }np# t          $ rc t          j        t          j	        d	                    
                                t
          |<   |                    t
          |                   }Y nw xY wt          t          ||           t          j        |          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 comparision.
        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tokens        S/var/www/book.euthymeo.com/html/venv/lib/python3.11/site-packages/flask_wtf/csrf.pyr   r      s8    );+A7  J (,7  J
 ":4DEEEW$$"),rz"~~">">"H"H"J"JGJ	1GGGJ/00EE 	1 	1 	1"),rz"~~">">"H"H"J"JGJGGGJ/00EEE	1 	:u%%%5s    B7 7A*D$#D$c                    t          |dt          j        d          }t          |ddd          }t          |ddd	
          }| st          d          |t          vrt          d          t          |d          }	 |                    | |          }n5# t          $ r t          d          t          $ r t          d          w xY wt          t          |         |          st          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 comparision.
        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.zThe CSRF token is invalid.zThe CSRF tokens do not match.N)
r#   r   r$   r   r   r   loadsr
   r	   r   )datar$   
time_limitr.   r/   r0   r1   s          r2   r   r   ;   sF   & );+A7  J (,7  J )4%  J  <:;;;  BCCCz0@AAAA<j11 = = =;<<< < < <:;;;< 
+U33 ?=>>>? ?s   ?B 2C	TCSRF is not configured.c                 p    |  t           j                            ||          } |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
    )r   configr-   RuntimeError)valueconfig_namedefaultr6   r   s        r2   r#   r#   m   s@     }"&&{G<< $EM7###L    c                   *     e Zd Z fdZd Zd Z xZS )_FlaskFormCSRFc                 l    |j         | _         t          t          |                               |          S N)metasuperrD   
setup_form)selfform	__class__s     r2   rI   z_FlaskFormCSRF.setup_form   s*    I	^T**55d;;;rB   c                 L    t          | j        j        | j        j                  S )N)r$   r.   )r   rG   csrf_secretcsrf_field_name)rJ   csrf_token_fields     r2   generate_csrf_tokenz"_FlaskFormCSRF.generate_csrf_token   s)    y,i/
 
 
 	
rB   c                    t          j        dd          rd S 	 t          |j        | j        j        | j        j        | j        j                   d S # t          $ r+}t          
                    |j        d                     d }~ww xY w)N
csrf_validFr   )r   r-   r   r9   rG   rN   csrf_time_limitrO   r   loggerinfoargs)rJ   rK   fieldes       r2   validate_csrf_tokenz"_FlaskFormCSRF.validate_csrf_token   s    5u%% 	F		
	%	)	)	      	 	 	KKq	"""	s   5A 
B&B  B)__name__
__module____qualname__rI   rQ   rZ   __classcell__rL   s   @r2   rD   rD      sV        < < < < <
 
 
      rB   rD   c                   >    e Zd ZdZd
dZd Zd Zd Zd Zd Z	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                     t                      | _        t                      | _        |r|                     |           d S d S rF   )set_exempt_views_exempt_blueprintsinit_app)rJ   apps     r2   __init__zCSRFProtect.__init__   sD     UU"%%% 	MM#	 	rB   c                 D     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            j	         f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-Tokenr4   r5   WTF_CSRF_SSL_STRICTc                      dt           iS )Nr   )r    rB   r2   <lambda>z&CSRFProtect.init_app.<locals>.<lambda>   s    |]&C rB   c                     j         d         sd S j         d         sd S t          j        j         d         vrd S t          j        sd S t          j        j        v rd S j                            t          j                  } d                    | j	        | j
                  }|j        v rd S                                  d S )Nrj   rk   rl   z{0}.{1})r=   r   methodendpoint	blueprintrd   view_functionsr-   formatr\   r[   rc   protect)viewdestrf   rJ   s     r2   csrf_protectz*CSRFProtect.init_app.<locals>.csrf_protect   s    :01 :67 ~SZ0B%CCC#  D$;;;%))'*:;;D##DOT]CCDt)))LLNNNNNrB   )

extensionsr=   
setdefaultrb   r-   r   	jinja_envglobalscontext_processorbefore_request)rJ   rf   r   s   `` r2   re   zCSRFProtect.init_app   sG   !%v
0$777
6===),SZ^^ B B B.
 .
 * *
%& 	
3\BBB
 ?	
 	
 	
 	
3T:::
3T:::.;l+CCDDD			 	 	 	 	 
		 	 	rB   c                 \   t           j        d         }t          j                            |          }|r|S t          j        D ]/}|                    |          rt          j        |         }|r|c S 0t           j        d         D ]'}t          j                            |          }|r|c S (d S )Nr   rq   )r   r=   r   rK   r-   endswithheaders)rJ   r/   
base_tokenkeyr   header_names         r2   _get_csrf_tokenzCSRFProtect._get_csrf_token   s     '(=>
\%%j11
 	 < 	& 	&C||J'' &$\#.
 &%%%% '-.@A 	" 	"K ,,[99J "!!!!" trB   c                 v   t           j        t          j        d         vrd S 	 t	          |                                            n\# t          $ rO}t                              |j	        d                    | 
                    |j	        d                    Y d }~nd }~ww xY wt           j        rt          j        d         rot           j        s| 
                    d           d                    t           j                  }t          t           j        |          s| 
                    d           dt           _        d S )Nrl   r   rr   zThe referrer header is missing.zhttps://{0}/z%The referrer does not match the host.T)r   rw   r   r=   r   r   r   rU   rV   rW   _error_response	is_securereferrerr{   hostsame_originr   rS   )rJ   rY   good_referrers      r2   r|   zCSRFProtect.protect   s*   >!34F!GGGF	,$..001111 	, 	, 	,KKq	"""  ++++++++	,  	N!34I!J 	N# H$$%FGGG*11',??Mw/?? N$$%LMMMs   !A 
BABBc                    t          |t                    r!| j                            |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)

        .)

isinstancer   rd   addnamer   joinr\   r[   rc   )rJ   r}   view_locations      r2   exemptzCSRFProtect.exempt  s    " dI&& 	#''	222KdL)) 	G MMHHdot}%EFFM}---rB   c                      t          |          rF   )	CSRFError)rJ   reasons     r2   r   zCSRFProtect._error_response-  s    rB   c                     t          j        t          d          d           t                    fd            }|| _        S )a  Register a function that will generate the response for CSRF errors.

        .. deprecated:: 0.14
            Use the standard Flask error system with
            ``@app.errorhandler(CSRFError)`` instead. This will be removed in
            version 1.0.

        The function will be passed one argument, ``reason``. By default it
        will raise a :class:`~flask_wtf.csrf.CSRFError`. ::

            @csrf.error_handler
            def csrf_error(reason):
                return render_template('error.html', reason=reason)

        Due to historical reasons, the function may either return a response
        or raise an exception with :func:`flask.abort`.
        z"@csrf.error_handler" is deprecated. Use the standard Flask error system with "@app.errorhandler(CSRFError)" instead. This will be removed in 1.0.   
stacklevelc                 ^    t          j         |                     }t          |          )N)response)r   make_responser   )r   r   r}   s     r2   handlerz*CSRFProtect.error_handler.<locals>.handlerI  s,    "0f>>HX....rB   )warningswarnr   r   r   )rJ   r}   r   s    ` r2   error_handlerzCSRFProtect.error_handler0  so    & 	0&
 
 		 	 	 	 
t	/ 	/ 	/ 	/ 
	/  'rB   rF   )r[   r\   r]   __doc__rg   re   r   r|   r   r   r   rt   rB   r2   r   r      s            ) ) )V  2  *  :         rB   r   c                   $     e Zd ZdZd fd	Z xZS )CsrfProtectzW
    .. deprecated:: 0.14
        Renamed to :class:`~flask_wtf.csrf.CSRFProtect`.
    Nc                     t          j        t          d          d           t          t          |                               |           d S )NzU"flask_wtf.CsrfProtect" has been renamed to "CSRFProtect" and will be removed in 1.0.r   r   )rf   )r   r   r   rH   r   rg   )rJ   rf   rL   s     r2   rg   zCsrfProtect.__init__X  s\    0*
 
 	 	 	 	 	k4  ))c)22222rB   rF   )r[   r\   r]   r   rg   r^   r_   s   @r2   r   r   R  sG         
3 3 3 3 3 3 3 3 3 3rB   r   c                       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)r[   r\   r]   r   descriptionrt   rB   r2   r   r   `  s          ,KKKrB   r   c                     t          |           }t          |          }|j        |j        k    o|j        |j        k    o|j        |j        k    S rF   )r   schemehostnameport)current_uricompare_uricurrentcompares       r2   r   r   k  sS    {##G{##G 	'.( 	) 00	)LGL(rB   )NN)NNN)NTr;   ))r%   loggingr'   r   	functoolsr   flaskr   r   r   r   r   itsdangerousr	   r
   r   werkzeug.exceptionsr   werkzeug.securityr   wtformsr   wtforms.csrf.corer   _compatr   r   r   __all__	getLoggerr[   rU   r   r   r#   rD   objectr   r   r   r   rt   rB   r2   <module>r      s     				        = = = = = = = = = = = = = = J J J J J J J J J J * * * * * * * * * * * * # # # # # # " " " " " " G G G G G G G G G G
;		8	$	$$ $ $ $N/? /? /? /?f !%4   0    T   8n n n n n& n n nb3 3 3 3 3+ 3 3 3, , , , ,
 , , ,    rB   