Allow primary devices to change names of linked devices

This commit is contained in:
Jon Chambers
2024-10-29 09:52:38 -04:00
committed by GitHub
parent 712f3affd9
commit f3b22e04e8
14 changed files with 231 additions and 41 deletions

View File

@@ -26,7 +26,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -187,12 +186,66 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
final byte[] deviceName = TestRandomUtil.nextBytes(128);
final SetDeviceNameResponse ignored = authenticatedServiceStub().setDeviceName(SetDeviceNameRequest.newBuilder()
.setId(deviceId)
.setName(ByteString.copyFrom(deviceName))
.build());
verify(device).setName(deviceName);
}
@Test
void setLinkedDeviceNameFromPrimary() {
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, Device.PRIMARY_ID);
final byte deviceId = Device.PRIMARY_ID + 1;
final Device device = mock(Device.class);
when(authenticatedAccount.getDevice(deviceId)).thenReturn(Optional.of(device));
final byte[] deviceName = TestRandomUtil.nextBytes(128);
final SetDeviceNameResponse ignored = authenticatedServiceStub().setDeviceName(SetDeviceNameRequest.newBuilder()
.setId(deviceId)
.setName(ByteString.copyFrom(deviceName))
.build());
verify(device).setName(deviceName);
}
@Test
void setPrimaryDeviceNameFromLinkedDevice() {
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, (byte) (Device.PRIMARY_ID + 1));
final byte deviceId = Device.PRIMARY_ID;
final Device device = mock(Device.class);
when(authenticatedAccount.getDevice(deviceId)).thenReturn(Optional.of(device));
final byte[] deviceName = TestRandomUtil.nextBytes(128);
assertStatusException(Status.PERMISSION_DENIED,
() -> authenticatedServiceStub().setDeviceName(SetDeviceNameRequest.newBuilder()
.setId(deviceId)
.setName(ByteString.copyFrom(deviceName))
.build()));
verify(device, never()).setName(deviceName);
}
@Test
void setDeviceNameNotFound() {
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, Device.PRIMARY_ID);
when(authenticatedAccount.getDevice(anyByte())).thenReturn(Optional.empty());
final byte[] deviceName = TestRandomUtil.nextBytes(128);
assertStatusException(Status.NOT_FOUND,
() -> authenticatedServiceStub().setDeviceName(SetDeviceNameRequest.newBuilder()
.setId(Device.PRIMARY_ID + 1)
.setName(ByteString.copyFrom(deviceName))
.build()));
}
@ParameterizedTest
@MethodSource
void setDeviceNameIllegalArgument(final SetDeviceNameRequest request) {
@@ -203,11 +256,25 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
private static Stream<Arguments> setDeviceNameIllegalArgument() {
return Stream.of(
// No device name
Arguments.of(SetDeviceNameRequest.newBuilder().build()),
Arguments.of(SetDeviceNameRequest.newBuilder()
.setId(Device.PRIMARY_ID)
.build()),
// Excessively-long device name
Arguments.of(SetDeviceNameRequest.newBuilder()
.setName(ByteString.copyFrom(RandomStringUtils.randomAlphanumeric(1024).getBytes(StandardCharsets.UTF_8)))
.setId(Device.PRIMARY_ID)
.setName(ByteString.copyFrom(TestRandomUtil.nextBytes(1024)))
.build()),
// No device ID
Arguments.of(SetDeviceNameRequest.newBuilder()
.setName(ByteString.copyFrom(TestRandomUtil.nextBytes(32)))
.build()),
// Out-of-bounds device ID
Arguments.of(SetDeviceNameRequest.newBuilder()
.setId(Device.MAXIMUM_DEVICE_ID + 1)
.setName(ByteString.copyFrom(TestRandomUtil.nextBytes(32)))
.build())
);
}

View File

@@ -27,8 +27,6 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.signal.chat.common.EcPreKey;
import org.signal.chat.common.EcSignedPreKey;
@@ -306,9 +304,8 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
verifyNoInteractions(keysManager);
}
@ParameterizedTest
@ValueSource(bytes = {KeysGrpcHelper.ALL_DEVICES, 1})
void getPreKeysDeviceNotFound(final byte deviceId) {
@Test
void getPreKeysDeviceNotFound() {
final UUID accountIdentifier = UUID.randomUUID();
final byte[] unidentifiedAccessKey = TestRandomUtil.nextBytes(UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH);
@@ -329,7 +326,7 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
.setTargetIdentifier(ServiceIdentifier.newBuilder()
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
.setUuid(UUIDUtil.toByteString(accountIdentifier)))
.setDeviceId(deviceId))
.setDeviceId(Device.PRIMARY_ID))
.build());
}

View File

@@ -37,7 +37,6 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.signal.chat.common.EcPreKey;
import org.signal.chat.common.EcSignedPreKey;
@@ -592,9 +591,8 @@ class KeysGrpcServiceTest extends SimpleBaseGrpcTest<KeysGrpcService, KeysGrpc.K
.build()));
}
@ParameterizedTest
@ValueSource(bytes = {KeysGrpcHelper.ALL_DEVICES, 1})
void getPreKeysDeviceNotFound(final byte deviceId) {
@Test
void getPreKeysDeviceNotFound() {
final UUID accountIdentifier = UUID.randomUUID();
final Account targetAccount = mock(Account.class);
@@ -611,7 +609,7 @@ class KeysGrpcServiceTest extends SimpleBaseGrpcTest<KeysGrpcService, KeysGrpc.K
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
.setUuid(UUIDUtil.toByteString(accountIdentifier))
.build())
.setDeviceId(deviceId)
.setDeviceId(Device.PRIMARY_ID)
.build()));
}