0
0
mirror of https://github.com/signalapp/Signal-Server.git synced 2024-09-19 19:42:18 +02:00

Retire Device#hasMessageDeliveryChannel()

This commit is contained in:
Jon Chambers 2024-06-25 12:44:41 -04:00 committed by Jon Chambers
parent 1a09f5807b
commit 73e0aea85c
11 changed files with 40 additions and 95 deletions

View File

@ -14,7 +14,6 @@ import java.util.OptionalInt;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.util.DeviceNameByteArrayAdapter;
@ -187,10 +186,6 @@ public class Device {
this.capabilities = capabilities;
}
public boolean hasMessageDeliveryChannel() {
return fetchesMessages || StringUtils.isNotEmpty(getApnId()) || StringUtils.isNotEmpty(getGcmId());
}
public boolean isExpired() {
return isPrimary()
? lastSeen < (System.currentTimeMillis() - ALLOWED_PRIMARY_IDLE_MILLIS)

View File

@ -22,6 +22,7 @@ import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
@ -245,7 +246,7 @@ public class MessagePersister implements Managed {
// its messages) is unlinked
final Device deviceToDelete = account.getDevices()
.stream()
.filter(d -> !d.isPrimary() && !d.hasMessageDeliveryChannel())
.filter(d -> !d.isPrimary() && !deviceHasMessageDeliveryChannel(d))
.min(Comparator.comparing(Device::getLastSeen))
.or(() ->
Flux.fromIterable(account.getDevices())
@ -288,4 +289,8 @@ public class MessagePersister implements Managed {
}
});
}
private static boolean deviceHasMessageDeliveryChannel(final Device device) {
return device.getFetchesMessages() || StringUtils.isNotEmpty(device.getApnId()) || StringUtils.isNotEmpty(device.getGcmId());
}
}

View File

