From 2f5574760154afc400953b56efcfae55faaea801 Mon Sep 17 00:00:00 2001
From: Jon Chambers <63609320+jon-signal@users.noreply.github.com>
Date: Fri, 7 Jun 2024 13:39:11 -0400
Subject: [PATCH] Remove expiration check from `Device#isEnabled()`
---
...hEnablementRefreshRequirementProvider.java | 4 +--
.../auth/ContainerRequestUtil.java | 2 +-
.../textsecuregcm/auth/OptionalAccess.java | 2 +-
.../controllers/KeysController.java | 4 +--
.../textsecuregcm/grpc/KeysGrpcHelper.java | 2 +-
.../textsecuregcm/storage/Account.java | 6 ++--
.../storage/AccountsManager.java | 2 +-
.../textsecuregcm/storage/Device.java | 7 ++--
.../storage/MessagePersister.java | 2 +-
.../util/DestinationDeviceValidator.java | 2 +-
...rocessPushNotificationFeedbackCommand.java | 2 +-
.../auth/AccountAuthenticatorTest.java | 12 +++----
...blementRefreshRequirementProviderTest.java | 8 ++---
.../auth/ContainerRequestUtilTest.java | 2 +-
.../controllers/KeysControllerTest.java | 8 ++---
.../controllers/MessageControllerTest.java | 18 ++++------
.../grpc/KeysGrpcServiceTest.java | 2 +-
.../textsecuregcm/storage/AccountTest.java | 30 ++++++++---------
.../storage/ChangeNumberManagerTest.java | 16 ++++-----
.../textsecuregcm/storage/DeviceTest.java | 33 ++++---------------
.../storage/MessagePersisterTest.java | 28 ++++++++--------
.../textsecuregcm/tests/util/AuthHelper.java | 10 +++---
.../tests/util/DevicesHelper.java | 7 ++--
.../util/DestinationDeviceValidatorTest.java | 2 +-
...ssPushNotificationFeedbackCommandTest.java | 16 ++++-----
25 files changed, 99 insertions(+), 128 deletions(-)
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProvider.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProvider.java
index 3385f3621..053c31964 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProvider.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProvider.java
@@ -23,9 +23,9 @@ import org.whispersystems.textsecuregcm.util.Pair;
/**
* This {@link WebsocketRefreshRequirementProvider} observes intra-request changes in {@link Account#isEnabled()} and
- * {@link Device#isEnabled()}.
+ * {@link Device#hasMessageDeliveryChannel()}.
*
- * If a change in {@link Account#isEnabled()} or any associated {@link Device#isEnabled()} is observed, then any active
+ * If a change in {@link Account#isEnabled()} or any associated {@link Device#hasMessageDeliveryChannel()} is observed, then any active
* WebSocket connections for the account must be closed in order for clients to get a refreshed
* {@link io.dropwizard.auth.Auth} object with a current device list.
*
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtil.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtil.java
index eb2ecf029..666afbe6c 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtil.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtil.java
@@ -17,7 +17,7 @@ import java.util.stream.Collectors;
class ContainerRequestUtil {
private static Map buildDevicesEnabledMap(final Account account) {
- return account.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::isEnabled));
+ return account.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::hasMessageDeliveryChannel));
}
/**
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/OptionalAccess.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/OptionalAccess.java
index 9a6edb87b..21435bbe9 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/auth/OptionalAccess.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/OptionalAccess.java
@@ -31,7 +31,7 @@ public class OptionalAccess {
Optional targetDevice = targetAccount.get().getDevice(deviceId);
- if (targetDevice.isPresent() && targetDevice.get().isEnabled()) {
+ if (targetDevice.isPresent() && targetDevice.get().hasMessageDeliveryChannel()) {
return;
}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java
index f5b1f636c..2c517902c 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java
@@ -440,11 +440,11 @@ public class KeysController {
private List parseDeviceId(String deviceId, Account account) {
if (deviceId.equals("*")) {
- return account.getDevices().stream().filter(Device::isEnabled).toList();
+ return account.getDevices().stream().filter(Device::hasMessageDeliveryChannel).toList();
}
try {
byte id = Byte.parseByte(deviceId);
- return account.getDevice(id).filter(Device::isEnabled).map(List::of).orElse(List.of());
+ return account.getDevice(id).filter(Device::hasMessageDeliveryChannel).map(List::of).orElse(List.of());
} catch (NumberFormatException e) {
throw new WebApplicationException(Response.status(422).build());
}
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcHelper.java b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcHelper.java
index 249e234c2..792e31a90 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcHelper.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcHelper.java
@@ -39,7 +39,7 @@ class KeysGrpcHelper {
: Flux.from(Mono.justOrEmpty(targetAccount.getDevice(targetDeviceId)));
return devices
- .filter(Device::isEnabled)
+ .filter(Device::hasMessageDeliveryChannel)
.switchIfEmpty(Mono.error(Status.NOT_FOUND.asException()))
.flatMap(device -> Flux.merge(
Mono.fromFuture(() -> keysManager.takeEC(targetAccount.getIdentifier(identityType), device.getId())),
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java
index 77660d489..87009c56c 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java
@@ -296,14 +296,14 @@ public class Account {
requireNotStale();
return devices.stream()
- .filter(Device::isEnabled)
+ .filter(Device::hasMessageDeliveryChannel)
.allMatch(device -> device.getCapabilities() != null && predicate.test(device.getCapabilities()));
}
public boolean isEnabled() {
requireNotStale();
- return getPrimaryDevice().isEnabled();
+ return getPrimaryDevice().hasMessageDeliveryChannel();
}
public byte getNextDeviceId() {
@@ -327,7 +327,7 @@ public class Account {
return devices.stream()
.filter(d -> Device.PRIMARY_ID != d.getId())
- .anyMatch(Device::isEnabled);
+ .anyMatch(Device::hasMessageDeliveryChannel);
}
public void setIdentityKey(final IdentityKey identityKey) {
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java
index 1e74a04d5..52cc6917c 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java
@@ -490,7 +490,7 @@ public class AccountsManager {
account.getDevices()
.stream()
- .filter(Device::isEnabled)
+ .filter(Device::hasMessageDeliveryChannel)
.forEach(device -> device.setPhoneNumberIdentityRegistrationId(pniRegistrationIds.get(device.getId())));
account.setPhoneNumberIdentityKey(pniIdentityKey);
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java
index a7f1c759f..db41de17e 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java
@@ -11,7 +11,6 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.Duration;
import java.util.List;
import java.util.OptionalInt;
-import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.Nullable;
@@ -199,10 +198,8 @@ public class Device {
this.capabilities = capabilities;
}
- public boolean isEnabled() {
- boolean hasChannel = fetchesMessages || StringUtils.isNotEmpty(getApnId()) || StringUtils.isNotEmpty(getGcmId());
-
- return (id == PRIMARY_ID && hasChannel) || (id != PRIMARY_ID && hasChannel && !isExpired());
+ public boolean hasMessageDeliveryChannel() {
+ return fetchesMessages || StringUtils.isNotEmpty(getApnId()) || StringUtils.isNotEmpty(getGcmId());
}
public boolean isExpired() {
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/MessagePersister.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/MessagePersister.java
index d189f352d..fc1a515ef 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/MessagePersister.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/MessagePersister.java
@@ -245,7 +245,7 @@ public class MessagePersister implements Managed {
// its messages) is unlinked
final Device deviceToDelete = account.getDevices()
.stream()
- .filter(d -> !d.isPrimary() && !d.isEnabled())
+ .filter(d -> !d.isPrimary() && !d.hasMessageDeliveryChannel())
.min(Comparator.comparing(Device::getLastSeen))
.or(() ->
Flux.fromIterable(account.getDevices())
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidator.java b/service/src/main/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidator.java
index 38c8c43c4..c13cfced1 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidator.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidator.java
@@ -89,7 +89,7 @@ public class DestinationDeviceValidator {
final Set excludedDeviceIds) throws MismatchedDevicesException {
final Set accountDeviceIds = account.getDevices().stream()
- .filter(Device::isEnabled)
+ .filter(Device::hasMessageDeliveryChannel)
.map(Device::getId)
.filter(deviceId -> !excludedDeviceIds.contains(deviceId))
.collect(Collectors.toSet());
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommand.java b/service/src/main/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommand.java
index 04f7a42fd..2dcf0fedc 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommand.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommand.java
@@ -130,7 +130,7 @@ public class ProcessPushNotificationFeedbackCommand extends AbstractSinglePassCr
@VisibleForTesting
boolean deviceNeedsUpdate(final Device device) {
- return pushFeedbackIntervalElapsed(device) && (device.isEnabled() || device.getLastSeen() > device.getUninstalledFeedbackTimestamp());
+ return pushFeedbackIntervalElapsed(device) && (device.hasMessageDeliveryChannel() || device.getLastSeen() > device.getUninstalledFeedbackTimestamp());
}
@VisibleForTesting
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticatorTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticatorTest.java
index c54f5bd17..19071dde3 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticatorTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticatorTest.java
@@ -163,7 +163,7 @@ class AccountAuthenticatorTest {
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@@ -193,7 +193,7 @@ class AccountAuthenticatorTest {
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@@ -226,7 +226,7 @@ class AccountAuthenticatorTest {
when(account.getDevice(deviceId)).thenReturn(Optional.of(authenticatedDevice));
when(account.isEnabled()).thenReturn(accountEnabled);
when(authenticatedDevice.getId()).thenReturn(deviceId);
- when(authenticatedDevice.isEnabled()).thenReturn(deviceEnabled);
+ when(authenticatedDevice.hasMessageDeliveryChannel()).thenReturn(deviceEnabled);
when(authenticatedDevice.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@@ -262,7 +262,7 @@ class AccountAuthenticatorTest {
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.Version.V1);
@@ -299,7 +299,7 @@ class AccountAuthenticatorTest {
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
@@ -327,7 +327,7 @@ class AccountAuthenticatorTest {
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getAuthTokenHash()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
when(credentials.getVersion()).thenReturn(SaltedTokenHash.CURRENT_VERSION);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProviderTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProviderTest.java
index bc3a913e2..aa4e07336 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProviderTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/auth/AuthEnablementRefreshRequirementProviderTest.java
@@ -136,7 +136,7 @@ class AuthEnablementRefreshRequirementProviderTest {
void testDeviceEnabledChanged(final Map initialEnabled, final Map finalEnabled) {
assert initialEnabled.size() == finalEnabled.size();
- assert account.getPrimaryDevice().isEnabled();
+ assert account.getPrimaryDevice().hasMessageDeliveryChannel();
initialEnabled.forEach((deviceId, enabled) ->
DevicesHelper.setEnabled(account.getDevice(deviceId).orElseThrow(), enabled));
@@ -177,7 +177,7 @@ class AuthEnablementRefreshRequirementProviderTest {
@Test
void testDeviceAdded() {
- assert account.getPrimaryDevice().isEnabled();
+ assert account.getPrimaryDevice().hasMessageDeliveryChannel();
final int initialDeviceCount = account.getDevices().size();
@@ -204,7 +204,7 @@ class AuthEnablementRefreshRequirementProviderTest {
@ParameterizedTest
@ValueSource(ints = {1, 2})
void testDeviceRemoved(final int removedDeviceCount) {
- assert account.getPrimaryDevice().isEnabled();
+ assert account.getPrimaryDevice().hasMessageDeliveryChannel();
final List initialDeviceIds = account.getDevices().stream().map(Device::getId).toList();
@@ -367,7 +367,7 @@ class AuthEnablementRefreshRequirementProviderTest {
DevicesHelper.setEnabled(device, enabled);
- assert device.isEnabled() == enabled;
+ assert device.hasMessageDeliveryChannel() == enabled;
return String.format("Set account to %s", enabled);
}
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtilTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtilTest.java
index e0a87d3f0..cef8b85a2 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtilTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/auth/ContainerRequestUtilTest.java
@@ -35,7 +35,7 @@ public class ContainerRequestUtilTest {
.forEach(id -> {
final Device device = mock(Device.class);
when(device.getId()).thenReturn((byte) id);
- when(device.isEnabled()).thenReturn(id != disabledDeviceId);
+ when(device.hasMessageDeliveryChannel()).thenReturn(id != disabledDeviceId);
devices.add(device);
});
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/KeysControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/KeysControllerTest.java
index 25b03efb4..27bab634c 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/KeysControllerTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/KeysControllerTest.java
@@ -221,10 +221,10 @@ 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.isEnabled()).thenReturn(true);
- when(sampleDevice2.isEnabled()).thenReturn(true);
- when(sampleDevice3.isEnabled()).thenReturn(false);
- when(sampleDevice4.isEnabled()).thenReturn(true);
+ 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);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java
index e6f2407d4..bc6cc87f5 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java
@@ -58,7 +58,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -211,13 +210,13 @@ class MessageControllerTest {
@BeforeEach
void setup() {
final List singleDeviceList = List.of(
- generateTestDevice(SINGLE_DEVICE_ID1, SINGLE_DEVICE_REG_ID1, SINGLE_DEVICE_PNI_REG_ID1, System.currentTimeMillis(), System.currentTimeMillis())
+ generateTestDevice(SINGLE_DEVICE_ID1, SINGLE_DEVICE_REG_ID1, SINGLE_DEVICE_PNI_REG_ID1, true)
);
final List multiDeviceList = List.of(
- generateTestDevice(MULTI_DEVICE_ID1, MULTI_DEVICE_REG_ID1, MULTI_DEVICE_PNI_REG_ID1, System.currentTimeMillis(), System.currentTimeMillis()),
- generateTestDevice(MULTI_DEVICE_ID2, MULTI_DEVICE_REG_ID2, MULTI_DEVICE_PNI_REG_ID2, System.currentTimeMillis(), System.currentTimeMillis()),
- generateTestDevice(MULTI_DEVICE_ID3, MULTI_DEVICE_REG_ID3, MULTI_DEVICE_PNI_REG_ID3, System.currentTimeMillis(), System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31))
+ generateTestDevice(MULTI_DEVICE_ID1, MULTI_DEVICE_REG_ID1, MULTI_DEVICE_PNI_REG_ID1, true),
+ generateTestDevice(MULTI_DEVICE_ID2, MULTI_DEVICE_REG_ID2, MULTI_DEVICE_PNI_REG_ID2, true),
+ generateTestDevice(MULTI_DEVICE_ID3, MULTI_DEVICE_REG_ID3, MULTI_DEVICE_PNI_REG_ID3, false)
);
Account singleDeviceAccount = AccountsHelper.generateTestAccount(SINGLE_DEVICE_RECIPIENT, SINGLE_DEVICE_UUID, SINGLE_DEVICE_PNI, singleDeviceList, UNIDENTIFIED_ACCESS_BYTES);
@@ -260,14 +259,12 @@ class MessageControllerTest {
}
private static Device generateTestDevice(final byte id, final int registrationId, final int pniRegistrationId,
- final long createdAt, final long lastSeen) {
+ final boolean enabled) {
final Device device = new Device();
device.setId(id);
device.setRegistrationId(registrationId);
device.setPhoneNumberIdentityRegistrationId(pniRegistrationId);
- device.setCreated(createdAt);
- device.setLastSeen(lastSeen);
- device.setGcmId("isgcm");
+ device.setFetchesMessages(enabled);
return device;
}
@@ -1125,8 +1122,7 @@ class MessageControllerTest {
IntStream.range(1, devicesPerRecipient + 1)
.mapToObj(
d -> generateTestDevice(
- (byte) d, 100 + d, 10 * d, System.currentTimeMillis(),
- System.currentTimeMillis()))
+ (byte) d, 100 + d, 10 * d, true))
.collect(Collectors.toList());
final UUID aci = new UUID(0L, (long) i);
final UUID pni = new UUID(1L, (long) i);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcServiceTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcServiceTest.java
index ff89cd503..748820eac 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcServiceTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/KeysGrpcServiceTest.java
@@ -489,7 +489,7 @@ class KeysGrpcServiceTest extends SimpleBaseGrpcTest testHasEnabledLinkedDevice() {
final Device enabledPrimary = mock(Device.class);
- when(enabledPrimary.isEnabled()).thenReturn(true);
+ when(enabledPrimary.hasMessageDeliveryChannel()).thenReturn(true);
when(enabledPrimary.getId()).thenReturn(Device.PRIMARY_ID);
final Device disabledPrimary = mock(Device.class);
@@ -304,7 +304,7 @@ class AccountTest {
final byte linked1DeviceId = Device.PRIMARY_ID + 1;
final Device enabledLinked1 = mock(Device.class);
- when(enabledLinked1.isEnabled()).thenReturn(true);
+ when(enabledLinked1.hasMessageDeliveryChannel()).thenReturn(true);
when(enabledLinked1.getId()).thenReturn(linked1DeviceId);
final Device disabledLinked1 = mock(Device.class);
@@ -312,7 +312,7 @@ class AccountTest {
final byte linked2DeviceId = Device.PRIMARY_ID + 2;
final Device enabledLinked2 = mock(Device.class);
- when(enabledLinked2.isEnabled()).thenReturn(true);
+ when(enabledLinked2.hasMessageDeliveryChannel()).thenReturn(true);
when(enabledLinked2.getId()).thenReturn(linked2DeviceId);
final Device disabledLinked2 = mock(Device.class);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java
index 0d895efd3..1238e8904 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/ChangeNumberManagerTest.java
@@ -134,7 +134,7 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
- when(d2.isEnabled()).thenReturn(true);
+ when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@@ -181,7 +181,7 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
- when(d2.isEnabled()).thenReturn(true);
+ when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@@ -228,7 +228,7 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
- when(d2.isEnabled()).thenReturn(true);
+ when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@@ -273,7 +273,7 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
- when(d2.isEnabled()).thenReturn(true);
+ when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@@ -316,7 +316,7 @@ public class ChangeNumberManagerTest {
when(account.getPhoneNumberIdentifier()).thenReturn(pni);
final Device d2 = mock(Device.class);
- when(d2.isEnabled()).thenReturn(true);
+ when(d2.hasMessageDeliveryChannel()).thenReturn(true);
final byte deviceId2 = 2;
when(d2.getId()).thenReturn(deviceId2);
@@ -361,7 +361,7 @@ public class ChangeNumberManagerTest {
for (byte i = 1; i <= 3; i++) {
final Device device = mock(Device.class);
when(device.getId()).thenReturn(i);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getRegistrationId()).thenReturn((int) i);
devices.add(device);
@@ -400,7 +400,7 @@ public class ChangeNumberManagerTest {
for (byte i = 1; i <= 3; i++) {
final Device device = mock(Device.class);
when(device.getId()).thenReturn(i);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getRegistrationId()).thenReturn((int) i);
devices.add(device);
@@ -439,7 +439,7 @@ public class ChangeNumberManagerTest {
for (byte i = 1; i <= 3; i++) {
final Device device = mock(Device.class);
when(device.getId()).thenReturn(i);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getRegistrationId()).thenReturn((int) i);
devices.add(device);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/DeviceTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/DeviceTest.java
index 87529d7c7..9619abe48 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/DeviceTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/DeviceTest.java
@@ -19,41 +19,22 @@ class DeviceTest {
@ParameterizedTest
@MethodSource
- void testIsEnabled(final boolean primary, final boolean fetchesMessages, final String apnId, final String gcmId,
- final Duration timeSinceLastSeen, final boolean expectEnabled) {
-
- final long lastSeen = System.currentTimeMillis() - timeSinceLastSeen.toMillis();
+ void testHasMessageDeliveryChannel(final boolean fetchesMessages, final String apnId, final String gcmId, final boolean expectEnabled) {
final Device device = new Device();
- device.setId(primary ? Device.PRIMARY_ID : Device.PRIMARY_ID + 1);
device.setFetchesMessages(fetchesMessages);
device.setApnId(apnId);
device.setGcmId(gcmId);
- device.setCreated(lastSeen);
- device.setLastSeen(lastSeen);
- assertEquals(expectEnabled, device.isEnabled());
+ assertEquals(expectEnabled, device.hasMessageDeliveryChannel());
}
- private static Stream testIsEnabled() {
+ private static Stream testHasMessageDeliveryChannel() {
return Stream.of(
- // primary fetchesMessages apnId gcmId lastSeen expectEnabled
- Arguments.of(true, false, null, null, Duration.ofDays(60), false),
- Arguments.of(true, false, null, null, Duration.ofDays(1), false),
- Arguments.of(true, false, null, "gcm-id", Duration.ofDays(60), true),
- Arguments.of(true, false, null, "gcm-id", Duration.ofDays(1), true),
- Arguments.of(true, false, "apn-id", null, Duration.ofDays(60), true),
- Arguments.of(true, false, "apn-id", null, Duration.ofDays(1), true),
- Arguments.of(true, true, null, null, Duration.ofDays(60), true),
- Arguments.of(true, true, null, null, Duration.ofDays(1), true),
- Arguments.of(false, false, null, null, Duration.ofDays(60), false),
- Arguments.of(false, false, null, null, Duration.ofDays(1), false),
- Arguments.of(false, false, null, "gcm-id", Duration.ofDays(60), false),
- Arguments.of(false, false, null, "gcm-id", Duration.ofDays(1), true),
- Arguments.of(false, false, "apn-id", null, Duration.ofDays(60), false),
- Arguments.of(false, false, "apn-id", null, Duration.ofDays(1), true),
- Arguments.of(false, true, null, null, Duration.ofDays(60), false),
- Arguments.of(false, true, null, null, Duration.ofDays(1), true)
+ 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)
);
}
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/MessagePersisterTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/MessagePersisterTest.java
index 4bfb7bbcc..716311a39 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/MessagePersisterTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/MessagePersisterTest.java
@@ -258,23 +258,23 @@ class MessagePersisterTest {
final Device primary = mock(Device.class);
when(primary.getId()).thenReturn((byte) 1);
when(primary.isPrimary()).thenReturn(true);
- when(primary.isEnabled()).thenReturn(true);
+ when(primary.hasMessageDeliveryChannel()).thenReturn(true);
final Device activeA = mock(Device.class);
when(activeA.getId()).thenReturn((byte) 2);
- when(activeA.isEnabled()).thenReturn(true);
+ when(activeA.hasMessageDeliveryChannel()).thenReturn(true);
final Device inactiveB = mock(Device.class);
final byte inactiveId = 3;
when(inactiveB.getId()).thenReturn(inactiveId);
- when(inactiveB.isEnabled()).thenReturn(false);
+ when(inactiveB.hasMessageDeliveryChannel()).thenReturn(false);
final Device inactiveC = mock(Device.class);
when(inactiveC.getId()).thenReturn((byte) 4);
- when(inactiveC.isEnabled()).thenReturn(false);
+ when(inactiveC.hasMessageDeliveryChannel()).thenReturn(false);
final Device activeD = mock(Device.class);
when(activeD.getId()).thenReturn((byte) 5);
- when(activeD.isEnabled()).thenReturn(true);
+ when(activeD.hasMessageDeliveryChannel()).thenReturn(true);
final Device destination = mock(Device.class);
when(destination.getId()).thenReturn(DESTINATION_DEVICE_ID);
- when(destination.isEnabled()).thenReturn(true);
+ when(destination.hasMessageDeliveryChannel()).thenReturn(true);
when(destinationAccount.getDevices()).thenReturn(List.of(primary, activeA, inactiveB, inactiveC, activeD, destination));
@@ -302,27 +302,27 @@ class MessagePersisterTest {
final byte primaryId = 1;
when(primary.getId()).thenReturn(primaryId);
when(primary.isPrimary()).thenReturn(true);
- when(primary.isEnabled()).thenReturn(true);
+ when(primary.hasMessageDeliveryChannel()).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.isEnabled()).thenReturn(true);
+ when(deviceA.hasMessageDeliveryChannel()).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.isEnabled()).thenReturn(true);
+ when(deviceB.hasMessageDeliveryChannel()).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.isEnabled()).thenReturn(true);
+ when(destination.hasMessageDeliveryChannel()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(destination)))
.thenReturn(Mono.just(5L));
@@ -352,27 +352,27 @@ class MessagePersisterTest {
final byte primaryId = 1;
when(primary.getId()).thenReturn(primaryId);
when(primary.isPrimary()).thenReturn(true);
- when(primary.isEnabled()).thenReturn(true);
+ when(primary.hasMessageDeliveryChannel()).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.isEnabled()).thenReturn(true);
+ when(deviceA.hasMessageDeliveryChannel()).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.isEnabled()).thenReturn(true);
+ when(deviceB.hasMessageDeliveryChannel()).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.isEnabled()).thenReturn(true);
+ when(destination.hasMessageDeliveryChannel()).thenReturn(true);
when(messagesManager.getEarliestUndeliveredTimestampForDevice(any(), eq(destination)))
.thenReturn(Mono.just(2L));
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java
index 3a0786575..ec39cc176 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java
@@ -138,11 +138,11 @@ 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.isEnabled()).thenReturn(true);
- when(VALID_DEVICE_TWO.isEnabled()).thenReturn(true);
+ when(VALID_DEVICE.hasMessageDeliveryChannel()).thenReturn(true);
+ when(VALID_DEVICE_TWO.hasMessageDeliveryChannel()).thenReturn(true);
when(UNDISCOVERABLE_DEVICE.isPrimary()).thenReturn(true);
- when(VALID_DEVICE_3_PRIMARY.isEnabled()).thenReturn(true);
- when(VALID_DEVICE_3_LINKED.isEnabled()).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);
@@ -279,7 +279,7 @@ public class AuthHelper {
when(device.getAuthTokenHash()).thenReturn(saltedTokenHash);
when(device.isPrimary()).thenReturn(true);
when(device.getId()).thenReturn(Device.PRIMARY_ID);
- when(device.isEnabled()).thenReturn(true);
+ 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);
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/DevicesHelper.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/DevicesHelper.java
index 82d837e8f..1f5181553 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/DevicesHelper.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/util/DevicesHelper.java
@@ -6,9 +6,7 @@
package org.whispersystems.textsecuregcm.tests.util;
import java.util.Random;
-import org.signal.libsignal.protocol.ecc.Curve;
import org.whispersystems.textsecuregcm.storage.Device;
-import org.whispersystems.textsecuregcm.util.Util;
public class DevicesHelper {
@@ -48,13 +46,12 @@ public class DevicesHelper {
public static void setEnabled(Device device, boolean enabled) {
if (enabled) {
device.setGcmId("testGcmId" + RANDOM.nextLong());
- device.setLastSeen(Util.todayInMillis());
} else {
- device.setLastSeen(0);
+ device.setGcmId(null);
}
// fail fast, to guard against a change to the isEnabled() implementation causing unexpected test behavior
- assert enabled == device.isEnabled();
+ assert enabled == device.hasMessageDeliveryChannel();
}
}
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidatorTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidatorTest.java
index b78c6a71a..b80a8f3f4 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidatorTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/util/DestinationDeviceValidatorTest.java
@@ -107,7 +107,7 @@ class DestinationDeviceValidatorTest {
enabledStateByDeviceId.forEach((deviceId, enabled) -> {
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(enabled);
+ when(device.hasMessageDeliveryChannel()).thenReturn(enabled);
when(device.getId()).thenReturn(deviceId);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommandTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommandTest.java
index ca498c49d..95eee6b32 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommandTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/workers/ProcessPushNotificationFeedbackCommandTest.java
@@ -98,7 +98,7 @@ class ProcessPushNotificationFeedbackCommandTest {
final Account accountWithActiveDevice = mock(Account.class);
{
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(accountWithActiveDevice.getDevices()).thenReturn(List.of(device));
}
@@ -106,7 +106,7 @@ class ProcessPushNotificationFeedbackCommandTest {
final Account accountWithUninstalledDevice = mock(Account.class);
{
final Device uninstalledDevice = mock(Device.class);
- when(uninstalledDevice.isEnabled()).thenReturn(true);
+ when(uninstalledDevice.hasMessageDeliveryChannel()).thenReturn(true);
when(uninstalledDevice.getUninstalledFeedbackTimestamp())
.thenReturn(clock.instant().minus(ProcessPushNotificationFeedbackCommand.MAX_TOKEN_REFRESH_DELAY.multipliedBy(2)).toEpochMilli());
@@ -116,7 +116,7 @@ class ProcessPushNotificationFeedbackCommandTest {
final Account accountWithAlreadyDisabledUninstalledDevice = mock(Account.class);
{
final Device previouslyDisabledUninstalledDevice = mock(Device.class);
- when(previouslyDisabledUninstalledDevice.isEnabled()).thenReturn(false);
+ when(previouslyDisabledUninstalledDevice.hasMessageDeliveryChannel()).thenReturn(false);
when(previouslyDisabledUninstalledDevice.getUninstalledFeedbackTimestamp())
.thenReturn(clock.instant().minus(ProcessPushNotificationFeedbackCommand.MAX_TOKEN_REFRESH_DELAY.multipliedBy(2)).toEpochMilli());
@@ -196,7 +196,7 @@ class ProcessPushNotificationFeedbackCommandTest {
{
// Device is active, enabled, and has no push feedback
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getUninstalledFeedbackTimestamp()).thenReturn(0L);
when(device.getLastSeen()).thenReturn(CURRENT_TIME.toEpochMilli());
@@ -206,7 +206,7 @@ class ProcessPushNotificationFeedbackCommandTest {
{
// Device is active, but not enabled, and has no push feedback
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(false);
+ when(device.hasMessageDeliveryChannel()).thenReturn(false);
when(device.getUninstalledFeedbackTimestamp()).thenReturn(0L);
when(device.getLastSeen()).thenReturn(CURRENT_TIME.toEpochMilli());
@@ -216,7 +216,7 @@ class ProcessPushNotificationFeedbackCommandTest {
{
// Device is active, enabled, and has "mature" push feedback
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(true);
+ when(device.hasMessageDeliveryChannel()).thenReturn(true);
when(device.getUninstalledFeedbackTimestamp()).thenReturn(maturePushFeedbackTimestamp);
when(device.getLastSeen()).thenReturn(CURRENT_TIME.toEpochMilli());
@@ -226,7 +226,7 @@ class ProcessPushNotificationFeedbackCommandTest {
{
// Device is active, but not enabled, and has "mature" push feedback
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(false);
+ when(device.hasMessageDeliveryChannel()).thenReturn(false);
when(device.getUninstalledFeedbackTimestamp()).thenReturn(maturePushFeedbackTimestamp);
when(device.getLastSeen()).thenReturn(CURRENT_TIME.toEpochMilli());
@@ -236,7 +236,7 @@ class ProcessPushNotificationFeedbackCommandTest {
{
// Device is inactive, not enabled, and has "mature" push feedback
final Device device = mock(Device.class);
- when(device.isEnabled()).thenReturn(false);
+ when(device.hasMessageDeliveryChannel()).thenReturn(false);
when(device.getUninstalledFeedbackTimestamp()).thenReturn(maturePushFeedbackTimestamp);
when(device.getLastSeen()).thenReturn(maturePushFeedbackTimestamp);