Retire AccountsManager#updateDeviceAuthentication

This commit is contained in:
Jon Chambers 2026-04-15 10:12:37 -04:00 committed by Jon Chambers
parent bb7d855aca
commit bb589d6daa
4 changed files with 1 additions and 58 deletions

View File

@ -10,7 +10,6 @@ import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
import com.google.common.annotations.VisibleForTesting;
import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.basic.BasicCredentials;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tags;
import java.time.Clock;
@ -36,9 +35,6 @@ public class AccountAuthenticator implements Authenticator<BasicCredentials, Aut
private static final String DAYS_SINCE_LAST_SEEN_DISTRIBUTION_NAME = name(AccountAuthenticator.class, "daysSinceLastSeen");
private static final String IS_PRIMARY_DEVICE_TAG = "isPrimary";
private static final Counter OLD_TOKEN_VERSION_COUNTER =
Metrics.counter(name(AccountAuthenticator.class, "oldTokenVersionCounter"));
@VisibleForTesting
static final char DEVICE_ID_SEPARATOR = '.';
@ -104,14 +100,7 @@ public class AccountAuthenticator implements Authenticator<BasicCredentials, Aut
SaltedTokenHash deviceSaltedTokenHash = device.get().getAuthTokenHash();
if (deviceSaltedTokenHash.verify(basicCredentials.getPassword())) {
succeeded = true;
Account authenticatedAccount = updateLastSeen(account.get(), device.get());
if (deviceSaltedTokenHash.getVersion() != SaltedTokenHash.CURRENT_VERSION) {
OLD_TOKEN_VERSION_COUNTER.increment();
authenticatedAccount = accountsManager.updateDeviceAuthentication(
authenticatedAccount,
device.get(),
SaltedTokenHash.generateFor(basicCredentials.getPassword())); // new credentials have current version
}
final Account authenticatedAccount = updateLastSeen(account.get(), device.get());
return Optional.of(new AuthenticatedDevice(authenticatedAccount.getIdentifier(IdentityType.ACI),
device.get().getId(),
Instant.ofEpochMilli(authenticatedAccount.getPrimaryDevice().getLastSeen())));

View File

@ -11,7 +11,6 @@ import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import io.dropwizard.lifecycle.Managed;
import io.lettuce.core.RedisCommandTimeoutException;
import io.lettuce.core.RedisException;
@ -64,7 +63,6 @@ import org.signal.libsignal.protocol.IdentityKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.DisconnectionRequestManager;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.controllers.MismatchedDevices;
import org.whispersystems.textsecuregcm.controllers.MismatchedDevicesException;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
@ -957,11 +955,6 @@ public class AccountsManager extends RedisPubSubAdapter<String, String> implemen
});
}
public Account updateDeviceAuthentication(final Account account, final Device device, final SaltedTokenHash credentials) {
Preconditions.checkArgument(credentials.getVersion() == SaltedTokenHash.CURRENT_VERSION);
return updateDevice(account, device.getId(), device1 -> device1.setAuthTokenHash(credentials));
}
/**
* @param account account to update
* @param updater must return {@code true} if the account was actually updated

View File

@ -175,7 +175,6 @@ class AccountAuthenticatorTest {
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.orElseThrow().accountIdentifier()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(device.getId());
verify(accountsManager, never()).updateDeviceAuthentication(any(), any(), any());
}
@Test
@ -205,7 +204,6 @@ class AccountAuthenticatorTest {
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.orElseThrow().accountIdentifier()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(device.getId());
verify(accountsManager, never()).updateDeviceAuthentication(any(), any(), any());
}
@CartesianTest
@ -244,37 +242,6 @@ class AccountAuthenticatorTest {
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(authenticatedDevice.getId());
}
@Test
void testAuthenticateV1() {
final UUID uuid = UUID.randomUUID();
final byte deviceId = 1;
final String password = "12345";
final Account account = mock(Account.class);
final Device device = mock(Device.class);
final SaltedTokenHash credentials = mock(SaltedTokenHash.class);
clock.unpin();
when(accountsManager.getByAccountIdentifier(uuid)).thenReturn(Optional.of(account));
when(account.getUuid()).thenReturn(uuid);
when(account.getIdentifier(IdentityType.ACI)).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.getPrimaryDevice()).thenReturn(device);
when(device.getId()).thenReturn(deviceId);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.Version.V1);
final Optional<AuthenticatedDevice> maybeAuthenticatedAccount =
accountAuthenticator.authenticate(new BasicCredentials(uuid.toString(), password));
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.orElseThrow().accountIdentifier()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(device.getId());
verify(accountsManager, times(1)).updateDeviceAuthentication(
any(), // this won't be 'account', because it'll already be updated by updateDeviceLastSeen
eq(device), any());
}
@Test
void testAuthenticateAccountNotFound() {
assertThat(accountAuthenticator.authenticate(new BasicCredentials(UUID.randomUUID().toString(), "password")))

View File

@ -25,7 +25,6 @@ import org.mockito.MockingDetails;
import org.mockito.stubbing.Stubbing;
import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.ecc.ECKeyPair;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
@ -122,11 +121,6 @@ public class AccountsHelper {
answer.getArgument(1, Device.class).setLastSeen(answer.getArgument(2, Long.class));
return mockAccountsManager.update(answer.getArgument(0, Account.class), account -> {});
});
when(mockAccountsManager.updateDeviceAuthentication(any(), any(), any())).thenAnswer(answer -> {
answer.getArgument(1, Device.class).setAuthTokenHash(answer.getArgument(2, SaltedTokenHash.class));
return mockAccountsManager.update(answer.getArgument(0, Account.class), account -> {});
});
}
public static void setupMockGet(final AccountsManager mockAccountsManager, final Set<Account> mockAccounts) {