Retire `paymentActivation` capability

This commit is contained in:
Katherine 2024-10-08 16:01:09 -04:00 committed by GitHub
parent d550c69f7f
commit 93515e5a0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 35 additions and 86 deletions

View File

@ -126,7 +126,7 @@ public class TestUser {
}
public AccountAttributes accountAttributes() {
return new AccountAttributes(true, registrationId, pniRegistrationId, "".getBytes(StandardCharsets.UTF_8), "", true, new Device.DeviceCapabilities(false, false, false, false, false))
return new AccountAttributes(true, registrationId, pniRegistrationId, "".getBytes(StandardCharsets.UTF_8), "", true, new Device.DeviceCapabilities(false, false, false, false))
.withUnidentifiedAccessKey(unidentifiedAccessKey)
.withRecoveryPassword(registrationPassword);
}

View File

@ -8,13 +8,11 @@ package org.whispersystems.textsecuregcm.entities;
import org.whispersystems.textsecuregcm.storage.Account;
public record UserCapabilities(
// TODO: Remove the paymentActivation capability entirely sometime soon after 2024-10-07
boolean paymentActivation,
boolean deleteSync,
boolean versionedExpirationTimer) {
public static UserCapabilities createForAccount(final Account account) {
return new UserCapabilities(true, account.isDeleteSyncSupported(),
return new UserCapabilities(account.isDeleteSyncSupported(),
account.isVersionedExpirationTimerSupported());
}
}

View File

@ -191,7 +191,6 @@ public class DevicesGrpcService extends ReactorDevicesGrpc.DevicesImplBase {
d -> d.setCapabilities(new Device.DeviceCapabilities(
request.getStorage(),
request.getTransfer(),
request.getPaymentActivation(),
request.getDeleteSync(),
request.getVersionedExpirationTimer())))))
.thenReturn(SetCapabilitiesResponse.newBuilder().build());

View File

