Retire verification code storage machinery

This commit is contained in:
Jon Chambers
2023-08-03 18:26:23 -04:00
committed by Jon Chambers
parent 625637b888
commit a131f2116f
9 changed files with 1 additions and 394 deletions

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.auth;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class StoredVerificationCodeTest {
@ParameterizedTest
@MethodSource
void isValid(final StoredVerificationCode storedVerificationCode, final String code, final boolean expectValid) {
assertEquals(expectValid, storedVerificationCode.isValid(code));
}
private static Stream<Arguments> isValid() {
return Stream.of(
Arguments.of(new StoredVerificationCode("code", System.currentTimeMillis(), null, null), "code", true),
Arguments.of(new StoredVerificationCode("code", System.currentTimeMillis(), null, null), "incorrect", false),
Arguments.of(new StoredVerificationCode("", System.currentTimeMillis(), null, null), "", false)
);
}
}

View File

@@ -57,7 +57,6 @@ import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.entities.AccountIdentifierResponse;
@@ -83,7 +82,6 @@ import org.whispersystems.textsecuregcm.spam.ScoreThresholdProvider;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.RegistrationRecoveryPasswordsManager;
import org.whispersystems.textsecuregcm.storage.StoredVerificationCodeManager;
import org.whispersystems.textsecuregcm.storage.UsernameHashNotAvailableException;
import org.whispersystems.textsecuregcm.storage.UsernameReservationNotFoundException;
import org.whispersystems.textsecuregcm.tests.util.AccountsHelper;
@@ -124,7 +122,6 @@ class AccountControllerTest {
private static final String NICE_HOST = "127.0.0.1";
private static final String RATE_LIMITED_IP_HOST = "10.0.0.1";
private static StoredVerificationCodeManager pendingAccountsManager = mock(StoredVerificationCodeManager.class);
private static AccountsManager accountsManager = mock(AccountsManager.class);
private static RateLimiters rateLimiters = mock(RateLimiters.class);
private static RateLimiter rateLimiter = mock(RateLimiter.class);
@@ -204,24 +201,6 @@ class AccountControllerTest {
when(senderTransfer.getUuid()).thenReturn(SENDER_TRANSFER_UUID);
when(senderTransfer.getNumber()).thenReturn(SENDER_TRANSFER);
when(pendingAccountsManager.getCodeForNumber(SENDER)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), "1234-push", null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_OLD)).thenReturn(Optional.empty());
when(pendingAccountsManager.getCodeForNumber(SENDER_PIN)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), null, null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_REG_LOCK)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), null, null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_OVER_PIN)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), null, null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_OVER_PREFIX)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), "1234-push", null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_PREAUTH)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), "validchallenge", null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_HAS_STORAGE)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), null, null)));
when(pendingAccountsManager.getCodeForNumber(SENDER_TRANSFER)).thenReturn(
Optional.of(new StoredVerificationCode(null, System.currentTimeMillis(), null, null)));
when(accountsManager.getByE164(eq(SENDER_PIN))).thenReturn(Optional.of(senderPinAccount));
when(accountsManager.getByE164(eq(SENDER_REG_LOCK))).thenReturn(Optional.of(senderRegLockAccount));
when(accountsManager.getByE164(eq(SENDER_OVER_PIN))).thenReturn(Optional.of(senderPinAccount));
@@ -244,7 +223,6 @@ class AccountControllerTest {
@AfterEach
void teardown() {
reset(
pendingAccountsManager,
accountsManager,
rateLimiters,
rateLimiter,

View File

@@ -316,15 +316,6 @@ public final class DynamoDbExtensionSchema {
.build()),
List.of(), List.of()),
VERIFICATION_CODES("verification_codes_test",
VerificationCodeStore.KEY_E164,
null,
List.of(AttributeDefinition.builder()
.attributeName(VerificationCodeStore.KEY_E164)
.attributeType(ScalarAttributeType.S)
.build()),
List.of(), List.of()),
VERIFICATION_SESSIONS("verification_sessions_test",
VerificationSessions.KEY_KEY,
null,

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.storage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
class StoredVerificationCodeManagerTest {
private VerificationCodeStore verificationCodeStore;
private StoredVerificationCodeManager storedVerificationCodeManager;
@BeforeEach
void setUp() {
verificationCodeStore = mock(VerificationCodeStore.class);
storedVerificationCodeManager = new StoredVerificationCodeManager(verificationCodeStore);
}
@Test
void store() {
final String number = "+18005551234";
final StoredVerificationCode code = mock(StoredVerificationCode.class);
storedVerificationCodeManager.store(number, code);
verify(verificationCodeStore).insert(number, code);
}
@Test
void remove() {
final String number = "+18005551234";
storedVerificationCodeManager.remove(number);
verify(verificationCodeStore).remove(number);
}
@Test
void getCodeForNumber() {
final String number = "+18005551234";
when(verificationCodeStore.findForNumber(number)).thenReturn(Optional.empty());
assertEquals(Optional.empty(), storedVerificationCodeManager.getCodeForNumber(number));
final StoredVerificationCode storedVerificationCode = mock(StoredVerificationCode.class);
when(verificationCodeStore.findForNumber(number)).thenReturn(Optional.of(storedVerificationCode));
assertEquals(Optional.of(storedVerificationCode), storedVerificationCodeManager.getCodeForNumber(number));
}
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.storage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
class VerificationCodeStoreTest {
private VerificationCodeStore verificationCodeStore;
private static final String PHONE_NUMBER = "+14151112222";
private static final long VALID_TIMESTAMP = Instant.now().toEpochMilli();
private static final long EXPIRED_TIMESTAMP = Instant.now().minus(StoredVerificationCode.EXPIRATION).minus(
Duration.ofHours(1)).toEpochMilli();
@RegisterExtension
static final DynamoDbExtension DYNAMO_DB_EXTENSION = new DynamoDbExtension(Tables.VERIFICATION_CODES);
@BeforeEach
void setUp() {
verificationCodeStore = new VerificationCodeStore(
DYNAMO_DB_EXTENSION.getDynamoDbClient(), Tables.VERIFICATION_CODES.tableName());
}
@Test
void testStoreAndFind() {
assertEquals(Optional.empty(), verificationCodeStore.findForNumber(PHONE_NUMBER));
final StoredVerificationCode originalCode = new StoredVerificationCode("1234", VALID_TIMESTAMP, "abcd",
"session".getBytes(StandardCharsets.UTF_8));
final StoredVerificationCode secondCode = new StoredVerificationCode("5678", VALID_TIMESTAMP, "efgh",
"changed-session".getBytes(StandardCharsets.UTF_8));
verificationCodeStore.insert(PHONE_NUMBER, originalCode);
{
final Optional<StoredVerificationCode> maybeCode = verificationCodeStore.findForNumber(PHONE_NUMBER);
assertTrue(maybeCode.isPresent());
assertTrue(storedVerificationCodesAreEqual(originalCode, maybeCode.get()));
}
verificationCodeStore.insert(PHONE_NUMBER, secondCode);
{
final Optional<StoredVerificationCode> maybeCode = verificationCodeStore.findForNumber(PHONE_NUMBER);
assertTrue(maybeCode.isPresent());
assertTrue(storedVerificationCodesAreEqual(secondCode, maybeCode.get()));
}
}
@Test
void testRemove() {
assertEquals(Optional.empty(), verificationCodeStore.findForNumber(PHONE_NUMBER));
verificationCodeStore.insert(PHONE_NUMBER,
new StoredVerificationCode("1234", VALID_TIMESTAMP, "abcd", "session".getBytes(StandardCharsets.UTF_8)));
assertTrue(verificationCodeStore.findForNumber(PHONE_NUMBER).isPresent());
verificationCodeStore.remove(PHONE_NUMBER);
assertFalse(verificationCodeStore.findForNumber(PHONE_NUMBER).isPresent());
verificationCodeStore.insert(PHONE_NUMBER,
new StoredVerificationCode("1234", EXPIRED_TIMESTAMP, "abcd", "session".getBytes(StandardCharsets.UTF_8)));
assertFalse(verificationCodeStore.findForNumber(PHONE_NUMBER).isPresent());
}
private static boolean storedVerificationCodesAreEqual(final StoredVerificationCode first, final StoredVerificationCode second) {
if (first == null && second == null) {
return true;
} else if (first == null || second == null) {
return false;
}
return Objects.equals(first.code(), second.code()) &&
first.timestamp() == second.timestamp() &&
Objects.equals(first.pushCode(), second.pushCode()) &&
Arrays.equals(first.sessionId(), second.sessionId());
}
}