Retire authenticated device getters

This commit is contained in:
Jon Chambers
2025-06-23 09:10:30 -05:00
committed by GitHub
parent 68b84dd56b
commit 483404a67f
34 changed files with 181 additions and 254 deletions

View File

@@ -31,6 +31,7 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.junitpioneer.jupiter.cartesian.CartesianTest;
import org.whispersystems.textsecuregcm.identity.IdentityType;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
@@ -78,8 +79,8 @@ class AccountAuthenticatorTest {
void testUpdateLastSeenMiddleOfDay() {
clock.pin(Instant.ofEpochMilli(currentTime));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Device device1 = acct1.getDevices().stream().findFirst().orElseThrow();
final Device device2 = acct2.getDevices().stream().findFirst().orElseThrow();
final Account updatedAcct1 = accountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = accountAuthenticator.updateLastSeen(acct2, device2);
@@ -98,8 +99,8 @@ class AccountAuthenticatorTest {
void testUpdateLastSeenStartOfDay() {
clock.pin(Instant.ofEpochMilli(today));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Device device1 = acct1.getDevices().stream().findFirst().orElseThrow();
final Device device2 = acct2.getDevices().stream().findFirst().orElseThrow();
final Account updatedAcct1 = accountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = accountAuthenticator.updateLastSeen(acct2, device2);
@@ -118,8 +119,8 @@ class AccountAuthenticatorTest {
void testUpdateLastSeenEndOfDay() {
clock.pin(Instant.ofEpochMilli(today + 86_400_000L - 1));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Device device1 = acct1.getDevices().stream().findFirst().orElseThrow();
final Device device2 = acct2.getDevices().stream().findFirst().orElseThrow();
final Account updatedAcct1 = accountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = accountAuthenticator.updateLastSeen(acct2, device2);
@@ -138,7 +139,7 @@ class AccountAuthenticatorTest {
void testNeverWriteYesterday() {
clock.pin(Instant.ofEpochMilli(today));
final Device device = oldAccount.getDevices().stream().findFirst().get();
final Device device = oldAccount.getDevices().stream().findFirst().orElseThrow();
accountAuthenticator.updateLastSeen(oldAccount, device);
@@ -160,7 +161,9 @@ class AccountAuthenticatorTest {
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);
@@ -170,9 +173,9 @@ class AccountAuthenticatorTest {
accountAuthenticator.authenticate(new BasicCredentials(uuid.toString(), password));
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(device);
verify(accountsManager, never()).updateDeviceAuthentication(any(), any(), any());;
assertThat(maybeAuthenticatedAccount.orElseThrow().accountIdentifier()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(device.getId());
verify(accountsManager, never()).updateDeviceAuthentication(any(), any(), any());
}
@Test
@@ -188,7 +191,9 @@ class AccountAuthenticatorTest {
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);
@@ -198,15 +203,13 @@ class AccountAuthenticatorTest {
accountAuthenticator.authenticate(new BasicCredentials(uuid + "." + deviceId, password));
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(device);
assertThat(maybeAuthenticatedAccount.orElseThrow().accountIdentifier()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(device.getId());
verify(accountsManager, never()).updateDeviceAuthentication(any(), any(), any());
}
@CartesianTest
void testAuthenticateEnabled(
@CartesianTest.Values(booleans = {true, false}) final boolean accountEnabled,
@CartesianTest.Values(booleans = {true, false}) final boolean deviceEnabled,
@CartesianTest.Values(booleans = {true, false}) final boolean authenticatedDeviceIsPrimary) {
final UUID uuid = UUID.randomUUID();
final byte deviceId = (byte) (authenticatedDeviceIsPrimary ? 1 : 2);
@@ -219,7 +222,9 @@ class AccountAuthenticatorTest {
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(authenticatedDevice));
when(account.getPrimaryDevice()).thenReturn(authenticatedDevice);
when(authenticatedDevice.getId()).thenReturn(deviceId);
when(authenticatedDevice.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
@@ -235,9 +240,8 @@ class AccountAuthenticatorTest {
accountAuthenticator.authenticate(new BasicCredentials(identifier, password));
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(authenticatedDevice);
assertThat(maybeAuthenticatedAccount.orElseThrow().accountIdentifier()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.orElseThrow().deviceId()).isEqualTo(authenticatedDevice.getId());
}
@Test
@@ -253,7 +257,9 @@ class AccountAuthenticatorTest {
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);
@@ -263,8 +269,8 @@ class AccountAuthenticatorTest {
accountAuthenticator.authenticate(new BasicCredentials(uuid.toString(), password));
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(device);
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());
@@ -288,7 +294,9 @@ class AccountAuthenticatorTest {
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);
@@ -314,7 +322,9 @@ class AccountAuthenticatorTest {
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);

View File

@@ -8,12 +8,12 @@ package org.whispersystems.textsecuregcm.auth;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nullable;
import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest;
import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse;
@@ -21,7 +21,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.util.TestClock;
@@ -59,26 +58,8 @@ class IdlePrimaryDeviceAuthenticatedWebSocketUpgradeFilterTest {
}
private static List<Arguments> handleAuthentication() {
final Device activePrimaryDevice = mock(Device.class);
when(activePrimaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
when(activePrimaryDevice.isPrimary()).thenReturn(true);
when(activePrimaryDevice.getLastSeen()).thenReturn(CLOCK.millis());
final Device minIdlePrimaryDevice = mock(Device.class);
when(minIdlePrimaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
when(minIdlePrimaryDevice.isPrimary()).thenReturn(true);
when(minIdlePrimaryDevice.getLastSeen())
.thenReturn(CLOCK.instant().minus(MIN_IDLE_DURATION).minusSeconds(1).toEpochMilli());
final Device linkedDevice = mock(Device.class);
when(linkedDevice.getId()).thenReturn((byte) (Device.PRIMARY_ID + 1));
when(linkedDevice.isPrimary()).thenReturn(false);
final Account accountWithActivePrimaryDevice = mock(Account.class);
when(accountWithActivePrimaryDevice.getPrimaryDevice()).thenReturn(activePrimaryDevice);
final Account accountWithMinIdlePrimaryDevice = mock(Account.class);
when(accountWithMinIdlePrimaryDevice.getPrimaryDevice()).thenReturn(minIdlePrimaryDevice);
final Instant activePrimaryDeviceLastSeen = CLOCK.instant();
final Instant idlePrimaryDeviceLastSeen = CLOCK.instant().minus(MIN_IDLE_DURATION).minusSeconds(1);
return List.of(
Arguments.argumentSet("Anonymous",
@@ -86,19 +67,19 @@ class IdlePrimaryDeviceAuthenticatedWebSocketUpgradeFilterTest {
null),
Arguments.argumentSet("Authenticated as active primary device",
new AuthenticatedDevice(accountWithActivePrimaryDevice, activePrimaryDevice),
new AuthenticatedDevice(UUID.randomUUID(), Device.PRIMARY_ID, activePrimaryDeviceLastSeen),
null),
Arguments.argumentSet("Authenticated as idle primary device",
new AuthenticatedDevice(accountWithMinIdlePrimaryDevice, minIdlePrimaryDevice),
new AuthenticatedDevice(UUID.randomUUID(), Device.PRIMARY_ID, idlePrimaryDeviceLastSeen),
null),
Arguments.argumentSet("Authenticated as linked device with active primary device",
new AuthenticatedDevice(accountWithActivePrimaryDevice, linkedDevice),
new AuthenticatedDevice(UUID.randomUUID(), (byte) (Device.PRIMARY_ID + 1), activePrimaryDeviceLastSeen),
null),
Arguments.argumentSet("Authenticated as linked device with min-idle primary device",
new AuthenticatedDevice(accountWithMinIdlePrimaryDevice, linkedDevice),
Arguments.argumentSet("Authenticated as linked device with idle primary device",
new AuthenticatedDevice(UUID.randomUUID(), (byte) (Device.PRIMARY_ID + 1), idlePrimaryDeviceLastSeen),
IdlePrimaryDeviceAuthenticatedWebSocketUpgradeFilter.IDLE_PRIMARY_DEVICE_ALERT)
);
}