Remove groups v2 capability

* wip removing groups v2 capabilities

* comments

* finish removing groups v2 references

* hardcode gv1migration flag on user capability, remove other references
This commit is contained in:
katherine-signal 2022-11-21 09:31:47 -08:00 committed by GitHub
parent cb50b44d8f
commit fb4ed20ff5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 39 additions and 343 deletions

View File

@ -188,7 +188,7 @@ public class DeviceController {
} }
final DeviceCapabilities capabilities = accountAttributes.getCapabilities(); final DeviceCapabilities capabilities = accountAttributes.getCapabilities();
if (capabilities != null && isCapabilityDowngrade(account.get(), capabilities, userAgent)) { if (capabilities != null && isCapabilityDowngrade(account.get(), capabilities)) {
throw new WebApplicationException(Response.status(409).build()); throw new WebApplicationException(Response.status(409).build());
} }
@ -236,7 +236,7 @@ public class DeviceController {
return new VerificationCode(randomInt); return new VerificationCode(randomInt);
} }
private boolean isCapabilityDowngrade(Account account, DeviceCapabilities capabilities, String userAgent) { private boolean isCapabilityDowngrade(Account account, DeviceCapabilities capabilities) {
boolean isDowngrade = false; boolean isDowngrade = false;
isDowngrade |= account.isStoriesSupported() && !capabilities.isStories(); isDowngrade |= account.isStoriesSupported() && !capabilities.isStories();
@ -244,35 +244,8 @@ public class DeviceController {
isDowngrade |= account.isChangeNumberSupported() && !capabilities.isChangeNumber(); isDowngrade |= account.isChangeNumberSupported() && !capabilities.isChangeNumber();
isDowngrade |= account.isAnnouncementGroupSupported() && !capabilities.isAnnouncementGroup(); isDowngrade |= account.isAnnouncementGroupSupported() && !capabilities.isAnnouncementGroup();
isDowngrade |= account.isSenderKeySupported() && !capabilities.isSenderKey(); isDowngrade |= account.isSenderKeySupported() && !capabilities.isSenderKey();
isDowngrade |= account.isGv1MigrationSupported() && !capabilities.isGv1Migration();
isDowngrade |= account.isGiftBadgesSupported() && !capabilities.isGiftBadges(); isDowngrade |= account.isGiftBadgesSupported() && !capabilities.isGiftBadges();
if (account.isGroupsV2Supported()) {
try {
switch (UserAgentUtil.parseUserAgentString(userAgent).getPlatform()) {
case DESKTOP:
case ANDROID: {
if (!capabilities.isGv2_3()) {
isDowngrade = true;
}
break;
}
case IOS: {
if (!capabilities.isGv2_2() && !capabilities.isGv2_3()) {
isDowngrade = true;
}
break;
}
}
} catch (final UnrecognizedUserAgentException e) {
// If we can't parse the UA string, the client is for sure too old to support groups V2
isDowngrade = true;
}
}
return isDowngrade; return isDowngrade;
} }
} }

View File

