clean flake8 except provider code

This commit is contained in:
stvnrlly
2022-10-14 14:45:27 +00:00
parent 65f15b21b0
commit e9fdfd59f4
35 changed files with 178 additions and 166 deletions

View File

@@ -10,6 +10,7 @@ from app.notifications.sns_handlers import sns_notification_handler
ses_callback_blueprint = Blueprint('notifications_ses_callback', __name__)
DEFAULT_MAX_AGE = timedelta(days=10000)
# 400 counts as a permanent failure so SNS will not retry.
# 500 counts as a failed delivery attempt so SNS will retry.
# See https://docs.aws.amazon.com/sns/latest/dg/DeliveryPolicies.html#DeliveryPolicies
@@ -21,7 +22,7 @@ def email_ses_callback_handler():
return jsonify(
result="error", message=str(e.message)
), e.status_code
message = data.get("Message")
if "mail" in message:
process_ses_results.apply_async([{"Message": message}], queue=QueueNames.NOTIFY)

View File

@@ -1,10 +1,10 @@
from flask import Blueprint, json, jsonify, request
from flask import Blueprint # , json, jsonify, request
# from app.celery.process_sms_client_response_tasks import (
# process_sms_client_response,
# )
from app.config import QueueNames
from app.errors import InvalidRequest, register_errors
# from app.config import QueueNames
from app.errors import register_errors
sms_callback_blueprint = Blueprint("sms_callback", __name__, url_prefix="/notifications/sms")
register_errors(sms_callback_blueprint)

View File

@@ -106,13 +106,13 @@ def persist_notification(
updated_at=None
):
current_app.logger.info('Presisting notification')
notification_created_at = created_at or datetime.utcnow()
if not notification_id:
notification_id = uuid.uuid4()
current_app.logger.info('Presisting notification with id {}'.format(notification_id))
notification = Notification(
id=notification_id,
template_id=template_id,
@@ -135,7 +135,7 @@ def persist_notification(
document_download_count=document_download_count,
updated_at=updated_at
)
current_app.logger.info('Presisting notification with to address: {}'.format(notification.to))
if notification_type == SMS_TYPE:

View File

@@ -24,6 +24,7 @@ INBOUND_SMS_COUNTER = Counter(
['provider']
)
@receive_notifications_blueprint.route('/notifications/sms/receive/sns', methods=['POST'])
def receive_sns_sms():
"""
@@ -37,13 +38,13 @@ def receive_sns_sms():
"previousPublishedMessageId":"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}
"""
# Whether or not to ignore inbound SMS replies
if not current_app.config['RECEIVE_INBOUND_SMS']:
return jsonify(
result="success", message="SMS-SNS callback succeeded"
), 200
try:
post_data = sns_notification_handler(request.data, request.headers)
except Exception as e:
@@ -53,13 +54,16 @@ def receive_sns_sms():
# TODO wrap this up
if "inboundMessageId" in message:
# TODO use standard formatting we use for all US numbers
inbound_number = message['destinationNumber'].replace('+','')
inbound_number = message['destinationNumber'].replace('+', '')
service = fetch_potential_service(inbound_number, 'sns')
if not service:
# since this is an issue with our service <-> number mapping, or no inbound_sms service permission
# we should still tell SNS that we received it successfully
current_app.logger.warning(f"Mapping between service and inbound number: {inbound_number} is broken, or service does not have permission to receive inbound sms")
current_app.logger.warning(
f"Mapping between service and inbound number: {inbound_number} is broken, \
or service does not have permission to receive inbound sms"
)
return jsonify(
result="success", message="SMS-SNS callback succeeded"
), 200
@@ -79,7 +83,6 @@ def receive_sns_sms():
date_received=date_received,
provider_name=provider_name)
# TODO ensure inbound sms callback endpoints are accessible and functioning for notify api users, then uncomment the task below
tasks.send_inbound_sms_to_service.apply_async([str(inbound.id), str(service.id)], queue=QueueNames.NOTIFY)
current_app.logger.debug(

View File

@@ -19,6 +19,7 @@ _cert_url_re = re.compile(
r'sns\.([a-z]{1,3}-[a-z]+-[0-9]{1,2})\.amazonaws\.com',
)
class ValidationError(Exception):
"""
ValidationError. Raised when a message fails integrity checks.
@@ -56,7 +57,7 @@ def get_string_to_sign(sns_payload):
for field in fields:
field_value = sns_payload.get(field)
if not isinstance(field_value, str):
if field == 'Subject' and field_value == None:
if field == 'Subject' and field_value is None:
continue
raise ValidationError(f"In {field}, found non-string value: {field_value}")
string_to_sign += field + '\n' + field_value + '\n'
@@ -77,25 +78,26 @@ def validate_sns_cert(sns_payload):
# Amazon SNS currently supports signature version 1.
if sns_payload.get('SignatureVersion') != '1':
raise ValidationError("Wrong Signature Version (expected 1)")
validate_arn(sns_payload)
string_to_sign = get_string_to_sign(sns_payload)
# Key signing cert url via Lambda and via webhook are slightly different
signing_cert_url = sns_payload.get('SigningCertUrl') if 'SigningCertUrl' in sns_payload else sns_payload.get('SigningCertURL')
signing_cert_url = sns_payload.get('SigningCertUrl') if 'SigningCertUrl' in \
sns_payload else sns_payload.get('SigningCertURL')
if not isinstance(signing_cert_url, str):
raise ValidationError("Signing cert url must be a string")
cert_scheme, cert_netloc, *_ = urlparse(signing_cert_url)
if cert_scheme != 'https' or not re.match(_cert_url_re, cert_netloc):
raise ValidationError("Cert does not appear to be from AWS")
certificate = _signing_cert_cache.get(signing_cert_url)
if certificate is None:
certificate = get_certificate(signing_cert_url)
if isinstance(certificate, six.text_type):
certificate = certificate.encode()
signature = base64.b64decode(sns_payload["Signature"])
try:
@@ -107,4 +109,4 @@ def validate_sns_cert(sns_payload):
)
return True
except oscrypto.errors.SignatureError:
raise ValidationError("Invalid signature")
raise ValidationError("Invalid signature")

View File

@@ -45,7 +45,9 @@ def sns_notification_handler(data, headers):
try:
validate_sns_cert(message)
except Exception as e:
current_app.logger.error(f"SES-SNS callback failed: validation failed with error: Signature validation failed with error {e}")
current_app.logger.error(
f"SES-SNS callback failed: validation failed with error: Signature validation failed with error {e}"
)
raise InvalidRequest("SES-SNS callback failed: validation failed", 400)
if message.get('Type') == 'SubscriptionConfirmation':
@@ -55,12 +57,18 @@ def sns_notification_handler(data, headers):
try:
response.raise_for_status()
except Exception as e:
current_app.logger.warning(f"Attempt to raise_for_status()SubscriptionConfirmation Type message files for response: {response.text} with error {e}")
raise InvalidRequest("SES-SNS callback failed: attempt to raise_for_status()SubscriptionConfirmation Type message failed", 400)
current_app.logger.warning(
f"Attempt to raise_for_status()SubscriptionConfirmation Type \
message files for response: {response.text} with error {e}"
)
raise InvalidRequest(
"SES-SNS callback failed: attempt to raise_for_status()SubscriptionConfirmation \
Type message failed", 400
)
current_app.logger.info("SES-SNS auto-confirm subscription callback succeeded")
return message
# TODO remove after smoke testing on prod is implemented
current_app.logger.info(f"SNS message: {message} is a valid message. Attempting to process it now.")
return message