mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-01 07:35:34 -05:00
Remove the abstract ClientResponses class. Refactor aws_ses not to require the class.
All three client now use a response_map for the delivery receipt processing.
This commit is contained in:
@@ -16,23 +16,3 @@ class Client(object):
|
||||
STATISTICS_REQUESTED = 'requested'
|
||||
STATISTICS_DELIVERED = 'delivered'
|
||||
STATISTICS_FAILURE = 'failure'
|
||||
|
||||
|
||||
class ClientResponse:
|
||||
def __init__(self):
|
||||
self.__response_model__ = None
|
||||
|
||||
def response_code_to_object(self, response_code):
|
||||
return self.__response_model__[response_code]
|
||||
|
||||
def response_code_to_message(self, response_code):
|
||||
return self.response_code_to_object(response_code)['message']
|
||||
|
||||
def response_code_to_notification_status(self, response_code):
|
||||
return self.response_code_to_object(response_code)['notification_status']
|
||||
|
||||
def response_code_to_notification_statistics_status(self, response_code):
|
||||
return self.response_code_to_object(response_code)['notification_statistics_status']
|
||||
|
||||
def response_code_to_notification_success(self, response_code):
|
||||
return self.response_code_to_object(response_code)['success']
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
import boto3
|
||||
from flask import current_app
|
||||
from monotonic import monotonic
|
||||
from app.clients import ClientResponse, STATISTICS_DELIVERED, STATISTICS_FAILURE
|
||||
from app.clients import STATISTICS_DELIVERED, STATISTICS_FAILURE
|
||||
from app.clients.email import (EmailClientException, EmailClient)
|
||||
|
||||
ses_response_map = {
|
||||
'Bounce': {
|
||||
"message": 'Bounced',
|
||||
"success": False,
|
||||
"notification_status": 'bounce',
|
||||
"notification_statistics_status": STATISTICS_FAILURE
|
||||
},
|
||||
'Delivery': {
|
||||
"message": 'Delivered',
|
||||
"success": True,
|
||||
"notification_status": 'delivered',
|
||||
"notification_statistics_status": STATISTICS_DELIVERED
|
||||
},
|
||||
'Complaint': {
|
||||
"message": 'Complaint',
|
||||
"success": False,
|
||||
"notification_status": 'complaint',
|
||||
"notification_statistics_status": STATISTICS_FAILURE
|
||||
}
|
||||
}
|
||||
|
||||
class AwsSesResponses(ClientResponse):
|
||||
def __init__(self):
|
||||
ClientResponse.__init__(self)
|
||||
self.__response_model__ = {
|
||||
'Bounce': {
|
||||
"message": 'Bounced',
|
||||
"success": False,
|
||||
"notification_status": 'bounce',
|
||||
"notification_statistics_status": STATISTICS_FAILURE
|
||||
},
|
||||
'Delivery': {
|
||||
"message": 'Delivered',
|
||||
"success": True,
|
||||
"notification_status": 'delivered',
|
||||
"notification_statistics_status": STATISTICS_DELIVERED
|
||||
},
|
||||
'Complaint': {
|
||||
"message": 'Complaint',
|
||||
"success": False,
|
||||
"notification_status": 'complaint',
|
||||
"notification_statistics_status": STATISTICS_FAILURE
|
||||
}
|
||||
}
|
||||
|
||||
def get_aws_responses(status):
|
||||
return ses_response_map[status]
|
||||
|
||||
|
||||
class AwsSesClientException(EmailClientException):
|
||||
|
||||
@@ -11,7 +11,7 @@ from flask import (
|
||||
)
|
||||
from utils.recipients import allowed_to_send_to, first_column_heading
|
||||
from utils.template import Template
|
||||
from app.clients.email.aws_ses import AwsSesResponses
|
||||
from app.clients.email.aws_ses import get_aws_responses
|
||||
from app import api_user, encryption, create_uuid, DATETIME_FORMAT, DATE_FORMAT
|
||||
from app.authentication.auth import require_admin
|
||||
from app.dao import (
|
||||
@@ -36,46 +36,40 @@ notifications = Blueprint('notifications', __name__)
|
||||
from app.errors import register_errors
|
||||
|
||||
register_errors(notifications)
|
||||
aws_response = AwsSesResponses()
|
||||
|
||||
|
||||
@notifications.route('/notifications/email/ses', methods=['POST'])
|
||||
def process_ses_response():
|
||||
client_name = 'SES'
|
||||
try:
|
||||
ses_request = json.loads(request.data)
|
||||
if 'Message' not in ses_request:
|
||||
current_app.logger.error(
|
||||
"SES callback failed: message missing"
|
||||
)
|
||||
|
||||
errors = validate_callback_data(data=ses_request, fields=['Message'], client_name=client_name)
|
||||
if errors:
|
||||
return jsonify(
|
||||
result="error", message="SES callback failed: message missing"
|
||||
result="error", message=errors
|
||||
), 400
|
||||
|
||||
ses_message = json.loads(ses_request['Message'])
|
||||
|
||||
if 'notificationType' not in ses_message:
|
||||
current_app.logger.error(
|
||||
"SES callback failed: notificationType missing"
|
||||
)
|
||||
errors = validate_callback_data(data=ses_message, fields=['notificationType'], client_name=client_name)
|
||||
if errors:
|
||||
return jsonify(
|
||||
result="error", message="SES callback failed: notificationType missing"
|
||||
result="error", message=errors
|
||||
), 400
|
||||
|
||||
notification_type = ses_message['notificationType']
|
||||
try:
|
||||
aws_response.response_code_to_object(ses_message['notificationType'])
|
||||
aws_response_dict = get_aws_responses(notification_type)
|
||||
except KeyError:
|
||||
current_app.logger.info(
|
||||
"SES callback failed: status {} not found.".format(ses_message['notificationType'])
|
||||
)
|
||||
message = "{} callback failed: status {} not found".format(client_name, notification_type)
|
||||
current_app.logger.info(message)
|
||||
return jsonify(
|
||||
result="error",
|
||||
message="SES callback failed: status {} not found".format(ses_message['notificationType'])
|
||||
message=message
|
||||
), 400
|
||||
|
||||
notification_status = aws_response.response_code_to_notification_status(ses_message['notificationType'])
|
||||
notification_statistics_status = aws_response.response_code_to_notification_statistics_status(
|
||||
ses_message['notificationType']
|
||||
)
|
||||
notification_status = aws_response_dict['notification_status']
|
||||
notification_statistics_status = aws_response_dict['notification_statistics_status']
|
||||
|
||||
try:
|
||||
source = ses_message['mail']['source']
|
||||
@@ -101,11 +95,11 @@ def process_ses_response():
|
||||
message="SES callback failed: notification not found. Status {}".format(notification_status)
|
||||
), 404
|
||||
|
||||
if not aws_response.response_code_to_notification_success(ses_message['notificationType']):
|
||||
if not aws_response_dict['success']:
|
||||
current_app.logger.info(
|
||||
"SES delivery failed: notification {} has error found. Status {}".format(
|
||||
reference,
|
||||
aws_response.response_code_to_message(ses_message['notificationType'])
|
||||
aws_response_dict['message']
|
||||
)
|
||||
)
|
||||
|
||||
@@ -123,10 +117,10 @@ def process_ses_response():
|
||||
|
||||
except ValueError as ex:
|
||||
current_app.logger.exception(
|
||||
"SES callback failed: invalid json {}".format(ex)
|
||||
"{} callback failed: invalid json {}".format(client_name, ex)
|
||||
)
|
||||
return jsonify(
|
||||
result="error", message="SES callback failed: invalid json"
|
||||
result="error", message="{} callback failed: invalid json".format(client_name)
|
||||
), 400
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user