@ -12,8 +12,7 @@ public class UserCapabilities {
public static UserCapabilities createForAccount(Account account) { public static UserCapabilities createForAccount(Account account) {
return new UserCapabilities( return new UserCapabilities(
account.isGroupsV2Supported(), true,
account.isGv1MigrationSupported(),
account.isSenderKeySupported(), account.isSenderKeySupported(),
account.isAnnouncementGroupSupported(), account.isAnnouncementGroupSupported(),
account.isChangeNumberSupported(), account.isChangeNumberSupported(),
@ -21,9 +20,6 @@ public class UserCapabilities {
account.isGiftBadgesSupported()); account.isGiftBadgesSupported());
} }
@JsonProperty
private boolean gv2;
@JsonProperty("gv1-migration") @JsonProperty("gv1-migration")
private boolean gv1Migration; private boolean gv1Migration;
@ -45,7 +41,7 @@ public class UserCapabilities {
public UserCapabilities() { public UserCapabilities() {
} }
public UserCapabilities(final boolean gv2, public UserCapabilities(
boolean gv1Migration, boolean gv1Migration,
final boolean senderKey, final boolean senderKey,
final boolean announcementGroup, final boolean announcementGroup,
@ -53,7 +49,6 @@ public class UserCapabilities {
final boolean stories, final boolean stories,
final boolean giftBadges) { final boolean giftBadges) {
this.gv2 = gv2;
this.gv1Migration = gv1Migration; this.gv1Migration = gv1Migration;
this.senderKey = senderKey; this.senderKey = senderKey;
this.announcementGroup = announcementGroup; this.announcementGroup = announcementGroup;
@ -62,10 +57,6 @@ public class UserCapabilities {
this.giftBadges = giftBadges; this.giftBadges = giftBadges;
} }
public boolean isGv2() {
return gv2;
}
public boolean isGv1Migration() { public boolean isGv1Migration() {
return gv1Migration; return gv1Migration;
} }

View File

@ -181,14 +181,6 @@ public class Account {
return devices.stream().filter(device -> device.getId() == deviceId).findFirst(); return devices.stream().filter(device -> device.getId() == deviceId).findFirst();
} }
public boolean isGroupsV2Supported() {
requireNotStale();
return devices.stream()
.filter(Device::isEnabled)
.allMatch(Device::isGroupsV2Supported);
}
public boolean isStorageSupported() { public boolean isStorageSupported() {
requireNotStale(); requireNotStale();
@ -201,10 +193,6 @@ public class Account {
return getMasterDevice().map(Device::getCapabilities).map(Device.DeviceCapabilities::isTransfer).orElse(false); return getMasterDevice().map(Device::getCapabilities).map(Device.DeviceCapabilities::isTransfer).orElse(false);
} }
public boolean isGv1MigrationSupported() {
return allEnabledDevicesHaveCapability(DeviceCapabilities::isGv1Migration);
}
public boolean isSenderKeySupported() { public boolean isSenderKeySupported() {
return allEnabledDevicesHaveCapability(DeviceCapabilities::isSenderKey); return allEnabledDevicesHaveCapability(DeviceCapabilities::isSenderKey);
} }

View File

@ -252,39 +252,13 @@ public class Device {
return this.userAgent; return this.userAgent;
} }
public boolean isGroupsV2Supported() {
final boolean groupsV2Supported;
if (this.capabilities != null) {
final boolean ios = this.apnId != null || this.voipApnId != null;
groupsV2Supported = this.capabilities.isGv2_3() || (ios && this.capabilities.isGv2_2());
} else {
groupsV2Supported = false;
}
return groupsV2Supported;
}
public static class DeviceCapabilities { public static class DeviceCapabilities {
@JsonProperty
private boolean gv2;
@JsonProperty("gv2-2")
private boolean gv2_2;
@JsonProperty("gv2-3")
private boolean gv2_3;
@JsonProperty @JsonProperty
private boolean storage; private boolean storage;
@JsonProperty @JsonProperty
private boolean transfer; private boolean transfer;
@JsonProperty("gv1-migration")
private boolean gv1Migration;
@JsonProperty @JsonProperty
private boolean senderKey; private boolean senderKey;
@ -306,15 +280,11 @@ public class Device {
public DeviceCapabilities() { public DeviceCapabilities() {
} }
public DeviceCapabilities(boolean gv2, final boolean gv2_2, final boolean gv2_3, boolean storage, boolean transfer, public DeviceCapabilities(boolean storage, boolean transfer,
boolean gv1Migration, final boolean senderKey, final boolean announcementGroup, final boolean changeNumber, final boolean senderKey, final boolean announcementGroup, final boolean changeNumber,
final boolean pni, final boolean stories, final boolean giftBadges) { final boolean pni, final boolean stories, final boolean giftBadges) {
this.gv2 = gv2;
this.gv2_2 = gv2_2;
this.gv2_3 = gv2_3;
this.storage = storage; this.storage = storage;
this.transfer = transfer; this.transfer = transfer;
this.gv1Migration = gv1Migration;
this.senderKey = senderKey; this.senderKey = senderKey;
this.announcementGroup = announcementGroup; this.announcementGroup = announcementGroup;
this.changeNumber = changeNumber; this.changeNumber = changeNumber;
@ -323,18 +293,6 @@ public class Device {
this.giftBadges = giftBadges; this.giftBadges = giftBadges;
} }
public boolean isGv2() {
return gv2;
}
public boolean isGv2_2() {
return gv2_2;
}
public boolean isGv2_3() {
return gv2_3;
}
public boolean isStorage() { public boolean isStorage() {
return storage; return storage;
} }
@ -343,10 +301,6 @@ public class Device {
return transfer; return transfer;
} }
public boolean isGv1Migration() {
return gv1Migration;
}
public boolean isSenderKey() { public boolean isSenderKey() {
return senderKey; return senderKey;
} }

View File

@ -193,8 +193,6 @@ class ProfileControllerTest {
when(profileAccount.getUuid()).thenReturn(AuthHelper.VALID_UUID_TWO); when(profileAccount.getUuid()).thenReturn(AuthHelper.VALID_UUID_TWO);
when(profileAccount.getPhoneNumberIdentifier()).thenReturn(AuthHelper.VALID_PNI_TWO); when(profileAccount.getPhoneNumberIdentifier()).thenReturn(AuthHelper.VALID_PNI_TWO);
when(profileAccount.isEnabled()).thenReturn(true); when(profileAccount.isEnabled()).thenReturn(true);
when(profileAccount.isGroupsV2Supported()).thenReturn(false);
when(profileAccount.isGv1MigrationSupported()).thenReturn(false);
when(profileAccount.isSenderKeySupported()).thenReturn(false); when(profileAccount.isSenderKeySupported()).thenReturn(false);
when(profileAccount.isAnnouncementGroupSupported()).thenReturn(false); when(profileAccount.isAnnouncementGroupSupported()).thenReturn(false);
when(profileAccount.isChangeNumberSupported()).thenReturn(false); when(profileAccount.isChangeNumberSupported()).thenReturn(false);
@ -207,8 +205,6 @@ class ProfileControllerTest {
when(capabilitiesAccount.getIdentityKey()).thenReturn(ACCOUNT_IDENTITY_KEY); when(capabilitiesAccount.getIdentityKey()).thenReturn(ACCOUNT_IDENTITY_KEY);
when(capabilitiesAccount.getPhoneNumberIdentityKey()).thenReturn(ACCOUNT_PHONE_NUMBER_IDENTITY_KEY); when(capabilitiesAccount.getPhoneNumberIdentityKey()).thenReturn(ACCOUNT_PHONE_NUMBER_IDENTITY_KEY);
when(capabilitiesAccount.isEnabled()).thenReturn(true); when(capabilitiesAccount.isEnabled()).thenReturn(true);
when(capabilitiesAccount.isGroupsV2Supported()).thenReturn(true);
when(capabilitiesAccount.isGv1MigrationSupported()).thenReturn(true);
when(capabilitiesAccount.isSenderKeySupported()).thenReturn(true); when(capabilitiesAccount.isSenderKeySupported()).thenReturn(true);
when(capabilitiesAccount.isAnnouncementGroupSupported()).thenReturn(true); when(capabilitiesAccount.isAnnouncementGroupSupported()).thenReturn(true);
when(capabilitiesAccount.isChangeNumberSupported()).thenReturn(true); when(capabilitiesAccount.isChangeNumberSupported()).thenReturn(true);
@ -396,7 +392,6 @@ class ProfileControllerTest {
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(BaseProfileResponse.class); .get(BaseProfileResponse.class);
assertThat(profile.getCapabilities().isGv2()).isTrue();
assertThat(profile.getCapabilities().isGv1Migration()).isTrue(); assertThat(profile.getCapabilities().isGv1Migration()).isTrue();
assertThat(profile.getCapabilities().isSenderKey()).isTrue(); assertThat(profile.getCapabilities().isSenderKey()).isTrue();
assertThat(profile.getCapabilities().isAnnouncementGroup()).isTrue(); assertThat(profile.getCapabilities().isAnnouncementGroup()).isTrue();
@ -408,8 +403,7 @@ class ProfileControllerTest {
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO)) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.get(BaseProfileResponse.class); .get(BaseProfileResponse.class);
assertThat(profile.getCapabilities().isGv2()).isFalse(); assertThat(profile.getCapabilities().isGv1Migration()).isTrue();
assertThat(profile.getCapabilities().isGv1Migration()).isFalse();
assertThat(profile.getCapabilities().isSenderKey()).isFalse(); assertThat(profile.getCapabilities().isSenderKey()).isFalse();
assertThat(profile.getCapabilities().isAnnouncementGroup()).isFalse(); assertThat(profile.getCapabilities().isAnnouncementGroup()).isFalse();
} }
@ -753,8 +747,7 @@ class ProfileControllerTest {
assertThat(profile.getAbout()).isEqualTo("about"); assertThat(profile.getAbout()).isEqualTo("about");
assertThat(profile.getAboutEmoji()).isEqualTo("emoji"); assertThat(profile.getAboutEmoji()).isEqualTo("emoji");
assertThat(profile.getAvatar()).isEqualTo("profiles/validavatar"); assertThat(profile.getAvatar()).isEqualTo("profiles/validavatar");
assertThat(profile.getBaseProfileResponse().getCapabilities().isGv2()).isFalse(); assertThat(profile.getBaseProfileResponse().getCapabilities().isGv1Migration()).isTrue();
assertThat(profile.getBaseProfileResponse().getCapabilities().isGv1Migration()).isFalse();
assertThat(profile.getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO); assertThat(profile.getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO);
assertThat(profile.getBaseProfileResponse().getBadges()).hasSize(1).element(0).has(new Condition<>( assertThat(profile.getBaseProfileResponse().getBadges()).hasSize(1).element(0).has(new Condition<>(
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name")); badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));

View File

@ -603,7 +603,7 @@ class AccountsManagerTest {
@ValueSource(booleans = {true, false}) @ValueSource(booleans = {true, false})
void testCreateWithStorageCapability(final boolean hasStorage) throws InterruptedException { void testCreateWithStorageCapability(final boolean hasStorage) throws InterruptedException {
final AccountAttributes attributes = new AccountAttributes(false, 0, null, null, true, final AccountAttributes attributes = new AccountAttributes(false, 0, null, null, true,
new DeviceCapabilities(false, false, false, hasStorage, false, false, false, false, false, false, false, false)); new DeviceCapabilities(hasStorage, false, false, false, false, false, false, false));
final Account account = accountsManager.create("+18005550123", "password", null, attributes, new ArrayList<>()); final Account account = accountsManager.create("+18005550123", "password", null, attributes, new ArrayList<>());

View File

@ -73,66 +73,4 @@ class DeviceTest {
Arguments.of(false, true, null, null, mock(SignedPreKey.class), Duration.ofDays(1), true) Arguments.of(false, true, null, null, mock(SignedPreKey.class), Duration.ofDays(1), true)
); );
} }
@ParameterizedTest
@MethodSource("argumentsForTestIsGroupsV2Supported")
void testIsGroupsV2Supported(final boolean master, final String apnId, final boolean gv2Capability,
final boolean gv2_2Capability, final boolean gv2_3Capability, final boolean expectGv2Supported) {
final Device.DeviceCapabilities capabilities = new Device.DeviceCapabilities(gv2Capability, gv2_2Capability,
gv2_3Capability, false, false, false,
false, false, false, false, false, false);
final Device device = new Device();
device.setId(master ? Device.MASTER_ID : Device.MASTER_ID + 1);
device.setApnId(apnId);
device.setCapabilities(capabilities);
assertEquals(expectGv2Supported, device.isGroupsV2Supported());
}
private static Stream<Arguments> argumentsForTestIsGroupsV2Supported() {
return Stream.of(
// master apnId gv2 gv2-2 gv2-3 capable
// Android master
Arguments.of(true, null, false, false, false, false),
Arguments.of(true, null, true, false, false, false),
Arguments.of(true, null, false, true, false, false),
Arguments.of(true, null, true, true, false, false),
Arguments.of(true, null, false, false, true, true),
Arguments.of(true, null, true, false, true, true),
Arguments.of(true, null, false, true, true, true),
Arguments.of(true, null, true, true, true, true),
// iOS master
Arguments.of(true, "apn-id", false, false, false, false),
Arguments.of(true, "apn-id", true, false, false, false),
Arguments.of(true, "apn-id", false, true, false, true),
Arguments.of(true, "apn-id", true, true, false, true),
Arguments.of(true, "apn-id", false, false, true, true),
Arguments.of(true, "apn-id", true, false, true, true),
Arguments.of(true, "apn-id", false, true, true, true),
Arguments.of(true, "apn-id", true, true, true, true),
// iOS linked
Arguments.of(false, "apn-id", false, false, false, false),
Arguments.of(false, "apn-id", true, false, false, false),
Arguments.of(false, "apn-id", false, true, false, true),
Arguments.of(false, "apn-id", true, true, false, true),
Arguments.of(false, "apn-id", false, false, true, true),
Arguments.of(false, "apn-id", true, false, true, true),
Arguments.of(false, "apn-id", false, true, true, true),
Arguments.of(false, "apn-id", true, true, true, true),
// desktop linked
Arguments.of(false, null, false, false, false, false),
Arguments.of(false, null, true, false, false, false),
Arguments.of(false, null, false, true, false, false),
Arguments.of(false, null, true, true, false, false),
Arguments.of(false, null, false, false, true, true),
Arguments.of(false, null, true, false, true, true),
Arguments.of(false, null, false, true, true, true),
Arguments.of(false, null, true, true, true, true)
);
}
} }

View File

@ -124,8 +124,6 @@ class DeviceControllerTest {
when(account.getNumber()).thenReturn(AuthHelper.VALID_NUMBER); when(account.getNumber()).thenReturn(AuthHelper.VALID_NUMBER);
when(account.getUuid()).thenReturn(AuthHelper.VALID_UUID); when(account.getUuid()).thenReturn(AuthHelper.VALID_UUID);
when(account.isEnabled()).thenReturn(false); when(account.isEnabled()).thenReturn(false);
when(account.isGroupsV2Supported()).thenReturn(true);
when(account.isGv1MigrationSupported()).thenReturn(true);
when(account.isSenderKeySupported()).thenReturn(true); when(account.isSenderKeySupported()).thenReturn(true);
when(account.isAnnouncementGroupSupported()).thenReturn(true); when(account.isAnnouncementGroupSupported()).thenReturn(true);
when(account.isChangeNumberSupported()).thenReturn(true); when(account.isChangeNumberSupported()).thenReturn(true);
@ -303,78 +301,9 @@ class DeviceControllerTest {
verifyNoMoreInteractions(messagesManager); verifyNoMoreInteractions(messagesManager);
} }
@ParameterizedTest
@MethodSource
void deviceDowngradeCapabilitiesTest(final String userAgent, final boolean gv2, final boolean gv2_2,
final boolean gv2_3, final int expectedStatus) {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(gv2, gv2_2, gv2_3, true, false, true, true, true,
true, true, true, true);
AccountAttributes accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
Response response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header(HttpHeaders.USER_AGENT, userAgent)
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(expectedStatus);
if (expectedStatus >= 300) {
verifyNoMoreInteractions(messagesManager);
}
}
private static Stream<Arguments> deviceDowngradeCapabilitiesTest() {
return Stream.of(
// User-Agent gv2 gv2-2 gv2-3 expected
Arguments.of( "Signal-Android/4.68.3 Android/25", false, false, false, 409 ),
Arguments.of( "Signal-Android/4.68.3 Android/25", true, false, false, 409 ),
Arguments.of( "Signal-Android/4.68.3 Android/25", false, true, false, 409 ),
Arguments.of( "Signal-Android/4.68.3 Android/25", false, false, true, 200 ),
Arguments.of( "Signal-iOS/3.9.0", false, false, false, 409 ),
Arguments.of( "Signal-iOS/3.9.0", true, false, false, 409 ),
Arguments.of( "Signal-iOS/3.9.0", false, true, false, 200 ),
Arguments.of( "Signal-iOS/3.9.0", false, false, true, 200 ),
Arguments.of( "Signal-Desktop/1.32.0-beta.3", false, false, false, 409 ),
Arguments.of( "Signal-Desktop/1.32.0-beta.3", true, false, false, 409 ),
Arguments.of( "Signal-Desktop/1.32.0-beta.3", false, true, false, 409 ),
Arguments.of( "Signal-Desktop/1.32.0-beta.3", false, false, true, 200 ),
Arguments.of( "Old client with unparsable UA", false, false, false, 409 ),
Arguments.of( "Old client with unparsable UA", true, false, false, 409 ),
Arguments.of( "Old client with unparsable UA", false, true, false, 409 ),
Arguments.of( "Old client with unparsable UA", false, false, true, 409 )
);
}
@Test
void deviceDowngradeGv1MigrationTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, false, false, true, true,
true, true, true, true);
AccountAttributes accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
Response response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header(HttpHeaders.USER_AGENT, "Signal-Android/4.68.3 Android/25")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, false, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header(HttpHeaders.USER_AGENT, "Signal-Android/4.68.3 Android/25")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
}
@Test @Test
void deviceDowngradeSenderKeyTest() { void deviceDowngradeSenderKeyTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, false, true, DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, false, true,
true, true, true, true); true, true, true, true);
AccountAttributes accountAttributes = AccountAttributes accountAttributes =
new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
@ -387,7 +316,7 @@ class DeviceControllerTest {
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409); assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true); deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources response = resources
.getJerseyTest() .getJerseyTest()
@ -401,7 +330,7 @@ class DeviceControllerTest {
@Test @Test
void deviceDowngradeAnnouncementGroupTest() { void deviceDowngradeAnnouncementGroupTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, false, DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, false,
true, true, true, true); true, true, true, true);
AccountAttributes accountAttributes = AccountAttributes accountAttributes =
new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
@ -414,7 +343,7 @@ class DeviceControllerTest {
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409); assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true); deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources response = resources
.getJerseyTest() .getJerseyTest()
@ -428,7 +357,7 @@ class DeviceControllerTest {
@Test @Test
void deviceDowngradeChangeNumberTest() { void deviceDowngradeChangeNumberTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true,
false, true, true, true); false, true, true, true);
AccountAttributes accountAttributes = AccountAttributes accountAttributes =
new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
@ -442,7 +371,7 @@ class DeviceControllerTest {
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409); assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true); deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources response = resources
.getJerseyTest() .getJerseyTest()
@ -457,7 +386,7 @@ class DeviceControllerTest {
@Test @Test
void deviceDowngradePniTest() { void deviceDowngradePniTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true,
false, true, true); false, true, true);
AccountAttributes accountAttributes = AccountAttributes accountAttributes =
new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
@ -470,7 +399,7 @@ class DeviceControllerTest {
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409); assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true); deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources response = resources
.getJerseyTest() .getJerseyTest()
@ -485,7 +414,7 @@ class DeviceControllerTest {
@Test @Test
void deviceDowngradeStoriesTest() { void deviceDowngradeStoriesTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true,
true, false, true); true, false, true);
AccountAttributes accountAttributes = AccountAttributes accountAttributes =
new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
@ -499,7 +428,7 @@ class DeviceControllerTest {
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409); assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true); deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources response = resources
.getJerseyTest() .getJerseyTest()
@ -514,7 +443,7 @@ class DeviceControllerTest {
@Test @Test
void deviceDowngradeGiftBadgesTest() { void deviceDowngradeGiftBadgesTest() {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, false); DeviceCapabilities deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, false);
AccountAttributes accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); AccountAttributes accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
Response response = resources Response response = resources
.getJerseyTest() .getJerseyTest()
@ -525,7 +454,7 @@ class DeviceControllerTest {
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE)); .put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409); assertThat(response.getStatus()).isEqualTo(409);
deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true); deviceCapabilities = new DeviceCapabilities(true, true, true, true, true, true, true, true);
accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities); accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
response = resources response = resources
.getJerseyTest() .getJerseyTest()

