o
    ›¨ÊhŒB  ã                   @   s>  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mZmZmZ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 zd dlZd dlmZ ddlm Z  W n e!y{   eeddd�ƒZe"Zeeddd�ƒZ Y nw G dd„ de	ƒZ#G dd„ de#ƒZ$G dd„ de#ƒZ%G dd„ deeƒZ&dS )é    N)Ú	b64decode)ÚHttpResponse)Úparse_datetimeé   )ÚAnymailBaseWebhookViewé   )ÚAnymailAPIErrorÚAnymailConfigurationErrorÚAnymailImproperlyInstalledÚAnymailWebhookValidationFailureÚ
_LazyError)ÚAnymailInboundMessage)ÚAnymailInboundEventÚAnymailTrackingEventÚ	EventTypeÚRejectReasonÚinboundÚtracking)ÚcombineÚget_anymail_settingÚgetfirst)ÚClientError)Ú_get_anymail_boto3_paramsÚboto3Ú
amazon_ses)Úmissing_packageÚbackendc                       s\   e Zd ZdZdZ‡ fdd„Zedd„ ƒZdd„ Z‡ fd	d
„Z	dd„ Z
dd„ Zdd„ Z‡  ZS )ÚAmazonSESBaseWebhookViewz;Base view class for Amazon SES webhooks (SNS Notifications)z
Amazon SESc                    s@   t d| j|dd�| _t|d�\| _| _tt| ƒjdi |¤Ž d S )NÚauto_confirm_sns_subscriptionsT)Úesp_nameÚkwargsÚdefault)r    © )	r   r   Úauto_confirm_enabledr   Úsession_paramsÚclient_paramsÚsuperr   Ú__init__)Úselfr    ©Ú	__class__r"   úM/var/www/html/env/lib/python3.10/site-packages/anymail/webhooks/amazon_ses.pyr'   !   s
   
ÿz!AmazonSESBaseWebhookView.__init__c              
   C   sh   t | dƒs1z| j | jpd¡}t |¡| _W | jS  ttt	fy0 } z	t
d| j |d�‚d }~ww | jS )NÚ_sns_messagezutf-8zMalformed SNS message body %r©Úraised_from)ÚhasattrÚbodyÚdecodeÚencodingÚjsonÚloadsr,   Ú	TypeErrorÚ
ValueErrorÚUnicodeDecodeErrorr   )Úrequestr0   Úerrr"   r"   r+   Ú_parse_sns_message*   s   
þ€ÿz+AmazonSESBaseWebhookView._parse_sns_messagec                 C   s†   |   |¡}|j dd¡}| dd¡}||krtd||f ƒ‚|dvr(td| ƒ‚|j dd¡}| dd¡}||krAtd	||f ƒ‚d S )
NÚHTTP_X_AMZ_SNS_MESSAGE_TYPEz<<missing>>ÚTypezGSNS header "x-amz-sns-message-type: %s" doesn't match body "Type": "%s")ÚNotificationÚSubscriptionConfirmationÚUnsubscribeConfirmationzUnknown SNS message type '%s'ÚHTTP_X_AMZ_SNS_MESSAGE_IDÚ	MessageIdzJSNS header "x-amz-sns-message-id: %s" doesn't match body "MessageId": "%s")r:   ÚMETAÚgetr   r   )r(   r8   Úsns_messageÚheader_typeÚ	body_typeÚ	header_idÚbody_idr"   r"   r+   Úvalidate_request5   s(   
ÿÿÿÿÿz)AmazonSESBaseWebhookView.validate_requestc                    sF   | j r|j d¡stdd�}d|d< |S tt| ƒj|g|¢R i |¤ŽS )NÚHTTP_AUTHORIZATIONi‘  )Ústatusz$Basic realm="Anymail WEBHOOK_SECRET"zWWW-Authenticate)Ú
basic_authrB   rC   r   r&   r   Úpost)r(   r8   Úargsr    Úresponser)   r"   r+   rM   L   s
   
zAmazonSESBaseWebhookView.postc              	   C   sŽ   g }|   |¡}| d¡}|dkr<| d¡}zt |¡}W n ttfy3   |dkr*ntd| ƒ‚Y |S w |  ||¡}|S |dkrE|  |¡ |S )Nr<   r=   ÚMessagezASuccessfully validated SNS topic for Amazon SES event publishing.zUnparsable SNS Message %rr>   )	r:   rC   r3   r4   r5   r6   r   Úesp_to_anymail_eventsÚauto_confirm_sns_subscription)r(   r8   ÚeventsrD   Úsns_typeÚmessage_stringÚ	ses_eventr"   r"   r+   Úparse_eventsU   s&   


þöý
z%AmazonSESBaseWebhookView.parse_eventsc                 C   s   t ƒ ‚)N)ÚNotImplementedError)r(   rV   rD   r"   r"   r+   rQ   j   s   z.AmazonSESBaseWebhookView.esp_to_anymail_eventsc                 C   sl   | j sdS | jstdj| d¡| d¡d�ƒ‚tjjd	i | j¤Žj	d
i | j
¤Ž}|j|d |d dd� dS )a  Automatically accept a subscription to Amazon SNS topics, if the request is expected.

        If an SNS SubscriptionConfirmation arrives with HTTP basic auth proving it is meant for us,
        automatically load the SubscribeURL to confirm the subscription.
        Na=  Anymail received an unexpected SubscriptionConfirmation request for Amazon SNS topic '{topic_arn!s}'. (Anymail can automatically confirm SNS subscriptions if you set a WEBHOOK_SECRET and use that in your SNS notification url. Or you can manually confirm this subscription in the SNS dashboard with token '{token!s}'.)ÚTopicArnÚToken)Ú	topic_arnÚtokenÚsnsÚtrue)rY   rZ   ÚAuthenticateOnUnsubscriber"   )r]   )r#   rL   r   ÚformatrC   r   ÚsessionÚSessionr$   Úclientr%   Úconfirm_subscription)r(   rD   Ú
sns_clientr"   r"   r+   rR   m   s   üÿ"	
ÿz6AmazonSESBaseWebhookView.auto_confirm_sns_subscription)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r'   Ústaticmethodr:   rI   rM   rW   rQ   rR   Ú__classcell__r"   r"   r)   r+   r      s    	

	r   c                   @   ó   e Zd ZdZeZdd„ ZdS )ÚAmazonSESTrackingWebhookViewz-Handler for Amazon SES tracking notificationsc                    s¨  t |ddgdƒ}|dkrtd| d¡ ƒ‚| d¡}zt|d ƒ}W n ttfy/   d }Y nw | d	i ¡}| d
¡}| dg ¡}i }	g }
| dg ¡D ].}|d  ¡ }|dkr_|
 |d ¡ qK|dkryz	t 	|d ¡}	W qK tt
tfyx   Y qKw qKt||||	|
|d�‰ dd„ |D ƒ}| | ¡ i ¡}|dkr±ˆ jtjdjd3i |¤Žtjd� dd„ |d D ƒ}nš|dkrÐˆ jtj| d¡tj| d¡d� dd„ |d D ƒ}n{|dkréˆ jtj| d ¡d!� d"d„ |d# D ƒ}nb|d$krõˆ jtjd%� nV|d&k�rˆ jtj|d' tjd� nD|d(k�rˆ jtj| d¡d)� n3|d*k�r-ˆ jtj| d¡| d+¡d,� n|d-k�rA|d. }ˆ jtj|d/ d0� n
ˆ jtjd1| d0� ‡ fd2d„|D ƒS )4NÚ	eventTypeÚnotificationTypez<<type missing>>ÚReceivedz–You seem to have set an Amazon SES *inbound* receipt rule to publish to an SNS Topic that posts to Anymail's *tracking* webhook URL. (SNS TopicArn %s)rY   rA   Ú	TimestampÚmailÚ	messageIdÚdestinationÚheadersÚnamezx-tagÚvaluez
x-metadata)Ú	esp_eventÚevent_idÚ
message_idÚmetadataÚtagsÚ	timestampc                 S   ó   g | ]}t |d �‘qS ©©Ú	recipient©Údict)Ú.0Úemail_addressr"   r"   r+   Ú
<listcomp>»   s    ÿÿzFAmazonSESTrackingWebhookView.esp_to_anymail_events.<locals>.<listcomp>ÚBouncez{bounceType}: {bounceSubType})Ú
event_typeÚdescriptionÚreject_reasonc                 S   s"   g | ]}t |d  | d¡d�‘qS )ÚemailAddressÚdiagnosticCode)r�   Úmta_response)rƒ   rC   ©r„   r�   r"   r"   r+   r†   È   s    ý
þÚbouncedRecipientsÚ	ComplaintÚcomplaintFeedbackTypeÚ	userAgent)rˆ   r‰   rŠ   Ú
user_agentc                 S   s   g | ]	}t |d  d�‘qS )r‹   r€   r‚   rŽ   r"   r"   r+   r†   Ó   s
    þ
ÿÚcomplainedRecipientsÚDeliveryÚsmtpResponse)rˆ   r�   c                 S   r~   r   r‚   rŽ   r"   r"   r+   r†   Û   s
    þ
