o
    5˜ŽjØ)  ã                   @   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 d dl	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! e
rjd 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)Ú	AwaitableÚCallable)ÚTYPE_CHECKINGÚAnyÚcast)ÚJsonPayloadÚMultipartWriterÚPayloadÚweb)ÚHandler)ÚApplication)Ú
middleware)ÚBotÚ
DispatcherÚloggers)ÚTelegramMethod)ÚTelegramType)ÚIPFilter)Ú	InputFileÚ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    ú[/var/www/kodo/Anonymous/send/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)r.   F)ÚheadersÚgetÚsplitr	   r   Ú	transportÚget_extra_info)r,   r-   Úforwarded_forÚ_Ú	peer_nameÚhostr    r    r%   Úcheck_ip0   s   r<   c                    s$   t dtjdtdtf‡ fdd„ƒ}|S )z)

    :param ip_filter:
    :return:
    r-   Úhandlerr   c                 “   s:   �t ˆ | d�\}}|stj d|¡ t ¡ ‚|| ƒI d H S )N)r,   r-   z,Blocking request from an unauthorized IP: %s)r<   r   ÚwebhookÚwarningr   ÚHTTPUnauthorized)r-   r=   Ú
ip_addressÚaccept©r,   r    r%   Ú_ip_filter_middlewareK   s   €z3ip_filter_middleware.<locals>._ip_filter_middleware)r   r   ÚRequestr   r   )r,   rD   r    rC   r%   Úip_filter_middlewareB   s   	rF   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 dB 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   rH   rI   ÚsetÚ_background_feed_update_tasks)Úselfr   rH   rI   r    r    r%   Ú__init__W   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)rL   r   rN   r   r    r    r%   Úregisterj   s   zBaseRequestHandler.registerr   r   c                 Ï   s   �|   ¡ I d H  d S ©N)Úclose)rL   r   r   r    r    r%   rP   u   s   €z BaseRequestHandler._handle_closec                 Ã   s   �d S rU   r    ©rL   r    r    r%   rV   x   s   €zBaseRequestHandler.closer-   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    ©rL   r-   r    r    r%   Úresolve_bot|   s    zBaseRequestHandler.resolve_botÚtelegram_secret_tokenÚbotc                 C   s   d S rU   r    ©rL   rZ   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[   r^   ©r[   Úresultr    )r   Úfeed_raw_updaterI   Ú
isinstancer   Úsilent_call_request)rL   r[   r^   ra   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©Úloadsr_   )Údumps)ÚasyncioÚcreate_taskre   ÚjsonÚsessionÚ
json_loadsrK   ÚaddÚadd_done_callbackÚdiscardr   Újson_responseÚ
json_dumps)rL   r[   r-   Úfeed_update_taskr    r    r%   Ú_handle_request_background�   s   €þÿz-BaseRequestHandler._handle_request_backgroundra   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)ry   Úfilename)r
   r   ÚsecretsÚtoken_urlsafer*   Ú__api_method__Úset_content_dispositionÚ
model_dumpÚitemsrl   Úprepare_valueÚreadr|   )rL   r[   ra   Ú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 )Nrf   r`   )Úbody)	r   Úfeed_webhook_updaterk   rl   rm   rI   r   ÚResponser‰   )rL   r[   r-   ra   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-Tokenr.   ÚUnauthorizedi‘  )rŠ   Ústatus)r[   r-   )	rY   r]   r3   r4   r   rŒ   rH   rt   r�   )rL   r-   r[   r    r    r%   rS   È   s   €zBaseRequestHandler.handle)F©r   N)Ú__name__Ú
__module__Ú__qualname__r   Úboolr   rM   Ústrr   rT   rP   r   rV   r   rE   r   rY   r]   Údictre   rŒ   rt   r   r   r   r‰   r�   rS   Ú__call__r    r    r    r%   rG   V   s>    ýþýü
û
þ
ý
ü%rG   c                       st   e Zd Z		ddededededB 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[   rH   Úsecret_tokenrI   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   rH   Nr    )ÚsuperrM   r[   r™   )rL   r   r[   rH   r™   rI   ©Ú	__class__r    r%   rM   Ô   s   
zSimpleRequestHandler.__init__rZ   c                 C   s   | j r
t || j ¡S dS ©NT)r™   r}   Úcompare_digestr\   r    r    r%   r]   è   s   z"SimpleRequestHandler.verify_secretc                 Ã   s   �| j j ¡ I dH  dS )z#
        Close bot session
        N)r[   rl   rV   rW   r    r    r%   rV   í   s   €zSimpleRequestHandler.closer-   c                 Ã   s   �| j S rU   )r[   rX   r    r    r%   rY   ó   s   €z SimpleRequestHandler.resolve_bot©TNr�   )r‘   r’   r“   r   r   r”   r•   r   rM   r]   rV   r   rE   rY   Ú__classcell__r    r    rœ   r%   r˜   Ó   s&    ûþýüûúù
r˜   c                       s–   e Zd Z		ddededeeef dB 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   rH   Úbot_settingsrI   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›   rM   r£   Úbots)rL   r   rH   r£   rI   rœ   r    r%   rM   ø   s
   
z!TokenBasedRequestHandler.__init__rZ   r[   c                 C   s   dS rž   r    r\   r    r    r%   r]     s   z&TokenBasedRequestHandler.verify_secretc                 Ã   s&   �| j  ¡ D ]
}|j ¡ I d H  qd S rU   )r¤   Úvaluesrl   rV   )rL   r[   r    r    r%   rV     s   €ÿzTokenBasedRequestHandler.closerN   r   r   c                   s0   d|vr
d}t |ƒ‚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}' substringrN   N)Ú
ValueErrorr›   rT   )rL   r   rN   r   Úmsgrœ   r    r%   rT     s   z!TokenBasedRequestHandler.registerr-   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£   )rL   r-   r©   r    r    r%   rY   '  s
   €


z$TokenBasedRequestHandler.resolve_botr    r�   )r‘   r’   r“   r   r”   r–   r•   r   rM   r   r]   rV   r   rT   r   rE   rY   r¡   r    r    rœ   r%   r¢   ÷   s$    üþýüûú
r¢   ).ri   r}   Úabcr   r   r   Úcollections.abcr   r   Útypingr   r   r	   Úaiohttpr
   r   r   r   Úaiohttp.typedefsr   Úaiohttp.web_appr   Úaiohttp.web_middlewaresr   Úaiogramr   r   r   Úaiogram.methodsr   Úaiogram.methods.baser   Úaiogram.webhook.securityr   Úaiogram.typesr   r+   rE   Útupler•   r”   r<   rF   rG   r˜   r¢   r    r    r    r%   Ú<module>   s4     ÿ
þ}$