Switched to a composed request object model for anonymous keys gRPC operations

This commit is contained in:
Jon Chambers 2023-07-27 14:49:55 -04:00 committed by Chris Eager
parent 6e5ffbe7b5
commit 2d132128e1
3 changed files with 37 additions and 33 deletions

View File

@ -28,14 +28,14 @@ public class KeysAnonymousGrpcService extends ReactorKeysAnonymousGrpc.KeysAnony
@Override @Override
public Mono<GetPreKeysResponse> getPreKeys(final GetPreKeysAnonymousRequest request) { public Mono<GetPreKeysResponse> getPreKeys(final GetPreKeysAnonymousRequest request) {
final ServiceIdentifier serviceIdentifier = final ServiceIdentifier serviceIdentifier =
ServiceIdentifierUtil.fromGrpcServiceIdentifier(request.getTargetIdentifier()); ServiceIdentifierUtil.fromGrpcServiceIdentifier(request.getRequest().getTargetIdentifier());
return Mono.fromFuture(accountsManager.getByServiceIdentifierAsync(serviceIdentifier)) return Mono.fromFuture(accountsManager.getByServiceIdentifierAsync(serviceIdentifier))
.flatMap(Mono::justOrEmpty) .flatMap(Mono::justOrEmpty)
.switchIfEmpty(Mono.error(Status.UNAUTHENTICATED.asException())) .switchIfEmpty(Mono.error(Status.UNAUTHENTICATED.asException()))
.flatMap(targetAccount -> .flatMap(targetAccount ->
UnidentifiedAccessUtil.checkUnidentifiedAccess(targetAccount, request.getUnidentifiedAccessKey().toByteArray()) UnidentifiedAccessUtil.checkUnidentifiedAccess(targetAccount, request.getUnidentifiedAccessKey().toByteArray())
? KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), request.getDeviceId(), keysManager) ? KeysGrpcHelper.getPreKeys(targetAccount, serviceIdentifier.identityType(), request.getRequest().getDeviceId(), keysManager)
: Mono.error(Status.UNAUTHENTICATED.asException())); : Mono.error(Status.UNAUTHENTICATED.asException()));
} }
} }

View File

