Fix usage of OutgoingEmailValidator to make sure TLD override works

The call to DomainValidator.updateTLDOverride may only be done before
the call to EmailValidator.getInstance otherwise it throws an exception.

Putting the DomainValidator.updateTLDOverride call inside a static
block doesn't seem to be safe enough. Protect it with an atomic boolean
insteed.

Also fix CreateEmail and CreateAccount to use OutgoingEmailValidator
instead of EmailValidator.getInstance directly. By directly using it we
don't necessarily set up the TLD override correctly before first use.

Bug: Issue 4521
Change-Id: I92a6c98d8ae188c08da7c0a077d67000dfdab4fd
This commit is contained in:
David Pursehouse
2016-09-08 17:43:25 +09:00
parent fdfc3738fc
commit 3aaf831893
3 changed files with 10 additions and 8 deletions

View File

@@ -38,6 +38,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.CreateAccount.Input; import com.google.gerrit.server.account.CreateAccount.Input;
import com.google.gerrit.server.group.GroupsCollection; import com.google.gerrit.server.group.GroupsCollection;
import com.google.gerrit.server.mail.OutgoingEmailValidator;
import com.google.gerrit.server.ssh.SshKeyCache; import com.google.gerrit.server.ssh.SshKeyCache;
import com.google.gwtorm.server.OrmDuplicateKeyException; import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -45,8 +46,6 @@ import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import org.apache.commons.validator.routines.EmailValidator;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -132,7 +131,7 @@ public class CreateAccount implements RestModifyView<TopLevelResource, Input> {
throw new UnprocessableEntityException( throw new UnprocessableEntityException(
"email '" + input.email + "' already exists"); "email '" + input.email + "' already exists");
} }
if (!EmailValidator.getInstance().isValid(input.email)) { if (!OutgoingEmailValidator.isValid(input.email)) {
throw new BadRequestException("invalid email address"); throw new BadRequestException("invalid email address");
} }
} }

View File

@@ -28,6 +28,7 @@ import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.GetEmails.EmailInfo; import com.google.gerrit.server.account.GetEmails.EmailInfo;
import com.google.gerrit.server.mail.OutgoingEmailValidator;
import com.google.gerrit.server.config.AuthConfig; import com.google.gerrit.server.config.AuthConfig;
import com.google.gerrit.server.mail.RegisterNewEmailSender; import com.google.gerrit.server.mail.RegisterNewEmailSender;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -35,7 +36,6 @@ import com.google.inject.Inject;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import org.apache.commons.validator.routines.EmailValidator;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -85,7 +85,7 @@ public class CreateEmail implements RestModifyView<AccountResource, EmailInput>
input = new EmailInput(); input = new EmailInput();
} }
if (!EmailValidator.getInstance().isValid(email)) { if (!OutgoingEmailValidator.isValid(email)) {
throw new BadRequestException("invalid email address"); throw new BadRequestException("invalid email address");
} }

View File

@@ -19,12 +19,15 @@ import static org.apache.commons.validator.routines.DomainValidator.ArrayType.GE
import org.apache.commons.validator.routines.DomainValidator; import org.apache.commons.validator.routines.DomainValidator;
import org.apache.commons.validator.routines.EmailValidator; import org.apache.commons.validator.routines.EmailValidator;
import java.util.concurrent.atomic.AtomicBoolean;
public class OutgoingEmailValidator { public class OutgoingEmailValidator {
static { private static final AtomicBoolean initialized = new AtomicBoolean(false);
DomainValidator.updateTLDOverride(GENERIC_PLUS, new String[]{"local"});
}
public static boolean isValid(String addr) { public static boolean isValid(String addr) {
if (!initialized.getAndSet(true)) {
DomainValidator.updateTLDOverride(GENERIC_PLUS, new String[]{"local"});
}
return EmailValidator.getInstance(true, true).isValid(addr); return EmailValidator.getInstance(true, true).isValid(addr);
} }
} }