Run black on moto & test directories.

This commit is contained in:
Asher Foa 2019-10-31 08:44:26 -07:00
commit 96e5b1993d
507 changed files with 52541 additions and 47814 deletions

View file

@ -6,5 +6,4 @@ class MessageRejectedError(RESTError):
code = 400
def __init__(self, message):
super(MessageRejectedError, self).__init__(
"MessageRejected", message)
super(MessageRejectedError, self).__init__("MessageRejected", message)

View file

@ -11,32 +11,20 @@ COMMON_MAIL = {
"sourceArn": "arn:aws:ses:us-west-2:888888888888:identity/example.com",
"sourceIp": "127.0.3.0",
"sendingAccountId": "123456789012",
"destination": [
"recipient@example.com"
],
"destination": ["recipient@example.com"],
"headersTruncated": False,
"headers": [
{
"name": "From",
"value": "\"Sender Name\" <sender@example.com>"
},
{
"name": "To",
"value": "\"Recipient Name\" <recipient@example.com>"
}
{"name": "From", "value": '"Sender Name" <sender@example.com>'},
{"name": "To", "value": '"Recipient Name" <recipient@example.com>'},
],
"commonHeaders": {
"from": [
"Sender Name <sender@example.com>"
],
"from": ["Sender Name <sender@example.com>"],
"date": "Mon, 08 Oct 2018 14:05:45 +0000",
"to": [
"Recipient Name <recipient@example.com>"
],
"to": ["Recipient Name <recipient@example.com>"],
"messageId": " custom-message-ID",
"subject": "Message sent using Amazon SES"
}
}
"subject": "Message sent using Amazon SES",
},
},
}
BOUNCE = {
"bounceType": "Permanent",
@ -46,30 +34,26 @@ BOUNCE = {
"status": "5.0.0",
"action": "failed",
"diagnosticCode": "smtp; 550 user unknown",
"emailAddress": "recipient1@example.com"
"emailAddress": "recipient1@example.com",
},
{
"status": "4.0.0",
"action": "delayed",
"emailAddress": "recipient2@example.com"
}
"emailAddress": "recipient2@example.com",
},
],
"reportingMTA": "example.com",
"timestamp": "2012-05-25T14:59:38.605Z",
"feedbackId": "000001378603176d-5a4b5ad9-6f30-4198-a8c3-b1eb0c270a1d-000000",
"remoteMtaIp": "127.0.2.0"
"remoteMtaIp": "127.0.2.0",
}
COMPLAINT = {
"userAgent": "AnyCompany Feedback Loop (V0.01)",
"complainedRecipients": [
{
"emailAddress": "recipient1@example.com"
}
],
"complainedRecipients": [{"emailAddress": "recipient1@example.com"}],
"complaintFeedbackType": "abuse",
"arrivalDate": "2009-12-03T04:24:21.000-05:00",
"timestamp": "2012-05-25T14:59:38.623Z",
"feedbackId": "000001378603177f-18c07c78-fa81-4a58-9dd1-fedc3cb8f49a-000000"
"feedbackId": "000001378603177f-18c07c78-fa81-4a58-9dd1-fedc3cb8f49a-000000",
}
DELIVERY = {
"timestamp": "2014-05-28T22:41:01.184Z",
@ -77,5 +61,5 @@ DELIVERY = {
"recipients": ["success@simulator.amazonses.com"],
"smtpResponse": "250 ok: Message 64111812 accepted",
"reportingMTA": "a8-70.smtp-out.amazonses.com",
"remoteMtaIp": "127.0.2.0"
"remoteMtaIp": "127.0.2.0",
}

View file

@ -40,7 +40,6 @@ class SESFeedback(BaseModel):
class Message(BaseModel):
def __init__(self, message_id, source, subject, body, destinations):
self.id = message_id
self.source = source
@ -50,13 +49,7 @@ class Message(BaseModel):
class TemplateMessage(BaseModel):
def __init__(self,
message_id,
source,
template,
template_data,
destinations):
def __init__(self, message_id, source, template, template_data, destinations):
self.id = message_id
self.source = source
self.template = template
@ -65,7 +58,6 @@ class TemplateMessage(BaseModel):
class RawMessage(BaseModel):
def __init__(self, message_id, source, destinations, raw_data):
self.id = message_id
self.source = source
@ -74,7 +66,6 @@ class RawMessage(BaseModel):
class SESQuota(BaseModel):
def __init__(self, sent):
self.sent = sent
@ -84,7 +75,6 @@ class SESQuota(BaseModel):
class SESBackend(BaseBackend):
def __init__(self):
self.addresses = []
self.email_addresses = []
@ -97,7 +87,7 @@ class SESBackend(BaseBackend):
_, address = parseaddr(source)
if address in self.addresses:
return True
user, host = address.split('@', 1)
user, host = address.split("@", 1)
return host in self.domains
def verify_email_identity(self, address):
@ -116,7 +106,7 @@ class SESBackend(BaseBackend):
return self.email_addresses
def delete_identity(self, identity):
if '@' in identity:
if "@" in identity:
self.addresses.remove(identity)
else:
self.domains.remove(identity)
@ -124,11 +114,9 @@ class SESBackend(BaseBackend):
def send_email(self, source, subject, body, destinations, region):
recipient_count = sum(map(len, destinations.values()))
if recipient_count > RECIPIENT_LIMIT:
raise MessageRejectedError('Too many recipients.')
raise MessageRejectedError("Too many recipients.")
if not self._is_verified_address(source):
raise MessageRejectedError(
"Email address not verified %s" % source
)
raise MessageRejectedError("Email address not verified %s" % source)
self.__process_sns_feedback__(source, destinations, region)
@ -138,23 +126,21 @@ class SESBackend(BaseBackend):
self.sent_message_count += recipient_count
return message
def send_templated_email(self, source, template, template_data, destinations, region):
def send_templated_email(
self, source, template, template_data, destinations, region
):
recipient_count = sum(map(len, destinations.values()))
if recipient_count > RECIPIENT_LIMIT:
raise MessageRejectedError('Too many recipients.')
raise MessageRejectedError("Too many recipients.")
if not self._is_verified_address(source):
raise MessageRejectedError(
"Email address not verified %s" % source
)
raise MessageRejectedError("Email address not verified %s" % source)
self.__process_sns_feedback__(source, destinations, region)
message_id = get_random_message_id()
message = TemplateMessage(message_id,
source,
template,
template_data,
destinations)
message = TemplateMessage(
message_id, source, template, template_data, destinations
)
self.sent_messages.append(message)
self.sent_message_count += recipient_count
return message
@ -162,10 +148,11 @@ class SESBackend(BaseBackend):
def __type_of_message__(self, destinations):
"""Checks the destination for any special address that could indicate delivery,
complaint or bounce like in SES simualtor"""
alladdress = destinations.get(
"ToAddresses", []) + destinations.get(
"CcAddresses", []) + destinations.get(
"BccAddresses", [])
alladdress = (
destinations.get("ToAddresses", [])
+ destinations.get("CcAddresses", [])
+ destinations.get("BccAddresses", [])
)
for addr in alladdress:
if SESFeedback.SUCCESS_ADDR in addr:
return SESFeedback.DELIVERY
@ -198,30 +185,29 @@ class SESBackend(BaseBackend):
_, source_email_address = parseaddr(source)
if source_email_address not in self.addresses:
raise MessageRejectedError(
"Did not have authority to send from email %s" % source_email_address
"Did not have authority to send from email %s"
% source_email_address
)
recipient_count = len(destinations)
message = email.message_from_string(raw_data)
if source is None:
if message['from'] is None:
raise MessageRejectedError(
"Source not specified"
)
if message["from"] is None:
raise MessageRejectedError("Source not specified")
_, source_email_address = parseaddr(message['from'])
_, source_email_address = parseaddr(message["from"])
if source_email_address not in self.addresses:
raise MessageRejectedError(
"Did not have authority to send from email %s" % source_email_address
"Did not have authority to send from email %s"
% source_email_address
)
for header in 'TO', 'CC', 'BCC':
for header in "TO", "CC", "BCC":
recipient_count += sum(
d.strip() and 1 or 0
for d in message.get(header, '').split(',')
d.strip() and 1 or 0 for d in message.get(header, "").split(",")
)
if recipient_count > RECIPIENT_LIMIT:
raise MessageRejectedError('Too many recipients.')
raise MessageRejectedError("Too many recipients.")
self.__process_sns_feedback__(source, destinations, region)

View file

@ -8,15 +8,14 @@ from .models import ses_backend
class EmailResponse(BaseResponse):
def verify_email_identity(self):
address = self.querystring.get('EmailAddress')[0]
address = self.querystring.get("EmailAddress")[0]
ses_backend.verify_email_identity(address)
template = self.response_template(VERIFY_EMAIL_IDENTITY)
return template.render()
def verify_email_address(self):
address = self.querystring.get('EmailAddress')[0]
address = self.querystring.get("EmailAddress")[0]
ses_backend.verify_email_address(address)
template = self.response_template(VERIFY_EMAIL_ADDRESS)
return template.render()
@ -32,94 +31,88 @@ class EmailResponse(BaseResponse):
return template.render(email_addresses=email_addresses)
def verify_domain_dkim(self):
domain = self.querystring.get('Domain')[0]
domain = self.querystring.get("Domain")[0]
ses_backend.verify_domain(domain)
template = self.response_template(VERIFY_DOMAIN_DKIM_RESPONSE)
return template.render()
def verify_domain_identity(self):
domain = self.querystring.get('Domain')[0]
domain = self.querystring.get("Domain")[0]
ses_backend.verify_domain(domain)
template = self.response_template(VERIFY_DOMAIN_IDENTITY_RESPONSE)
return template.render()
def delete_identity(self):
domain = self.querystring.get('Identity')[0]
domain = self.querystring.get("Identity")[0]
ses_backend.delete_identity(domain)
template = self.response_template(DELETE_IDENTITY_RESPONSE)
return template.render()
def send_email(self):
bodydatakey = 'Message.Body.Text.Data'
if 'Message.Body.Html.Data' in self.querystring:
bodydatakey = 'Message.Body.Html.Data'
bodydatakey = "Message.Body.Text.Data"
if "Message.Body.Html.Data" in self.querystring:
bodydatakey = "Message.Body.Html.Data"
body = self.querystring.get(bodydatakey)[0]
source = self.querystring.get('Source')[0]
subject = self.querystring.get('Message.Subject.Data')[0]
destinations = {
'ToAddresses': [],
'CcAddresses': [],
'BccAddresses': [],
}
source = self.querystring.get("Source")[0]
subject = self.querystring.get("Message.Subject.Data")[0]
destinations = {"ToAddresses": [], "CcAddresses": [], "BccAddresses": []}
for dest_type in destinations:
# consume up to 51 to allow exception
for i in six.moves.range(1, 52):
field = 'Destination.%s.member.%s' % (dest_type, i)
field = "Destination.%s.member.%s" % (dest_type, i)
address = self.querystring.get(field)
if address is None:
break
destinations[dest_type].append(address[0])
message = ses_backend.send_email(source, subject, body, destinations, self.region)
message = ses_backend.send_email(
source, subject, body, destinations, self.region
)
template = self.response_template(SEND_EMAIL_RESPONSE)
return template.render(message=message)
def send_templated_email(self):
source = self.querystring.get('Source')[0]
template = self.querystring.get('Template')
template_data = self.querystring.get('TemplateData')
source = self.querystring.get("Source")[0]
template = self.querystring.get("Template")
template_data = self.querystring.get("TemplateData")
destinations = {
'ToAddresses': [],
'CcAddresses': [],
'BccAddresses': [],
}
destinations = {"ToAddresses": [], "CcAddresses": [], "BccAddresses": []}
for dest_type in destinations:
# consume up to 51 to allow exception
for i in six.moves.range(1, 52):
field = 'Destination.%s.member.%s' % (dest_type, i)
field = "Destination.%s.member.%s" % (dest_type, i)
address = self.querystring.get(field)
if address is None:
break
destinations[dest_type].append(address[0])
message = ses_backend.send_templated_email(source,
template,
template_data,
destinations,
self.region)
message = ses_backend.send_templated_email(
source, template, template_data, destinations, self.region
)
template = self.response_template(SEND_TEMPLATED_EMAIL_RESPONSE)
return template.render(message=message)
def send_raw_email(self):
source = self.querystring.get('Source')
source = self.querystring.get("Source")
if source is not None:
source, = source
(source,) = source
raw_data = self.querystring.get('RawMessage.Data')[0]
raw_data = self.querystring.get("RawMessage.Data")[0]
raw_data = base64.b64decode(raw_data)
if six.PY3:
raw_data = raw_data.decode('utf-8')
raw_data = raw_data.decode("utf-8")
destinations = []
# consume up to 51 to allow exception
for i in six.moves.range(1, 52):
field = 'Destinations.member.%s' % i
field = "Destinations.member.%s" % i
address = self.querystring.get(field)
if address is None:
break
destinations.append(address[0])
message = ses_backend.send_raw_email(source, destinations, raw_data, self.region)
message = ses_backend.send_raw_email(
source, destinations, raw_data, self.region
)
template = self.response_template(SEND_RAW_EMAIL_RESPONSE)
return template.render(message=message)

View file

@ -1,11 +1,6 @@
from __future__ import unicode_literals
from .responses import EmailResponse
url_bases = [
"https?://email.(.+).amazonaws.com",
"https?://ses.(.+).amazonaws.com",
]
url_bases = ["https?://email.(.+).amazonaws.com", "https?://ses.(.+).amazonaws.com"]
url_paths = {
'{0}/$': EmailResponse.dispatch,
}
url_paths = {"{0}/$": EmailResponse.dispatch}

View file

@ -4,16 +4,16 @@ import string
def random_hex(length):
return ''.join(random.choice(string.ascii_lowercase) for x in range(length))
return "".join(random.choice(string.ascii_lowercase) for x in range(length))
def get_random_message_id():
return "{0}-{1}-{2}-{3}-{4}-{5}-{6}".format(
random_hex(16),
random_hex(8),
random_hex(4),
random_hex(4),
random_hex(4),
random_hex(12),
random_hex(6),
random_hex(16),
random_hex(8),
random_hex(4),
random_hex(4),
random_hex(4),
random_hex(12),
random_hex(6),
)