File: //home/arjun/projects/buyercall_forms/buyercall/buyercall/lib/__pycache__/rate_limit.cpython-38.pyc
U
k�if�0 � @ st d dl Z d dlmZmZ d dlmZ d dlZd dlmZmZ d dl m
Z
e �e�Z
G dd� de�ZG dd � d �ZdS )
� N)�datetime� timedelta)�Enum)�jsonify�request)�current_userc @ sN e Zd ZdZdZdZdZdZdZdZ e
eed�d d
��Z
e
ed�dd
��ZdS )�
TimePeriod�second�minute�hour�day�week�month�year)�value�returnc C s |dd� | j �� D �kS )Nc S s g | ]
}|j �qS � �r )�.0�memberr r �J/home/arjun/projects/buyercall_forms/buyercall/buyercall/lib/rate_limit.py�
<listcomp> s z'TimePeriod.is_valid.<locals>.<listcomp>)�__members__�values)�clsr r r r �is_valid s zTimePeriod.is_validr c C s | D ]}|j |kr| S qd S �Nr )r r �itemr r r �get_by_value s
zTimePeriod.get_by_valueN)�__name__�
__module__�__qualname__�SECOND�MINUTE�HOUR�DAY�WEEK�MONTH�YEAR�classmethod�str�boolr r r r r r r s r c @ s� e Zd ZdZdd� Zdd� Zdd� Zdd � Zede d�dd
��Z
ded�dd�Zee
ed�dd��Zdd� Zeed�dd��Zd
S )� RateLimitz"Custom rate-limiting functionalityc C s d | _ d | _d | _d S r )�redis_client�
parsed_limits�
excluded_urls��selfr r r �__init__# s zRateLimit.__init__c C sL t j|j�d�|j�d�d�| _| �|j�d��| _| �|j�d��| _d S )N�REDIS_CONFIG_URL�REDIS_CONFIG_PORT)�host�port�REQUEST_RATE_LIMIT�REQUEST_RATE_LIMIT_EXCLUDE) �redisZStrictRedis�config�getr- �
_parse_limitsr. �_validate_excludesr/ )r1 Z flask_appr r r �init_app( s
�zRateLimit.init_appc
C s� | � � r4tdd� | jd D ��r4tdd� | jD ��r8d S �zLt�� }d}dd� | jd D �}|rh|d nd }|svW d S d }tj�d��r^d tj k�rXtj �
d d �}|s�W d S |�d
�d }|s�W d S ddlm
} |�|�}|s�W d S dd
lm} | j�| j|k��� }
|
�sW d S ddlm} d|
j� d|� �}|j�|jdk|j|
jk��� }|j}nW d S |�spt�spW d S |�s�t�r�t�� }d|� d|� �}| j�|�}
d }| j�
dg �D ] }||�
d�k�r�|} �qԐq�|
�r�t|
�
d|d ��}t|
�
dd��}t|
�
dd��}|
�
dt�� �|��}t�|� � |�}t�� |k�r�|d }d}d}| �!|d �}t�� t"|d� }| j�#|d|� | j�#|d|� | j�#|d|�|�� | j�#|d|� |dk�r0|d7 }|�
d��r�||�
dd�k�r�|dk�r�ddl$m%} ddl&m'} |d � d|d � �}tj(�
d��r:tj(�
d�n
tj(�
d �}|�)|�}|�
d!d ��r�|�
d!d"�� d#|�
d$d"�� d#|�
d%d"�� �}nd }|j*|tj|tj+||d&� | j�#|dd� n| j�#|d|� t,d'd(�d)fW S nR|d }d}| �!|d �}t�� t"|d� }| j�#|d|� | j�#|d|�|�� ||dk�r@dnd8 }|||d k �rZdn|d 7 }| j�#|d|� | j�#|d|� W n8 t-k
�r� } zt.�/d*t0|�� �� W 5 d }~X Y nX d S )+Nc S s g | ]}t tj��|��qS r �r* r �path�
startswith�r �urlr r r r 0 s z!RateLimit.set.<locals>.<listcomp>�urlsc S s g | ]}t tj��|��qS r r? rB r r r r 1 s �%Y-%m-%d %H:%M:%Sc S s g | ]}t tj��|�r|�qS r r? �r �_patternr r r r 6 s r z/apiZ Authorize� � )�ApiToken)�Partnership)�Userzrate_limit:partnership-�:�partnerzrate_limit:user-�detail� remaining_requests�number�
requests_sents notify_limit� expiry�period��seconds�notify_limit)� send_request_limit_exceeded_mail)�IpApi� per �HTTP_X_FORWARDED_FOR�REMOTE_ADDR�city� z, �
regionName�country)�method�user_ip�locationz%Rate limit exceeded. Try again later.)�errorsi� zRate-Limit Error : )1�_is_config_valid�anyr. r/ r �get_idr r@ rA �headersr; �split�'buyercall.blueprints.partnership.modelsrJ Zcheck_tokenrK �query�filterZapi_token_id�first� buyercall.blueprints.user.modelsrL �id�role�partnership_idr- �hgetall�intr �utcnow�strftime�strptime�decode�_get_expiryr ZhsetZ#buyercall.blueprints.sysadmin.tasksrX Z.buyercall.blueprints.sysadmin.utilities.ip_apirY �environ�get_request_complete_details�delayra r � Exception�logger�warningr* )r1 �user_id� dt_stringrG �key�auth_header�tokenrJ Z api_tokenrK �partnershiprL Zpartner_user�rate_limit_data�_limit_item�rule�remaining_requests�
requests_sentrW �expiry�expiry_date�expiry_timerX rY Z
_limit_stringrb Z
ip_detailsrc �excr r r �set. s� ��
�
�
�
. �&z
RateLimit.setc C s� | � � r4tdd� | jd D ��r4tdd� | jD ��r8|S t�� }d}dd� | jd D �}|rd|d nd }|sp|S d|� d |� �}d }| j�d
g �D ]}||�d�kr�|} q�q�| j�|�}|d } d}
| � |d
�}t
�� t|d� }|�r6t
|�d|d ��} t
|�dd��}
|�dt
�� �|��}
t
�|
�� |�}dt|d �fdt|
�fdt| �fd|�|�fg}|D ]}|jj|� �ql|S )Nc S s g | ]}t tj��|��qS r r? rB r r r r � s z!RateLimit.get.<locals>.<listcomp>rD c S s g | ]}t tj��|��qS r r? rB r r r r � s rE c S s g | ]}t tj��|�r|�qS r r? rF r r r r � s r zrate_limit:rM rO rQ rI rT rU rP rR rS zX-RateLimit-LimitzX-RateLimit-SentzX-RateLimit-RemainingzX-RateLimit-Reset)re rf r. r/ r rg r; r- rr rx r rt r rs ru rv rw r* rh �
add_header)r1 �responser r� rG r� r� r� r� r� r� r� r� r� rh �headerr r r r; � sH
��
�z
RateLimit.getN)�limit_stringc C s� zp| rdt | �kr*t�d| � d�� W d S | �d�\}}t�|�sZt�d| � d�� W d S t�|�}t|�|fW S tk
r� t�d| � d�� Y d S X d S )NZper�Invalid config: "�"rZ ) r* r} r~ ri r r r rs r| )r� �limitrT r r r �_parse_limit_value� s
zRateLimit._parse_limit_value)�
limit_rulec
s z�g g d�}|D ]�� � � dg �}� � d�}� � d�}t� fdd�dD ��sR W d S t|t�sd W d S |rl|st W d S | �|�\}}|r�|s� W d S ||||d�}|d �|� |d
�|� q|W S tk
�r } z t� dt
| �� d�� W Y �d S d } ~ X Y nX d S )
N)rD rO �url_starts_withr� rW c 3 s | ]}|� kV qd S r r )r r� �r� r r � <genexpr>� s z*RateLimit._parse_limits.<locals>.<genexpr>)r� r� )rD rQ rT rW rD rO r� r� )r; �all�
isinstance�listr� �extend�appendr| r} �debugr* )
r1 r� Z rl_configZ_urls�_limitZ
_notify_limitrQ rT Z_item_config�er r� r r<