o
    Fh)                     @   sf  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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% dedededdfddZ&de%dej'dee(e)f fddZ*de%de	ej'egee f f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)JsonPayloadMultipartWriterPayloadweb)Handler)Application)
middleware)Bot
Dispatcherloggers)TelegramMethod)TelegramType)	InputFile)IPFilterapp
dispatcherkwargsreturnc                   sh   |  d j |dtdtddf fdd}dtdtddf 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   akwr   Nc                         j di I d H  d S N )emit_startupr   r    r   workflow_datar#   Q/var/www/html/venv/lib/python3.10/site-packages/aiogram/webhook/aiohttp_server.py
on_startup#      z%setup_application.<locals>.on_startupc                     r!   r"   )emit_shutdownr%   r&   r#   r(   on_shutdown&   r*   z&setup_application.<locals>.on_shutdown)r'   r   r)   appendr,   )r   r   r   r)   r,   r#   r&   r(   setup_application   s   
r.   	ip_filterrequestc                 C   s^   |j dd }r|jddd^}}||| v fS tt|jd }r-|\}}||| v fS dS )NzX-Forwarded-For ,   )maxsplitpeername)r1   F)headersgetsplitr   r   	transportget_extra_info)r/   r0   forwarded_for_	peer_namehostr#   r#   r(   check_ip-   s   r?   c                    s$   t dtjdtdtf fdd}|S )z)

    :param ip_filter:
    :return:
    r0   handlerr   c                    s:   t  | d\}}|stjd| t || I d H S )N)r/   r0   z,Blocking request from an unauthorized IP: %s)r?   r   webhookwarningr   HTTPUnauthorized)r0   r@   
ip_addressacceptr/   r#   r(   _ip_filter_middlewareH   s   z3ip_filter_middleware.<locals>._ip_filter_middleware)r   r   Requestr   r   )r/   rG   r#   rF   r(   ip_filter_middleware?   s   	rI   c                	   @   s$  e Zd Z	d'dedededdfddZd	ed
ededdfddZ	dededdfddZ
ed(ddZedejdefddZedededefddZdedeeef ddfddZdedejdejfddZded eee  defd!d"Zdedejdejfd#d$Zdejdejfd%d&ZeZdS ))BaseRequestHandlerFr   handle_in_backgrounddatar   Nc                 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   rK   rL   set_background_feed_update_tasks)selfr   rK   rL   r#   r#   r(   __init__T   s   zBaseRequestHandler.__init__pathr   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_closerouter	add_routehandlerO   r   rQ   r   r#   r#   r(   registerg   s   zBaseRequestHandler.registerr   r    c                    s   |   I d H  d S N)close)rO   r   r    r#   r#   r(   rS   r   s   z BaseRequestHandler._handle_closec                    s   d S rY   r#   rO   r#   r#   r(   rZ   u   s   zBaseRequestHandler.closer0   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#   rO   r0   r#   r#   r(   resolve_boty   s   
zBaseRequestHandler.resolve_bottelegram_secret_tokenbotc                 C   s   d S rY   r#   rO   r^   r_   r#   r#   r(   verify_secret   s   z BaseRequestHandler.verify_secretupdatec                    sJ   | j jd||d| jI d H }t|tr#| j j||dI d H  d S d S )Nr_   rb   r_   resultr#   )r   feed_raw_updaterL   
isinstancer   silent_call_request)rO   r_   rb   re   r#   r#   r(   _background_feed_update   s
    
z*BaseRequestHandler._background_feed_updatec                    sT   t | j||j|jjdI d H d}| j| || jj	 t
ji |jjdS )Nloadsrc   )dumps)asynciocreate_taskri   jsonsession
json_loadsrN   addadd_done_callbackdiscardr   json_response
json_dumps)rO   r_   r0   feed_update_taskr#   r#   r(   _handle_request_background   s   z-BaseRequestHandler._handle_request_backgroundre   c                 C   s   |st i S tddtd d}||j}|jddd i }|jdd D ]\}}|j	j
|||d	}|s9q)||}|jd|d q)| D ]\}}|||}|jd||jp^|d
 qJ|S )Nz	form-datawebhookBoundary   )boundarymethod)nameF)warnings)r_   files)r}   filename)r   r   secretstoken_urlsafer-   __api_method__set_content_disposition
