o
    [h                     @   sl   d Z ddlmZ ddlZddlZddlmZ ddlmZmZ ddl	m
Z
 dd	lmZ d
ZG dd deZdS )a  
A provided CSRF implementation which puts CSRF data in a session.

This can be used fairly comfortably with many `request.session` type
objects, including the Werkzeug/Flask session store, Django sessions, and
potentially other similar objects which use a dict-like API for storing
session keys.

The basic concept is a randomly generated value is stored in the user's
session, and an hmac-sha1 of it (along with an optional expiration time,
for extra security) is used as the value of the csrf_token. If this token
validates with the hmac of the random value + expiration time, and the
expiration time is not passed, the CSRF validation will pass.
    )unicode_literalsN)sha1)datetime	timedelta   )ValidationError   )CSRF)SessionCSRFc                       sP   e Zd ZdZ fddZdd Zdd Zdd	 Zed
d Z	edd Z
  ZS )r
   z%Y%m%d%H%M%Sc                    s   |j | _tt| |S )N)meta	form_metasuperr
   
setup_form)selfform	__class__ {/home/ubuntu/experiments/live_experiments/Pythonexperiments/Otree/venv/lib/python3.10/site-packages/wtforms/csrf/session.pyr       s   zSessionCSRF.setup_formc                 C   s   | j }|jd u rtd|jd u rtd| j}d|vr'ttd	 |d< | j
r>|  | j
 | j}d|d |f }nd}|d }tj|j|dtd}d	||	 f S )
Nz<must set `csrf_secret` on class Meta for SessionCSRF to workz2Must provide a session-like object as csrf contextcsrf@   z%s%s utf8	digestmodz%s##%s)r   csrf_secret	Exceptioncsrf_context	TypeErrorsessionr   osurandom	hexdigest
time_limitnowstrftimeTIME_FORMAThmacnewencode)r   Zcsrf_token_fieldr   r   expiresZ
csrf_build	hmac_csrfr   r   r   generate_csrf_token$   s   

zSessionCSRF.generate_csrf_tokenc           	      C   s   | j }|jrd|jvrt|d|jdd\}}| jd | d}tj|j	|t
d}| |kr;t|d| jrQ|  | j}||krSt|dd S d S )	Nz##zCSRF token missingr   r   r   r   zCSRF failedzCSRF token expired)r   datar   gettextsplitr   r)   r'   r(   r   r   r"   r#   r$   r%   r&   )	r   r   fieldr   r*   r+   Z	check_valZhmac_compareZnow_formattedr   r   r   validate_csrf_token:   s   zSessionCSRF.validate_csrf_tokenc                 C   s   t  S )zP
        Get the current time. Used for test mocking/overriding mainly.
        )r   r$   r   r   r   r   r$   L   s   zSessionCSRF.nowc                 C   s   t | jdtddS )NZcsrf_time_limit   )minutes)getattrr   r   r2   r   r   r   r#   R      zSessionCSRF.time_limitc                 C   s   t | jjd| jjS )Nr   )r5   r   r   r2   r   r   r   r   V   r6   zSessionCSRF.session)__name__
__module____qualname__r&   r   r,   r1   r$   propertyr#   r   __classcell__r   r   r   r   r
      s    
r
   )__doc__
__future__r   r'   r    hashlibr   r   r   Z
validatorsr   corer	   __all__r
   r   r   r   r   <module>   s    