From 33e3223cbfd12a16c2fe2f1bd58f4e3cc8ddb439 Mon Sep 17 00:00:00 2001 From: Rachel Guan Date: Mon, 30 Aug 2021 11:51:05 -0400 Subject: [PATCH] Update expiring certificate notification email content (#1294) * Update expiring certificate notification email content * Improve test cases --- ...ingCertificateNotificationEmailAction.java | 10 ++- .../registry/config/files/default-config.yaml | 49 +++++++++++- ...ertificateNotificationEmailActionTest.java | 80 +++++++++++++++++-- 3 files changed, 126 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java b/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java index 4cb3a0fc8..4f79f84cc 100644 --- a/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java +++ b/core/src/main/java/google/registry/batch/SendExpiringCertificateNotificationEmailAction.java @@ -165,7 +165,8 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable getEmailBody( registrar.getRegistrarName(), certificateType, - certificateChecker.getCertificate(certificate.get()).getNotAfter())) + certificateChecker.getCertificate(certificate.get()).getNotAfter(), + registrar.getClientId())) .setRecipients(recipients) .setCcs(getEmailAddresses(registrar, Type.ADMIN)) .build()); @@ -289,14 +290,17 @@ public class SendExpiringCertificateNotificationEmailAction implements Runnable */ @VisibleForTesting @SuppressWarnings("lgtm[java/dereferenced-value-may-be-null]") - String getEmailBody(String registrarName, CertificateType type, Date expirationDate) { + String getEmailBody( + String registrarName, CertificateType type, Date expirationDate, String registrarId) { checkArgumentNotNull(expirationDate, "Expiration date cannot be null"); checkArgumentNotNull(type, "Certificate type cannot be null"); + checkArgumentNotNull(registrarId, "Registrar Id cannot be null"); return String.format( expirationWarningEmailBodyText, registrarName, type.getDisplayName(), - DATE_FORMATTER.print(new DateTime(expirationDate))); + DATE_FORMATTER.print(new DateTime(expirationDate)), + registrarId); } /** diff --git a/core/src/main/java/google/registry/config/files/default-config.yaml b/core/src/main/java/google/registry/config/files/default-config.yaml index 5afe0b8b6..082a5a0e6 100644 --- a/core/src/main/java/google/registry/config/files/default-config.yaml +++ b/core/src/main/java/google/registry/config/files/default-config.yaml @@ -456,12 +456,53 @@ sslCertificateValidation: # The minimum number of days between two successive expiring notification emails. expirationWarningIntervalDays: 15 # Text for expiring certificate notification email subject. - expirationWarningEmailSubjectText: Certificate Expring Within 30 Days. + expirationWarningEmailSubjectText: "[Important] Expiring SSL certificate for Google Registry EPP connection" # Text for expiring certificate notification email body that accepts 3 parameters: # registrar name, certificate type, and expiration date, respectively. - expirationWarningEmailBodyText: | - Hello Registrar %s, - The %s certificate is expiring on %s. + expirationWarningEmailBodyText: > + Dear %1$s, + + We would like to inform you that your %2$s SSL certificate will expire at + %3$s. Please take note that using expired certificates will prevent + successful Registry login. + + Kindly update your production account certificate within the support + console using the following steps: + + 1. Navigate to support.registry.google and login using your + %4$s@registry.google credentials. + * If this is your first time logging in, you will be prompted to + reset your password, so please keep your new password safe. + * If you are already logged in with some other Google account(s) but + not your %4$s@registry.google account, you need to click on + “Add Account” and login using your %4$s@registry.google credentials. + 2. Select “Settings > Security” from the left navigation bar. + 3. Click “Edit” on the top left corner. + 4. Enter your full certificate string + (including lines -----BEGIN CERTIFICATE----- and + -----END CERTIFICATE-----) in the box. + 5. Click “Save”. If there are validation issues with the form, you will + be prompted to fix them and click “Save” again. + + A failover SSL certificate can also be added in order to prevent connection + issues once your main certificate expires. Connecting with either of the + certificates will work with our production EPP server. + + Further information about our EPP connection requirements can be found in + section 9.2 in the updated Technical Guide in your Google Drive folder. + + Note that account certificate changes take a few minutes to become + effective and that the existing connections will remain unaffected by + the change. + + If you also would like to update your OT&E account certificate, please send + an email from your primary or technical contact to + registry-support@google.com and include the full certificate string + (including lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----). + + Regards, + Google Registry + # The minimum number of bits an RSA key must contain. minimumRsaKeyLength: 2048 # The ECDSA curves that are allowed for public keys. diff --git a/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java b/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java index 3f66130ed..40ab4c242 100644 --- a/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java +++ b/core/src/test/java/google/registry/batch/SendExpiringCertificateNotificationEmailActionTest.java @@ -66,6 +66,51 @@ class SendExpiringCertificateNotificationEmailActionTest { private SendExpiringCertificateNotificationEmailAction action; private Registrar sampleRegistrar; private Response response; + private static final String expirationWarningEmailBodyText = + " Dear %1$s,\n" + + "\n" + + " We would like to inform you that your %2$s SSL certificate will expire at\n" + + " %3$s. Please take note that using expired certificates will prevent\n" + + " successful Registry login.\n" + + "\n" + + " Kindly update your production account certificate within the support\n" + + " console using the following steps:\n" + + "\n" + + " 1. Navigate to support.registry.google and login using your\n" + + " %4$s@registry.google credentials.\n" + + " * If this is your first time logging in, you will be prompted to\n" + + " reset your password, so please keep your new password safe.\n" + + " * If you are already logged in with some other Google account(s) but\n" + + " not your %4$s@registry.google account, you need to click on\n" + + " “Add Account” and login using your %4$s@registry.google credentials.\n" + + " 2. Select “Settings > Security” from the left navigation bar.\n" + + " 3. Click “Edit” on the top left corner.\n" + + " 4. Enter your full certificate string\n" + + " (including lines -----BEGIN CERTIFICATE----- and\n" + + " -----END CERTIFICATE-----) in the box.\n" + + " 5. Click “Save”. If there are validation issues with the form, you will\n" + + " be prompted to fix them and click “Save” again.\n" + + "\n" + + " A failover SSL certificate can also be added in order to prevent connection\n" + + " issues once your main certificate expires. Connecting with either of the\n" + + " certificates will work with our production EPP server.\n" + + "\n" + + " Further information about our EPP connection requirements can be found in\n" + + " section 9.2 in the updated Technical Guide in your Google Drive folder.\n" + + "\n" + + " Note that account certificate changes take a few minutes to become\n" + + " effective and that the existing connections will remain unaffected by\n" + + " the change.\n" + + "\n" + + " If you also would like to update your OT&E account certificate, please send\n" + + " an email from your primary or technical contact to\n" + + " registry-support@google.com and include the full certificate string\n" + + " (including lines -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----).\n" + + "\n" + + " Regards,\n" + + " Google Registry\n"; + private static final String expirationWarningEmailSubjectText = + "[Important] Expiring SSL certificate for Google " + "Registry EPP connection"; @BeforeEach void beforeEach() throws Exception { @@ -77,9 +122,6 @@ class SendExpiringCertificateNotificationEmailActionTest { 2048, ImmutableSet.of("secp256r1", "secp384r1"), clock); - String expirationWarningEmailBodyText = - " Hello Registrar %s,\n" + " The %s certificate is expiring on %s."; - String expirationWarningEmailSubjectText = "expiring certificate notification email"; action = new SendExpiringCertificateNotificationEmailAction( @@ -578,12 +620,21 @@ class SendExpiringCertificateNotificationEmailActionTest { String registrarName = "good registrar"; String certExpirationDateStr = "2021-06-15"; CertificateType certificateType = CertificateType.PRIMARY; + String registrarId = "registrarid"; String emailBody = action.getEmailBody( - registrarName, certificateType, DateTime.parse(certExpirationDateStr).toDate()); + registrarName, + certificateType, + DateTime.parse(certExpirationDateStr).toDate(), + registrarId); assertThat(emailBody).contains(registrarName); assertThat(emailBody).contains(certificateType.getDisplayName()); assertThat(emailBody).contains(certExpirationDateStr); + assertThat(emailBody).contains(registrarId + "@registry.google"); + assertThat(emailBody).doesNotContain("%1$s@registry.google"); + assertThat(emailBody).doesNotContain("%2$s@registry.google"); + assertThat(emailBody).doesNotContain("%3$s@registry.google"); + assertThat(emailBody).doesNotContain("%4$s@registry.google"); } @TestOfyAndSql @@ -591,7 +642,9 @@ class SendExpiringCertificateNotificationEmailActionTest { IllegalArgumentException thrown = assertThrows( IllegalArgumentException.class, - () -> action.getEmailBody("good registrar", CertificateType.FAILOVER, null)); + () -> + action.getEmailBody( + "good registrar", CertificateType.FAILOVER, null, "registrarId")); assertThat(thrown).hasMessageThat().contains("Expiration date cannot be null"); } @@ -601,7 +654,22 @@ class SendExpiringCertificateNotificationEmailActionTest { assertThrows( IllegalArgumentException.class, () -> - action.getEmailBody("good registrar", null, DateTime.parse("2021-06-15").toDate())); + action.getEmailBody( + "good registrar", null, DateTime.parse("2021-06-15").toDate(), "registrarId")); assertThat(thrown).hasMessageThat().contains("Certificate type cannot be null"); } + + @TestOfyAndSql + void getEmailBody_throwsIllegalArgumentException_noRegistrarId() { + IllegalArgumentException thrown = + assertThrows( + IllegalArgumentException.class, + () -> + action.getEmailBody( + "good registrar", + CertificateType.FAILOVER, + DateTime.parse("2021-06-15").toDate(), + null)); + assertThat(thrown).hasMessageThat().contains("Registrar Id cannot be null"); + } }