From 53bdd946d6c5e411fd3f7b207f9c5344115011eb Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Mon, 15 Jun 2015 15:42:05 -0700 Subject: [PATCH] Update TextSecure envelope protobuf. Support envelope 'content' field. // FREEBIE --- protobuf/Makefile | 2 +- ...ngMessageSignal.proto => TextSecure.proto} | 17 +- .../controllers/MessageController.java | 32 +- .../entities/EncryptedOutgoingMessage.java | 5 +- .../entities/IncomingMessage.java | 8 +- .../textsecuregcm/entities/MessageProtos.java | 460 +++++++++++------- .../entities/OutgoingMessageEntity.java | 12 +- .../textsecuregcm/push/PushSender.java | 20 +- .../textsecuregcm/push/ReceiptSender.java | 18 +- .../textsecuregcm/push/WebsocketSender.java | 4 +- .../textsecuregcm/storage/Messages.java | 23 +- .../storage/MessagesManager.java | 5 +- .../websocket/DeadLetterHandler.java | 5 +- .../websocket/WebSocketConnection.java | 31 +- src/main/resources/messagedb.xml | 8 + .../controllers/FederatedControllerTest.java | 2 +- .../controllers/MessageControllerTest.java | 22 +- .../controllers/ReceiptControllerTest.java | 5 +- .../websocket/WebSocketConnectionTest.java | 43 +- 19 files changed, 438 insertions(+), 284 deletions(-) rename protobuf/{OutgoingMessageSignal.proto => TextSecure.proto} (75%) diff --git a/protobuf/Makefile b/protobuf/Makefile index 6f143a0c8..a5c54aafe 100644 --- a/protobuf/Makefile +++ b/protobuf/Makefile @@ -1,3 +1,3 @@ all: - protoc --java_out=../src/main/java/ OutgoingMessageSignal.proto PubSubMessage.proto \ No newline at end of file + protoc --java_out=../src/main/java/ TextSecure.proto PubSubMessage.proto diff --git a/protobuf/OutgoingMessageSignal.proto b/protobuf/TextSecure.proto similarity index 75% rename from protobuf/OutgoingMessageSignal.proto rename to protobuf/TextSecure.proto index 4278a2855..1a85722d6 100644 --- a/protobuf/OutgoingMessageSignal.proto +++ b/protobuf/TextSecure.proto @@ -19,23 +19,22 @@ package textsecure; option java_package = "org.whispersystems.textsecuregcm.entities"; option java_outer_classname = "MessageProtos"; -message OutgoingMessageSignal { +message Envelope { enum Type { UNKNOWN = 0; CIPHERTEXT = 1; KEY_EXCHANGE = 2; PREKEY_BUNDLE = 3; -// PLAINTEXT = 4; RECEIPT = 5; } - optional uint32 type = 1; - optional string source = 2; - optional uint32 sourceDevice = 7; - optional string relay = 3; -// repeated string destinations = 4; - optional uint64 timestamp = 5; - optional bytes message = 6; + optional Type type = 1; + optional string source = 2; + optional uint32 sourceDevice = 7; + optional string relay = 3; + optional uint64 timestamp = 5; + optional bytes legacyMessage = 6; // Contains an encrypted DataMessage + optional bytes content = 8; // Contains an encrypted Content } message ProvisioningUuid { diff --git a/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java b/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java index 07cb0d43e..377212028 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java +++ b/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java @@ -23,7 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.entities.IncomingMessage; import org.whispersystems.textsecuregcm.entities.IncomingMessageList; -import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.entities.MessageResponse; import org.whispersystems.textsecuregcm.entities.MismatchedDevices; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; @@ -169,7 +169,7 @@ public class MessageController { try { Optional message = messagesManager.delete(account.getNumber(), source, timestamp); - if (message.isPresent() && message.get().getType() != OutgoingMessageSignal.Type.RECEIPT_VALUE) { + if (message.isPresent() && message.get().getType() != Envelope.Type.RECEIPT_VALUE) { receiptSender.sendReceipt(account, message.get().getSource(), message.get().getTimestamp(), @@ -212,16 +212,21 @@ public class MessageController { throws NoSuchUserException, IOException { try { - Optional messageBody = getMessageBody(incomingMessage); - OutgoingMessageSignal.Builder messageBuilder = OutgoingMessageSignal.newBuilder(); + Optional messageBody = getMessageBody(incomingMessage); + Optional messageContent = getMessageContent(incomingMessage); + Envelope.Builder messageBuilder = Envelope.newBuilder(); - messageBuilder.setType(incomingMessage.getType()) + messageBuilder.setType(Envelope.Type.valueOf(incomingMessage.getType())) .setSource(source.getNumber()) .setTimestamp(timestamp == 0 ? System.currentTimeMillis() : timestamp) - .setSourceDevice((int)source.getAuthenticatedDevice().get().getId()); + .setSourceDevice((int) source.getAuthenticatedDevice().get().getId()); if (messageBody.isPresent()) { - messageBuilder.setMessage(ByteString.copyFrom(messageBody.get())); + messageBuilder.setLegacyMessage(ByteString.copyFrom(messageBody.get())); + } + + if (messageContent.isPresent()) { + messageBuilder.setContent(ByteString.copyFrom(messageContent.get())); } if (source.getRelay().isPresent()) { @@ -343,6 +348,8 @@ public class MessageController { } private Optional getMessageBody(IncomingMessage message) { + if (Util.isEmpty(message.getBody())) return Optional.absent(); + try { return Optional.of(Base64.decode(message.getBody())); } catch (IOException ioe) { @@ -350,4 +357,15 @@ public class MessageController { return Optional.absent(); } } + + private Optional getMessageContent(IncomingMessage message) { + if (Util.isEmpty(message.getContent())) return Optional.absent(); + + try { + return Optional.of(Base64.decode(message.getContent())); + } catch (IOException ioe) { + logger.debug("Bad B64", ioe); + return Optional.absent(); + } + } } diff --git a/src/main/java/org/whispersystems/textsecuregcm/entities/EncryptedOutgoingMessage.java b/src/main/java/org/whispersystems/textsecuregcm/entities/EncryptedOutgoingMessage.java index 980b51cff..d286ac578 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/entities/EncryptedOutgoingMessage.java +++ b/src/main/java/org/whispersystems/textsecuregcm/entities/EncryptedOutgoingMessage.java @@ -18,7 +18,7 @@ package org.whispersystems.textsecuregcm.entities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.util.Base64; import org.whispersystems.textsecuregcm.util.Util; @@ -44,8 +44,7 @@ public class EncryptedOutgoingMessage { private final byte[] serialized; private final String serializedAndEncoded; - public EncryptedOutgoingMessage(OutgoingMessageSignal outgoingMessage, - String signalingKey) + public EncryptedOutgoingMessage(Envelope outgoingMessage, String signalingKey) throws CryptoEncodingException { byte[] plaintext = outgoingMessage.toByteArray(); diff --git a/src/main/java/org/whispersystems/textsecuregcm/entities/IncomingMessage.java b/src/main/java/org/whispersystems/textsecuregcm/entities/IncomingMessage.java index 7f4c42168..ff48511a1 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/entities/IncomingMessage.java +++ b/src/main/java/org/whispersystems/textsecuregcm/entities/IncomingMessage.java @@ -34,9 +34,11 @@ public class IncomingMessage { private int destinationRegistrationId; @JsonProperty - @NotEmpty private String body; + @JsonProperty + private String content; + @JsonProperty private String relay; @@ -67,4 +69,8 @@ public class IncomingMessage { public int getDestinationRegistrationId() { return destinationRegistrationId; } + + public String getContent() { + return content; + } } diff --git a/src/main/java/org/whispersystems/textsecuregcm/entities/MessageProtos.java b/src/main/java/org/whispersystems/textsecuregcm/entities/MessageProtos.java index acd50ecf6..f2b7060de 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/entities/MessageProtos.java +++ b/src/main/java/org/whispersystems/textsecuregcm/entities/MessageProtos.java @@ -1,5 +1,5 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! -// source: OutgoingMessageSignal.proto +// source: TextSecure.proto package org.whispersystems.textsecuregcm.entities; @@ -8,18 +8,18 @@ public final class MessageProtos { public static void registerAllExtensions( com.google.protobuf.ExtensionRegistry registry) { } - public interface OutgoingMessageSignalOrBuilder + public interface EnvelopeOrBuilder extends com.google.protobuf.MessageOrBuilder { - // optional uint32 type = 1; + // optional .textsecure.Envelope.Type type = 1; /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ boolean hasType(); /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ - int getType(); + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type getType(); // optional string source = 2; /** @@ -64,50 +64,68 @@ public final class MessageProtos { // optional uint64 timestamp = 5; /** * optional uint64 timestamp = 5; - * - *
-     *  repeated string destinations = 4;
-     * 
*/ boolean hasTimestamp(); /** * optional uint64 timestamp = 5; - * - *
-     *  repeated string destinations = 4;
-     * 
*/ long getTimestamp(); - // optional bytes message = 6; + // optional bytes legacyMessage = 6; /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+     * Contains an encrypted DataMessage
+     * 
*/ - boolean hasMessage(); + boolean hasLegacyMessage(); /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+     * Contains an encrypted DataMessage
+     * 
*/ - com.google.protobuf.ByteString getMessage(); + com.google.protobuf.ByteString getLegacyMessage(); + + // optional bytes content = 8; + /** + * optional bytes content = 8; + * + *
+     * Contains an encrypted Content
+     * 
+ */ + boolean hasContent(); + /** + * optional bytes content = 8; + * + *
+     * Contains an encrypted Content
+     * 
+ */ + com.google.protobuf.ByteString getContent(); } /** - * Protobuf type {@code textsecure.OutgoingMessageSignal} + * Protobuf type {@code textsecure.Envelope} */ - public static final class OutgoingMessageSignal extends + public static final class Envelope extends com.google.protobuf.GeneratedMessage - implements OutgoingMessageSignalOrBuilder { - // Use OutgoingMessageSignal.newBuilder() to construct. - private OutgoingMessageSignal(com.google.protobuf.GeneratedMessage.Builder builder) { + implements EnvelopeOrBuilder { + // Use Envelope.newBuilder() to construct. + private Envelope(com.google.protobuf.GeneratedMessage.Builder builder) { super(builder); this.unknownFields = builder.getUnknownFields(); } - private OutgoingMessageSignal(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + private Envelope(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - private static final OutgoingMessageSignal defaultInstance; - public static OutgoingMessageSignal getDefaultInstance() { + private static final Envelope defaultInstance; + public static Envelope getDefaultInstance() { return defaultInstance; } - public OutgoingMessageSignal getDefaultInstanceForType() { + public Envelope getDefaultInstanceForType() { return defaultInstance; } @@ -117,7 +135,7 @@ public final class MessageProtos { getUnknownFields() { return this.unknownFields; } - private OutgoingMessageSignal( + private Envelope( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { @@ -141,8 +159,14 @@ public final class MessageProtos { break; } case 8: { - bitField0_ |= 0x00000001; - type_ = input.readUInt32(); + int rawValue = input.readEnum(); + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type value = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + type_ = value; + } break; } case 18: { @@ -162,7 +186,7 @@ public final class MessageProtos { } case 50: { bitField0_ |= 0x00000020; - message_ = input.readBytes(); + legacyMessage_ = input.readBytes(); break; } case 56: { @@ -170,6 +194,11 @@ public final class MessageProtos { sourceDevice_ = input.readUInt32(); break; } + case 66: { + bitField0_ |= 0x00000040; + content_ = input.readBytes(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -184,33 +213,33 @@ public final class MessageProtos { } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_descriptor; + return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_descriptor; } protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable + return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_fieldAccessorTable .ensureFieldAccessorsInitialized( - org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.class, org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.Builder.class); + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.class, org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Builder.class); } - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public OutgoingMessageSignal parsePartialFrom( + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Envelope parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { - return new OutgoingMessageSignal(input, extensionRegistry); + return new Envelope(input, extensionRegistry); } }; @java.lang.Override - public com.google.protobuf.Parser getParserForType() { + public com.google.protobuf.Parser getParserForType() { return PARSER; } /** - * Protobuf enum {@code textsecure.OutgoingMessageSignal.Type} + * Protobuf enum {@code textsecure.Envelope.Type} */ public enum Type implements com.google.protobuf.ProtocolMessageEnum { @@ -230,14 +259,10 @@ public final class MessageProtos { * PREKEY_BUNDLE = 3; */ PREKEY_BUNDLE(3, 3), - /** - * PLAINTEXT = 4; - */ - PLAINTEXT(4, 4), /** * RECEIPT = 5; */ - RECEIPT(5, 5), + RECEIPT(4, 5), ; /** @@ -256,10 +281,6 @@ public final class MessageProtos { * PREKEY_BUNDLE = 3; */ public static final int PREKEY_BUNDLE_VALUE = 3; - /** - * PLAINTEXT = 4; - */ - public static final int PLAINTEXT_VALUE = 4; /** * RECEIPT = 5; */ @@ -274,7 +295,6 @@ public final class MessageProtos { case 1: return CIPHERTEXT; case 2: return KEY_EXCHANGE; case 3: return PREKEY_BUNDLE; - case 4: return PLAINTEXT; case 5: return RECEIPT; default: return null; } @@ -302,7 +322,7 @@ public final class MessageProtos { } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.getDescriptor().getEnumTypes().get(0); + return org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.getDescriptor().getEnumTypes().get(0); } private static final Type[] VALUES = values(); @@ -324,23 +344,23 @@ public final class MessageProtos { this.value = value; } - // @@protoc_insertion_point(enum_scope:textsecure.OutgoingMessageSignal.Type) + // @@protoc_insertion_point(enum_scope:textsecure.Envelope.Type) } private int bitField0_; - // optional uint32 type = 1; + // optional .textsecure.Envelope.Type type = 1; public static final int TYPE_FIELD_NUMBER = 1; - private int type_; + private org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type type_; /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ public boolean hasType() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ - public int getType() { + public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type getType() { return type_; } @@ -451,48 +471,73 @@ public final class MessageProtos { private long timestamp_; /** * optional uint64 timestamp = 5; - * - *
-     *  repeated string destinations = 4;
-     * 
*/ public boolean hasTimestamp() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional uint64 timestamp = 5; - * - *
-     *  repeated string destinations = 4;
-     * 
*/ public long getTimestamp() { return timestamp_; } - // optional bytes message = 6; - public static final int MESSAGE_FIELD_NUMBER = 6; - private com.google.protobuf.ByteString message_; + // optional bytes legacyMessage = 6; + public static final int LEGACYMESSAGE_FIELD_NUMBER = 6; + private com.google.protobuf.ByteString legacyMessage_; /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+     * Contains an encrypted DataMessage
+     * 
*/ - public boolean hasMessage() { + public boolean hasLegacyMessage() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+     * Contains an encrypted DataMessage
+     * 
*/ - public com.google.protobuf.ByteString getMessage() { - return message_; + public com.google.protobuf.ByteString getLegacyMessage() { + return legacyMessage_; + } + + // optional bytes content = 8; + public static final int CONTENT_FIELD_NUMBER = 8; + private com.google.protobuf.ByteString content_; + /** + * optional bytes content = 8; + * + *
+     * Contains an encrypted Content
+     * 
+ */ + public boolean hasContent() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * optional bytes content = 8; + * + *
+     * Contains an encrypted Content
+     * 
+ */ + public com.google.protobuf.ByteString getContent() { + return content_; } private void initFields() { - type_ = 0; + type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN; source_ = ""; sourceDevice_ = 0; relay_ = ""; timestamp_ = 0L; - message_ = com.google.protobuf.ByteString.EMPTY; + legacyMessage_ = com.google.protobuf.ByteString.EMPTY; + content_ = com.google.protobuf.ByteString.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -507,7 +552,7 @@ public final class MessageProtos { throws java.io.IOException { getSerializedSize(); if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeUInt32(1, type_); + output.writeEnum(1, type_.getNumber()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { output.writeBytes(2, getSourceBytes()); @@ -519,11 +564,14 @@ public final class MessageProtos { output.writeUInt64(5, timestamp_); } if (((bitField0_ & 0x00000020) == 0x00000020)) { - output.writeBytes(6, message_); + output.writeBytes(6, legacyMessage_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { output.writeUInt32(7, sourceDevice_); } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBytes(8, content_); + } getUnknownFields().writeTo(output); } @@ -535,7 +583,7 @@ public final class MessageProtos { size = 0; if (((bitField0_ & 0x00000001) == 0x00000001)) { size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(1, type_); + .computeEnumSize(1, type_.getNumber()); } if (((bitField0_ & 0x00000002) == 0x00000002)) { size += com.google.protobuf.CodedOutputStream @@ -551,12 +599,16 @@ public final class MessageProtos { } if (((bitField0_ & 0x00000020) == 0x00000020)) { size += com.google.protobuf.CodedOutputStream - .computeBytesSize(6, message_); + .computeBytesSize(6, legacyMessage_); } if (((bitField0_ & 0x00000004) == 0x00000004)) { size += com.google.protobuf.CodedOutputStream .computeUInt32Size(7, sourceDevice_); } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(8, content_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -569,53 +621,53 @@ public final class MessageProtos { return super.writeReplace(); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom(byte[] data) + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom(java.io.InputStream input) + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseFrom(input, extensionRegistry); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseDelimitedFrom(java.io.InputStream input) + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return PARSER.parseDelimitedFrom(input); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseDelimitedFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return PARSER.parseDelimitedFrom(input, extensionRegistry); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return PARSER.parseFrom(input); } - public static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parseFrom( + public static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { @@ -624,7 +676,7 @@ public final class MessageProtos { public static Builder newBuilder() { return Builder.create(); } public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal prototype) { + public static Builder newBuilder(org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope prototype) { return newBuilder().mergeFrom(prototype); } public Builder toBuilder() { return newBuilder(this); } @@ -636,24 +688,24 @@ public final class MessageProtos { return builder; } /** - * Protobuf type {@code textsecure.OutgoingMessageSignal} + * Protobuf type {@code textsecure.Envelope} */ public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder - implements org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignalOrBuilder { + implements org.whispersystems.textsecuregcm.entities.MessageProtos.EnvelopeOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_descriptor; + return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_descriptor; } protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable + return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_fieldAccessorTable .ensureFieldAccessorsInitialized( - org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.class, org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.Builder.class); + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.class, org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Builder.class); } - // Construct using org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.newBuilder() + // Construct using org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.newBuilder() private Builder() { maybeForceBuilderInitialization(); } @@ -673,7 +725,7 @@ public final class MessageProtos { public Builder clear() { super.clear(); - type_ = 0; + type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN; bitField0_ = (bitField0_ & ~0x00000001); source_ = ""; bitField0_ = (bitField0_ & ~0x00000002); @@ -683,8 +735,10 @@ public final class MessageProtos { bitField0_ = (bitField0_ & ~0x00000008); timestamp_ = 0L; bitField0_ = (bitField0_ & ~0x00000010); - message_ = com.google.protobuf.ByteString.EMPTY; + legacyMessage_ = com.google.protobuf.ByteString.EMPTY; bitField0_ = (bitField0_ & ~0x00000020); + content_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000040); return this; } @@ -694,23 +748,23 @@ public final class MessageProtos { public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_OutgoingMessageSignal_descriptor; + return org.whispersystems.textsecuregcm.entities.MessageProtos.internal_static_textsecure_Envelope_descriptor; } - public org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal getDefaultInstanceForType() { - return org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.getDefaultInstance(); + public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope getDefaultInstanceForType() { + return org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.getDefaultInstance(); } - public org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal build() { - org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal result = buildPartial(); + public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope build() { + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } - public org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal buildPartial() { - org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal result = new org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal(this); + public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope buildPartial() { + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope result = new org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope(this); int from_bitField0_ = bitField0_; int to_bitField0_ = 0; if (((from_bitField0_ & 0x00000001) == 0x00000001)) { @@ -736,23 +790,27 @@ public final class MessageProtos { if (((from_bitField0_ & 0x00000020) == 0x00000020)) { to_bitField0_ |= 0x00000020; } - result.message_ = message_; + result.legacyMessage_ = legacyMessage_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.content_ = content_; result.bitField0_ = to_bitField0_; onBuilt(); return result; } public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal) { - return mergeFrom((org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal)other); + if (other instanceof org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope) { + return mergeFrom((org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope)other); } else { super.mergeFrom(other); return this; } } - public Builder mergeFrom(org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal other) { - if (other == org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal.getDefaultInstance()) return this; + public Builder mergeFrom(org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope other) { + if (other == org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.getDefaultInstance()) return this; if (other.hasType()) { setType(other.getType()); } @@ -772,8 +830,11 @@ public final class MessageProtos { if (other.hasTimestamp()) { setTimestamp(other.getTimestamp()); } - if (other.hasMessage()) { - setMessage(other.getMessage()); + if (other.hasLegacyMessage()) { + setLegacyMessage(other.getLegacyMessage()); + } + if (other.hasContent()) { + setContent(other.getContent()); } this.mergeUnknownFields(other.getUnknownFields()); return this; @@ -787,11 +848,11 @@ public final class MessageProtos { com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { - org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal parsedMessage = null; + org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope parsedMessage = null; try { parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal) e.getUnfinishedMessage(); + parsedMessage = (org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope) e.getUnfinishedMessage(); throw e; } finally { if (parsedMessage != null) { @@ -802,35 +863,38 @@ public final class MessageProtos { } private int bitField0_; - // optional uint32 type = 1; - private int type_ ; + // optional .textsecure.Envelope.Type type = 1; + private org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN; /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ public boolean hasType() { return ((bitField0_ & 0x00000001) == 0x00000001); } /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ - public int getType() { + public org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type getType() { return type_; } /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ - public Builder setType(int value) { + public Builder setType(org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type value) { + if (value == null) { + throw new NullPointerException(); + } bitField0_ |= 0x00000001; type_ = value; onChanged(); return this; } /** - * optional uint32 type = 1; + * optional .textsecure.Envelope.Type type = 1; */ public Builder clearType() { bitField0_ = (bitField0_ & ~0x00000001); - type_ = 0; + type_ = org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope.Type.UNKNOWN; onChanged(); return this; } @@ -1020,30 +1084,18 @@ public final class MessageProtos { private long timestamp_ ; /** * optional uint64 timestamp = 5; - * - *
-       *  repeated string destinations = 4;
-       * 
*/ public boolean hasTimestamp() { return ((bitField0_ & 0x00000010) == 0x00000010); } /** * optional uint64 timestamp = 5; - * - *
-       *  repeated string destinations = 4;
-       * 
*/ public long getTimestamp() { return timestamp_; } /** * optional uint64 timestamp = 5; - * - *
-       *  repeated string destinations = 4;
-       * 
*/ public Builder setTimestamp(long value) { bitField0_ |= 0x00000010; @@ -1053,10 +1105,6 @@ public final class MessageProtos { } /** * optional uint64 timestamp = 5; - * - *
-       *  repeated string destinations = 4;
-       * 
*/ public Builder clearTimestamp() { bitField0_ = (bitField0_ & ~0x00000010); @@ -1065,51 +1113,119 @@ public final class MessageProtos { return this; } - // optional bytes message = 6; - private com.google.protobuf.ByteString message_ = com.google.protobuf.ByteString.EMPTY; + // optional bytes legacyMessage = 6; + private com.google.protobuf.ByteString legacyMessage_ = com.google.protobuf.ByteString.EMPTY; /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+       * Contains an encrypted DataMessage
+       * 
*/ - public boolean hasMessage() { + public boolean hasLegacyMessage() { return ((bitField0_ & 0x00000020) == 0x00000020); } /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+       * Contains an encrypted DataMessage
+       * 
*/ - public com.google.protobuf.ByteString getMessage() { - return message_; + public com.google.protobuf.ByteString getLegacyMessage() { + return legacyMessage_; } /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+       * Contains an encrypted DataMessage
+       * 
*/ - public Builder setMessage(com.google.protobuf.ByteString value) { + public Builder setLegacyMessage(com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000020; - message_ = value; + legacyMessage_ = value; onChanged(); return this; } /** - * optional bytes message = 6; + * optional bytes legacyMessage = 6; + * + *
+       * Contains an encrypted DataMessage
+       * 
*/ - public Builder clearMessage() { + public Builder clearLegacyMessage() { bitField0_ = (bitField0_ & ~0x00000020); - message_ = getDefaultInstance().getMessage(); + legacyMessage_ = getDefaultInstance().getLegacyMessage(); onChanged(); return this; } - // @@protoc_insertion_point(builder_scope:textsecure.OutgoingMessageSignal) + // optional bytes content = 8; + private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY; + /** + * optional bytes content = 8; + * + *
+       * Contains an encrypted Content
+       * 
+ */ + public boolean hasContent() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * optional bytes content = 8; + * + *
+       * Contains an encrypted Content
+       * 
+ */ + public com.google.protobuf.ByteString getContent() { + return content_; + } + /** + * optional bytes content = 8; + * + *
+       * Contains an encrypted Content
+       * 
+ */ + public Builder setContent(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + content_ = value; + onChanged(); + return this; + } + /** + * optional bytes content = 8; + * + *
+       * Contains an encrypted Content
+       * 
+ */ + public Builder clearContent() { + bitField0_ = (bitField0_ & ~0x00000040); + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:textsecure.Envelope) } static { - defaultInstance = new OutgoingMessageSignal(true); + defaultInstance = new Envelope(true); defaultInstance.initFields(); } - // @@protoc_insertion_point(class_scope:textsecure.OutgoingMessageSignal) + // @@protoc_insertion_point(class_scope:textsecure.Envelope) } public interface ProvisioningUuidOrBuilder @@ -1584,10 +1700,10 @@ public final class MessageProtos { } private static com.google.protobuf.Descriptors.Descriptor - internal_static_textsecure_OutgoingMessageSignal_descriptor; + internal_static_textsecure_Envelope_descriptor; private static com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable; + internal_static_textsecure_Envelope_fieldAccessorTable; private static com.google.protobuf.Descriptors.Descriptor internal_static_textsecure_ProvisioningUuid_descriptor; private static @@ -1602,28 +1718,28 @@ public final class MessageProtos { descriptor; static { java.lang.String[] descriptorData = { - "\n\033OutgoingMessageSignal.proto\022\ntextsecur" + - "e\"\344\001\n\025OutgoingMessageSignal\022\014\n\004type\030\001 \001(" + - "\r\022\016\n\006source\030\002 \001(\t\022\024\n\014sourceDevice\030\007 \001(\r\022" + - "\r\n\005relay\030\003 \001(\t\022\021\n\ttimestamp\030\005 \001(\004\022\017\n\007mes" + - "sage\030\006 \001(\014\"d\n\004Type\022\013\n\007UNKNOWN\020\000\022\016\n\nCIPHE" + - "RTEXT\020\001\022\020\n\014KEY_EXCHANGE\020\002\022\021\n\rPREKEY_BUND" + - "LE\020\003\022\r\n\tPLAINTEXT\020\004\022\013\n\007RECEIPT\020\005\" \n\020Prov" + - "isioningUuid\022\014\n\004uuid\030\001 \001(\tB:\n)org.whispe" + - "rsystems.textsecuregcm.entitiesB\rMessage" + - "Protos" + "\n\020TextSecure.proto\022\ntextsecure\"\372\001\n\010Envel" + + "ope\022\'\n\004type\030\001 \001(\0162\031.textsecure.Envelope." + + "Type\022\016\n\006source\030\002 \001(\t\022\024\n\014sourceDevice\030\007 \001" + + "(\r\022\r\n\005relay\030\003 \001(\t\022\021\n\ttimestamp\030\005 \001(\004\022\025\n\r" + + "legacyMessage\030\006 \001(\014\022\017\n\007content\030\010 \001(\014\"U\n\004" + + "Type\022\013\n\007UNKNOWN\020\000\022\016\n\nCIPHERTEXT\020\001\022\020\n\014KEY" + + "_EXCHANGE\020\002\022\021\n\rPREKEY_BUNDLE\020\003\022\013\n\007RECEIP" + + "T\020\005\" \n\020ProvisioningUuid\022\014\n\004uuid\030\001 \001(\tB:\n" + + ")org.whispersystems.textsecuregcm.entiti" + + "esB\rMessageProtos" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { public com.google.protobuf.ExtensionRegistry assignDescriptors( com.google.protobuf.Descriptors.FileDescriptor root) { descriptor = root; - internal_static_textsecure_OutgoingMessageSignal_descriptor = + internal_static_textsecure_Envelope_descriptor = getDescriptor().getMessageTypes().get(0); - internal_static_textsecure_OutgoingMessageSignal_fieldAccessorTable = new + internal_static_textsecure_Envelope_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_textsecure_OutgoingMessageSignal_descriptor, - new java.lang.String[] { "Type", "Source", "SourceDevice", "Relay", "Timestamp", "Message", }); + internal_static_textsecure_Envelope_descriptor, + new java.lang.String[] { "Type", "Source", "SourceDevice", "Relay", "Timestamp", "LegacyMessage", "Content", }); internal_static_textsecure_ProvisioningUuid_descriptor = getDescriptor().getMessageTypes().get(1); internal_static_textsecure_ProvisioningUuid_fieldAccessorTable = new diff --git a/src/main/java/org/whispersystems/textsecuregcm/entities/OutgoingMessageEntity.java b/src/main/java/org/whispersystems/textsecuregcm/entities/OutgoingMessageEntity.java index 8a1babd71..ca3144115 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/entities/OutgoingMessageEntity.java +++ b/src/main/java/org/whispersystems/textsecuregcm/entities/OutgoingMessageEntity.java @@ -26,10 +26,14 @@ public class OutgoingMessageEntity { @JsonProperty private byte[] message; + @JsonProperty + private byte[] content; + public OutgoingMessageEntity() {} public OutgoingMessageEntity(long id, int type, String relay, long timestamp, - String source, int sourceDevice, byte[] message) + String source, int sourceDevice, byte[] message, + byte[] content) { this.id = id; this.type = type; @@ -38,6 +42,7 @@ public class OutgoingMessageEntity { this.source = source; this.sourceDevice = sourceDevice; this.message = message; + this.content = content; } public int getType() { @@ -64,7 +69,12 @@ public class OutgoingMessageEntity { return message; } + public byte[] getContent() { + return content; + } + public long getId() { return id; } + } diff --git a/src/main/java/org/whispersystems/textsecuregcm/push/PushSender.java b/src/main/java/org/whispersystems/textsecuregcm/push/PushSender.java index 887070827..96cc8be07 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/push/PushSender.java +++ b/src/main/java/org/whispersystems/textsecuregcm/push/PushSender.java @@ -29,11 +29,9 @@ import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.websocket.WebsocketAddress; -import java.util.LinkedHashMap; import java.util.concurrent.TimeUnit; -import io.dropwizard.lifecycle.Managed; -import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; public class PushSender { @@ -51,7 +49,7 @@ public class PushSender { this.webSocketSender = websocketSender; } - public void sendMessage(Account account, Device device, OutgoingMessageSignal message) + public void sendMessage(Account account, Device device, Envelope message) throws NotPushRegisteredException, TransientPushFailureException { if (device.getGcmId() != null) sendGcmMessage(account, device, message); @@ -64,21 +62,21 @@ public class PushSender { return webSocketSender; } - private void sendGcmMessage(Account account, Device device, OutgoingMessageSignal message) + private void sendGcmMessage(Account account, Device device, Envelope message) throws TransientPushFailureException, NotPushRegisteredException { if (device.getFetchesMessages()) sendNotificationGcmMessage(account, device, message); else sendPayloadGcmMessage(account, device, message); } - private void sendPayloadGcmMessage(Account account, Device device, OutgoingMessageSignal message) + private void sendPayloadGcmMessage(Account account, Device device, Envelope message) throws TransientPushFailureException, NotPushRegisteredException { try { String number = account.getNumber(); long deviceId = device.getId(); String registrationId = device.getGcmId(); - boolean isReceipt = message.getType() == OutgoingMessageSignal.Type.RECEIPT_VALUE; + boolean isReceipt = message.getType() == Envelope.Type.RECEIPT; EncryptedOutgoingMessage encryptedMessage = new EncryptedOutgoingMessage(message, device.getSignalingKey()); GcmMessage gcmMessage = new GcmMessage(registrationId, number, (int) deviceId, encryptedMessage.toEncodedString(), isReceipt, false); @@ -89,7 +87,7 @@ public class PushSender { } } - private void sendNotificationGcmMessage(Account account, Device device, OutgoingMessageSignal message) + private void sendNotificationGcmMessage(Account account, Device device, Envelope message) throws TransientPushFailureException { DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, message, WebsocketSender.Type.GCM); @@ -102,12 +100,12 @@ public class PushSender { } } - private void sendApnMessage(Account account, Device device, OutgoingMessageSignal outgoingMessage) + private void sendApnMessage(Account account, Device device, Envelope outgoingMessage) throws TransientPushFailureException { DeliveryStatus deliveryStatus = webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.APN); - if (!deliveryStatus.isDelivered() && outgoingMessage.getType() != OutgoingMessageSignal.Type.RECEIPT_VALUE) { + if (!deliveryStatus.isDelivered() && outgoingMessage.getType() != Envelope.Type.RECEIPT) { ApnMessage apnMessage; if (!Util.isEmpty(device.getVoipApnId())) { @@ -127,7 +125,7 @@ public class PushSender { } } - private void sendWebSocketMessage(Account account, Device device, OutgoingMessageSignal outgoingMessage) + private void sendWebSocketMessage(Account account, Device device, Envelope outgoingMessage) { webSocketSender.sendMessage(account, device, outgoingMessage, WebsocketSender.Type.WEB); } diff --git a/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java b/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java index 6ab16c05f..55de18d3f 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java +++ b/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java @@ -2,7 +2,7 @@ package org.whispersystems.textsecuregcm.push; import com.google.common.base.Optional; import org.whispersystems.textsecuregcm.controllers.NoSuchUserException; -import org.whispersystems.textsecuregcm.entities.MessageProtos; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.federation.NoSuchPeerException; import org.whispersystems.textsecuregcm.storage.Account; @@ -55,15 +55,13 @@ public class ReceiptSender { private void sendDirectReceipt(Account source, String destination, long messageId) throws NotPushRegisteredException, TransientPushFailureException, NoSuchUserException { - Account destinationAccount = getDestinationAccount(destination); - Set destinationDevices = destinationAccount.getDevices(); - - MessageProtos.OutgoingMessageSignal.Builder message = - MessageProtos.OutgoingMessageSignal.newBuilder() - .setSource(source.getNumber()) - .setSourceDevice((int) source.getAuthenticatedDevice().get().getId()) - .setTimestamp(messageId) - .setType(MessageProtos.OutgoingMessageSignal.Type.RECEIPT_VALUE); + Account destinationAccount = getDestinationAccount(destination); + Set destinationDevices = destinationAccount.getDevices(); + Envelope.Builder message = Envelope.newBuilder() + .setSource(source.getNumber()) + .setSourceDevice((int) source.getAuthenticatedDevice().get().getId()) + .setTimestamp(messageId) + .setType(Envelope.Type.RECEIPT); if (source.getRelay().isPresent()) { message.setRelay(source.getRelay().get()); diff --git a/src/main/java/org/whispersystems/textsecuregcm/push/WebsocketSender.java b/src/main/java/org/whispersystems/textsecuregcm/push/WebsocketSender.java index 942073bab..756896257 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/push/WebsocketSender.java +++ b/src/main/java/org/whispersystems/textsecuregcm/push/WebsocketSender.java @@ -31,7 +31,7 @@ import org.whispersystems.textsecuregcm.websocket.ProvisioningAddress; import org.whispersystems.textsecuregcm.websocket.WebsocketAddress; import static com.codahale.metrics.MetricRegistry.name; -import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage; public class WebsocketSender { @@ -66,7 +66,7 @@ public class WebsocketSender { this.pubSubManager = pubSubManager; } - public DeliveryStatus sendMessage(Account account, Device device, OutgoingMessageSignal message, Type channel) { + public DeliveryStatus sendMessage(Account account, Device device, Envelope message, Type channel) { WebsocketAddress address = new WebsocketAddress(account.getNumber(), device.getId()); PubSubMessage pubSubMessage = PubSubMessage.newBuilder() .setType(PubSubMessage.Type.DELIVER) diff --git a/src/main/java/org/whispersystems/textsecuregcm/storage/Messages.java b/src/main/java/org/whispersystems/textsecuregcm/storage/Messages.java index 99e97d10a..8f7e962f1 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/storage/Messages.java +++ b/src/main/java/org/whispersystems/textsecuregcm/storage/Messages.java @@ -10,7 +10,7 @@ import org.skife.jdbi.v2.sqlobject.SqlQuery; import org.skife.jdbi.v2.sqlobject.SqlUpdate; import org.skife.jdbi.v2.sqlobject.customizers.Mapper; import org.skife.jdbi.v2.tweak.ResultSetMapper; -import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; import java.lang.annotation.Annotation; @@ -33,11 +33,12 @@ public abstract class Messages { private static final String DESTINATION = "destination"; private static final String DESTINATION_DEVICE = "destination_device"; private static final String MESSAGE = "message"; + private static final String CONTENT = "content"; - @SqlQuery("INSERT INTO messages (" + TYPE + ", " + RELAY + ", " + TIMESTAMP + ", " + SOURCE + ", " + SOURCE_DEVICE + ", " + DESTINATION + ", " + DESTINATION_DEVICE + ", " + MESSAGE + ") " + - "VALUES (:type, :relay, :timestamp, :source, :source_device, :destination, :destination_device, :message) " + - "RETURNING (SELECT COUNT(id) FROM messages WHERE " + DESTINATION + " = :destination AND " + DESTINATION_DEVICE + " = :destination_device AND " + TYPE + " != " + OutgoingMessageSignal.Type.RECEIPT_VALUE + ")") - abstract int store(@MessageBinder OutgoingMessageSignal message, + @SqlQuery("INSERT INTO messages (" + TYPE + ", " + RELAY + ", " + TIMESTAMP + ", " + SOURCE + ", " + SOURCE_DEVICE + ", " + DESTINATION + ", " + DESTINATION_DEVICE + ", " + MESSAGE + ", " + CONTENT + ") " + + "VALUES (:type, :relay, :timestamp, :source, :source_device, :destination, :destination_device, :message, :content) " + + "RETURNING (SELECT COUNT(id) FROM messages WHERE " + DESTINATION + " = :destination AND " + DESTINATION_DEVICE + " = :destination_device AND " + TYPE + " != " + Envelope.Type.RECEIPT_VALUE + ")") + abstract int store(@MessageBinder Envelope message, @Bind("destination") String destination, @Bind("destination_device") long destinationDevice); @@ -71,7 +72,8 @@ public abstract class Messages { resultSet.getLong(TIMESTAMP), resultSet.getString(SOURCE), resultSet.getInt(SOURCE_DEVICE), - resultSet.getBytes(MESSAGE)); + resultSet.getBytes(MESSAGE), + resultSet.getBytes(CONTENT)); } } @@ -82,18 +84,19 @@ public abstract class Messages { public static class AccountBinderFactory implements BinderFactory { @Override public Binder build(Annotation annotation) { - return new Binder() { + return new Binder() { @Override public void bind(SQLStatement sql, MessageBinder accountBinder, - OutgoingMessageSignal message) + Envelope message) { - sql.bind(TYPE, message.getType()); + sql.bind(TYPE, message.getType().getNumber()); sql.bind(RELAY, message.getRelay()); sql.bind(TIMESTAMP, message.getTimestamp()); sql.bind(SOURCE, message.getSource()); sql.bind(SOURCE_DEVICE, message.getSourceDevice()); - sql.bind(MESSAGE, message.getMessage().toByteArray()); + sql.bind(MESSAGE, message.hasLegacyMessage() ? message.getLegacyMessage().toByteArray() : null); + sql.bind(CONTENT, message.hasContent() ? message.getContent().toByteArray() : null); } }; } diff --git a/src/main/java/org/whispersystems/textsecuregcm/storage/MessagesManager.java b/src/main/java/org/whispersystems/textsecuregcm/storage/MessagesManager.java index e163a922c..dfcf16f95 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/storage/MessagesManager.java +++ b/src/main/java/org/whispersystems/textsecuregcm/storage/MessagesManager.java @@ -2,9 +2,8 @@ package org.whispersystems.textsecuregcm.storage; import com.google.common.base.Optional; -import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; -import org.whispersystems.textsecuregcm.util.Pair; import java.util.List; @@ -16,7 +15,7 @@ public class MessagesManager { this.messages = messages; } - public int insert(String destination, long destinationDevice, OutgoingMessageSignal message) { + public int insert(String destination, long destinationDevice, Envelope message) { return this.messages.store(message, destination, destinationDevice) + 1; } diff --git a/src/main/java/org/whispersystems/textsecuregcm/websocket/DeadLetterHandler.java b/src/main/java/org/whispersystems/textsecuregcm/websocket/DeadLetterHandler.java index 516609a67..e5421a827 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/websocket/DeadLetterHandler.java +++ b/src/main/java/org/whispersystems/textsecuregcm/websocket/DeadLetterHandler.java @@ -4,9 +4,8 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.dispatch.DispatchChannel; -import org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.storage.MessagesManager; -import org.whispersystems.textsecuregcm.storage.PubSubProtos; import org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage; public class DeadLetterHandler implements DispatchChannel { @@ -29,7 +28,7 @@ public class DeadLetterHandler implements DispatchChannel { switch (pubSubMessage.getType().getNumber()) { case PubSubMessage.Type.DELIVER_VALUE: - OutgoingMessageSignal message = OutgoingMessageSignal.parseFrom(pubSubMessage.getContent()); + Envelope message = Envelope.parseFrom(pubSubMessage.getContent()); messagesManager.insert(address.getNumber(), address.getDeviceId(), message); break; } diff --git a/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java b/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java index 5410b2a23..27e243437 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java +++ b/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java @@ -29,7 +29,7 @@ import javax.ws.rs.WebApplicationException; import java.io.IOException; import java.util.List; -import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import static org.whispersystems.textsecuregcm.storage.PubSubProtos.PubSubMessage; public class WebSocketConnection implements DispatchChannel { @@ -69,7 +69,7 @@ public class WebSocketConnection implements DispatchChannel { processStoredMessages(); break; case PubSubMessage.Type.DELIVER_VALUE: - sendMessage(OutgoingMessageSignal.parseFrom(pubSubMessage.getContent()), Optional.absent()); + sendMessage(Envelope.parseFrom(pubSubMessage.getContent()), Optional.absent()); break; default: logger.warn("Unknown pubsub message: " + pubSubMessage.getType().getNumber()); @@ -88,7 +88,7 @@ public class WebSocketConnection implements DispatchChannel { processStoredMessages(); } - private void sendMessage(final OutgoingMessageSignal message, + private void sendMessage(final Envelope message, final Optional storedMessageId) { try { @@ -99,7 +99,7 @@ public class WebSocketConnection implements DispatchChannel { Futures.addCallback(response, new FutureCallback() { @Override public void onSuccess(@Nullable WebSocketResponseMessage response) { - boolean isReceipt = message.getType() == OutgoingMessageSignal.Type.RECEIPT_VALUE; + boolean isReceipt = message.getType() == Envelope.Type.RECEIPT; if (isSuccessResponse(response)) { if (storedMessageId.isPresent()) messagesManager.delete(account.getNumber(), storedMessageId.get()); @@ -123,7 +123,7 @@ public class WebSocketConnection implements DispatchChannel { } } - private void requeueMessage(OutgoingMessageSignal message) { + private void requeueMessage(Envelope message) { try { pushSender.sendMessage(account, device, message); } catch (NotPushRegisteredException | TransientPushFailureException e) { @@ -132,7 +132,7 @@ public class WebSocketConnection implements DispatchChannel { } } - private void sendDeliveryReceiptFor(OutgoingMessageSignal message) { + private void sendDeliveryReceiptFor(Envelope message) { try { receiptSender.sendReceipt(account, message.getSource(), message.getTimestamp(), message.hasRelay() ? Optional.of(message.getRelay()) : @@ -148,12 +148,19 @@ public class WebSocketConnection implements DispatchChannel { List messages = messagesManager.getMessagesForDevice(account.getNumber(), device.getId()); for (OutgoingMessageEntity message : messages) { - OutgoingMessageSignal.Builder builder = OutgoingMessageSignal.newBuilder() - .setType(message.getType()) - .setMessage(ByteString.copyFrom(message.getMessage())) - .setSourceDevice(message.getSourceDevice()) - .setSource(message.getSource()) - .setTimestamp(message.getTimestamp()); + Envelope.Builder builder = Envelope.newBuilder() + .setType(Envelope.Type.valueOf(message.getType())) + .setSourceDevice(message.getSourceDevice()) + .setSource(message.getSource()) + .setTimestamp(message.getTimestamp()); + + if (message.getMessage() != null) { + builder.setLegacyMessage(ByteString.copyFrom(message.getMessage())); + } + + if (message.getContent() != null) { + builder.setContent(ByteString.copyFrom(message.getContent())); + } if (message.getRelay() != null && !message.getRelay().isEmpty()) { builder.setRelay(message.getRelay()); diff --git a/src/main/resources/messagedb.xml b/src/main/resources/messagedb.xml index 47b8b6dd1..54b212b59 100644 --- a/src/main/resources/messagedb.xml +++ b/src/main/resources/messagedb.xml @@ -57,4 +57,12 @@ + + + + + + + + diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java index d0a455029..2cc364511 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java @@ -106,7 +106,7 @@ public class FederatedControllerTest { assertThat("Good Response", response.getStatus(), is(equalTo(204))); - verify(pushSender).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); + verify(pushSender).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.Envelope.class)); } @Test diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java index 94c5d79e4..f6d081b35 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java @@ -3,13 +3,12 @@ package org.whispersystems.textsecuregcm.tests.controllers; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Optional; import com.sun.jersey.api.client.ClientResponse; -import org.hamcrest.CoreMatchers; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.whispersystems.textsecuregcm.controllers.MessageController; import org.whispersystems.textsecuregcm.entities.IncomingMessageList; -import org.whispersystems.textsecuregcm.entities.MessageProtos; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.entities.MismatchedDevices; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity; import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntityList; @@ -25,7 +24,6 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; -import org.whispersystems.textsecuregcm.util.SystemMapper; import javax.ws.rs.core.MediaType; import java.util.HashSet; @@ -100,7 +98,7 @@ public class MessageControllerTest { assertThat("Good Response", response.getStatus(), is(equalTo(200))); - verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); + verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class)); } @Test @@ -114,7 +112,7 @@ public class MessageControllerTest { assertThat("Good Response", response.getStatus(), is(equalTo(200))); - verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); + verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class)); } @Test @@ -164,7 +162,7 @@ public class MessageControllerTest { assertThat("Good Response Code", response.getStatus(), is(equalTo(200))); - verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); + verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class)); } @Test @@ -193,8 +191,8 @@ public class MessageControllerTest { final long timestampTwo = 313388; List messages = new LinkedList() {{ - add(new OutgoingMessageEntity(1L, MessageProtos.OutgoingMessageSignal.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes())); - add(new OutgoingMessageEntity(2L, MessageProtos.OutgoingMessageSignal.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null)); + add(new OutgoingMessageEntity(1L, Envelope.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes(), null)); + add(new OutgoingMessageEntity(2L, Envelope.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null, null)); }}; when(messagesManager.getMessagesForDevice(eq(AuthHelper.VALID_NUMBER), eq(1L))).thenReturn(messages); @@ -220,15 +218,15 @@ public class MessageControllerTest { long timestamp = System.currentTimeMillis(); when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31337)) .thenReturn(Optional.of(new OutgoingMessageEntity(31337L, - MessageProtos.OutgoingMessageSignal.Type.CIPHERTEXT_VALUE, + Envelope.Type.CIPHERTEXT_VALUE, null, timestamp, - "+14152222222", 1, "hi".getBytes()))); + "+14152222222", 1, "hi".getBytes(), null))); when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31338)) .thenReturn(Optional.of(new OutgoingMessageEntity(31337L, - MessageProtos.OutgoingMessageSignal.Type.RECEIPT_VALUE, + Envelope.Type.RECEIPT_VALUE, null, System.currentTimeMillis(), - "+14152222222", 1, null))); + "+14152222222", 1, null, null))); when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31339)) diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java index 55cb2543e..b721ed23a 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java @@ -8,6 +8,7 @@ import org.junit.Rule; import org.junit.Test; import org.whispersystems.textsecuregcm.controllers.ReceiptController; import org.whispersystems.textsecuregcm.entities.MessageProtos; +import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.push.PushSender; import org.whispersystems.textsecuregcm.push.ReceiptSender; @@ -70,7 +71,7 @@ public class ReceiptControllerTest { assertThat(response.getStatus() == 204); - verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); + verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class)); } @Test @@ -82,7 +83,7 @@ public class ReceiptControllerTest { assertThat(response.getStatus() == 204); - verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.OutgoingMessageSignal.class)); + verify(pushSender, times(2)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class)); } diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java index ff4bb1903..fd4a700b1 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java @@ -5,7 +5,6 @@ import com.google.common.util.concurrent.SettableFuture; import com.google.protobuf.ByteString; import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.junit.Test; -import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; @@ -20,7 +19,6 @@ import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.PubSubManager; import org.whispersystems.textsecuregcm.storage.PubSubProtos; import org.whispersystems.textsecuregcm.util.Base64; -import org.whispersystems.textsecuregcm.util.Pair; import org.whispersystems.textsecuregcm.websocket.AuthenticatedConnectListener; import org.whispersystems.textsecuregcm.websocket.WebSocketAccountAuthenticator; import org.whispersystems.textsecuregcm.websocket.WebSocketConnection; @@ -28,7 +26,6 @@ import org.whispersystems.textsecuregcm.websocket.WebsocketAddress; import org.whispersystems.websocket.WebSocketClient; import org.whispersystems.websocket.messages.WebSocketResponseMessage; import org.whispersystems.websocket.session.WebSocketSessionContext; -import org.whispersystems.websocket.setup.WebSocketConnectListener; import java.io.IOException; import java.util.HashMap; @@ -38,12 +35,10 @@ import java.util.List; import java.util.Set; import io.dropwizard.auth.basic.BasicCredentials; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; -import static org.whispersystems.textsecuregcm.entities.MessageProtos.OutgoingMessageSignal; +import static org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; public class WebSocketConnectionTest { @@ -169,21 +164,21 @@ public class WebSocketConnectionTest { @Test public void testOnlineSend() throws Exception { MessagesManager storedMessages = mock(MessagesManager.class); - OutgoingMessageSignal firstMessage = OutgoingMessageSignal.newBuilder() - .setMessage(ByteString.copyFrom("first".getBytes())) - .setSource("sender1") - .setTimestamp(System.currentTimeMillis()) - .setSourceDevice(1) - .setType(OutgoingMessageSignal.Type.CIPHERTEXT_VALUE) - .build(); + Envelope firstMessage = Envelope.newBuilder() + .setLegacyMessage(ByteString.copyFrom("first".getBytes())) + .setSource("sender1") + .setTimestamp(System.currentTimeMillis()) + .setSourceDevice(1) + .setType(Envelope.Type.CIPHERTEXT) + .build(); - OutgoingMessageSignal secondMessage = OutgoingMessageSignal.newBuilder() - .setMessage(ByteString.copyFrom("second".getBytes())) - .setSource("sender2") - .setTimestamp(System.currentTimeMillis()) - .setSourceDevice(2) - .setType(OutgoingMessageSignal.Type.CIPHERTEXT_VALUE) - .build(); + Envelope secondMessage = Envelope.newBuilder() + .setLegacyMessage(ByteString.copyFrom("second".getBytes())) + .setSource("sender2") + .setTimestamp(System.currentTimeMillis()) + .setSourceDevice(2) + .setType(Envelope.Type.CIPHERTEXT) + .build(); List pendingMessages = new LinkedList<>(); @@ -246,15 +241,15 @@ public class WebSocketConnectionTest { futures.get(0).setException(new IOException()); verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()), eq(Optional.absent())); - verify(pushSender, times(1)).sendMessage(eq(account), eq(device), any(OutgoingMessageSignal.class)); + verify(pushSender, times(1)).sendMessage(eq(account), eq(device), any(Envelope.class)); connection.onDispatchUnsubscribed(websocketAddress.serialize()); verify(client).close(anyInt(), anyString()); } private OutgoingMessageEntity createMessage(long id, String sender, long timestamp, boolean receipt, String content) { - return new OutgoingMessageEntity(id, receipt ? OutgoingMessageSignal.Type.RECEIPT_VALUE : OutgoingMessageSignal.Type.CIPHERTEXT_VALUE, - null, timestamp, sender, 1, content.getBytes()); + return new OutgoingMessageEntity(id, receipt ? Envelope.Type.RECEIPT_VALUE : Envelope.Type.CIPHERTEXT_VALUE, + null, timestamp, sender, 1, content.getBytes(), null); } }