o
    ›¨Êhq1  ã                   @   sÈ   d dl Z d dlmZ d dlZd dlZd dlmZ d dl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mZmZmZ ddlmZmZmZ G dd„ de	ƒZG dd„ deƒZG dd„ deƒZdS )é    N)Údatetime)Úconstant_time_compare)Úutcé   )ÚAnymailBaseWebhookViewé   )ÚAnymailWebhookValidationFailure)ÚAnymailInboundMessage)ÚinboundÚtrackingÚAnymailInboundEventÚAnymailTrackingEventÚ	EventTypeÚRejectReason)Úget_anymail_settingÚcombineÚquerydict_getfirstc                       s8   e Zd ZdZdZdZdZ‡ fdd„Z‡ fdd„Z‡  Z	S )	ÚMailgunBaseWebhookViewz$Base view class for Mailgun webhooksÚMailgunFNc                    s8   t d| j|dd�}| d¡| _tt| ƒjdi |¤Ž d S )NÚapi_keyT)Úesp_nameÚkwargsÚ
allow_bareÚascii© )r   r   Úencoder   Úsuperr   Ú__init__)Úselfr   r   ©Ú	__class__r   úJ/var/www/html/env/lib/python3.10/site-packages/anymail/webhooks/mailgun.pyr      s
   ÿzMailgunBaseWebhookView.__init__c                    sŠ   t t| ƒ |¡ z|jd }|jd }t|jd ƒ}W n ty&   tdƒ‚w tj| j	d 
||¡ d¡tjd� ¡ }t||ƒsCtdƒ‚d S )	NÚtokenÚ	timestampÚ	signaturez7Mailgun webhook called without required security fieldsz{}{}r   )ÚkeyÚmsgÚ	digestmodz/Mailgun webhook called with incorrect signature)r   r   Úvalidate_requestÚPOSTÚstrÚKeyErrorr   ÚhmacÚnewr   Úformatr   ÚhashlibÚsha256Ú	hexdigestr   )r   Úrequestr"   r#   r$   Úexpected_signaturer   r   r!   r(      s    

ÿÿÿ
ÿz'MailgunBaseWebhookView.validate_request)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úwarn_if_no_basic_authr   r   r(   Ú__classcell__r   r   r   r!   r      s    r   c                   @   sz   e Zd ZdZeZejejej	ej
ejejejdœZejej	ejdœZdd„ Zdd„ Zdd	„ Zh d
£ZedhB eedœZdS )ÚMailgunTrackingWebhookViewz=Handler for Mailgun delivery and engagement tracking webhooks)Ú	deliveredÚdroppedÚbouncedÚ
complainedÚunsubscribedÚopenedÚclicked)ió  i]  i_  c                 C   s   |   |j¡gS ©N)Úesp_to_anymail_eventr)   ©r   r2   r   r   r!   Úparse_eventsJ   s   z'MailgunTrackingWebhookView.parse_eventsc                 C   s   t  |¡|_| j | d¡tj¡}tjt	|d ƒt
d�}| dd ¡p'| dd ¡}|r4| d¡s4d |¡}| dd ¡}| d	d ¡pE| d
d ¡}d }z	t	| d¡ƒ}W n5 ttfy\   Y nB ty†   z| d¡ d¡d }	W n ttfyy   Y nw |	dv r�tjntj}Y nw | j |d|  kr•dk ršn ntjntj¡}|  |¡}
| dd ¡p®| dg ¡}t|||| dd ¡| dd ¡|||||
| dd ¡| dd ¡|d�S )NÚeventr#   ©Útzz
Message-Idú
message-idú<z<{}>ÚdescriptionÚerrorÚnotificationÚcodeÚ.r   )Ú4Ú5i�  iX  ÚtagzX-Mailgun-Tagr"   Ú	recipientÚurlú
user-agent)Ú
event_typer#   Ú
message_idÚevent_idrS   Úreject_reasonrK   Úmta_responseÚtagsÚmetadataÚ	click_urlÚ
user_agentÚ	esp_event)r   Ú__get__ÚgetfirstÚevent_typesÚgetr   ÚUNKNOWNr   ÚfromtimestampÚintr   Ú
startswithr.   r+   Ú	TypeErrorÚ
ValueErrorÚsplitÚ
IndexErrorr   ÚBOUNCEDÚOTHERÚreject_reasonsÚ_extract_metadataÚgetlistr   )r   r_   rV   r#   rW   rK   rZ   rY   Ú
mta_statusÚstatus_classr\   r[   r   r   r!   rC   M   sX   
þ€ø
ý




óz/MailgunTrackingWebhookView.esp_to_anymail_eventc           	      C   sÎ   |  d¡}i }d|v r*t |d ¡}dd„ |D ƒ}t|ƒdkr(tdd„ |D ƒŽ }|S || jv re| j| }| ¡ D ],\}}||vrG|d ||< q8|dkrLq8t|ƒdkrSq8|d	v r^|d
 ||< q8|d ||< q8|S )NrF   úmessage-headersc                 S   s   g | ]
\}}|d kr|‘qS )zX-Mailgun-Variablesr   )Ú.0ÚfieldÚvaluer   r   r!   Ú
<listcomp>“   s    z@MailgunTrackingWebhookView._extract_metadata.<locals>.<listcomp>r   c                 S   s   g | ]}t  |¡‘qS r   )ÚjsonÚloads)rt   rv   r   r   r!   rw   –   s    éÿÿÿÿrR   >   r"   r$   r#   r   )ra   rx   ry   Úlenr   Ú_known_event_fieldsÚlists)	r   r_   rV   r\   ÚheadersÚ	variablesÚknown_fieldsru   Úvaluesr   r   r!   ro   ˆ   s*   

æ
z,MailgunTrackingWebhookView._extract_metadata>   ú	client-osúcampaign-idúclient-nameúclient-typeúdevice-typeúmailing-listúcampaign-nameÚhÚiprR   ÚcityrF   r"   ÚdomainÚregionÚcountryrS   r$   r#   ú
body-plainrI   rU   rT   )rA   r@   r?   N)r4   r5   r6   r7   r   Úsignalr   Ú	DELIVEREDÚREJECTEDrl   Ú
COMPLAINEDÚUNSUBSCRIBEDÚOPENEDÚCLICKEDrb   r   Ú	TIMED_OUTÚSPAMrn   rE   rC   ro   Ú_common_event_fieldsr|   r   r   r   r!   r:   .   s.    øø;,
úr:   c                   @   s,   e Zd ZdZeZdd„ Zdd„ Zdd„ ZdS )	ÚMailgunInboundWebhookViewz:Handler for Mailgun inbound (route forward-to-url) webhookc                 C   s   |   |¡gS rB   )rC   rD   r   r   r!   rE   Ë   s   z&MailgunInboundWebhookView.parse_eventsc              	   C   sÜ   |}d|j v rt |j d ¡}n|  |¡}|j  dd ¡|_|j  dd ¡|_|j  dd ¡|_|j  dd ¡|_| dd¡ 	¡ dk|_
z	t|d	 ƒ|_W n ttfyT   Y nw ttjtjt|j d
 ƒtd�|j  dd ¡||d�S )Nz	body-mimeÚsenderrS   zstripped-textzstripped-htmlzX-Mailgun-SflagÚNoÚyeszX-Mailgun-Sscorer#   rG   r"   )rV   r#   rX   r_   Úmessage)r)   r	   Úparse_raw_mimeÚmessage_from_mailgun_parsedrc   Úenvelope_senderÚenvelope_recipientÚstripped_textÚstripped_htmlÚlowerÚspam_detectedÚfloatÚ
spam_scorerh   ri   r   r   ÚINBOUNDr   re   rf   r   )r   r2   r_   rž   r   r   r!   rC   Î   s*   

ÿûz.MailgunInboundWebhookView.esp_to_anymail_eventc              	      s®   z	t ˆjd ƒ}W n ttfy   d}Y n(w dd„ td|d ƒD ƒ}dd„ t ˆj dd	¡¡ ¡ D ƒ‰ ‡ ‡fd
d„|D ƒ}t	j
t ˆjd ¡ˆj dd¡ˆj dd¡|d�S )z8Construct a Message from Mailgun's "fully-parsed" fieldszattachment-countNc                 S   s   g | ]}d | ‘qS )zattachment-%dr   )rt   Úir   r   r!   rw   õ   s    zIMailgunInboundWebhookView.message_from_mailgun_parsed.<locals>.<listcomp>r   c                 S   s   i | ]\}}||“qS r   r   )rt   ÚcidÚatt_idr   r   r!   Ú
<dictcomp>ö   s    
ÿzIMailgunInboundWebhookView.message_from_mailgun_parsed.<locals>.<dictcomp>zcontent-id-mapz{}c                    s(   g | ]}t jˆj| ˆ  |d ¡d�‘qS )N)Ú
content_id)r	   Ú'construct_attachment_from_uploaded_fileÚFILESrc   )rt   r¬   ©Úatt_cidsr2   r   r!   rw   ú   s    þÿÿrs   r�   z	body-html)r~   ÚtextÚhtmlÚattachments)rf   r)   r+   rh   Úrangerx   ry   rc   Úitemsr	   Ú	construct)r   r2   Úattachment_countrµ   Úatt_idsr   r±   r!   r    ì   s$   ÿþýüz5MailgunInboundWebhookView.message_from_mailgun_parsedN)	r4   r5   r6   r7   r
   r�   rE   rC   r    r   r   r   r!   rš   Æ   s    rš   )rx   r   r/   r,   Údjango.utils.cryptor   Údjango.utils.timezoner   Úbaser   Ú
exceptionsr   r
   r	   Úsignalsr   r   r   r   r   Úutilsr   r   r   r   r:   rš   r   r   r   r!   Ú<module>   s      