diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcService.java b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcService.java index 4ddad2e38..3fa856b90 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcService.java @@ -5,6 +5,7 @@ package org.whispersystems.textsecuregcm.grpc; import com.google.protobuf.ByteString; +import com.google.protobuf.Empty; import java.util.Optional; import java.util.concurrent.Flow; import org.signal.chat.backup.CopyMediaRequest; @@ -41,7 +42,6 @@ import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.backup.BackupFailedZkAuthenticationException; import org.whispersystems.textsecuregcm.backup.BackupInvalidArgumentException; import org.whispersystems.textsecuregcm.backup.BackupManager; -import org.whispersystems.textsecuregcm.backup.BackupNotFoundException; import org.whispersystems.textsecuregcm.backup.BackupPermissionException; import org.whispersystems.textsecuregcm.backup.BackupUploadDescriptor; import org.whispersystems.textsecuregcm.backup.BackupWrongCredentialTypeException; @@ -122,7 +122,7 @@ public class BackupsAnonymousGrpcService extends SimpleBackupsAnonymousGrpc.Back try { final AuthenticatedBackupUser backupUser = authenticateBackupUser(request.getSignedPresentation()); backupManager.ttlRefresh(backupUser); - return RefreshResponse.getDefaultInstance(); + return RefreshResponse.newBuilder().setSuccess(Empty.getDefaultInstance()).build(); } catch (BackupFailedZkAuthenticationException e) { return RefreshResponse.newBuilder() .setFailedAuthentication(FailedZkAuthentication.newBuilder().setDescription(e.getMessage()).build()) @@ -140,7 +140,7 @@ public class BackupsAnonymousGrpcService extends SimpleBackupsAnonymousGrpc.Back final byte[] signature = request.getSignedPresentation().getPresentationSignature().toByteArray(); backupManager.setPublicKey(presentation, signature, publicKey); - return SetPublicKeyResponse.getDefaultInstance(); + return SetPublicKeyResponse.newBuilder().setSuccess(Empty.getDefaultInstance()).build(); } @@ -260,7 +260,7 @@ public class BackupsAnonymousGrpcService extends SimpleBackupsAnonymousGrpc.Back try { final AuthenticatedBackupUser backupUser = authenticateBackupUser(request.getSignedPresentation()); backupManager.deleteEntireBackup(backupUser); - return DeleteAllResponse.getDefaultInstance(); + return DeleteAllResponse.newBuilder().setSuccess(Empty.getDefaultInstance()).build(); } catch (BackupFailedZkAuthenticationException e) { return DeleteAllResponse.newBuilder() .setFailedAuthentication(FailedZkAuthentication.newBuilder().setDescription(e.getMessage())) diff --git a/service/src/main/proto/org/signal/chat/backups.proto b/service/src/main/proto/org/signal/chat/backups.proto index a11b4fbd1..f3660ba3b 100644 --- a/service/src/main/proto/org/signal/chat/backups.proto +++ b/service/src/main/proto/org/signal/chat/backups.proto @@ -162,7 +162,7 @@ service BackupsAnonymous { // Refresh the backup, indicating that the backup is still active. Clients // must periodically upload new backups or perform a refresh. If a backup has - // not been active for 30 days, it may deleted + // not been active for 30 days, it may be deleted. rpc Refresh(RefreshRequest) returns (RefreshResponse) {} // Retrieve an upload form that can be used to perform a resumable upload @@ -212,15 +212,21 @@ message SetPublicKeyRequest { // The public key, serialized in libsignal's elliptic-curve public key format. bytes public_key = 2; } + message SetPublicKeyResponse { - // The provided backup auth credential presentation could not be - // authenticated. Either, the presentation could not be verified, or - // the public key signature was invalid, or there is no backup associated - // with the backup-id in the presentation. - // - // This may also be returned if there was an existing public key and the - // provided public key did not match. - errors.FailedZkAuthentication failed_authentication = 1 [(tag.reason) = "failed_authentication"]; + oneof outcome { + // The public key was successfully set + google.protobuf.Empty success = 1; + + // The provided backup auth credential presentation could not be + // authenticated. Either, the presentation could not be verified, or + // the public key signature was invalid, or there is no backup associated + // with the backup-id in the presentation. + // + // This may also be returned if there was an existing public key and the + // provided public key did not match. + errors.FailedZkAuthentication failed_authentication = 2 [(tag.reason) = "failed_authentication"]; + } } message GetCdnCredentialsRequest { @@ -311,11 +317,14 @@ message RefreshRequest { } message RefreshResponse { oneof outcome { + // The backup was successfully refreshed + google.protobuf.Empty success = 1; + // The provided backup auth credential presentation could not be // authenticated. Either, the presentation could not be verified, or // the public key signature was invalid, or there is no backup associated // with the backup-id in the presentation. - errors.FailedZkAuthentication failed_authentication = 1 [(tag.reason) = "failed_authentication"]; + errors.FailedZkAuthentication failed_authentication = 2 [(tag.reason) = "failed_authentication"]; } } @@ -323,7 +332,7 @@ message GetUploadFormRequest { SignedPresentation signed_presentation = 1; message MessagesUploadType { - uint64 uploadLength = 1; + uint64 upload_length = 1; } message MediaUploadType {} oneof upload_type { @@ -395,7 +404,7 @@ message CopyMediaRequest { SignedPresentation signed_presentation = 1; // Items to copy - repeated CopyMediaItem items = 2; + repeated CopyMediaItem items = 2; } message CopyMediaResponse { @@ -418,7 +427,7 @@ message CopyMediaResponse { // authenticated. Either, the presentation could not be verified, or // the public key signature was invalid, or there is no backup associated // with the backup-id in the presentation. - errors.FailedZkAuthentication failed_authentication = 3 [(tag.reason) = "failed_authentication"]; + errors.FailedZkAuthentication failed_authentication = 3 [(tag.reason) = "failed_authentication"]; // The source object was not found SourceNotFound source_not_found = 4; @@ -486,11 +495,14 @@ message DeleteAllRequest { } message DeleteAllResponse { oneof outcome { + // The backup was successfully scheduled for deletion + google.protobuf.Empty success = 1; + // The provided backup auth credential presentation could not be // authenticated. Either, the presentation could not be verified, or // the public key signature was invalid, or there is no backup associated // with the backup-id in the presentation. - errors.FailedZkAuthentication failed_authentication = 1 [(tag.reason) = "failed_authentication"]; + errors.FailedZkAuthentication failed_authentication = 2 [(tag.reason) = "failed_authentication"]; } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcServiceTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcServiceTest.java index 7ac361cb5..c8852565b 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcServiceTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/BackupsAnonymousGrpcServiceTest.java @@ -7,7 +7,6 @@ package org.whispersystems.textsecuregcm.grpc; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatNoException; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -50,6 +49,7 @@ import org.signal.chat.backup.GetUploadFormResponse; import org.signal.chat.backup.ListMediaRequest; import org.signal.chat.backup.ListMediaResponse; import org.signal.chat.backup.SetPublicKeyRequest; +import org.signal.chat.backup.SetPublicKeyResponse; import org.signal.chat.backup.SignedPresentation; import org.signal.libsignal.protocol.ecc.ECKeyPair; import org.signal.libsignal.zkgroup.VerificationFailedException; @@ -97,10 +97,11 @@ class BackupsAnonymousGrpcServiceTest extends @Test void setPublicKey() { - assertThatNoException().isThrownBy(() -> unauthenticatedServiceStub().setPublicKey(SetPublicKeyRequest.newBuilder() + assertThat(unauthenticatedServiceStub().setPublicKey(SetPublicKeyRequest.newBuilder() .setPublicKey(ByteString.copyFrom(ECKeyPair.generate().getPublicKey().serialize())) .setSignedPresentation(signedPresentation(presentation)) - .build())); + .build()) + .getOutcomeCase()).isEqualTo(SetPublicKeyResponse.OutcomeCase.SUCCESS); } @Test