Skip emailing registrars with a null or empty email address

Obviously this is a bad thing and would fail if it ever happened. If this does occur, we will send a warning email.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=240977242
This commit is contained in:
gbrodman 2019-03-29 07:47:51 -07:00 committed by jianglai
parent 8af9090fb0
commit d5fbdea37d
2 changed files with 62 additions and 4 deletions

View file

@ -14,12 +14,17 @@
package google.registry.reporting.spec11; package google.registry.reporting.spec11;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.base.Throwables.getRootCause; import static com.google.common.base.Throwables.getRootCause;
import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.io.Resources.getResource; import static com.google.common.io.Resources.getResource;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
import com.google.common.net.MediaType; import com.google.common.net.MediaType;
import com.google.template.soy.SoyFileSet; import com.google.template.soy.SoyFileSet;
import com.google.template.soy.parseinfo.SoyTemplateInfo; import com.google.template.soy.parseinfo.SoyTemplateInfo;
@ -40,6 +45,7 @@ import org.joda.time.LocalDate;
/** Provides e-mail functionality for Spec11 tasks, such as sending Spec11 reports to registrars. */ /** Provides e-mail functionality for Spec11 tasks, such as sending Spec11 reports to registrars. */
public class Spec11EmailUtils { public class Spec11EmailUtils {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private static final SoyTofu SOY_SAUCE = private static final SoyTofu SOY_SAUCE =
SoyFileSet.builder() SoyFileSet.builder()
.add( .add(
@ -81,8 +87,14 @@ public class Spec11EmailUtils {
SoyTemplateInfo soyTemplateInfo, SoyTemplateInfo soyTemplateInfo,
String subject, String subject,
Set<RegistrarThreatMatches> registrarThreatMatchesSet) { Set<RegistrarThreatMatches> registrarThreatMatchesSet) {
// Null/empty email address shouldn't throw an exception, but we should warn if they occur.
ImmutableSet<RegistrarThreatMatches> matchesWithoutEmails =
registrarThreatMatchesSet.stream()
.filter(matches -> isNullOrEmpty(matches.registrarEmailAddress()))
.collect(toImmutableSet());
try { try {
for (RegistrarThreatMatches registrarThreatMatches : registrarThreatMatchesSet) { for (RegistrarThreatMatches registrarThreatMatches :
Sets.difference(registrarThreatMatchesSet, matchesWithoutEmails)) {
emailRegistrar(date, soyTemplateInfo, subject, registrarThreatMatches); emailRegistrar(date, soyTemplateInfo, subject, registrarThreatMatches);
} }
} catch (Throwable e) { } catch (Throwable e) {
@ -92,9 +104,23 @@ public class Spec11EmailUtils {
String.format("Emailing spec11 reports failed due to %s", getRootCause(e).getMessage())); String.format("Emailing spec11 reports failed due to %s", getRootCause(e).getMessage()));
throw new RuntimeException("Emailing spec11 report failed", e); throw new RuntimeException("Emailing spec11 report failed", e);
} }
sendAlertEmail( if (matchesWithoutEmails.isEmpty()) {
String.format("Spec11 Pipeline Success %s", date), sendAlertEmail(
"Spec11 reporting completed successfully."); String.format("Spec11 Pipeline Success %s", date),
"Spec11 reporting completed successfully.");
} else {
logger.atSevere().log(
"Some Spec11 threat matches had no associated email addresses: %s", matchesWithoutEmails);
// TODO(b/129401965): Use only client IDs in this message
sendAlertEmail(
String.format("Spec11 Pipeline Warning %s", date),
String.format(
"No errors occurred but the following matches had no associated email: \n"
+ "%s\n\n"
+ "This should not occur; please make sure we have email addresses for these"
+ " registrar(s).",
matchesWithoutEmails));
}
} }
private void emailRegistrar( private void emailRegistrar(

View file

@ -14,6 +14,7 @@
package google.registry.reporting.spec11; package google.registry.reporting.spec11;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static google.registry.reporting.spec11.Spec11RegistrarThreatMatchesParserTest.sampleThreatMatches; import static google.registry.reporting.spec11.Spec11RegistrarThreatMatchesParserTest.sampleThreatMatches;
import static google.registry.testing.JUnitBackports.assertThrows; import static google.registry.testing.JUnitBackports.assertThrows;
@ -24,6 +25,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.MediaType; import com.google.common.net.MediaType;
import google.registry.reporting.spec11.soy.Spec11EmailSoyInfo; import google.registry.reporting.spec11.soy.Spec11EmailSoyInfo;
import google.registry.util.EmailMessage; import google.registry.util.EmailMessage;
@ -221,6 +223,36 @@ public class Spec11EmailUtilsTest {
Optional.empty()); Optional.empty());
} }
@Test
public void testWarning_emptyEmailAddressForRegistrars() throws Exception {
ImmutableSet<RegistrarThreatMatches> matchesWithoutEmails =
sampleThreatMatches().stream()
.map(matches -> RegistrarThreatMatches.create("", matches.threatMatches()))
.collect(toImmutableSet());
emailUtils.emailSpec11Reports(
date,
Spec11EmailSoyInfo.DAILY_SPEC_11_EMAIL,
"Super Cool Registry Daily Threat Detector [2018-07-15]",
matchesWithoutEmails);
verify(emailService).sendEmail(contentCaptor.capture());
validateMessage(
contentCaptor.getValue(),
"my-sender@test.com",
"my-receiver@test.com",
Optional.empty(),
"Spec11 Pipeline Warning 2018-07-15",
"No errors occurred but the following matches had no associated email: \n"
+ "[RegistrarThreatMatches{registrarEmailAddress=, threatMatches=[ThreatMatch"
+ "{threatType=MALWARE, platformType=ANY_PLATFORM, metadata=NONE,"
+ " fullyQualifiedDomainName=a.com}]}, RegistrarThreatMatches{registrarEmailAddress=,"
+ " threatMatches=[ThreatMatch{threatType=MALWARE, platformType=ANY_PLATFORM,"
+ " metadata=NONE, fullyQualifiedDomainName=b.com}, ThreatMatch{threatType=MALWARE,"
+ " platformType=ANY_PLATFORM, metadata=NONE, fullyQualifiedDomainName=c.com}]}]\n\n"
+ "This should not occur; please make sure we have email addresses for these"
+ " registrar(s).",
Optional.empty());
}
private void validateMessage( private void validateMessage(
EmailMessage message, EmailMessage message,
String from, String from,