Update Spec 11 emails body and add a bcc address.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=217150650
This commit is contained in:
jianglai 2018-10-15 08:58:14 -07:00 committed by Ben McIlwain
parent 8d93cd8edf
commit 476759e861
6 changed files with 99 additions and 22 deletions

View file

@ -815,6 +815,7 @@ public final class RegistryConfig {
* *
* @see google.registry.reporting.icann.ReportingEmailUtils * @see google.registry.reporting.icann.ReportingEmailUtils
* @see google.registry.reporting.billing.BillingEmailUtils * @see google.registry.reporting.billing.BillingEmailUtils
* @see google.registry.reporting.spec11.Spec11EmailUtils
*/ */
@Provides @Provides
@Config("alertRecipientEmailAddress") @Config("alertRecipientEmailAddress")
@ -827,13 +828,35 @@ public final class RegistryConfig {
* *
* @see google.registry.reporting.icann.ReportingEmailUtils * @see google.registry.reporting.icann.ReportingEmailUtils
* @see google.registry.reporting.billing.BillingEmailUtils * @see google.registry.reporting.billing.BillingEmailUtils
* @see google.registry.reporting.spec11.Spec11EmailUtils
*/ */
@Provides @Provides
@Config("alertSenderEmailAddress") @Config("alertSenderEmailAddress")
public static String provideAlertSenderEmailAddress( public static String provideAlertSenderEmailAddress(
@Config("projectId") String projectId, RegistryConfigSettings config) { @Config("projectId") String projectId, RegistryConfigSettings config) {
return String.format("%s@%s", projectId, config.misc.alertEmailSenderDomain); return String.format("%s-no-reply@%s", projectId, config.misc.alertEmailSenderDomain);
}
/**
* Returns the email address to which spec 11 email should be replied.
*
* @see google.registry.reporting.spec11.Spec11EmailUtils
*/
@Provides
@Config("spec11ReplyToEmailAddress")
public static String provideSpec11ReplyToEmailAddress(RegistryConfigSettings config) {
return config.misc.spec11ReplyToEmailAddress;
}
/**
* Returns the template for the body of the spec 11 email to the registrars.
*
* @see google.registry.reporting.spec11.Spec11EmailUtils
*/
@Provides
@Config("spec11EmailBodyTemplate")
public static String provideSpec11EmailBodyTemplate(RegistryConfigSettings config) {
return config.registryPolicy.spec11EmailBodyTemplate;
} }
/** /**

View file

@ -90,6 +90,7 @@ public class RegistryConfigSettings {
public String reservedTermsExportDisclaimer; public String reservedTermsExportDisclaimer;
public String whoisDisclaimer; public String whoisDisclaimer;
public String rdapTos; public String rdapTos;
public String spec11EmailBodyTemplate;
} }
/** Configuration for Cloud Datastore. */ /** Configuration for Cloud Datastore. */
@ -160,6 +161,7 @@ public class RegistryConfigSettings {
public static class Misc { public static class Misc {
public String sheetExportId; public String sheetExportId;
public String alertRecipientEmailAddress; public String alertRecipientEmailAddress;
public String spec11ReplyToEmailAddress;
public String alertEmailSenderDomain; public String alertEmailSenderDomain;
public int asyncDeleteDelaySeconds; public int asyncDeleteDelaySeconds;
} }

View file

@ -142,6 +142,33 @@ registryPolicy:
We reserve the right to modify this agreement at any time. We reserve the right to modify this agreement at any time.
# Body of the spec 11 email sent to registrars.
# Items in braces are to be replaced.
spec11EmailBodyTemplate: |
Dear registrar partner,
The registry conducts periodic technical analyses of all domains registered
in its TLDs. As part of this analysis, the following domains that you
manage were flagged for potential security concerns:
{LIST_OF_THREATS}
Please communicate these findings to the registrant and work with the
registrant to mitigate any security issues and have the domains delisted.
Some helpful sites for getting off a blocked list include:
- Google Search Console (https://search.google.com/search-console/about)
-- includes information and tools for webmasters to learn about and
mitigate security threats and have their websites delisted
- first.org -- a registry of Computer Emergency Response Teams (CERTs)
that may be able to assist in mitigation
- stopbadware.org -- a non-profit anti-malware organization that provides
support and information for webmasters dealing with security threats
If you have any questions regarding this notice, please contact
{REPLY_TO_EMAIL}.
datastore: datastore:
# Number of commit log buckets in Datastore. Lowering this after initial # Number of commit log buckets in Datastore. Lowering this after initial
# install risks losing up to a days' worth of differential backups. # install risks losing up to a days' worth of differential backups.
@ -305,6 +332,10 @@ misc:
# Address we send alert summary emails to. # Address we send alert summary emails to.
alertRecipientEmailAddress: email@example.com alertRecipientEmailAddress: email@example.com
# Address to which the Spec 11 emails to registrars should be replied. This needs
# to be a deliverable email address in case the registrars want to contact us.
spec11ReplyToEmailAddress: reply-to@example.com
# Domain for the email address we send alert summary emails from. # Domain for the email address we send alert summary emails from.
alertEmailSenderDomain: appspotmail.com alertEmailSenderDomain: appspotmail.com

View file

@ -47,8 +47,10 @@ public class Spec11EmailUtils {
private final YearMonth yearMonth; private final YearMonth yearMonth;
private final String alertSenderAddress; private final String alertSenderAddress;
private final String alertRecipientAddress; private final String alertRecipientAddress;
private final String spec11ReplyToAddress;
private final String reportingBucket; private final String reportingBucket;
private final String spec11ReportDirectory; private final String spec11ReportDirectory;
private final String spec11EmailBodyTemplate;
private final GcsUtils gcsUtils; private final GcsUtils gcsUtils;
private final Retrier retrier; private final Retrier retrier;
@ -58,6 +60,8 @@ public class Spec11EmailUtils {
YearMonth yearMonth, YearMonth yearMonth,
@Config("alertSenderEmailAddress") String alertSenderAddress, @Config("alertSenderEmailAddress") String alertSenderAddress,
@Config("alertRecipientEmailAddress") String alertRecipientAddress, @Config("alertRecipientEmailAddress") String alertRecipientAddress,
@Config("spec11ReplyToEmailAddress") String spec11ReplyToAddress,
@Config("spec11EmailBodyTemplate") String spec11EmailBodyTemplate,
@Config("reportingBucket") String reportingBucket, @Config("reportingBucket") String reportingBucket,
@Spec11ReportDirectory String spec11ReportDirectory, @Spec11ReportDirectory String spec11ReportDirectory,
GcsUtils gcsUtils, GcsUtils gcsUtils,
@ -66,8 +70,10 @@ public class Spec11EmailUtils {
this.yearMonth = yearMonth; this.yearMonth = yearMonth;
this.alertSenderAddress = alertSenderAddress; this.alertSenderAddress = alertSenderAddress;
this.alertRecipientAddress = alertRecipientAddress; this.alertRecipientAddress = alertRecipientAddress;
this.spec11ReplyToAddress = spec11ReplyToAddress;
this.reportingBucket = reportingBucket; this.reportingBucket = reportingBucket;
this.spec11ReportDirectory = spec11ReportDirectory; this.spec11ReportDirectory = spec11ReportDirectory;
this.spec11EmailBodyTemplate = spec11EmailBodyTemplate;
this.gcsUtils = gcsUtils; this.gcsUtils = gcsUtils;
this.retrier = retrier; this.retrier = retrier;
} }
@ -114,23 +120,24 @@ public class Spec11EmailUtils {
JSONObject reportJSON = new JSONObject(line); JSONObject reportJSON = new JSONObject(line);
String registrarEmail = reportJSON.getString(Spec11Pipeline.REGISTRAR_EMAIL_FIELD); String registrarEmail = reportJSON.getString(Spec11Pipeline.REGISTRAR_EMAIL_FIELD);
JSONArray threatMatches = reportJSON.getJSONArray(Spec11Pipeline.THREAT_MATCHES_FIELD); JSONArray threatMatches = reportJSON.getJSONArray(Spec11Pipeline.THREAT_MATCHES_FIELD);
StringBuilder body = StringBuilder threatList = new StringBuilder();
new StringBuilder("Hello registrar partner,\n")
.append("We have detected problems with the following domains:\n");
for (int i = 0; i < threatMatches.length(); i++) { for (int i = 0; i < threatMatches.length(); i++) {
ThreatMatch threatMatch = ThreatMatch.fromJSON(threatMatches.getJSONObject(i)); ThreatMatch threatMatch = ThreatMatch.fromJSON(threatMatches.getJSONObject(i));
body.append( threatList.append(
String.format( String.format(
"%s - %s\n", threatMatch.fullyQualifiedDomainName(), threatMatch.threatType())); "%s - %s\n", threatMatch.fullyQualifiedDomainName(), threatMatch.threatType()));
} }
body.append("At the moment, no action is required. This is purely informatory.") String body =
.append("Regards,\nGoogle Registry\n"); spec11EmailBodyTemplate
.replace("{REPLY_TO_EMAIL}", spec11ReplyToAddress)
.replace("{LIST_OF_THREATS}", threatList.toString());
Message msg = emailService.createMessage(); Message msg = emailService.createMessage();
msg.setSubject( msg.setSubject(
String.format("Google Registry Monthly Threat Detector [%s]", yearMonth.toString())); String.format("Google Registry Monthly Threat Detector [%s]", yearMonth.toString()));
msg.setText(body.toString()); msg.setText(body.toString());
msg.setFrom(new InternetAddress(alertSenderAddress)); msg.setFrom(new InternetAddress(alertSenderAddress));
msg.setRecipient(RecipientType.TO, new InternetAddress(registrarEmail)); msg.addRecipient(RecipientType.TO, new InternetAddress(registrarEmail));
msg.addRecipient(RecipientType.BCC, new InternetAddress(spec11ReplyToAddress));
emailService.sendMessage(msg); emailService.sendMessage(msg);
} }

View file

@ -19,6 +19,7 @@ java_library(
"@com_google_apis_google_api_services_dataflow", "@com_google_apis_google_api_services_dataflow",
"@com_google_appengine_api_1_0_sdk", "@com_google_appengine_api_1_0_sdk",
"@com_google_appengine_tools_appengine_gcs_client", "@com_google_appengine_tools_appengine_gcs_client",
"@com_google_code_findbugs_jsr305",
"@com_google_dagger", "@com_google_dagger",
"@com_google_guava", "@com_google_guava",
"@com_google_truth", "@com_google_truth",

View file

@ -36,7 +36,9 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import javax.annotation.Nullable;
import javax.mail.Message; import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
@ -83,6 +85,8 @@ public class Spec11EmailUtilsTest {
new YearMonth(2018, 6), new YearMonth(2018, 6),
"my-sender@test.com", "my-sender@test.com",
"my-receiver@test.com", "my-receiver@test.com",
"my-reply-to@test.com",
"{LIST_OF_THREATS}\n{REPLY_TO_EMAIL}",
"test-bucket", "test-bucket",
"icann/spec11/2018-06/SPEC11_MONTHLY_REPORT", "icann/spec11/2018-06/SPEC11_MONTHLY_REPORT",
gcsUtils, gcsUtils,
@ -99,27 +103,21 @@ public class Spec11EmailUtilsTest {
capturedMessages.get(0), capturedMessages.get(0),
"my-sender@test.com", "my-sender@test.com",
"a@fake.com", "a@fake.com",
"my-reply-to@test.com",
"Google Registry Monthly Threat Detector [2018-06]", "Google Registry Monthly Threat Detector [2018-06]",
"Hello registrar partner,\n" "a.com - MALWARE\n\nmy-reply-to@test.com");
+ "We have detected problems with the following domains:\n"
+ "a.com - MALWARE\n"
+ "At the moment, no action is required. This is purely informatory."
+ "Regards,\nGoogle Registry\n");
validateMessage( validateMessage(
capturedMessages.get(1), capturedMessages.get(1),
"my-sender@test.com", "my-sender@test.com",
"b@fake.com", "b@fake.com",
"my-reply-to@test.com",
"Google Registry Monthly Threat Detector [2018-06]", "Google Registry Monthly Threat Detector [2018-06]",
"Hello registrar partner,\n" "b.com - MALWARE\nc.com - MALWARE\n\nmy-reply-to@test.com");
+ "We have detected problems with the following domains:\n"
+ "b.com - MALWARE\n"
+ "c.com - MALWARE\n"
+ "At the moment, no action is required. This is purely informatory."
+ "Regards,\nGoogle Registry\n");
validateMessage( validateMessage(
capturedMessages.get(2), capturedMessages.get(2),
"my-sender@test.com", "my-sender@test.com",
"my-receiver@test.com", "my-receiver@test.com",
null,
"Spec11 Pipeline Success 2018-06", "Spec11 Pipeline Success 2018-06",
"Spec11 reporting completed successfully."); "Spec11 reporting completed successfully.");
} }
@ -163,6 +161,7 @@ public class Spec11EmailUtilsTest {
gotMessage.getValue(), gotMessage.getValue(),
"my-sender@test.com", "my-sender@test.com",
"my-receiver@test.com", "my-receiver@test.com",
null,
"Spec11 Emailing Failure 2018-06", "Spec11 Emailing Failure 2018-06",
"Emailing spec11 reports failed due to expected"); "Emailing spec11 reports failed due to expected");
} }
@ -175,17 +174,31 @@ public class Spec11EmailUtilsTest {
gotMessage.getValue(), gotMessage.getValue(),
"my-sender@test.com", "my-sender@test.com",
"my-receiver@test.com", "my-receiver@test.com",
null,
"Spec11 Pipeline Alert: 2018-06", "Spec11 Pipeline Alert: 2018-06",
"Alert!"); "Alert!");
} }
private void validateMessage( private void validateMessage(
Message message, String from, String recipient, String subject, String body) Message message,
String from,
String recipient,
@Nullable String replyTo,
String subject,
String body)
throws MessagingException, IOException { throws MessagingException, IOException {
assertThat(message.getFrom()).asList().containsExactly(new InternetAddress(from)); assertThat(message.getFrom()).asList().containsExactly(new InternetAddress(from));
assertThat(message.getAllRecipients()) assertThat(message.getRecipients(RecipientType.TO))
.asList() .asList()
.containsExactly(new InternetAddress(recipient)); .containsExactly(new InternetAddress(recipient));
if (replyTo == null) {
assertThat(message.getRecipients(RecipientType.BCC)).isNull();
} else {
assertThat(message.getRecipients(RecipientType.BCC))
.asList()
.containsExactly(new InternetAddress(replyTo));
}
assertThat(message.getRecipients(RecipientType.CC)).isNull();
assertThat(message.getSubject()).isEqualTo(subject); assertThat(message.getSubject()).isEqualTo(subject);
assertThat(message.getContentType()).isEqualTo("text/plain"); assertThat(message.getContentType()).isEqualTo("text/plain");
assertThat(message.getContent().toString()).isEqualTo(body); assertThat(message.getContent().toString()).isEqualTo(body);