@ -162,7 +162,6 @@ class AccountAuthenticatorTest {
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(device.getId()).thenReturn(deviceId);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@ -191,7 +190,6 @@ class AccountAuthenticatorTest {
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(device.getId()).thenReturn(deviceId);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@ -223,7 +221,6 @@ class AccountAuthenticatorTest {
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(authenticatedDevice));
when(authenticatedDevice.getId()).thenReturn(deviceId);
when(authenticatedDevice.hasMessageDeliveryChannel()).thenReturn(deviceEnabled);
when(authenticatedDevice.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@ -258,7 +255,6 @@ class AccountAuthenticatorTest {
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(device.getId()).thenReturn(deviceId);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.Version.V1);
@ -294,7 +290,6 @@ class AccountAuthenticatorTest {
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(device.getId()).thenReturn(deviceId);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@ -321,7 +316,6 @@ class AccountAuthenticatorTest {
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(device.getId()).thenReturn(deviceId);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);

View File

@ -221,10 +221,6 @@ class KeysControllerTest {
when(sampleDevice3.getRegistrationId()).thenReturn(SAMPLE_REGISTRATION_ID2);
when(sampleDevice4.getRegistrationId()).thenReturn(SAMPLE_REGISTRATION_ID4);
when(sampleDevice.getPhoneNumberIdentityRegistrationId()).thenReturn(OptionalInt.of(SAMPLE_PNI_REGISTRATION_ID));
when(sampleDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(sampleDevice2.hasMessageDeliveryChannel()).thenReturn(true);
when(sampleDevice3.hasMessageDeliveryChannel()).thenReturn(false);
when(sampleDevice4.hasMessageDeliveryChannel()).thenReturn(true);
when(sampleDevice.getId()).thenReturn(sampleDeviceId);
when(sampleDevice2.getId()).thenReturn(sampleDevice2Id);
when(sampleDevice3.getId()).thenReturn(sampleDevice3Id);

View File

@ -489,7 +489,6 @@ class KeysGrpcServiceTest extends SimpleBaseGrpcTest<KeysGrpcService, KeysGrpc.K
final Device device = mock(Device.class);
when(device.getId()).thenReturn(deviceId);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
devices.put(deviceId, device);
when(targetAccount.getDevice(deviceId)).thenReturn(Optional.of(device));

View File

@ -50,44 +50,35 @@ class AccountTest {
@BeforeEach
void setup() {
when(oldPrimaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
when(oldPrimaryDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(oldPrimaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
when(recentPrimaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
when(recentPrimaryDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(recentPrimaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
when(agingSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31));
when(agingSecondaryDevice.hasMessageDeliveryChannel()).thenReturn(false);
final byte deviceId2 = 2;
when(agingSecondaryDevice.getId()).thenReturn(deviceId2);
when(recentSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
when(recentSecondaryDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(recentSecondaryDevice.getId()).thenReturn(deviceId2);
when(oldSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
when(oldSecondaryDevice.hasMessageDeliveryChannel()).thenReturn(false);
when(oldSecondaryDevice.getId()).thenReturn(deviceId2);
when(paymentActivationCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, false));
when(paymentActivationCapableDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(paymentActivationIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, false, false));
when(paymentActivationIncapableDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(paymentActivationIncapableDeviceWithoutDeliveryChannel.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, false, false));
when(paymentActivationIncapableDeviceWithoutDeliveryChannel.hasMessageDeliveryChannel()).thenReturn(false);
when(paymentActivationCapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, false));
when(deleteSyncCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true)
);
when(deleteSyncCapableDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(deleteSyncIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, false)
);
when(deleteSyncIncapableDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(paymentActivationIncapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, false, false));
when(paymentActivationIncapableDeviceWithoutDeliveryChannel.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, false, false));
when(deleteSyncCapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, true));
when(deleteSyncIncapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, false));
}

View File

@ -134,7 +134,6 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@ -181,7 +180,6 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@ -228,7 +226,6 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@ -273,7 +270,6 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@ -316,7 +312,6 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@ -361,7 +356,6 @@ public class ChangeNumberManagerTest {
for (byte i = 1; i <= 3; i++) {
final Device device = mock(Device.class);
when(device.getId()).thenReturn(i);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getRegistrationId()).thenReturn((int) i);
devices.add(device);
@ -400,7 +394,6 @@ public class ChangeNumberManagerTest {
for (byte i = 1; i <= 3; i++) {
final Device device = mock(Device.class);
when(device.getId()).thenReturn(i);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getRegistrationId()).thenReturn((int) i);
devices.add(device);
@ -439,7 +432,6 @@ public class ChangeNumberManagerTest {
for (byte i = 1; i <= 3; i++) {
final Device device = mock(Device.class);
when(device.getId()).thenReturn(i);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getRegistrationId()).thenReturn((int) i);
devices.add(device);

View File

@ -9,35 +9,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.Duration;
import java.time.Instant;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
class DeviceTest {
@ParameterizedTest
@MethodSource
void testHasMessageDeliveryChannel(final boolean fetchesMessages, final String apnId, final String gcmId, final boolean expectEnabled) {
final Device device = new Device();
device.setFetchesMessages(fetchesMessages);
device.setApnId(apnId);
device.setGcmId(gcmId);
assertEquals(expectEnabled, device.hasMessageDeliveryChannel());
}
private static Stream<Arguments> testHasMessageDeliveryChannel() {
return Stream.of(
Arguments.of(false, null, null, false),
Arguments.of(false, null, "gcm-id", true),
Arguments.of(false, "apn-id", null, true),
Arguments.of(true, null, null, true)
);
}
@ParameterizedTest
@CsvSource({
"true, P1D, false",

View File

@ -81,8 +81,8 @@ class MessagePersisterTest {
void setUp() throws Exception {
messagesManager = mock(MessagesManager.class);
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager = mock(
DynamicConfigurationManager.class);
@SuppressWarnings("unchecked") final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager =
mock(DynamicConfigurationManager.class);
messagesDynamoDb = mock(MessagesDynamoDb.class);
accountsManager = mock(AccountsManager.class);
@ -107,6 +107,9 @@ class MessagePersisterTest {
messagePersister = new MessagePersister(messagesCache, messagesManager, accountsManager, clientPresenceManager,
keysManager, dynamicConfigurationManager, PERSIST_DELAY, 1, MoreExecutors.newDirectExecutorService());
when(messagesManager.clear(any(UUID.class), anyByte())).thenReturn(CompletableFuture.completedFuture(null));
when(keysManager.deleteSingleUsePreKeys(any(), anyByte())).thenReturn(CompletableFuture.completedFuture(null));
when(messagesManager.persistMessages(any(UUID.class), any(), any())).thenAnswer(invocation -> {
final UUID destinationUuid = invocation.getArgument(0);
final Device destinationDevice = invocation.getArgument(1);
@ -258,29 +261,29 @@ class MessagePersisterTest {
final Device primary = mock(Device.class);
when(primary.getId()).thenReturn((byte) 1);
when(primary.isPrimary()).thenReturn(true);
when(primary.hasMessageDeliveryChannel()).thenReturn(true);
when(primary.getFetchesMessages()).thenReturn(true);
final Device activeA = mock(Device.class);
when(activeA.getId()).thenReturn((byte) 2);
when(activeA.hasMessageDeliveryChannel()).thenReturn(true);
when(activeA.getFetchesMessages()).thenReturn(true);
final Device inactiveB = mock(Device.class);
final byte inactiveId = 3;
when(inactiveB.getId()).thenReturn(inactiveId);
when(inactiveB.hasMessageDeliveryChannel()).thenReturn(false);
final Device inactiveC = mock(Device.class);
when(inactiveC.getId()).thenReturn((byte) 4);
when(inactiveC.hasMessageDeliveryChannel()).thenReturn(false);
final Device activeD = mock(Device.class);
when(activeD.getId()).thenReturn((byte) 5);
when(activeD.hasMessageDeliveryChannel()).thenReturn(true);
when(activeD.getFetchesMessages()).thenReturn(true);
final Device destination = mock(Device.class);
when(destination.getId()).thenReturn(DESTINATION_DEVICE_ID);
when(destination.hasMessageDeliveryChannel()).thenReturn(true);
when(destinationAccount.getDevices()).thenReturn(List.of(primary, activeA, inactiveB, inactiveC, activeD, destination));
when(messagesManager.persistMessages(any(UUID.class), any(), anyList())).thenThrow(ItemCollectionSizeLimitExceededException.builder().build());
when(messagesManager.clear(any(UUID.class), anyByte())).thenReturn(CompletableFuture.completedFuture(null));
when(keysManager.deleteSingleUsePreKeys(any(), eq(inactiveId))).thenReturn(CompletableFuture.completedFuture(null));
assertTimeoutPreemptively(Duration.ofSeconds(1), () ->
messagePersister.persistQueue(destinationAccount, DESTINATION_DEVICE));
@ -302,27 +305,27 @@ class MessagePersisterTest {
final byte primaryId = 1;
when(primary.getId()).thenReturn(primaryId);
when(primary.isPrimary()).thenReturn(true);
when(primary.hasMessageDeliveryChannel()).thenReturn(true);
when(primary.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(primary)))
.thenReturn(Mono.just(4L));
final Device deviceA = mock(Device.class);
final byte deviceIdA = 2;
when(deviceA.getId()).thenReturn(deviceIdA);
when(deviceA.hasMessageDeliveryChannel()).thenReturn(true);
when(deviceA.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(deviceA)))
.thenReturn(Mono.empty());
final Device deviceB = mock(Device.class);
final byte deviceIdB = 3;
when(deviceB.getId()).thenReturn(deviceIdB);
when(deviceB.hasMessageDeliveryChannel()).thenReturn(true);
when(deviceB.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(deviceB)))
.thenReturn(Mono.just(2L));
final Device destination = mock(Device.class);
when(destination.getId()).thenReturn(DESTINATION_DEVICE_ID);
when(destination.hasMessageDeliveryChannel()).thenReturn(true);
when(destination.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(destination)))
.thenReturn(Mono.just(5L));
@ -352,27 +355,27 @@ class MessagePersisterTest {
final byte primaryId = 1;
when(primary.getId()).thenReturn(primaryId);
when(primary.isPrimary()).thenReturn(true);
when(primary.hasMessageDeliveryChannel()).thenReturn(true);
when(primary.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(primary)))
.thenReturn(Mono.just(1L));
final Device deviceA = mock(Device.class);
final byte deviceIdA = 2;
when(deviceA.getId()).thenReturn(deviceIdA);
when(deviceA.hasMessageDeliveryChannel()).thenReturn(true);
when(deviceA.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(deviceA)))
.thenReturn(Mono.just(3L));
final Device deviceB = mock(Device.class);
final byte deviceIdB = 2;
when(deviceB.getId()).thenReturn(deviceIdB);
when(deviceB.hasMessageDeliveryChannel()).thenReturn(true);
when(deviceB.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(deviceB)))
.thenReturn(Mono.empty());
final Device destination = mock(Device.class);
when(destination.getId()).thenReturn(DESTINATION_DEVICE_ID);
when(destination.hasMessageDeliveryChannel()).thenReturn(true);
when(destination.getFetchesMessages()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(destination)))
.thenReturn(Mono.just(2L));

View File

@ -138,11 +138,7 @@ public class AuthHelper {
when(VALID_DEVICE_3_PRIMARY.getId()).thenReturn(Device.PRIMARY_ID);
when(VALID_DEVICE_3_LINKED.getId()).thenReturn((byte) 2);
when(VALID_DEVICE.hasMessageDeliveryChannel()).thenReturn(true);
when(VALID_DEVICE_TWO.hasMessageDeliveryChannel()).thenReturn(true);
when(UNDISCOVERABLE_DEVICE.isPrimary()).thenReturn(true);
when(VALID_DEVICE_3_PRIMARY.hasMessageDeliveryChannel()).thenReturn(true);
when(VALID_DEVICE_3_LINKED.hasMessageDeliveryChannel()).thenReturn(true);
when(VALID_ACCOUNT.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(VALID_DEVICE));
when(VALID_ACCOUNT.getPrimaryDevice()).thenReturn(VALID_DEVICE);
@ -272,7 +268,6 @@ public class AuthHelper {
when(device.getAuthTokenHash()).thenReturn(saltedTokenHash);
when(device.isPrimary()).thenReturn(true);
when(device.getId()).thenReturn(Device.PRIMARY_ID);
when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
when(account.getPrimaryDevice()).thenReturn(device);
when(account.getNumber()).thenReturn(number);

View File

@ -107,7 +107,6 @@ class DestinationDeviceValidatorTest {
enabledStateByDeviceId.forEach((deviceId, enabled) -> {
final Device device = mock(Device.class);
when(device.hasMessageDeliveryChannel()).thenReturn(enabled);
when(device.getId()).thenReturn(deviceId);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));