From 534c577f592f1874e5dcc97781d51c5ec8e8128b Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Wed, 20 Oct 2021 16:13:39 -0400 Subject: [PATCH] Enforce phone number normalization when creating accounts or changing numbers --- .../textsecuregcm/WhisperServerService.java | 40 +++--- .../controllers/AccountController.java | 27 ++-- .../ImpossiblePhoneNumberExceptionMapper.java | 18 +++ ...nNormalizedPhoneNumberExceptionMapper.java | 21 ++++ .../NonNormalizedPhoneNumberResponse.java | 31 +++++ ...va => ImpossiblePhoneNumberException.java} | 6 +- ...=> NonNormalizedPhoneNumberException.java} | 4 +- .../textsecuregcm/util/Util.java | 16 +-- .../controllers/AccountControllerTest.java | 115 ++++++++++++++++++ .../tests/util/ValidNumberTest.java | 48 +------- 10 files changed, 235 insertions(+), 91 deletions(-) create mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/mappers/ImpossiblePhoneNumberExceptionMapper.java create mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberExceptionMapper.java create mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberResponse.java rename service/src/main/java/org/whispersystems/textsecuregcm/util/{ImpossibleNumberException.java => ImpossiblePhoneNumberException.java} (51%) rename service/src/main/java/org/whispersystems/textsecuregcm/util/{NonNormalizedNumberException.java => NonNormalizedPhoneNumberException.java} (72%) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index af4adcfdd..1c7e40a32 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -52,6 +52,7 @@ import java.util.concurrent.TimeUnit; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletRegistration; +import javax.ws.rs.ext.ExceptionMapper; import org.eclipse.jetty.servlets.CrossOriginFilter; import org.glassfish.jersey.server.ServerProperties; import org.jdbi.v3.core.Jdbi; @@ -111,7 +112,9 @@ import org.whispersystems.textsecuregcm.limits.UnsealedSenderRateLimiter; import org.whispersystems.textsecuregcm.liquibase.NameableMigrationsBundle; import org.whispersystems.textsecuregcm.mappers.DeviceLimitExceededExceptionMapper; import org.whispersystems.textsecuregcm.mappers.IOExceptionMapper; +import org.whispersystems.textsecuregcm.mappers.ImpossiblePhoneNumberExceptionMapper; import org.whispersystems.textsecuregcm.mappers.InvalidWebsocketAddressExceptionMapper; +import org.whispersystems.textsecuregcm.mappers.NonNormalizedPhoneNumberExceptionMapper; import org.whispersystems.textsecuregcm.mappers.RateLimitChallengeExceptionMapper; import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper; import org.whispersystems.textsecuregcm.mappers.RetryLaterExceptionMapper; @@ -708,29 +711,22 @@ public class WhisperServerService extends Application webSocketEnvironment, WebSocketEnvironment provisioningEnvironment) { - environment.jersey().register(new LoggingUnhandledExceptionMapper()); - environment.jersey().register(new IOExceptionMapper()); - environment.jersey().register(new RateLimitExceededExceptionMapper()); - environment.jersey().register(new InvalidWebsocketAddressExceptionMapper()); - environment.jersey().register(new DeviceLimitExceededExceptionMapper()); - environment.jersey().register(new RetryLaterExceptionMapper()); - environment.jersey().register(new ServerRejectedExceptionMapper()); - webSocketEnvironment.jersey().register(new LoggingUnhandledExceptionMapper()); - webSocketEnvironment.jersey().register(new IOExceptionMapper()); - webSocketEnvironment.jersey().register(new RateLimitExceededExceptionMapper()); - webSocketEnvironment.jersey().register(new InvalidWebsocketAddressExceptionMapper()); - webSocketEnvironment.jersey().register(new DeviceLimitExceededExceptionMapper()); - webSocketEnvironment.jersey().register(new RetryLaterExceptionMapper()); - webSocketEnvironment.jersey().register(new ServerRejectedExceptionMapper()); - - provisioningEnvironment.jersey().register(new LoggingUnhandledExceptionMapper()); - provisioningEnvironment.jersey().register(new IOExceptionMapper()); - provisioningEnvironment.jersey().register(new RateLimitExceededExceptionMapper()); - provisioningEnvironment.jersey().register(new InvalidWebsocketAddressExceptionMapper()); - provisioningEnvironment.jersey().register(new DeviceLimitExceededExceptionMapper()); - provisioningEnvironment.jersey().register(new RetryLaterExceptionMapper()); - provisioningEnvironment.jersey().register(new ServerRejectedExceptionMapper()); + List.of( + new LoggingUnhandledExceptionMapper(), + new IOExceptionMapper(), + new RateLimitExceededExceptionMapper(), + new InvalidWebsocketAddressExceptionMapper(), + new DeviceLimitExceededExceptionMapper(), + new RetryLaterExceptionMapper(), + new ServerRejectedExceptionMapper(), + new ImpossiblePhoneNumberExceptionMapper(), + new NonNormalizedPhoneNumberExceptionMapper() + ).forEach(exceptionMapper -> { + environment.jersey().register(exceptionMapper); + webSocketEnvironment.jersey().register(exceptionMapper); + provisioningEnvironment.jersey().register(exceptionMapper); + }); } private void registerCorsFilter(Environment environment) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java index dc209fbdc..b3491e9f6 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -80,6 +80,8 @@ import org.whispersystems.textsecuregcm.storage.UsernamesManager; import org.whispersystems.textsecuregcm.util.Constants; import org.whispersystems.textsecuregcm.util.ForwardedIpUtil; import org.whispersystems.textsecuregcm.util.Hex; +import org.whispersystems.textsecuregcm.util.ImpossiblePhoneNumberException; +import org.whispersystems.textsecuregcm.util.NonNormalizedPhoneNumberException; import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.VerificationCode; @@ -160,18 +162,18 @@ public class AccountController { @Timed @GET @Path("/{type}/preauth/{token}/{number}") + @Produces(MediaType.APPLICATION_JSON) public Response getPreAuth(@PathParam("type") String pushType, @PathParam("token") String pushToken, @PathParam("number") String number, @QueryParam("voip") Optional useVoip) - { + throws ImpossiblePhoneNumberException, NonNormalizedPhoneNumberException { + if (!"apn".equals(pushType) && !"fcm".equals(pushType)) { return Response.status(400).build(); } - if (!Util.isValidNumber(number)) { - return Response.status(400).build(); - } + Util.requireNormalizedNumber(number); String pushChallenge = generatePushChallenge(); StoredVerificationCode storedVerificationCode = new StoredVerificationCode(null, @@ -195,6 +197,7 @@ public class AccountController { @Timed @GET @Path("/{transport}/code/{number}") + @Produces(MediaType.APPLICATION_JSON) public Response createAccount(@PathParam("transport") String transport, @PathParam("number") String number, @HeaderParam("X-Forwarded-For") String forwardedFor, @@ -203,12 +206,9 @@ public class AccountController { @QueryParam("client") Optional client, @QueryParam("captcha") Optional captcha, @QueryParam("challenge") Optional pushChallenge) - throws RateLimitExceededException, RetryLaterException - { - if (!Util.isValidNumber(number)) { - logger.info("Invalid number: " + number); - throw new WebApplicationException(Response.status(400).build()); - } + throws RateLimitExceededException, RetryLaterException, ImpossiblePhoneNumberException, NonNormalizedPhoneNumberException { + + Util.requireNormalizedNumber(number); String sourceHost = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow(); @@ -340,6 +340,9 @@ public class AccountController { rateLimiters.getVerifyLimiter().validate(number); + // Note that successful verification depends on being able to find a stored verification code for the given number. + // We check that numbers are normalized before we store verification codes, and so don't need to re-assert + // normalization here. Optional storedVerificationCode = pendingAccounts.getCodeForNumber(number); if (storedVerificationCode.isEmpty() || !storedVerificationCode.get().isValid(verificationCode)) { @@ -385,7 +388,7 @@ public class AccountController { @Path("/number") @Produces(MediaType.APPLICATION_JSON) public void changeNumber(@Auth final AuthenticatedAccount authenticatedAccount, @Valid final ChangePhoneNumberRequest request) - throws RateLimitExceededException, InterruptedException { + throws RateLimitExceededException, InterruptedException, ImpossiblePhoneNumberException, NonNormalizedPhoneNumberException { if (request.getNumber().equals(authenticatedAccount.getAccount().getNumber())) { // This may be a request that got repeated due to poor network conditions or other client error; take no action, @@ -393,6 +396,8 @@ public class AccountController { return; } + Util.requireNormalizedNumber(request.getNumber()); + rateLimiters.getVerifyLimiter().validate(request.getNumber()); final Optional storedVerificationCode = diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/mappers/ImpossiblePhoneNumberExceptionMapper.java b/service/src/main/java/org/whispersystems/textsecuregcm/mappers/ImpossiblePhoneNumberExceptionMapper.java new file mode 100644 index 000000000..14878b7b6 --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/mappers/ImpossiblePhoneNumberExceptionMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright 2013-2021 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.whispersystems.textsecuregcm.mappers; + +import org.whispersystems.textsecuregcm.util.ImpossiblePhoneNumberException; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +public class ImpossiblePhoneNumberExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(final ImpossiblePhoneNumberException exception) { + return Response.status(Response.Status.BAD_REQUEST).build(); + } +} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberExceptionMapper.java b/service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberExceptionMapper.java new file mode 100644 index 000000000..192826042 --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberExceptionMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright 2013-2021 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.whispersystems.textsecuregcm.mappers; + +import org.whispersystems.textsecuregcm.util.NonNormalizedPhoneNumberException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.ExceptionMapper; + +public class NonNormalizedPhoneNumberExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(final NonNormalizedPhoneNumberException exception) { + return Response.status(Status.BAD_REQUEST) + .entity(new NonNormalizedPhoneNumberResponse(exception.getOriginalNumber(), exception.getNormalizedNumber())) + .build(); + } +} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberResponse.java b/service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberResponse.java new file mode 100644 index 000000000..155ae73bf --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/mappers/NonNormalizedPhoneNumberResponse.java @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2021 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.whispersystems.textsecuregcm.mappers; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class NonNormalizedPhoneNumberResponse { + + private final String originalNumber; + private final String normalizedNumber; + + @JsonCreator + NonNormalizedPhoneNumberResponse(@JsonProperty("originalNumber") final String originalNumber, + @JsonProperty("normalizedNumber") final String normalizedNumber) { + + this.originalNumber = originalNumber; + this.normalizedNumber = normalizedNumber; + } + + public String getOriginalNumber() { + return originalNumber; + } + + public String getNormalizedNumber() { + return normalizedNumber; + } +} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/ImpossibleNumberException.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/ImpossiblePhoneNumberException.java similarity index 51% rename from service/src/main/java/org/whispersystems/textsecuregcm/util/ImpossibleNumberException.java rename to service/src/main/java/org/whispersystems/textsecuregcm/util/ImpossiblePhoneNumberException.java index a07ffe714..1e6e0d73e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/ImpossibleNumberException.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/util/ImpossiblePhoneNumberException.java @@ -5,13 +5,13 @@ package org.whispersystems.textsecuregcm.util; -public class ImpossibleNumberException extends Exception { +public class ImpossiblePhoneNumberException extends Exception { - public ImpossibleNumberException() { + public ImpossiblePhoneNumberException() { super(); } - public ImpossibleNumberException(final Throwable cause) { + public ImpossiblePhoneNumberException(final Throwable cause) { super(cause); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/NonNormalizedNumberException.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/NonNormalizedPhoneNumberException.java similarity index 72% rename from service/src/main/java/org/whispersystems/textsecuregcm/util/NonNormalizedNumberException.java rename to service/src/main/java/org/whispersystems/textsecuregcm/util/NonNormalizedPhoneNumberException.java index c7e821097..4ce4d11b3 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/NonNormalizedNumberException.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/util/NonNormalizedPhoneNumberException.java @@ -5,12 +5,12 @@ package org.whispersystems.textsecuregcm.util; -public class NonNormalizedNumberException extends Exception { +public class NonNormalizedPhoneNumberException extends Exception { private final String originalNumber; private final String normalizedNumber; - public NonNormalizedNumberException(final String originalNumber, final String normalizedNumber) { + public NonNormalizedPhoneNumberException(final String originalNumber, final String normalizedNumber) { this.originalNumber = originalNumber; this.normalizedNumber = normalizedNumber; } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/Util.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/Util.java index 02b0d6e51..6001bbd6d 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/util/Util.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/util/Util.java @@ -45,21 +45,17 @@ public class Util { } } - public static boolean isValidNumber(String number) { - return number.matches("^\\+[0-9]+") && PHONE_NUMBER_UTIL.isPossibleNumber(number, null); - } - /** * Checks that the given number is a valid, E164-normalized phone number. * * @param number the number to check * - * @throws ImpossibleNumberException if the given number is not a valid phone number at all - * @throws NonNormalizedNumberException if the given number is a valid phone number, but isn't E164-normalized + * @throws ImpossiblePhoneNumberException if the given number is not a valid phone number at all + * @throws NonNormalizedPhoneNumberException if the given number is a valid phone number, but isn't E164-normalized */ - public static void requireNormalizedNumber(final String number) throws ImpossibleNumberException, NonNormalizedNumberException { + public static void requireNormalizedNumber(final String number) throws ImpossiblePhoneNumberException, NonNormalizedPhoneNumberException { if (!PHONE_NUMBER_UTIL.isPossibleNumber(number, null)) { - throw new ImpossibleNumberException(); + throw new ImpossiblePhoneNumberException(); } try { @@ -67,10 +63,10 @@ public class Util { final String normalizedNumber = PHONE_NUMBER_UTIL.format(phoneNumber, PhoneNumberFormat.E164); if (!number.equals(normalizedNumber)) { - throw new NonNormalizedNumberException(number, normalizedNumber); + throw new NonNormalizedPhoneNumberException(number, normalizedNumber); } } catch (final NumberParseException e) { - throw new ImpossibleNumberException(e); + throw new ImpossiblePhoneNumberException(e); } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java index 4f1060fdd..2c992f31f 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java @@ -72,6 +72,9 @@ import org.whispersystems.textsecuregcm.entities.RegistrationLock; import org.whispersystems.textsecuregcm.entities.RegistrationLockFailure; import org.whispersystems.textsecuregcm.limits.RateLimiter; import org.whispersystems.textsecuregcm.limits.RateLimiters; +import org.whispersystems.textsecuregcm.mappers.ImpossiblePhoneNumberExceptionMapper; +import org.whispersystems.textsecuregcm.mappers.NonNormalizedPhoneNumberExceptionMapper; +import org.whispersystems.textsecuregcm.mappers.NonNormalizedPhoneNumberResponse; import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper; import org.whispersystems.textsecuregcm.push.APNSender; import org.whispersystems.textsecuregcm.push.ApnMessage; @@ -154,6 +157,8 @@ class AccountControllerTest { ImmutableSet.of(AuthenticatedAccount.class, DisabledPermittedAuthenticatedAccount.class))) .addProvider(new RateLimitExceededExceptionMapper()) + .addProvider(new ImpossiblePhoneNumberExceptionMapper()) + .addProvider(new NonNormalizedPhoneNumberExceptionMapper()) .setMapper(SystemMapper.getMapper()) .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addResource(new AccountController(pendingAccountsManager, @@ -395,6 +400,39 @@ class AccountControllerTest { verifyNoMoreInteractions(gcmSender); } + @Test + void testGetPreauthImpossibleNumber() { + final Response response = resources.getJerseyTest() + .target("/v1/accounts/fcm/preauth/mytoken/BogusNumber") + .request() + .get(); + + assertThat(response.getStatus()).isEqualTo(400); + assertThat(response.readEntity(String.class)).isBlank(); + + verifyNoMoreInteractions(gcmSender); + verifyNoMoreInteractions(apnSender); + } + + @Test + void testGetPreauthNonNormalized() { + final String number = "+4407700900111"; + + final Response response = resources.getJerseyTest() + .target("/v1/accounts/fcm/preauth/mytoken/" + number) + .request() + .get(); + + assertThat(response.getStatus()).isEqualTo(400); + + final NonNormalizedPhoneNumberResponse responseEntity = response.readEntity(NonNormalizedPhoneNumberResponse.class); + assertThat(responseEntity.getOriginalNumber()).isEqualTo(number); + assertThat(responseEntity.getNormalizedNumber()).isEqualTo("+447700900111"); + + verifyNoMoreInteractions(gcmSender); + verifyNoMoreInteractions(apnSender); + } + @ParameterizedTest @ValueSource(booleans = {false, true}) void testSendCode(final boolean enrolledInVerifyExperiment) throws Exception { @@ -434,6 +472,43 @@ class AccountControllerTest { verify(abusiveHostRules).getAbusiveHostRulesFor(eq(NICE_HOST)); } + @Test + void testSendCodeImpossibleNumber() { + final Response response = + resources.getJerseyTest() + .target(String.format("/v1/accounts/sms/code/%s", "Definitely not a real number")) + .queryParam("challenge", "1234-push") + .request() + .header("X-Forwarded-For", NICE_HOST) + .get(); + + assertThat(response.getStatus()).isEqualTo(400); + assertThat(response.readEntity(String.class)).isBlank(); + + verify(smsSender, never()).deliverSmsVerification(any(), any(), any()); + } + + @Test + void testSendCodeNonNormalized() { + final String number = "+4407700900111"; + + final Response response = + resources.getJerseyTest() + .target(String.format("/v1/accounts/sms/code/%s", number)) + .queryParam("challenge", "1234-push") + .request() + .header("X-Forwarded-For", NICE_HOST) + .get(); + + assertThat(response.getStatus()).isEqualTo(400); + + final NonNormalizedPhoneNumberResponse responseEntity = response.readEntity(NonNormalizedPhoneNumberResponse.class); + assertThat(responseEntity.getOriginalNumber()).isEqualTo(number); + assertThat(responseEntity.getNormalizedNumber()).isEqualTo("+447700900111"); + + verify(smsSender, never()).deliverSmsVerification(any(), any(), any()); + } + @ParameterizedTest @ValueSource(booleans = {false, true}) public void testSendCodeVoiceNoLocale(final boolean enrolledInVerifyExperiment) throws Exception { @@ -1151,6 +1226,46 @@ class AccountControllerTest { verify(accountsManager).changeNumber(AuthHelper.VALID_ACCOUNT, number); } + @Test + void testChangePhoneNumberImpossibleNumber() throws InterruptedException { + final String number = "This is not a real phone number"; + final String code = "987654"; + + final Response response = + resources.getJerseyTest() + .target("/v1/accounts/number") + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(new ChangePhoneNumberRequest(number, code, null), + MediaType.APPLICATION_JSON_TYPE)); + + assertThat(response.getStatus()).isEqualTo(400); + assertThat(response.readEntity(String.class)).isBlank(); + verify(accountsManager, never()).changeNumber(any(), any()); + } + + @Test + void testChangePhoneNumberNonNormalized() throws InterruptedException { + final String number = "+4407700900111"; + final String code = "987654"; + + final Response response = + resources.getJerseyTest() + .target("/v1/accounts/number") + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(new ChangePhoneNumberRequest(number, code, null), + MediaType.APPLICATION_JSON_TYPE)); + + assertThat(response.getStatus()).isEqualTo(400); + + final NonNormalizedPhoneNumberResponse responseEntity = response.readEntity(NonNormalizedPhoneNumberResponse.class); + assertThat(responseEntity.getOriginalNumber()).isEqualTo(number); + assertThat(responseEntity.getNormalizedNumber()).isEqualTo("+447700900111"); + + verify(accountsManager, never()).changeNumber(any(), any()); + } + @Test void testChangePhoneNumberSameNumber() throws InterruptedException { final Response response = diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/ValidNumberTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/ValidNumberTest.java index 7f07c727c..475c835a1 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/ValidNumberTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/ValidNumberTest.java @@ -10,8 +10,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; -import org.whispersystems.textsecuregcm.util.ImpossibleNumberException; -import org.whispersystems.textsecuregcm.util.NonNormalizedNumberException; +import org.whispersystems.textsecuregcm.util.ImpossiblePhoneNumberException; +import org.whispersystems.textsecuregcm.util.NonNormalizedPhoneNumberException; import org.whispersystems.textsecuregcm.util.Util; import java.util.stream.Stream; @@ -22,44 +22,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; class ValidNumberTest { - @ParameterizedTest - @MethodSource - void isValid(final String number, final boolean expectValid) { - assertEquals(expectValid, Util.isValidNumber(number)); - } - - private static Stream isValid() { - return Stream.of( - // Valid numbers - Arguments.of("+14151231234", true), - Arguments.of("+71234567890", true), - Arguments.of("+447535742222", true), - Arguments.of("+4915174108888", true), - - // Invalid e164s - Arguments.of("+141512312341", false), - Arguments.of("+712345678901", false), - Arguments.of("+4475357422221", false), - Arguments.of("+491517410888811111", false), - - // Non-e164s - Arguments.of("+1 415 123 1234", false), - Arguments.of("+1 (415) 123-1234", false), - Arguments.of("+1 415)123-1234", false), - Arguments.of("71234567890", false), - Arguments.of("001447535742222", false), - Arguments.of(" +14151231234", false), - Arguments.of("+1415123123a", false), - - // Short region - Arguments.of("+298123456", true), - Arguments.of("+299123456", true), - Arguments.of("+376123456", true), - Arguments.of("+68512345", true), - Arguments.of("+689123456", true) - ); - } - @ParameterizedTest @ValueSource(strings = { "+447700900111", @@ -78,7 +40,7 @@ class ValidNumberTest { @Test void requireNormalizedNumberNull() { - assertThrows(ImpossibleNumberException.class, () -> Util.requireNormalizedNumber(null)); + assertThrows(ImpossiblePhoneNumberException.class, () -> Util.requireNormalizedNumber(null)); } @ParameterizedTest @@ -93,7 +55,7 @@ class ValidNumberTest { "+1415123123a" }) void requireNormalizedNumberImpossibleNumber(final String number) { - assertThrows(ImpossibleNumberException.class, () -> Util.requireNormalizedNumber(number)); + assertThrows(ImpossiblePhoneNumberException.class, () -> Util.requireNormalizedNumber(number)); } @ParameterizedTest @@ -104,6 +66,6 @@ class ValidNumberTest { "+1 415)123-1234", " +14151231234"}) void requireNormalizedNumberNonNormalized(final String number) { - assertThrows(NonNormalizedNumberException.class, () -> Util.requireNormalizedNumber(number)); + assertThrows(NonNormalizedPhoneNumberException.class, () -> Util.requireNormalizedNumber(number)); } }