ÿÚ
recipientsÚSend)rˆ   ÚRejectÚreasonÚOpen)rˆ   r“   ÚClickÚlink)rˆ   r“   Ú	click_urlzRendering FailureÚfailureÚerrorMessage)rˆ   r‰   zUnknown SES eventType '%s'c                    s    g | ]}t d i tˆ |ƒ¤Ž‘qS )r"   )r   r   )r„   Úrecipient_props©Úcommon_propsr"   r+   r†     s    ÿþr"   )r   r	   rC   r   ÚKeyErrorr6   ÚlowerÚappendr3   r4   r5   rƒ   Úupdater   ÚBOUNCEDr`   r   Ú
COMPLAINEDÚSPAMÚ	DELIVEREDÚSENTÚREJECTEDÚBLOCKEDÚOPENEDÚCLICKEDÚFAILEDÚUNKNOWN)r(   rV   rD   Úses_event_typery   r}   Úmail_objectrz   Úall_recipientsr{   r|   Úheaderrv   Úper_recipient_propsÚevent_objectr"   r¢   r+   rQ   �   sÌ   þÿ
ÿ
ÿýúþýýüþþþÿ
ý
þ
ý
þþ
ýz2AmazonSESTrackingWebhookView.esp_to_anymail_eventsN)rf   rg   rh   ri   r   ÚsignalrQ   r"   r"   r"   r+   rm   Š   ó    rm   c                   @   rl   )ÚAmazonSESInboundWebhookViewz,Handler for Amazon SES inbound notificationsc              
   C   s  |  d¡}|dkrtd|  d¡ ƒ‚|  di ¡}|  di ¡}|  di ¡}|  d¡}|d	krL|  d
¡}|  d¡dkrFt| d¡ƒ}t |¡}	njt |¡}	nd|dkr¤|d }
|d }tjj	d#i | j
¤Žjd$i | j¤Ž}t ¡ }z1z| |
||¡ | d¡ t |¡}	W n ty˜ } ztdj|
|d�|d�‚d }~ww W | ¡  n| ¡  w tdj||  d¡d�ƒ‚|  d¡|	_z	|d d |	_W n tttfyË   Y nw |  di ¡  dd¡ ¡ }dddœ  |¡|	_|  d ¡}zt|d! ƒ}W n ttfyû   d }Y nw tt j!||	||d"�gS )%Nro   rp   zžYou seem to have set an Amazon SES *sending* event or notification to publish to an SNS Topic that posts to Anymail's *inbound* webhook URL. (SNS TopicArn %s)rY   ÚreceiptÚactionrr   ÚtypeÚSNSÚcontentr2   ÚBASE64ÚasciiÚS3Ú
bucketNameÚ	objectKeyÚs3r   z\Anymail AmazonSESInboundWebhookView couldn't download S3 object '{bucket_name}:{object_key}')Úbucket_nameÚ
object_keyr-   z¨Anymail's Amazon SES inbound webhook works only with 'SNS' or 'S3' receipt rule actions, not SNS notifications for {action_type!s} actions. (SNS TopicArn {topic_arn!s}))Úaction_typer[   Úsourcer—   ÚspamVerdictrK   Ú FT)ÚPASSÚFAILrs   r}   )rˆ   ry   Úmessager}   rx   r"   )rÆ   )"rC   r	   r   Úencoder   Úparse_raw_mime_bytesÚparse_raw_mimer   ra   rb   r$   rc   r%   ÚioÚBytesIOÚdownload_fileobjÚseekÚparse_raw_mime_filer   ÚAnymailBotoClientAPIErrorr`   ÚcloseÚenvelope_senderÚenvelope_recipientr¤   r5   Ú
IndexErrorÚupperÚspam_detectedr   r6   r   r   ÚINBOUND)r(   rV   rD   r³   Úreceipt_objectÚaction_objectr´   rÉ   rÀ   rÏ   rÇ   rÈ   rÆ   r9   Úspam_statusry   r}   r"   r"   r+   rQ     s~   
þÿ

"
ÿý€þÿþÿÿ
ÿûz1AmazonSESInboundWebhookView.esp_to_anymail_eventsN)rf   rg   rh   ri   r   r¹   rQ   r"   r"   r"   r+   r»     rº   r»   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )rØ   z2An AnymailAPIError that is also a Boto ClientErrorc                    sP   |  d¡}t|tƒsJ ‚t|ƒdksJ ‚tt| ƒj|j|jd� || _	|| _
d S )Nr.   r   )Úerror_responseÚoperation_name)ÚpopÚ
isinstancer   Úlenr&   rØ   r'   rO   rä   rN   r.   )r(   rN   r    r.   r)   r"   r+   r'   X  s   

ÿ
z"AnymailBotoClientAPIError.__init__)rf   rg   rh   ri   r'   rk   r"   r"   r)   r+   rØ   V  s    rØ   )'rÓ   r3   Úbase64r   Údjango.httpr   Údjango.utils.dateparser   Úbaser   Ú
exceptionsr   r	   r
   r   r   r   r   Úsignalsr   r   r   r   r   Úutilsr   r   r   r   Úbotocore.exceptionsr   Úbackends.amazon_sesr   ÚImportErrorÚobjectr   rm   r»   rØ   r"   r"   r"   r+   Ú<module>   s0     ûn K