View File

@ -40,14 +40,6 @@ class AccountTest {
private final Device recentSecondaryDevice = mock(Device.class); private final Device recentSecondaryDevice = mock(Device.class);
private final Device oldSecondaryDevice = mock(Device.class); private final Device oldSecondaryDevice = mock(Device.class);
private final Device gv2CapableDevice = mock(Device.class);
private final Device gv2IncapableDevice = mock(Device.class);
private final Device gv2IncapableExpiredDevice = mock(Device.class);
private final Device gv1MigrationCapableDevice = mock(Device.class);
private final Device gv1MigrationIncapableDevice = mock(Device.class);
private final Device gv1MigrationIncapableExpiredDevice = mock(Device.class);
private final Device senderKeyCapableDevice = mock(Device.class); private final Device senderKeyCapableDevice = mock(Device.class);
private final Device senderKeyIncapableDevice = mock(Device.class); private final Device senderKeyIncapableDevice = mock(Device.class);
private final Device senderKeyIncapableExpiredDevice = mock(Device.class); private final Device senderKeyIncapableExpiredDevice = mock(Device.class);
@ -94,101 +86,77 @@ class AccountTest {
when(oldSecondaryDevice.isEnabled()).thenReturn(false); when(oldSecondaryDevice.isEnabled()).thenReturn(false);
when(oldSecondaryDevice.getId()).thenReturn(2L); when(oldSecondaryDevice.getId()).thenReturn(2L);
when(gv2CapableDevice.isGroupsV2Supported()).thenReturn(true);
when(gv2CapableDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
when(gv2CapableDevice.isEnabled()).thenReturn(true);
when(gv2IncapableDevice.isGroupsV2Supported()).thenReturn(false);
when(gv2IncapableDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
when(gv2IncapableDevice.isEnabled()).thenReturn(true);
when(gv2IncapableExpiredDevice.isGroupsV2Supported()).thenReturn(false);
when(gv2IncapableExpiredDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31));
when(gv2IncapableExpiredDevice.isEnabled()).thenReturn(false);
when(gv1MigrationCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, false, false, false, false, false, false));
when(gv1MigrationCapableDevice.isEnabled()).thenReturn(true);
when(gv1MigrationIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, false, false, false, false, false, false, false));
when(gv1MigrationIncapableDevice.isEnabled()).thenReturn(true);
when(gv1MigrationIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, false, false, false, false, false, false, false));
when(gv1MigrationIncapableExpiredDevice.isEnabled()).thenReturn(false);
when(senderKeyCapableDevice.getCapabilities()).thenReturn( when(senderKeyCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(senderKeyCapableDevice.isEnabled()).thenReturn(true); when(senderKeyCapableDevice.isEnabled()).thenReturn(true);
when(senderKeyIncapableDevice.getCapabilities()).thenReturn( when(senderKeyIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, false, false, false, false, false, false)); new DeviceCapabilities(true, true, false, false, false, false, false, false));
when(senderKeyIncapableDevice.isEnabled()).thenReturn(true); when(senderKeyIncapableDevice.isEnabled()).thenReturn(true);
when(senderKeyIncapableExpiredDevice.getCapabilities()).thenReturn( when(senderKeyIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, false, false, false, false, false, false)); new DeviceCapabilities(true, true, false, false, false, false, false, false));
when(senderKeyIncapableExpiredDevice.isEnabled()).thenReturn(false); when(senderKeyIncapableExpiredDevice.isEnabled()).thenReturn(false);
when(announcementGroupCapableDevice.getCapabilities()).thenReturn( when(announcementGroupCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, true, false, false, false, false)); new DeviceCapabilities(true, true, true, true, false, false, false, false));
when(announcementGroupCapableDevice.isEnabled()).thenReturn(true); when(announcementGroupCapableDevice.isEnabled()).thenReturn(true);
when(announcementGroupIncapableDevice.getCapabilities()).thenReturn( when(announcementGroupIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(announcementGroupIncapableDevice.isEnabled()).thenReturn(true); when(announcementGroupIncapableDevice.isEnabled()).thenReturn(true);
when(announcementGroupIncapableExpiredDevice.getCapabilities()).thenReturn( when(announcementGroupIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(announcementGroupIncapableExpiredDevice.isEnabled()).thenReturn(false); when(announcementGroupIncapableExpiredDevice.isEnabled()).thenReturn(false);
when(changeNumberCapableDevice.getCapabilities()).thenReturn( when(changeNumberCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, true, false, false, false)); new DeviceCapabilities(true, true, true, false, true, false, false, false));
when(changeNumberCapableDevice.isEnabled()).thenReturn(true); when(changeNumberCapableDevice.isEnabled()).thenReturn(true);
when(changeNumberIncapableDevice.getCapabilities()).thenReturn( when(changeNumberIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(changeNumberIncapableDevice.isEnabled()).thenReturn(true); when(changeNumberIncapableDevice.isEnabled()).thenReturn(true);
when(changeNumberIncapableExpiredDevice.getCapabilities()).thenReturn( when(changeNumberIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(changeNumberIncapableExpiredDevice.isEnabled()).thenReturn(false); when(changeNumberIncapableExpiredDevice.isEnabled()).thenReturn(false);
when(pniCapableDevice.getCapabilities()).thenReturn( when(pniCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, true, false, false)); new DeviceCapabilities(true, true, true, false, false, true, false, false));
when(pniCapableDevice.isEnabled()).thenReturn(true); when(pniCapableDevice.isEnabled()).thenReturn(true);
when(pniIncapableDevice.getCapabilities()).thenReturn( when(pniIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(pniIncapableDevice.isEnabled()).thenReturn(true); when(pniIncapableDevice.isEnabled()).thenReturn(true);
when(pniIncapableExpiredDevice.getCapabilities()).thenReturn( when(pniIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(pniIncapableExpiredDevice.isEnabled()).thenReturn(false); when(pniIncapableExpiredDevice.isEnabled()).thenReturn(false);
when(storiesCapableDevice.getId()).thenReturn(1L); when(storiesCapableDevice.getId()).thenReturn(1L);
when(storiesCapableDevice.getCapabilities()).thenReturn( when(storiesCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, true, false)); new DeviceCapabilities(true, true, true, false, false, false, true, false));
when(storiesCapableDevice.isEnabled()).thenReturn(true); when(storiesCapableDevice.isEnabled()).thenReturn(true);
when(storiesCapableDevice.getId()).thenReturn(2L); when(storiesCapableDevice.getId()).thenReturn(2L);
when(storiesIncapableDevice.getCapabilities()).thenReturn( when(storiesIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(storiesIncapableDevice.isEnabled()).thenReturn(true); when(storiesIncapableDevice.isEnabled()).thenReturn(true);
when(storiesCapableDevice.getId()).thenReturn(3L); when(storiesCapableDevice.getId()).thenReturn(3L);
when(storiesIncapableExpiredDevice.getCapabilities()).thenReturn( when(storiesIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, false, false, false, false, false)); new DeviceCapabilities(true, true, true, false, false, false, false, false));
when(storiesIncapableExpiredDevice.isEnabled()).thenReturn(false); when(storiesIncapableExpiredDevice.isEnabled()).thenReturn(false);
when(giftBadgesCapableDevice.getCapabilities()).thenReturn( when(giftBadgesCapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, true)); new DeviceCapabilities(true, true, true, true, true, true, true, true));
when(giftBadgesCapableDevice.isEnabled()).thenReturn(true); when(giftBadgesCapableDevice.isEnabled()).thenReturn(true);
when(giftBadgesIncapableDevice.getCapabilities()).thenReturn( when(giftBadgesIncapableDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, false)); new DeviceCapabilities(true, true, true, true, true, true, true, false));
when(giftBadgesIncapableDevice.isEnabled()).thenReturn(true); when(giftBadgesIncapableDevice.isEnabled()).thenReturn(true);
when(giftBadgesIncapableExpiredDevice.getCapabilities()).thenReturn( when(giftBadgesIncapableExpiredDevice.getCapabilities()).thenReturn(
new DeviceCapabilities(true, true, true, true, true, true, true, true, true, true, true, false)); new DeviceCapabilities(true, true, true, true, true, true, true, false));
when(giftBadgesIncapableExpiredDevice.isEnabled()).thenReturn(false); when(giftBadgesIncapableExpiredDevice.isEnabled()).thenReturn(false);
} }
@ -217,17 +185,6 @@ class AccountTest {
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledMasterDevice, disabledLinkedDevice)).isEnabled()); assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledMasterDevice, disabledLinkedDevice)).isEnabled());
} }
@Test
void testCapabilities() {
final Account uuidCapable = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(gv2CapableDevice), "1234".getBytes());
final Account uuidIncapable = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(gv2CapableDevice, gv2IncapableDevice), "1234".getBytes());
final Account uuidCapableWithExpiredIncapable = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(gv2CapableDevice, gv2IncapableExpiredDevice), "1234".getBytes());
assertTrue(uuidCapable.isGroupsV2Supported());
assertFalse(uuidIncapable.isGroupsV2Supported());
assertTrue(uuidCapableWithExpiredIncapable.isGroupsV2Supported());
}
@Test @Test
void testIsTransferSupported() { void testIsTransferSupported() {
final Device transferCapableMasterDevice = mock(Device.class); final Device transferCapableMasterDevice = mock(Device.class);
@ -288,31 +245,6 @@ class AccountTest {
assertTrue(account.isDiscoverableByPhoneNumber()); assertTrue(account.isDiscoverableByPhoneNumber());
} }
@Test
void isGroupsV2Supported() {
assertTrue(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), List.of(gv2CapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isGroupsV2Supported());
assertTrue(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
List.of(gv2CapableDevice, gv2IncapableExpiredDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isGroupsV2Supported());
assertFalse(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
List.of(gv2CapableDevice, gv2IncapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isGroupsV2Supported());
}
@Test
void isGv1MigrationSupported() {
assertTrue(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), List.of(gv1MigrationCapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isGv1MigrationSupported());
assertFalse(
AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(),
List.of(gv1MigrationCapableDevice, gv1MigrationIncapableDevice),
"1234".getBytes(StandardCharsets.UTF_8)).isGv1MigrationSupported());
assertTrue(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(),
UUID.randomUUID(), List.of(gv1MigrationCapableDevice, gv1MigrationIncapableExpiredDevice), "1234".getBytes(StandardCharsets.UTF_8))
.isGv1MigrationSupported());
}
@Test @Test
void isSenderKeySupported() { void isSenderKeySupported() {
assertThat(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), List.of(senderKeyCapableDevice), assertThat(AccountsHelper.generateTestAccount("+18005551234", UUID.randomUUID(), UUID.randomUUID(), List.of(senderKeyCapableDevice),

View File

@ -120,8 +120,6 @@ public class AccountsHelper {
case "isEnabled" -> when(updatedAccount.isEnabled()).thenAnswer(stubbing); case "isEnabled" -> when(updatedAccount.isEnabled()).thenAnswer(stubbing);
case "isDiscoverableByPhoneNumber" -> when(updatedAccount.isDiscoverableByPhoneNumber()).thenAnswer(stubbing); case "isDiscoverableByPhoneNumber" -> when(updatedAccount.isDiscoverableByPhoneNumber()).thenAnswer(stubbing);
case "getNextDeviceId" -> when(updatedAccount.getNextDeviceId()).thenAnswer(stubbing); case "getNextDeviceId" -> when(updatedAccount.getNextDeviceId()).thenAnswer(stubbing);
case "isGroupsV2Supported" -> when(updatedAccount.isGroupsV2Supported()).thenAnswer(stubbing);
case "isGv1MigrationSupported" -> when(updatedAccount.isGv1MigrationSupported()).thenAnswer(stubbing);
case "isSenderKeySupported" -> when(updatedAccount.isSenderKeySupported()).thenAnswer(stubbing); case "isSenderKeySupported" -> when(updatedAccount.isSenderKeySupported()).thenAnswer(stubbing);
case "isAnnouncementGroupSupported" -> when(updatedAccount.isAnnouncementGroupSupported()).thenAnswer(stubbing); case "isAnnouncementGroupSupported" -> when(updatedAccount.isAnnouncementGroupSupported()).thenAnswer(stubbing);
case "isChangeNumberSupported" -> when(updatedAccount.isChangeNumberSupported()).thenAnswer(stubbing); case "isChangeNumberSupported" -> when(updatedAccount.isChangeNumberSupported()).thenAnswer(stubbing);