mirror of
https://github.com/google/nomulus.git
synced 2025-08-01 07:26:29 +02:00
Enable/disable email sending by environments (#2099)
This commit is contained in:
parent
b8b5152336
commit
45666773ee
5 changed files with 77 additions and 16 deletions
|
@ -158,6 +158,12 @@ public final class RegistryConfig {
|
|||
return config.registryPolicy.contactAndHostRoidSuffix;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Config("isEmailSendingEnabled")
|
||||
public static boolean provideIsEmailSendingEnabled(RegistryConfigSettings config) {
|
||||
return config.misc.isEmailSendingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* The e-mail address for questions about integrating with the registry. Used in the
|
||||
* "contact-us" section of the registrar console.
|
||||
|
|
|
@ -205,6 +205,7 @@ public class RegistryConfigSettings {
|
|||
/** Miscellaneous configuration that doesn't quite fit in anywhere else. */
|
||||
public static class Misc {
|
||||
public String sheetExportId;
|
||||
public boolean isEmailSendingEnabled;
|
||||
public String alertRecipientEmailAddress;
|
||||
// TODO(b/279671974): remove below field after migration
|
||||
public String newAlertRecipientEmailAddress;
|
||||
|
|
|
@ -432,6 +432,9 @@ misc:
|
|||
# to. Leave this null to disable syncing.
|
||||
sheetExportId: null
|
||||
|
||||
# Whether emails may be sent. For Prod and Sandbox this should be true.
|
||||
isEmailSendingEnabled: false
|
||||
|
||||
# Address we send alert summary emails to.
|
||||
alertRecipientEmailAddress: email@example.com
|
||||
|
||||
|
|
|
@ -14,14 +14,15 @@
|
|||
|
||||
package google.registry.groups;
|
||||
|
||||
import static com.google.common.collect.ImmutableSet.toImmutableSet;
|
||||
import static com.google.common.collect.Iterables.toArray;
|
||||
|
||||
import com.google.api.client.http.HttpResponseException;
|
||||
import com.google.api.services.gmail.Gmail;
|
||||
import com.google.api.services.gmail.model.Message;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import google.registry.config.RegistryConfig.Config;
|
||||
import google.registry.util.EmailMessage;
|
||||
import google.registry.util.EmailMessage.Attachment;
|
||||
|
@ -46,8 +47,11 @@ import javax.mail.internet.MimeMultipart;
|
|||
/** Sends {@link EmailMessage EmailMessages} through Google Workspace using {@link Gmail}. */
|
||||
public final class GmailClient {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private final Gmail gmail;
|
||||
private final Retrier retrier;
|
||||
private final boolean isEmailSendingEnabled;
|
||||
private final InternetAddress outgoingEmailAddressWithUsername;
|
||||
private final InternetAddress replyToEmailAddress;
|
||||
|
||||
|
@ -55,12 +59,14 @@ public final class GmailClient {
|
|||
GmailClient(
|
||||
Gmail gmail,
|
||||
Retrier retrier,
|
||||
@Config("isEmailSendingEnabled") boolean isEmailSendingEnabled,
|
||||
@Config("gSuiteNewOutgoingEmailAddress") String gSuiteOutgoingEmailAddress,
|
||||
@Config("gSuiteOutgoingEmailDisplayName") String gSuiteOutgoingEmailDisplayName,
|
||||
@Config("replyToEmailAddress") InternetAddress replyToEmailAddress) {
|
||||
|
||||
this.gmail = gmail;
|
||||
this.retrier = retrier;
|
||||
this.isEmailSendingEnabled = isEmailSendingEnabled;
|
||||
this.replyToEmailAddress = replyToEmailAddress;
|
||||
try {
|
||||
this.outgoingEmailAddressWithUsername =
|
||||
|
@ -76,11 +82,22 @@ public final class GmailClient {
|
|||
* <p>If the sender as specified by {@link EmailMessage#from} differs from the caller's identity,
|
||||
* the caller must have delegated `send` authority to the sender.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
public Message sendEmail(EmailMessage emailMessage) {
|
||||
public void sendEmail(EmailMessage emailMessage) {
|
||||
if (!isEmailSendingEnabled) {
|
||||
logger.atInfo().log(
|
||||
String.format(
|
||||
"Email with subject %s would have been sent to recipients %s",
|
||||
emailMessage.subject().substring(0, Math.min(emailMessage.subject().length(), 15)),
|
||||
String.join(
|
||||
" , ",
|
||||
emailMessage.recipients().stream()
|
||||
.map(ia -> ia.toString())
|
||||
.collect(toImmutableSet()))));
|
||||
return;
|
||||
}
|
||||
Message message = toGmailMessage(toMimeMessage(emailMessage));
|
||||
// Unlike other Cloud APIs such as GCS and SecretManager, Gmail does not retry on errors.
|
||||
return retrier.callWithRetry(
|
||||
retrier.callWithRetry(
|
||||
// "me" is reserved word for the authorized user of the Gmail API.
|
||||
() -> this.gmail.users().messages().send("me", message).execute(),
|
||||
RetriableGmailExceptionPredicate.INSTANCE);
|
||||
|
|
|
@ -19,12 +19,19 @@ import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
|
|||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.api.client.http.HttpResponseException;
|
||||
import com.google.api.services.gmail.Gmail;
|
||||
import com.google.api.services.gmail.Gmail.Users;
|
||||
import com.google.api.services.gmail.Gmail.Users.Messages;
|
||||
import com.google.api.services.gmail.Gmail.Users.Messages.Send;
|
||||
import com.google.api.services.gmail.model.Message;
|
||||
import google.registry.groups.GmailClient.RetriableGmailExceptionPredicate;
|
||||
import google.registry.util.EmailMessage;
|
||||
|
@ -37,7 +44,6 @@ import javax.mail.Part;
|
|||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
|
@ -52,17 +58,45 @@ public class GmailClientTest {
|
|||
|
||||
@Mock private Gmail gmail;
|
||||
@Mock private HttpResponseException httpResponseException;
|
||||
private GmailClient gmailClient;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
gmailClient =
|
||||
new GmailClient(
|
||||
gmail,
|
||||
new Retrier(new SystemSleeper(), 3),
|
||||
"from@example.com",
|
||||
"My sender",
|
||||
new InternetAddress("replyTo@example.com"));
|
||||
private GmailClient getGmailClient(boolean isExternalEmailAllowed) throws Exception {
|
||||
return new GmailClient(
|
||||
gmail,
|
||||
new Retrier(new SystemSleeper(), 3),
|
||||
isExternalEmailAllowed,
|
||||
"from@example.com",
|
||||
"My sender",
|
||||
new InternetAddress("replyTo@example.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendEmail_sentWhenAllowed() throws Exception {
|
||||
EmailMessage message =
|
||||
EmailMessage.create(
|
||||
"subject",
|
||||
"body",
|
||||
new InternetAddress("from@example.com"),
|
||||
new InternetAddress("to@example.com"));
|
||||
Send gSend = mock(Send.class);
|
||||
Messages gMessages = mock(Messages.class);
|
||||
Users gUsers = mock(Users.class);
|
||||
when(gmail.users()).thenReturn(gUsers);
|
||||
when(gUsers.messages()).thenReturn(gMessages);
|
||||
when(gMessages.send(anyString(), any())).thenReturn(gSend);
|
||||
getGmailClient(true).sendEmail(message);
|
||||
verify(gmail, times(1)).users();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendEmail_notSentWhenNotAllowed() throws Exception {
|
||||
EmailMessage message =
|
||||
EmailMessage.create(
|
||||
"subject",
|
||||
"body",
|
||||
new InternetAddress("from@example.com"),
|
||||
new InternetAddress("to@example.com"));
|
||||
getGmailClient(false).sendEmail(message);
|
||||
verifyNoInteractions(gmail);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -86,7 +120,7 @@ public class GmailClientTest {
|
|||
.setContentType(CSV_UTF_8)
|
||||
.build())
|
||||
.build();
|
||||
MimeMessage mimeMessage = gmailClient.toMimeMessage(emailMessage);
|
||||
MimeMessage mimeMessage = getGmailClient(true).toMimeMessage(emailMessage);
|
||||
assertThat(mimeMessage.getFrom()).asList().containsExactly(fromAddr);
|
||||
assertThat(mimeMessage.getRecipients(RecipientType.TO)).asList().containsExactly(toAddr);
|
||||
assertThat(mimeMessage.getRecipients(RecipientType.CC)).asList().containsExactly(ccAddr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue