From acc95a4b6677548872fdf143333e36e2e551bc9d Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 28 Oct 2020 16:12:27 -0700 Subject: [PATCH 1/6] Fix notification view to actually show associated certs --- lemur/certificates/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lemur/certificates/views.py b/lemur/certificates/views.py index 18746636..a066f20f 100644 --- a/lemur/certificates/views.py +++ b/lemur/certificates/views.py @@ -1155,6 +1155,7 @@ class NotificationCertificatesList(AuthenticatedResource): ) parser.add_argument("creator", type=str, location="args") parser.add_argument("show", type=str, location="args") + parser.add_argument("showExpired", type=int, location="args") args = parser.parse_args() args["notification_id"] = notification_id From 5e696f36bf8762da59583e85cb2ad4647417bca2 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 28 Oct 2020 16:34:31 -0700 Subject: [PATCH 2/6] Add ability to override SourceArnn for SES --- docs/administration.rst | 10 ++++++++++ lemur/plugins/lemur_email/plugin.py | 18 +++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/administration.rst b/docs/administration.rst index 724b136f..a1eba56e 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -285,6 +285,16 @@ Lemur supports sending certificate expiration notifications through SES and SMTP you can send any mail. See: `Verifying Email Address in Amazon SES `_ +.. data:: LEMUR_SES_SOURCE_ARN + :noindex: + + Specifies an ARN to use as the SourceArn when sending emails via SES. + + .. note:: + This parameter is only required if you're using a sending authorization with SES. + See: `Using sending authorization with Amazon SES `_ + + .. data:: LEMUR_EMAIL :noindex: diff --git a/lemur/plugins/lemur_email/plugin.py b/lemur/plugins/lemur_email/plugin.py index 5b9c188e..39e76932 100644 --- a/lemur/plugins/lemur_email/plugin.py +++ b/lemur/plugins/lemur_email/plugin.py @@ -38,7 +38,7 @@ def render_html(template_name, options, certificates): def send_via_smtp(subject, body, targets): """ - Attempts to deliver email notification via SES service. + Attempts to deliver email notification via SMTP. :param subject: :param body: @@ -55,21 +55,25 @@ def send_via_smtp(subject, body, targets): def send_via_ses(subject, body, targets): """ - Attempts to deliver email notification via SMTP. + Attempts to deliver email notification via SES service. :param subject: :param body: :param targets: :return: """ client = boto3.client("ses", region_name="us-east-1") - client.send_email( - Source=current_app.config.get("LEMUR_EMAIL"), - Destination={"ToAddresses": targets}, - Message={ + source_arn = current_app.config.get("LEMUR_SES_SOURCE_ARN") + args = { + "Source": current_app.config.get("LEMUR_EMAIL"), + "Destination": {"ToAddresses": targets}, + "Message": { "Subject": {"Data": subject, "Charset": "UTF-8"}, "Body": {"Html": {"Data": body, "Charset": "UTF-8"}}, }, - ) + } + if source_arn: + args["SourceArn"] = source_arn + client.send_email(**args) class EmailNotificationPlugin(ExpirationNotificationPlugin): From 3e492e6310496e26c85ca1d42223b3e59c89322c Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Wed, 28 Oct 2020 17:09:54 -0700 Subject: [PATCH 3/6] Add ability to override SES region --- docs/administration.rst | 9 +++++++++ lemur/plugins/lemur_email/plugin.py | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/administration.rst b/docs/administration.rst index a1eba56e..7e94a4db 100644 --- a/docs/administration.rst +++ b/docs/administration.rst @@ -295,6 +295,15 @@ Lemur supports sending certificate expiration notifications through SES and SMTP See: `Using sending authorization with Amazon SES `_ +.. data:: LEMUR_SES_REGION + :noindex: + + Specifies a region for sending emails via SES. + + .. note:: + This parameter defaults to us-east-1 and is only required if you wish to use a different region. + + .. data:: LEMUR_EMAIL :noindex: diff --git a/lemur/plugins/lemur_email/plugin.py b/lemur/plugins/lemur_email/plugin.py index 39e76932..a9e35d16 100644 --- a/lemur/plugins/lemur_email/plugin.py +++ b/lemur/plugins/lemur_email/plugin.py @@ -61,7 +61,10 @@ def send_via_ses(subject, body, targets): :param targets: :return: """ - client = boto3.client("ses", region_name="us-east-1") + ses_region = current_app.config.get("LEMUR_SES_REGION") + if not ses_region: + ses_region = "us-east-1" + client = boto3.client("ses", region_name=ses_region) source_arn = current_app.config.get("LEMUR_SES_SOURCE_ARN") args = { "Source": current_app.config.get("LEMUR_EMAIL"), From 78afc060aeb1fdbc44890b3571746c9327587175 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 29 Oct 2020 13:41:47 -0700 Subject: [PATCH 4/6] Add subject for SNS messages and correct date format --- lemur/plugins/lemur_aws/sns.py | 9 ++++++--- lemur/plugins/lemur_aws/tests/test_sns.py | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lemur/plugins/lemur_aws/sns.py b/lemur/plugins/lemur_aws/sns.py index c98bbc0c..14109c11 100644 --- a/lemur/plugins/lemur_aws/sns.py +++ b/lemur/plugins/lemur_aws/sns.py @@ -15,16 +15,18 @@ from flask import current_app def publish(topic_arn, certificates, notification_type, **kwargs): sns_client = boto3.client("sns", **kwargs) message_ids = {} + subject = "Lemur: {0} Notification".format(notification_type.capitalize()) for certificate in certificates: - message_ids[certificate["name"]] = publish_single(sns_client, topic_arn, certificate, notification_type) + message_ids[certificate["name"]] = publish_single(sns_client, topic_arn, certificate, notification_type, subject) return message_ids -def publish_single(sns_client, topic_arn, certificate, notification_type): +def publish_single(sns_client, topic_arn, certificate, notification_type, subject): response = sns_client.publish( TopicArn=topic_arn, Message=format_message(certificate, notification_type), + Subject=subject, ) response_code = response["ResponseMetadata"]["HTTPStatusCode"] @@ -48,8 +50,9 @@ def format_message(certificate, notification_type): json_message = { "notification_type": notification_type, "certificate_name": certificate["name"], - "expires": arrow.get(certificate["validityEnd"]).format("YYYY-MM-ddTHH:mm:ss"), # 2047-12-T22:00:00 + "expires": arrow.get(certificate["validityEnd"]).format("YYYY-MM-DDTHH:mm:ss"), # 2047-12-31T22:00:00 "endpoints_detected": len(certificate["endpoints"]), + "owner": certificate["owner"], "details": create_certificate_url(certificate["name"]) } return json.dumps(json_message) diff --git a/lemur/plugins/lemur_aws/tests/test_sns.py b/lemur/plugins/lemur_aws/tests/test_sns.py index ce05c33c..59ef30f2 100644 --- a/lemur/plugins/lemur_aws/tests/test_sns.py +++ b/lemur/plugins/lemur_aws/tests/test_sns.py @@ -20,8 +20,9 @@ def test_format(certificate, endpoint): expected_message = { "notification_type": "expiration", "certificate_name": certificate["name"], - "expires": arrow.get(certificate["validityEnd"]).format("YYYY-MM-ddTHH:mm:ss"), + "expires": arrow.get(certificate["validityEnd"]).format("YYYY-MM-DDTHH:mm:ss"), "endpoints_detected": 0, + "owner": certificate["owner"], "details": "https://lemur.example.com/#/certificates/{name}".format(name=certificate["name"]) } assert expected_message == json.loads(format_message(certificate, "expiration")) @@ -57,7 +58,9 @@ def test_publish(certificate, endpoint): expected_message_id = message_ids[certificate["name"]] actual_message = next( (m for m in received_messages if json.loads(m["Body"])["MessageId"] == expected_message_id), None) - assert json.loads(actual_message["Body"])["Message"] == format_message(certificate, "expiration") + actual_json = json.loads(actual_message["Body"]) + assert actual_json["Message"] == format_message(certificate, "expiration") + assert actual_json["Subject"] == "Lemur: Expiration Notification" def get_options(): From 45cc9528d28416155197d72653996236c8843180 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 29 Oct 2020 13:48:43 -0700 Subject: [PATCH 5/6] Cleaner syntax for default region --- lemur/plugins/lemur_email/plugin.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lemur/plugins/lemur_email/plugin.py b/lemur/plugins/lemur_email/plugin.py index a9e35d16..f380c82e 100644 --- a/lemur/plugins/lemur_email/plugin.py +++ b/lemur/plugins/lemur_email/plugin.py @@ -61,9 +61,7 @@ def send_via_ses(subject, body, targets): :param targets: :return: """ - ses_region = current_app.config.get("LEMUR_SES_REGION") - if not ses_region: - ses_region = "us-east-1" + ses_region = current_app.config.get("LEMUR_SES_REGION", "us-east-1") client = boto3.client("ses", region_name=ses_region) source_arn = current_app.config.get("LEMUR_SES_SOURCE_ARN") args = { From 84f8905cf1a0cfb0c15c1c1b5974f54ee9527376 Mon Sep 17 00:00:00 2001 From: Jasmine Schladen Date: Thu, 29 Oct 2020 14:07:25 -0700 Subject: [PATCH 6/6] Hide expired certs for notifications --- lemur/static/app/angular/notifications/services.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lemur/static/app/angular/notifications/services.js b/lemur/static/app/angular/notifications/services.js index 02443701..9e8c9b33 100644 --- a/lemur/static/app/angular/notifications/services.js +++ b/lemur/static/app/angular/notifications/services.js @@ -27,7 +27,7 @@ angular.module('lemur') }; NotificationService.getCertificates = function (notification) { - notification.getList('certificates').then(function (certificates) { + notification.getList('certificates', {showExpired: 0}).then(function (certificates) { notification.certificates = certificates; }); }; @@ -40,7 +40,7 @@ angular.module('lemur') NotificationService.loadMoreCertificates = function (notification, page) { - notification.getList('certificates', {page: page}).then(function (certificates) { + notification.getList('certificates', {page: page, showExpired: 0}).then(function (certificates) { _.each(certificates, function (certificate) { notification.roles.push(certificate); });