a
    y{Jh(                     @   sR  d dl Z d dlZd dlmZmZ d dl mZ d dlmZmZm	Z	m
Z
mZmZmZ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mZmZ d d
lmZ d dlmZ d dl m!Z! d dl"m#Z# eeeddddZ$e#ej%ee&e'f dddZ(e#e	ej%egee f dddZ)G dd deZ*G dd de*Z+G dd de*Z,dS )    N)ABCabstractmethod)	Transport)Any	AwaitableCallableDictOptionalSetTuplecast)MultipartWriterweb)Application)Handler)
middleware)Bot
Dispatcherloggers)TelegramMethod)TelegramType)	InputFile)IPFilter)app
dispatcherkwargsreturnc                   s`   |  d j |ttdd fdd}ttdd fdd}| j| | j| dS )z
    This function helps to configure a startup-shutdown process

    :param app: aiohttp application
    :param dispatcher: aiogram dispatcher
    :param kwargs: additional data
    :return:
    )r   r   N)akwr   c                     s    j f i I d H  d S N)Zemit_startupr   r   r   workflow_data P/var/www/shaz/venv/lib/python3.9/site-packages/aiogram/webhook/aiohttp_server.py
on_startup#   s    z%setup_application.<locals>.on_startupc                     s    j f i I d H  d S r   )Zemit_shutdownr    r!   r#   r$   on_shutdown&   s    z&setup_application.<locals>.on_shutdown)r"   r   r%   appendr&   )r   r   r   r%   r&   r#   r!   r$   setup_application   s    
r(   )	ip_filterrequestr   c                 C   s^   |j dd }r0|jddd^}}||| v fS tt|jd }rZ|\}}||| v fS dS )NzX-Forwarded-For ,   )maxsplitZpeername)r+   F)headersgetsplitr   r   	transportZget_extra_info)r)   r*   Zforwarded_for_Z	peer_namehostr#   r#   r$   check_ip-   s    r5   )r)   r   c                    s    t tjttd fdd}|S )z)

    :param ip_filter:
    :return:
    )r*   handlerr   c                    s8   t  | d\}}|s*tjd| t || I d H S )N)r)   r*   z,Blocking request from an unauthorized IP: %s)r5   r   Zwebhookwarningr   ZHTTPUnauthorized)r*   r6   
ip_addressacceptr)   r#   r$   _ip_filter_middlewareH   s
    z3ip_filter_middleware.<locals>._ip_filter_middleware)r   r   Requestr   r   )r)   r;   r#   r:   r$   ip_filter_middleware?   s    	r=   c                   @   s   e Zd Zd"eeeddddZeeeddddZ	edd	d
dZ
eddddZeejedddZeeeedddZeeeef ddddZeejejdddZeeee  edddZeejejdddZejejdd d!ZeZdS )#BaseRequestHandlerFN)r   handle_in_backgrounddatar   c                 K   s   || _ || _|| _t | _dS )aZ  
        Base handler that helps to handle incoming request from aiohttp
        and propagate it to the Dispatcher

        :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
        :param handle_in_background: immediately responds to the Telegram instead of
            a waiting end of a handler process
        N)r   r?   r@   set_background_feed_update_tasks)selfr   r?   r@   r#   r#   r$   __init__T   s    zBaseRequestHandler.__init__pathr   r   r   c                K   s,   |j | j |jjd|| jfi | dS )z
        Register route and shutdown callback

        :param app: instance of aiohttp Application
        :param path: route path
        :param kwargs:
        POSTN)r&   r'   _handle_closeZrouterZ	add_routehandlerC   r   rF   r   r#   r#   r$   registerg   s    zBaseRequestHandler.register)r   r   c                    s   |   I d H  d S r   )close)rC   r   r#   r#   r$   rH   r   s    z BaseRequestHandler._handle_closer   c                    s   d S r   r#   rC   r#   r#   r$   rL   u   s    zBaseRequestHandler.closer*   r   c                    s   dS )z
        This method should be implemented in subclasses of this class.

        Resolve Bot instance from request.

        :param request:
        :return: Bot instance
        Nr#   rC   r*   r#   r#   r$   resolve_boty   s    
zBaseRequestHandler.resolve_bottelegram_secret_tokenbotr   c                 C   s   d S r   r#   rC   rS   rT   r#   r#   r$   verify_secret   s    z BaseRequestHandler.verify_secret)rT   updater   c                    sD   | j jf ||d| jI d H }t|tr@| j j||dI d H  d S )NrT   rW   rT   result)r   Zfeed_raw_updater@   
isinstancer   Zsilent_call_request)rC   rT   rW   rZ   r#   r#   r$   _background_feed_update   s     
z*BaseRequestHandler._background_feed_update)rT   r*   r   c                    sR   t | j||j|jjdI d H d}| j| || jj	 t
ji |jjdS )NloadsrX   )dumps)asyncioZcreate_taskr\   jsonsession
json_loadsrB   addZadd_done_callbackdiscardr   Zjson_responseZ
json_dumps)rC   rT   r*   Zfeed_update_taskr#   r#   r$   _handle_request_background   s    z-BaseRequestHandler._handle_request_background)rT   rZ   r   c                 C   s   t ddtd d}|s |S ||j}|jddd i }|jdd D ]8\}}|jj	|||d	}|snqN||}|jd|d qN| D ].\}}||
|}|jd||jp|d
 q|S )Nz	form-dataZwebhookBoundary   )boundarymethod)nameF)warnings)rT   files)rj   filename)r   secretsZtoken_urlsafer'   Z__api_method__Zset_content_dispositionZ
model_dumpitemsrb   Zprepare_valuereadrm   )rC   rT   rZ   writerpayloadrl   keyvaluer#   r#   r$   _build_response_writer   s.    
z)BaseRequestHandler._build_response_writerc                    sF   | j j||j|jjdI d H fi | jI d H }tj| j||ddS )Nr]   rY   )body)	r   Zfeed_webhook_updatera   rb   rc   r@   r   Responseru   )rC   rT   r*   rZ   r#   r#   r$   _handle_request   s    z"BaseRequestHandler._handle_requestc                    sb   |  |I d H }| |jdd|s4tjdddS | jrN| j||dI d H S | j||dI d H S )NzX-Telegram-Bot-Api-Secret-Tokenr+   Unauthorizedi  )rv   status)rT   r*   )	rQ   rV   r/   r0   r   rw   r?   rf   rx   )rC   r*   rT   r#   r#   r$   rI      s    zBaseRequestHandler.handle)F)__name__
__module____qualname__r   boolr   rD   strr   rK   rH   r   rL   r   r<   r   rQ   rV   r   r\   rw   rf   r	   r   r   r   ru   rx   rI   __call__r#   r#   r#   r$   r>   S   s.    r>   c                       sd   e Zd Zdeeeee edd fddZ	eeedddZ
dd	d
dZejedddZ  ZS )SimpleRequestHandlerTN)r   rT   r?   secret_tokenr@   r   c                    s(   t  jf ||d| || _|| _dS )aM  
        Handler for single Bot instance

        :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
        :param handle_in_background: immediately responds to the Telegram instead of
            a waiting end of handler process
        :param bot: instance of :class:`aiogram.client.bot.Bot`
        r   r?   N)superrD   rT   r   )rC   r   rT   r?   r   r@   	__class__r#   r$   rD      s    zSimpleRequestHandler.__init__rR   c                 C   s   | j rt|| j S dS NT)r   rn   compare_digestrU   r#   r#   r$   rV      s    z"SimpleRequestHandler.verify_secretrM   c                    s   | j j I dH  dS )z#
        Close bot session
        N)rT   rb   rL   rN   r#   r#   r$   rL      s    zSimpleRequestHandler.closerO   c                    s   | j S r   )rT   rP   r#   r#   r$   rQ      s    z SimpleRequestHandler.resolve_bot)TN)r{   r|   r}   r   r   r~   r	   r   r   rD   rV   rL   r   r<   rQ   __classcell__r#   r#   r   r$   r      s     r   c                       s   e Zd Zdeeeeeef  edd fddZ	ee
edddZdd	d
dZeeedd fddZeje
dddZ  ZS )TokenBasedRequestHandlerTN)r   r?   bot_settingsr@   r   c                    s4   t  jf ||d| |du r$i }|| _i | _dS )aP  
        Handler that supports multiple bots the context will be resolved
        from path variable 'bot_token'

        .. note::

            This handler is not recommended in due to token is available in URL
            and can be logged by reverse proxy server or other middleware.

        :param dispatcher: instance of :class:`aiogram.dispatcher.dispatcher.Dispatcher`
        :param handle_in_background: immediately responds to the Telegram instead of
            a waiting end of handler process
        :param bot_settings: kwargs that will be passed to new Bot instance
        r   N)r   rD   r   bots)rC   r   r?   r   r@   r   r#   r$   rD      s
    z!TokenBasedRequestHandler.__init__rR   c                 C   s   dS r   r#   rU   r#   r#   r$   rV   
  s    z&TokenBasedRequestHandler.verify_secretrM   c                    s$   | j  D ]}|j I d H  q
d S r   )r   valuesrb   rL   )rC   rT   r#   r#   r$   rL     s    zTokenBasedRequestHandler.closerE   c                   s,   d|vrt dt j|fd|i| dS )z
        Validate path, register route and shutdown callback

        :param app: instance of aiohttp Application
        :param path: route path
        :param kwargs:
        z{bot_token}z,Path should contains '{bot_token}' substringrF   N)
ValueErrorr   rK   rJ   r   r#   r$   rK     s    z!TokenBasedRequestHandler.registerrO   c                    s8   |j d }|| jvr.tf d|i| j| j|< | j| S )z
        Get bot token from a path and create or get from cache Bot instance

        :param request:
        :return:
        Z	bot_tokentoken)Z
match_infor   r   r   )rC   r*   r   r#   r#   r$   rQ     s    

z$TokenBasedRequestHandler.resolve_bot)TN)r{   r|   r}   r   r~   r	   r   r   r   rD   r   rV   rL   r   rK   r   r<   rQ   r   r#   r#   r   r$   r      s     r   )-r`   rn   abcr   r   r   typingr   r   r   r   r	   r
   r   r   Zaiohttpr   r   Zaiohttp.abcr   Zaiohttp.typedefsr   Zaiohttp.web_middlewaresr   Zaiogramr   r   r   Zaiogram.methodsr   Zaiogram.methods.baser   Zaiogram.typesr   Zaiogram.webhook.securityr   r(   r<   r   r~   r5   r=   r>   r   r   r#   r#   r#   r$   <module>   s*   (w$