@ -82,7 +82,6 @@ public class ProfileGrpcHelper {
@VisibleForTesting
static UserCapabilities buildUserCapabilities(final org.whispersystems.textsecuregcm.entities.UserCapabilities capabilities) {
return UserCapabilities.newBuilder()
.setPaymentActivation(capabilities.paymentActivation())
.setDeleteSync(capabilities.deleteSync())
.setVersionedExpirationTimer(capabilities.versionedExpirationTimer())
.build();

View File

@ -288,10 +288,6 @@ public class Account {
.orElse(false);
}
public boolean isPaymentActivationSupported() {
return allDevicesHaveCapability(DeviceCapabilities::paymentActivation);
}
public boolean isDeleteSyncSupported() {
return allDevicesHaveCapability(DeviceCapabilities::deleteSync);
}

View File

@ -221,7 +221,7 @@ public class Device {
return this.userAgent;
}
public record DeviceCapabilities(boolean storage, boolean transfer, boolean paymentActivation, boolean deleteSync,
public record DeviceCapabilities(boolean storage, boolean transfer, boolean deleteSync,
boolean versionedExpirationTimer) {
}
}

View File

@ -140,9 +140,8 @@ message ClearPushTokenResponse {}
message SetCapabilitiesRequest {
bool storage = 1;
bool transfer = 2;
bool paymentActivation = 3;
bool deleteSync = 4;
bool versionedExpirationTimer = 5;
bool deleteSync = 3;
bool versionedExpirationTimer = 4;
}
message SetCapabilitiesResponse {}

View File

@ -318,18 +318,14 @@ message ProfileAvatarUploadAttributes {
}
message UserCapabilities {
/**
* Whether all devices linked to the account support MobileCoin payments.
*/
bool payment_activation = 1;
/**
* Whether all devices linked to the account support delete syncing
*/
bool delete_sync = 2;
bool delete_sync = 1;
/**
* Whether all devices linked to the account support a versioned expiration timer
*/
bool versioned_expiration_timer = 3;
bool versioned_expiration_timer = 2;
}
message Badge {

View File

@ -129,7 +129,6 @@ class DeviceControllerTest {
when(account.getNumber()).thenReturn(AuthHelper.VALID_NUMBER);
when(account.getUuid()).thenReturn(AuthHelper.VALID_UUID);
when(account.getPhoneNumberIdentifier()).thenReturn(AuthHelper.VALID_PNI);
when(account.isPaymentActivationSupported()).thenReturn(false);
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
when(accountsManager.getByE164(AuthHelper.VALID_NUMBER)).thenReturn(Optional.of(account));
@ -199,7 +198,7 @@ class DeviceControllerTest {
when(asyncCommands.set(any(), any(), any())).thenReturn(MockRedisFuture.completedFuture(null));
final AccountAttributes accountAttributes = new AccountAttributes(fetchesMessages, 1234, 5678, null,
null, true, new DeviceCapabilities(true, true, true, false, false));
null, true, new DeviceCapabilities(true, true, false, false));
final LinkDeviceRequest request = new LinkDeviceRequest("link-device-token",
accountAttributes,
@ -272,7 +271,7 @@ class DeviceControllerTest {
when(accountsManager.checkDeviceLinkingToken(anyString())).thenReturn(Optional.of(AuthHelper.VALID_UUID));
final LinkDeviceRequest request = new LinkDeviceRequest("link-device-token",
new AccountAttributes(false, 1234, 5678, null, null, true, new DeviceCapabilities(true, true, true, deviceSupportsDeleteSync, false)),
new AccountAttributes(false, 1234, 5678, null, null, true, new DeviceCapabilities(true, true, deviceSupportsDeleteSync, false)),
new DeviceActivationRequest(aciSignedPreKey, pniSignedPreKey, aciPqLastResortPreKey, pniPqLastResortPreKey, Optional.empty(), Optional.of(new GcmRegistrationId("gcm-id"))));
try (final Response response = resources.getJerseyTest()
@ -327,7 +326,7 @@ class DeviceControllerTest {
when(accountsManager.checkDeviceLinkingToken(anyString())).thenReturn(Optional.of(AuthHelper.VALID_UUID));
final LinkDeviceRequest request = new LinkDeviceRequest("link-device-token",
new AccountAttributes(false, 1234, 5678, null, null, true, new DeviceCapabilities(true, true, true, deviceSupportsVersionedExpirationTimer, false)),
new AccountAttributes(false, 1234, 5678, null, null, true, new DeviceCapabilities(true, true, deviceSupportsVersionedExpirationTimer, false)),
new DeviceActivationRequest(aciSignedPreKey, pniSignedPreKey, aciPqLastResortPreKey, pniPqLastResortPreKey, Optional.empty(), Optional.of(new GcmRegistrationId("gcm-id"))));
try (final Response response = resources.getJerseyTest()
@ -416,7 +415,7 @@ class DeviceControllerTest {
when(asyncCommands.set(any(), any(), any())).thenReturn(MockRedisFuture.completedFuture(null));
final AccountAttributes accountAttributes = new AccountAttributes(true, 1234, 5678, null,
null, true, new DeviceCapabilities(true, true, true, false, false));
null, true, new DeviceCapabilities(true, true, false, false));
final LinkDeviceRequest request = new LinkDeviceRequest("link-device-token",
accountAttributes,
@ -750,7 +749,7 @@ class DeviceControllerTest {
when(asyncCommands.set(any(), any(), any())).thenReturn(MockRedisFuture.completedFuture(null));
final LinkDeviceRequest request = new LinkDeviceRequest("link-device-token",
new AccountAttributes(false, registrationId, pniRegistrationId, null, null, true, new DeviceCapabilities(true, true, true, false, false)),
new AccountAttributes(false, registrationId, pniRegistrationId, null, null, true, new DeviceCapabilities(true, true, false, false)),
new DeviceActivationRequest(aciSignedPreKey, pniSignedPreKey, aciPqLastResortPreKey, pniPqLastResortPreKey, Optional.of(new ApnRegistrationId("apn")), Optional.empty()));
try (final Response response = resources.getJerseyTest()
@ -809,7 +808,7 @@ class DeviceControllerTest {
@Test
void putCapabilitiesSuccessTest() {
final DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, false, false);
final DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, false, false);
final Response response = resources
.getJerseyTest()
.target("/v1/devices/capabilities")

View File

@ -454,7 +454,6 @@ class ProfileControllerTest {
assertEquals(isDeleteSyncSupported, profile.getCapabilities().deleteSync());
assertEquals(isVersionedExpirationTimerSupported, profile.getCapabilities().versionedExpirationTimer());
assertThat(profile.getCapabilities().paymentActivation()).isTrue();
}
@Test

View File

@ -526,10 +526,10 @@ class RegistrationControllerTest {
}
final AccountAttributes fetchesMessagesAccountAttributes =
new AccountAttributes(true, 1, 1, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false, false));
new AccountAttributes(true, 1, 1, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false));
final AccountAttributes pushAccountAttributes =
new AccountAttributes(false, 1, 1, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false, false));
new AccountAttributes(false, 1, 1, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false));
return Stream.of(
// "Fetches messages" is true, but an APNs token is provided
@ -615,7 +615,7 @@ class RegistrationControllerTest {
}
final AccountAttributes accountAttributes =
new AccountAttributes(true, 1, 1, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false, false));
new AccountAttributes(true, 1, 1, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false));
return Stream.of(
// Signed PNI EC pre-key is missing
@ -786,13 +786,13 @@ class RegistrationControllerTest {
final int registrationId = 1;
final int pniRegistrationId = 2;
final Device.DeviceCapabilities deviceCapabilities = new Device.DeviceCapabilities(false, false, false, false, false);
final Device.DeviceCapabilities deviceCapabilities = new Device.DeviceCapabilities(false, false, false, false);
final AccountAttributes fetchesMessagesAccountAttributes =
new AccountAttributes(true, registrationId, pniRegistrationId, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false, false));
new AccountAttributes(true, registrationId, pniRegistrationId, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false));
final AccountAttributes pushAccountAttributes =
new AccountAttributes(false, registrationId, pniRegistrationId, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false, false));
new AccountAttributes(false, registrationId, pniRegistrationId, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false));
final String apnsToken = "apns-token";
final String gcmToken = "gcm-token";
@ -906,7 +906,7 @@ class RegistrationControllerTest {
final IdentityKey pniIdentityKey = new IdentityKey(pniIdentityKeyPair.getPublicKey());
final AccountAttributes accountAttributes = new AccountAttributes(true, registrationId, pniRegistrationId, "name".getBytes(StandardCharsets.UTF_8), "reglock",
true, new Device.DeviceCapabilities(true, true, true, false, false));
true, new Device.DeviceCapabilities(true, true, false, false));
final RegistrationRequest request = new RegistrationRequest(
Base64.getEncoder().encodeToString(sessionId.getBytes(StandardCharsets.UTF_8)),

View File

@ -364,7 +364,6 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
@CartesianTest.Values(bytes = {Device.PRIMARY_ID, Device.PRIMARY_ID + 1}) final byte deviceId,
@CartesianTest.Values(booleans = {true, false}) final boolean storage,
@CartesianTest.Values(booleans = {true, false}) final boolean transfer,
@CartesianTest.Values(booleans = {true, false}) final boolean paymentActivation,
@CartesianTest.Values(booleans = {true, false}) final boolean deleteSync,
@CartesianTest.Values(booleans = {true, false}) final boolean versionedExpirationTimer) {
@ -376,7 +375,6 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
final SetCapabilitiesResponse ignored = authenticatedServiceStub().setCapabilities(SetCapabilitiesRequest.newBuilder()
.setStorage(storage)
.setTransfer(transfer)
.setPaymentActivation(paymentActivation)
.setDeleteSync(deleteSync)
.setVersionedExpirationTimer(versionedExpirationTimer)
.build());
@ -384,7 +382,6 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
final Device.DeviceCapabilities expectedCapabilities = new Device.DeviceCapabilities(
storage,
transfer,
paymentActivation,
deleteSync,
versionedExpirationTimer);

View File

@ -190,7 +190,6 @@ public class AccountCreationDeletionIntegrationTest {
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean());
final AccountAttributes accountAttributes = new AccountAttributes(deliveryChannels.fetchesMessages(),
@ -303,14 +302,14 @@ public class AccountCreationDeletionIntegrationTest {
final Account originalAccount = accountsManager.create(number,
new AccountAttributes(true, 1, 1, "name".getBytes(StandardCharsets.UTF_8), "registration-lock", false,
new Device.DeviceCapabilities(false, false, false, false, false)),
new Device.DeviceCapabilities(false, false, false, false)),
Collections.emptyList(),
new IdentityKey(aciKeyPair.getPublicKey()),
new IdentityKey(pniKeyPair.getPublicKey()),
new DeviceSpec(null,
"password?",
"OWI",
new Device.DeviceCapabilities(false, false, false, false, false),
new Device.DeviceCapabilities(false, false, false, false),
1,
2,
true,
@ -336,7 +335,6 @@ public class AccountCreationDeletionIntegrationTest {
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean());
final AccountAttributes accountAttributes = new AccountAttributes(deliveryChannels.fetchesMessages(),
@ -428,7 +426,6 @@ public class AccountCreationDeletionIntegrationTest {
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean(),
ThreadLocalRandom.current().nextBoolean());
final AccountAttributes accountAttributes = new AccountAttributes(true,

View File

@ -40,10 +40,6 @@ class AccountTest {
private final Device agingSecondaryDevice = mock(Device.class);
private final Device recentSecondaryDevice = mock(Device.class);
private final Device oldSecondaryDevice = mock(Device.class);
private final Device paymentActivationCapableDevice = mock(Device.class);
private final Device paymentActivationIncapableDevice = mock(Device.class);
private final Device paymentActivationIncapableDeviceWithoutDeliveryChannel = mock(Device.class);
private final Device deleteSyncCapableDevice = mock(Device.class);
private final Device deleteSyncIncapableDevice = mock(Device.class);
private final Device versionedExpirationTimerCapableDevice = mock(Device.class);
@ -67,33 +63,21 @@ class AccountTest {
when(oldSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
when(oldSecondaryDevice.getId()).thenReturn(deviceId2);
when(paymentActivationCapableDevice.getId()).thenReturn((byte) 1);
when(paymentActivationCapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, false, false));
when(paymentActivationIncapableDevice.getId()).thenReturn((byte) 2);
when(paymentActivationIncapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, false, false, false));
when(paymentActivationIncapableDeviceWithoutDeliveryChannel.getId()).thenReturn((byte) 3);
when(paymentActivationIncapableDeviceWithoutDeliveryChannel.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, false, false, false));
when(deleteSyncCapableDevice.getId()).thenReturn((byte) 1);
when(deleteSyncCapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, true, false));
.thenReturn(new DeviceCapabilities(true, true, true, false));
when(deleteSyncIncapableDevice.getId()).thenReturn((byte) 2);
when(deleteSyncIncapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, false, false));
.thenReturn(new DeviceCapabilities(true, true, false, false));
when(versionedExpirationTimerCapableDevice.getId()).thenReturn((byte) 1);
when(versionedExpirationTimerCapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, false, true));
.thenReturn(new DeviceCapabilities(true, true, false, true));
when(versionedExpirationTimerIncapableDevice.getId()).thenReturn((byte) 2);
when(versionedExpirationTimerIncapableDevice.getCapabilities())
.thenReturn(new DeviceCapabilities(true, true, true, false, false));
.thenReturn(new DeviceCapabilities(true, true, false, false));
}
@ -157,19 +141,6 @@ class AccountTest {
assertTrue(account.isDiscoverableByPhoneNumber());
}
@Test
void isPaymentActivationSupported() {
assertThat(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
List.of(paymentActivationCapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isPaymentActivationSupported()).isTrue();
assertThat(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
List.of(paymentActivationIncapableDevice, paymentActivationCapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isPaymentActivationSupported()).isFalse();
assertThat(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
List.of(paymentActivationIncapableDeviceWithoutDeliveryChannel, paymentActivationCapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isPaymentActivationSupported()).isFalse();
}
@Test
void isDeleteSyncSupported() {
assertTrue(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),

View File

@ -196,7 +196,7 @@ class AccountsManagerChangeNumberIntegrationTest {
final int rotatedPniRegistrationId = 17;
final ECKeyPair rotatedPniIdentityKeyPair = Curve.generateKeyPair();
final ECSignedPreKey rotatedSignedPreKey = KeysHelper.signedECPreKey(1L, rotatedPniIdentityKeyPair);
final AccountAttributes accountAttributes = new AccountAttributes(true, rotatedPniRegistrationId + 1, rotatedPniRegistrationId, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false, false));
final AccountAttributes accountAttributes = new AccountAttributes(true, rotatedPniRegistrationId + 1, rotatedPniRegistrationId, "test".getBytes(StandardCharsets.UTF_8), null, true, new Device.DeviceCapabilities(false, false, false, false));
final Account account = AccountsHelper.createAccount(accountsManager, originalNumber, accountAttributes);
keysManager.storeEcSignedPreKeys(account.getIdentifier(IdentityType.ACI),

View File

@ -159,7 +159,7 @@ class AccountsManagerConcurrentModificationIntegrationTest {
null,
"password",
null,
new Device.DeviceCapabilities(false, false, false, false, false),
new Device.DeviceCapabilities(false, false, false, false),
1,
2,
true,

View File

@ -917,7 +917,7 @@ class AccountsManagerTest {
@ValueSource(booleans = {true, false})
void testCreateWithStorageCapability(final boolean hasStorage) throws InterruptedException {
final AccountAttributes attributes = new AccountAttributes(false, 1, 2, null, null,
true, new DeviceCapabilities(hasStorage, false, false, false, false));
true, new DeviceCapabilities(hasStorage, false, false, false));
final Account account = createAccount("+18005550123", attributes);
@ -942,7 +942,7 @@ class AccountsManagerTest {
final byte[] deviceNameCiphertext = "device-name".getBytes(StandardCharsets.UTF_8);
final String password = "password";
final String signalAgent = "OWT";
final DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, false, false);
final DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, false, false);
final int aciRegistrationId = 17;
final int pniRegistrationId = 19;
final ECSignedPreKey aciSignedPreKey = KeysHelper.signedECPreKey(1, aciKeyPair);

View File

@ -177,7 +177,7 @@ public class AddRemoveDeviceIntegrationTest {
"device-name".getBytes(StandardCharsets.UTF_8),
"password",
"OWT",
new Device.DeviceCapabilities(true, true, true, false, false),
new Device.DeviceCapabilities(true, true, false, false),
1,
2,
true,
@ -223,7 +223,7 @@ public class AddRemoveDeviceIntegrationTest {
"device-name".getBytes(StandardCharsets.UTF_8),
"password",
"OWT",
new Device.DeviceCapabilities(true, true, true, false, false),
new Device.DeviceCapabilities(true, true, false, false),
1,
2,
true,
@ -245,7 +245,7 @@ public class AddRemoveDeviceIntegrationTest {
"device-name".getBytes(StandardCharsets.UTF_8),
"password",
"OWT",
new Device.DeviceCapabilities(true, true, true, false, false),
new Device.DeviceCapabilities(true, true, false, false),
1,
2,
true,
@ -282,7 +282,7 @@ public class AddRemoveDeviceIntegrationTest {
"device-name".getBytes(StandardCharsets.UTF_8),
"password",
"OWT",
new Device.DeviceCapabilities(true, true, true, false, false),
new Device.DeviceCapabilities(true, true, false, false),
1,
2,
true,
@ -336,7 +336,7 @@ public class AddRemoveDeviceIntegrationTest {
"device-name".getBytes(StandardCharsets.UTF_8),
"password",
"OWT",
new Device.DeviceCapabilities(true, true, true, false, false),
new Device.DeviceCapabilities(true, true, false, false),
1,
2,
true,

View File

@ -147,7 +147,6 @@ public class AccountsHelper {
case "getPrimaryDevice" -> when(updatedAccount.getPrimaryDevice()).thenAnswer(stubbing);
case "isDiscoverableByPhoneNumber" -> when(updatedAccount.isDiscoverableByPhoneNumber()).thenAnswer(stubbing);
case "getNextDeviceId" -> when(updatedAccount.getNextDeviceId()).thenAnswer(stubbing);
case "isPaymentActivationSupported" -> when(updatedAccount.isPaymentActivationSupported()).thenAnswer(stubbing);
case "isDeleteSyncSupported" -> when(updatedAccount.isDeleteSyncSupported()).thenAnswer(stubbing);
case "isVersionedExpirationTimerSupported" -> when(updatedAccount.isVersionedExpirationTimerSupported()).thenAnswer(stubbing);
case "getRegistrationLock" -> when(updatedAccount.getRegistrationLock()).thenAnswer(stubbing);