model_dumpitemsrp   prepare_valuereadr   )rO   r_   re   writerpayloadr   keyvaluer#   r#   r(   _build_response_writer   s.   
z)BaseRequestHandler._build_response_writerc                    sH   | j j||j|jjdI d H fi | jI d H }tj| j||ddS )Nrj   rd   )body)	r   feed_webhook_updatero   rp   rq   rL   r   Responser   )rO   r_   r0   re   r#   r#   r(   _handle_request   s   z"BaseRequestHandler._handle_requestc                    sd   |  |I d H }| |jdd|stjdddS | jr(| j||dI d H S | j||dI d H S )NzX-Telegram-Bot-Api-Secret-Tokenr1   Unauthorizedi  )r   status)r_   r0   )	r]   ra   r6   r7   r   r   rK   rx   r   )rO   r0   r_   r#   r#   r(   rV      s   zBaseRequestHandler.handle)Fr   N)__name__
__module____qualname__r   boolr   rP   strr   rX   rS   r   rZ   r   rH   r   r]   ra   r   ri   r   rx   r	   r   r   r   r   r   rV   __call__r#   r#   r#   r(   rJ   S   s>    



#rJ   c                       st   e Zd Z		ddedededee deddf fd	d
Z	dededefddZ
dddZdejdefddZ  ZS )SimpleRequestHandlerTNr   r_   rK   secret_tokenrL   r   c                    s(   t  jd||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   rK   Nr#   )superrP   r_   r   )rO   r   r_   rK   r   rL   	__class__r#   r(   rP      s   
zSimpleRequestHandler.__init__r^   c                 C   s   | j r
t|| j S dS NT)r   r   compare_digestr`   r#   r#   r(   ra      s   z"SimpleRequestHandler.verify_secretc                    s   | j j I dH  dS )z#
        Close bot session
        N)r_   rp   rZ   r[   r#   r#   r(   rZ      s   zSimpleRequestHandler.closer0   c                    s   | j S rY   )r_   r\   r#   r#   r(   r]      s   z SimpleRequestHandler.resolve_botTNr   )r   r   r   r   r   r   r	   r   r   rP   ra   rZ   r   rH   r]   __classcell__r#   r#   r   r(   r      s&    
r   c                       s   e Zd Z		ddededeeeef  deddf
 fdd	Z	d
ede
defddZdddZdedededdf fddZdejde
fddZ  ZS )TokenBasedRequestHandlerTNr   rK   bot_settingsrL   r   c                    s4   t  jd||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   Nr#   )r   rP   r   bots)rO   r   rK   r   rL   r   r#   r(   rP      s
   
z!TokenBasedRequestHandler.__init__r^   r_   c                 C   s   dS r   r#   r`   r#   r#   r(   ra     s   z&TokenBasedRequestHandler.verify_secretc                    s&   | j  D ]
}|j I d H  qd S rY   )r   valuesrp   rZ   )rO   r_   r#   r#   r(   rZ     s   zTokenBasedRequestHandler.closerQ   r   r   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}' substringrQ   N)
ValueErrorr   rX   rW   r   r#   r(   rX     s   z!TokenBasedRequestHandler.registerr0   c                    s:   |j d }|| jvrtdd|i| j| j|< | j| S )z
        Get bot token from a path and create or get from cache Bot instance

        :param request:
        :return:
        	bot_tokentokenNr#   )
match_infor   r   r   )rO   r0   r   r#   r#   r(   r]   !  s
   


z$TokenBasedRequestHandler.resolve_botr   r   )r   r   r   r   r   r	   r   r   r   rP   r   ra   rZ   r   rX   r   rH   r]   r   r#   r#   r   r(   r      s$    
r   )/rm   r   abcr   r   r   typingr   r   r   r   r	   r
   r   r   aiohttpr   r   r   r   aiohttp.typedefsr   aiohttp.web_appr   aiohttp.web_middlewaresr   aiogramr   r   r   aiogram.methodsr   aiogram.methods.baser   aiogram.typesr   aiogram.webhook.securityr   r.   rH   r   r   r?   rI   rJ   r   r   r#   r#   r#   r(   <module>   s0    ( 
{$