diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index 1b9bc9f70..03f65dfa3 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -554,7 +554,7 @@ public class WhisperServerService extends Application(ImmutableSet.of(Account.class, DisabledPermittedAccount.class))); environment.jersey().register(new TimestampResponseFilter()); - environment.jersey().register(new AccountController(pendingAccountsManager, accountsManager, usernamesManager, abusiveHostRules, rateLimiters, smsSender, directoryQueue, messagesManager, dynamicConfigurationManager, turnTokenGenerator, config.getTestDevices(), recaptchaClient, gcmSender, apnSender, backupCredentialsGenerator, verifyExperimentEnrollmentManager)); + environment.jersey().register(new AccountController(pendingAccountsManager, accountsManager, usernamesManager, abusiveHostRules, rateLimiters, smsSender, directoryQueue, messagesManager, keysDynamoDb, dynamicConfigurationManager, turnTokenGenerator, config.getTestDevices(), recaptchaClient, gcmSender, apnSender, backupCredentialsGenerator, verifyExperimentEnrollmentManager)); environment.jersey().register(new DeviceController(pendingDevicesManager, accountsManager, messagesManager, keysDynamoDb, directoryQueue, rateLimiters, config.getMaxDevices())); environment.jersey().register(new DirectoryController(directoryCredentialsGenerator)); environment.jersey().register(new ProvisioningController(rateLimiters, provisioningManager)); 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 3b723a708..141de3cd8 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -75,6 +75,7 @@ import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; +import org.whispersystems.textsecuregcm.storage.KeysDynamoDb; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager; import org.whispersystems.textsecuregcm.storage.UsernamesManager; @@ -120,6 +121,7 @@ public class AccountController { private final SmsSender smsSender; private final DirectoryQueue directoryQueue; private final MessagesManager messagesManager; + private final KeysDynamoDb keys; private final DynamicConfigurationManager dynamicConfigurationManager; private final TurnTokenGenerator turnTokenGenerator; private final Map testDevices; @@ -138,6 +140,7 @@ public class AccountController { SmsSender smsSenderFactory, DirectoryQueue directoryQueue, MessagesManager messagesManager, + KeysDynamoDb keys, DynamicConfigurationManager dynamicConfigurationManager, TurnTokenGenerator turnTokenGenerator, Map testDevices, @@ -155,6 +158,7 @@ public class AccountController { this.smsSender = smsSenderFactory; this.directoryQueue = directoryQueue; this.messagesManager = messagesManager; + this.keys = keys; this.dynamicConfigurationManager = dynamicConfigurationManager; this.testDevices = testDevices; this.turnTokenGenerator = turnTokenGenerator; @@ -780,7 +784,12 @@ public class AccountController { } directoryQueue.refreshRegisteredUser(account); - maybeExistingAccount.ifPresent(definitelyExistingAccount -> messagesManager.clear(definitelyExistingAccount.getUuid())); + + maybeExistingAccount.ifPresent(definitelyExistingAccount -> { + messagesManager.clear(definitelyExistingAccount.getUuid()); + keys.delete(definitelyExistingAccount); + }); + pendingAccounts.remove(number); return account; 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 50c969793..f95314cac 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 @@ -76,6 +76,7 @@ import org.whispersystems.textsecuregcm.storage.AbusiveHostRules; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; +import org.whispersystems.textsecuregcm.storage.KeysDynamoDb; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager; import org.whispersystems.textsecuregcm.storage.UsernamesManager; @@ -122,6 +123,7 @@ class AccountControllerTest { private static SmsSender smsSender = mock(SmsSender.class); private static DirectoryQueue directoryQueue = mock(DirectoryQueue.class); private static MessagesManager storedMessages = mock(MessagesManager.class); + private static KeysDynamoDb keys = mock(KeysDynamoDb.class); private static TurnTokenGenerator turnTokenGenerator = mock(TurnTokenGenerator.class); private static Account senderPinAccount = mock(Account.class); private static Account senderRegLockAccount = mock(Account.class); @@ -155,6 +157,7 @@ class AccountControllerTest { smsSender, directoryQueue, storedMessages, + keys, dynamicConfigurationManager, turnTokenGenerator, new HashMap<>(), @@ -260,6 +263,7 @@ class AccountControllerTest { smsSender, directoryQueue, storedMessages, + keys, turnTokenGenerator, senderPinAccount, senderRegLockAccount, @@ -1246,6 +1250,33 @@ class AccountControllerTest { assertThat(response.getStatus()).isEqualTo(200); } + @Test + void testVerifyReregistration() throws InterruptedException { + final UUID existingUuid = UUID.randomUUID(); + final Account existingAccount = mock(Account.class); + + when(existingAccount.getUuid()).thenReturn(existingUuid); + when(accountsManager.get(SENDER)).thenReturn(Optional.of(existingAccount)); + + AccountCreationResult result = + resources.getJerseyTest() + .target(String.format("/v1/accounts/code/%s", "1234")) + .request() + .header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar")) + .put(Entity.entity(new AccountAttributes(false, 2222, null, null, null, true, null), + MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); + + final ArgumentCaptor accountArgumentCaptor = ArgumentCaptor.forClass(Account.class); + + verify(accountsManager, times(1)).create(accountArgumentCaptor.capture()); + verify(directoryQueue, times(1)).refreshRegisteredUser(argThat(account -> SENDER.equals(account.getNumber()))); + + verify(storedMessages).clear(existingUuid); + verify(keys).delete(existingAccount); + + assertThat(accountArgumentCaptor.getValue().isDiscoverableByPhoneNumber()).isTrue(); + } + @Test void testSetPin() throws Exception { Response response =