@ -146,21 +146,14 @@ message GetPreKeysRequest {
message GetPreKeysAnonymousRequest { message GetPreKeysAnonymousRequest {
/** /**
* The service identifier of the account for which to retrieve pre-keys. * The request to retrieve pre-keys for a specific account/device(s).
*/ */
common.ServiceIdentifier target_identifier = 1; GetPreKeysRequest request = 1;
/**
* The ID of the device associated with the targeted account for which to
* retrieve pre-keys. If not set, pre-keys are returned for all devices
* associated with the targeted account.
*/
uint64 device_id = 2;
/** /**
* The unidentified access key (UAK) for the targeted account. * The unidentified access key (UAK) for the targeted account.
*/ */
bytes unidentified_access_key = 3; bytes unidentified_access_key = 2;
} }
message GetPreKeysResponse { message GetPreKeysResponse {

View File

@ -30,6 +30,7 @@ import org.signal.chat.common.EcSignedPreKey;
import org.signal.chat.common.KemSignedPreKey; import org.signal.chat.common.KemSignedPreKey;
import org.signal.chat.common.ServiceIdentifier; import org.signal.chat.common.ServiceIdentifier;
import org.signal.chat.keys.GetPreKeysAnonymousRequest; import org.signal.chat.keys.GetPreKeysAnonymousRequest;
import org.signal.chat.keys.GetPreKeysRequest;
import org.signal.chat.keys.GetPreKeysResponse; import org.signal.chat.keys.GetPreKeysResponse;
import org.signal.chat.keys.KeysAnonymousGrpc; import org.signal.chat.keys.KeysAnonymousGrpc;
import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.protocol.IdentityKey;
@ -101,13 +102,15 @@ class KeysAnonymousGrpcServiceTest {
when(targetDevice.getSignedPreKey(IdentityType.ACI)).thenReturn(ecSignedPreKey); when(targetDevice.getSignedPreKey(IdentityType.ACI)).thenReturn(ecSignedPreKey);
final GetPreKeysResponse response = keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder() final GetPreKeysResponse response = keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
.setUnidentifiedAccessKey(ByteString.copyFrom(unidentifiedAccessKey))
.setRequest(GetPreKeysRequest.newBuilder()
.setTargetIdentifier(ServiceIdentifier.newBuilder() .setTargetIdentifier(ServiceIdentifier.newBuilder()
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI) .setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
.setUuid(UUIDUtil.toByteString(identifier)) .setUuid(UUIDUtil.toByteString(identifier))
.build()) .build())
.setDeviceId(Device.MASTER_ID) .setDeviceId(Device.MASTER_ID)
.setUnidentifiedAccessKey(ByteString.copyFrom(unidentifiedAccessKey)) .build())
.build()); .build());
final GetPreKeysResponse expectedResponse = GetPreKeysResponse.newBuilder() final GetPreKeysResponse expectedResponse = GetPreKeysResponse.newBuilder()
.setIdentityKey(ByteString.copyFrom(identityKey.serialize())) .setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
@ -152,11 +155,13 @@ class KeysAnonymousGrpcServiceTest {
@SuppressWarnings("ResultOfMethodCallIgnored") final StatusRuntimeException statusRuntimeException = @SuppressWarnings("ResultOfMethodCallIgnored") final StatusRuntimeException statusRuntimeException =
assertThrows(StatusRuntimeException.class, assertThrows(StatusRuntimeException.class,
() -> keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder() () -> keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
.setTargetIdentifier(ServiceIdentifier.newBuilder() .setRequest(GetPreKeysRequest.newBuilder()
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI) .setTargetIdentifier(ServiceIdentifier.newBuilder()
.setUuid(UUIDUtil.toByteString(identifier)) .setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
.setUuid(UUIDUtil.toByteString(identifier))
.build())
.setDeviceId(Device.MASTER_ID)
.build()) .build())
.setDeviceId(Device.MASTER_ID)
.build())); .build()));
assertEquals(Status.UNAUTHENTICATED.getCode(), statusRuntimeException.getStatus().getCode()); assertEquals(Status.UNAUTHENTICATED.getCode(), statusRuntimeException.getStatus().getCode());
@ -168,13 +173,16 @@ class KeysAnonymousGrpcServiceTest {
.thenReturn(CompletableFuture.completedFuture(Optional.empty())); .thenReturn(CompletableFuture.completedFuture(Optional.empty()));
@SuppressWarnings("ResultOfMethodCallIgnored") final StatusRuntimeException exception = @SuppressWarnings("ResultOfMethodCallIgnored") final StatusRuntimeException exception =
assertThrows(StatusRuntimeException.class, () -> keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder() assertThrows(StatusRuntimeException.class,
.setUnidentifiedAccessKey(UUIDUtil.toByteString(UUID.randomUUID())) () -> keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
.setTargetIdentifier(ServiceIdentifier.newBuilder() .setUnidentifiedAccessKey(UUIDUtil.toByteString(UUID.randomUUID()))
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI) .setRequest(GetPreKeysRequest.newBuilder()
.setUuid(UUIDUtil.toByteString(UUID.randomUUID())) .setTargetIdentifier(ServiceIdentifier.newBuilder()
.build()) .setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
.build())); .setUuid(UUIDUtil.toByteString(UUID.randomUUID()))
.build())
.build())
.build()));
assertEquals(Status.Code.UNAUTHENTICATED, exception.getStatus().getCode()); assertEquals(Status.Code.UNAUTHENTICATED, exception.getStatus().getCode());
} }
@ -198,14 +206,17 @@ class KeysAnonymousGrpcServiceTest {
.thenReturn(CompletableFuture.completedFuture(Optional.of(targetAccount))); .thenReturn(CompletableFuture.completedFuture(Optional.of(targetAccount)));
@SuppressWarnings("ResultOfMethodCallIgnored") final StatusRuntimeException exception = @SuppressWarnings("ResultOfMethodCallIgnored") final StatusRuntimeException exception =
assertThrows(StatusRuntimeException.class, () -> keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder() assertThrows(StatusRuntimeException.class,
.setUnidentifiedAccessKey(ByteString.copyFrom(unidentifiedAccessKey)) () -> keysAnonymousStub.getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
.setTargetIdentifier(ServiceIdentifier.newBuilder() .setUnidentifiedAccessKey(ByteString.copyFrom(unidentifiedAccessKey))
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI) .setRequest(GetPreKeysRequest.newBuilder()
.setUuid(UUIDUtil.toByteString(accountIdentifier)) .setTargetIdentifier(ServiceIdentifier.newBuilder()
.build()) .setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
.setDeviceId(deviceId) .setUuid(UUIDUtil.toByteString(accountIdentifier))
.build())); .build())
.setDeviceId(deviceId)
.build())
.build()));
assertEquals(Status.Code.NOT_FOUND, exception.getStatus().getCode()); assertEquals(Status.Code.NOT_FOUND, exception.getStatus().getCode());
} }