Added in publish by phone number

This commit is contained in:
Terry Cain 2017-09-26 00:21:07 +01:00
parent aad408b8ac
commit 56c65bc67c
No known key found for this signature in database
GPG Key ID: 14D90844E4E9B9F3
5 changed files with 121 additions and 1 deletions

View File

@ -221,6 +221,12 @@ class SNSBackend(BaseBackend):
except KeyError:
raise SNSNotFoundError("Topic with arn {0} not found".format(arn))
def get_topic_from_phone_number(self, number):
for subscription in self.subscriptions.values():
if subscription.protocol == 'sms' and subscription.endpoint == number:
return subscription.topic.arn
raise SNSNotFoundError('Could not find valid subscription')
def set_topic_attribute(self, topic_arn, attribute_name, attribute_value):
topic = self.get_topic(topic_arn)
setattr(topic, attribute_name, attribute_value)

View File

@ -6,6 +6,8 @@ from collections import defaultdict
from moto.core.responses import BaseResponse
from moto.core.utils import camelcase_to_underscores
from .models import sns_backends
from .exceptions import SNSNotFoundError
from .utils import is_e164
class SNSResponse(BaseResponse):
@ -136,6 +138,13 @@ class SNSResponse(BaseResponse):
topic_arn = self._get_param('TopicArn')
endpoint = self._get_param('Endpoint')
protocol = self._get_param('Protocol')
if protocol == 'sms' and not is_e164(endpoint):
return self._error(
'InvalidParameter',
'Phone number does not meet the E164 format'
), dict(status=400)
subscription = self.backend.subscribe(topic_arn, endpoint, protocol)
if self.request_json:
@ -229,7 +238,28 @@ class SNSResponse(BaseResponse):
def publish(self):
target_arn = self._get_param('TargetArn')
topic_arn = self._get_param('TopicArn')
arn = target_arn if target_arn else topic_arn
phone_number = self._get_param('PhoneNumber')
if phone_number is not None:
# Check phone is correct syntax (e164)
if not is_e164(phone_number):
return self._error(
'InvalidParameter',
'Phone number does not meet the E164 format'
), dict(status=400)
# Look up topic arn by phone number
try:
arn = self.backend.get_topic_from_phone_number(phone_number)
except SNSNotFoundError:
return self._error(
'ParameterValueInvalid',
'Could not find topic associated with phone number'
), dict(status=400)
elif target_arn is not None:
arn = target_arn
else:
arn = topic_arn
message = self._get_param('Message')
message_id = self.backend.publish(arn, message)

View File

@ -1,6 +1,9 @@
from __future__ import unicode_literals
import re
import uuid
E164_REGEX = re.compile(r'^\+?[1-9]\d{1,14}$')
def make_arn_for_topic(account_id, name, region_name):
return "arn:aws:sns:{0}:{1}:{2}".format(region_name, account_id, name)
@ -9,3 +12,7 @@ def make_arn_for_topic(account_id, name, region_name):
def make_arn_for_subscription(topic_arn):
subscription_id = uuid.uuid4()
return "{0}:{1}".format(topic_arn, subscription_id)
def is_e164(number):
return E164_REGEX.match(number) is not None

View File

@ -10,6 +10,7 @@ from freezegun import freeze_time
import sure # noqa
from moto.packages.responses import responses
from botocore.exceptions import ClientError
from moto import mock_sns, mock_sqs
from freezegun import freeze_time
@ -43,6 +44,49 @@ def test_publish_to_sqs():
acquired_message.should.equal(expected)
@mock_sns
def test_publish_sms():
client = boto3.client('sns', region_name='us-east-1')
client.create_topic(Name="some-topic")
resp = client.create_topic(Name="some-topic")
arn = resp['TopicArn']
client.subscribe(
TopicArn=arn,
Protocol='sms',
Endpoint='+15551234567'
)
result = client.publish(PhoneNumber="+15551234567", Message="my message")
result.should.contain('MessageId')
@mock_sns
def test_publish_bad_sms():
client = boto3.client('sns', region_name='us-east-1')
client.create_topic(Name="some-topic")
resp = client.create_topic(Name="some-topic")
arn = resp['TopicArn']
client.subscribe(
TopicArn=arn,
Protocol='sms',
Endpoint='+15551234567'
)
try:
# Test invalid number
client.publish(PhoneNumber="NAA+15551234567", Message="my message")
except ClientError as err:
err.response['Error']['Code'].should.equal('InvalidParameter')
try:
# Test not found number
client.publish(PhoneNumber="+44001234567", Message="my message")
except ClientError as err:
err.response['Error']['Code'].should.equal('ParameterValueInvalid')
@mock_sqs
@mock_sns
def test_publish_to_sqs_dump_json():

View File

@ -11,6 +11,39 @@ from moto import mock_sns
from moto.sns.models import DEFAULT_PAGE_SIZE
@mock_sns
def test_subscribe_sms():
client = boto3.client('sns', region_name='us-east-1')
client.create_topic(Name="some-topic")
resp = client.create_topic(Name="some-topic")
arn = resp['TopicArn']
resp = client.subscribe(
TopicArn=arn,
Protocol='sms',
Endpoint='+15551234567'
)
resp.should.contain('SubscriptionArn')
@mock_sns
def test_subscribe_bad_sms():
client = boto3.client('sns', region_name='us-east-1')
client.create_topic(Name="some-topic")
resp = client.create_topic(Name="some-topic")
arn = resp['TopicArn']
try:
# Test invalid number
client.subscribe(
TopicArn=arn,
Protocol='sms',
Endpoint='NAA+15551234567'
)
except ClientError as err:
err.response['Error']['Code'].should.equal('InvalidParameter')
@mock_sns
def test_creating_subscription():
conn = boto3.client('sns', region_name='us-east-1')