Add methods to convert `IncomingMessage`/`OutgoingMessageEntity` instances into `Envelope` entities

This commit is contained in:
Jon Chambers 2022-07-27 14:04:28 -04:00 committed by Jon Chambers
parent e28f1e8ceb
commit d385838dc1
4 changed files with 77 additions and 54 deletions

View File

@ -520,29 +520,19 @@ public class MessageController {
String userAgentString)
throws NoSuchUserException {
try {
Optional<byte[]> messageContent = getMessageContent(incomingMessage);
Envelope.Builder messageBuilder = Envelope.newBuilder();
final Envelope envelope;
final Envelope.Type envelopeType = Envelope.Type.forNumber(incomingMessage.type());
if (envelopeType == null) {
try {
envelope = incomingMessage.toEnvelope(destinationUuid,
source.map(AuthenticatedAccount::getAccount).orElse(null),
source.map(authenticatedAccount -> authenticatedAccount.getAuthenticatedDevice().getId()).orElse(null),
timestamp == 0 ? System.currentTimeMillis() : timestamp);
} catch (final IllegalArgumentException e) {
logger.warn("Received bad envelope type {} from {}", incomingMessage.type(), userAgentString);
throw new BadRequestException();
throw new BadRequestException(e);
}
messageBuilder.setType(envelopeType)
.setTimestamp(timestamp == 0 ? System.currentTimeMillis() : timestamp)
.setServerTimestamp(System.currentTimeMillis())
.setDestinationUuid(destinationUuid.toString());
source.ifPresent(authenticatedAccount ->
messageBuilder.setSource(authenticatedAccount.getAccount().getNumber())
.setSourceUuid(authenticatedAccount.getAccount().getUuid().toString())
.setSourceDevice((int) authenticatedAccount.getAuthenticatedDevice().getId()));
messageContent.ifPresent(bytes -> messageBuilder.setContent(ByteString.copyFrom(bytes)));
messageSender.sendMessage(destinationAccount, destinationDevice, messageBuilder.build(), online);
messageSender.sendMessage(destinationAccount, destinationDevice, envelope, online);
} catch (NotPushRegisteredException e) {
if (destinationDevice.isMaster()) throw new NoSuchUserException(e);
else logger.debug("Not registered", e);

View File

@ -4,6 +4,39 @@
*/
package org.whispersystems.textsecuregcm.entities;
public record IncomingMessage(int type, long destinationDeviceId, int destinationRegistrationId,
String content) {
import com.google.protobuf.ByteString;
import org.apache.commons.lang3.StringUtils;
import org.whispersystems.textsecuregcm.storage.Account;
import javax.annotation.Nullable;
import java.util.Base64;
import java.util.UUID;
public record IncomingMessage(int type, long destinationDeviceId, int destinationRegistrationId, String content) {
public MessageProtos.Envelope toEnvelope(final UUID destinationUuid, @Nullable Account sourceAccount, @Nullable Long sourceDeviceId, final long timestamp) {
final MessageProtos.Envelope.Type envelopeType = MessageProtos.Envelope.Type.forNumber(type());
if (envelopeType == null) {
throw new IllegalArgumentException("Bad envelope type: " + type());
}
final MessageProtos.Envelope.Builder envelopeBuilder = MessageProtos.Envelope.newBuilder();
envelopeBuilder.setType(envelopeType)
.setTimestamp(timestamp)
.setServerTimestamp(System.currentTimeMillis())
.setDestinationUuid(destinationUuid.toString());
if (sourceAccount != null && sourceDeviceId != null) {
envelopeBuilder.setSource(sourceAccount.getNumber())
.setSourceUuid(sourceAccount.getUuid().toString())
.setSourceDevice(sourceDeviceId.intValue());
}
if (StringUtils.isNotEmpty(content())) {
envelopeBuilder.setContent(ByteString.copyFrom(Base64.getDecoder().decode(content())));
}
return envelopeBuilder.build();
}
}

View File

@ -5,8 +5,8 @@
package org.whispersystems.textsecuregcm.entities;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.protobuf.ByteString;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.Objects;
import java.util.UUID;
@ -15,6 +15,34 @@ public record OutgoingMessageEntity(UUID guid, int type, long timestamp, String
int sourceDevice, UUID destinationUuid, UUID updatedPni, byte[] content,
long serverTimestamp) {
public MessageProtos.Envelope toEnvelope() {
final MessageProtos.Envelope.Builder builder = MessageProtos.Envelope.newBuilder()
.setType(MessageProtos.Envelope.Type.forNumber(type()))
.setTimestamp(timestamp())
.setServerTimestamp(serverTimestamp())
.setDestinationUuid(destinationUuid().toString())
.setServerGuid(guid().toString());
if (StringUtils.isNotEmpty(source())) {
builder.setSource(source())
.setSourceDevice(sourceDevice());
if (sourceUuid() != null) {
builder.setSourceUuid(sourceUuid().toString());
}
}
if (content() != null) {
builder.setContent(ByteString.copyFrom(content()));
}
if (updatedPni() != null) {
builder.setUpdatedPni(updatedPni().toString());
}
return builder.build();
}
@Override
public boolean equals(final Object o) {
if (this == o) {

View File

@ -13,9 +13,9 @@ import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries;
import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.ByteString;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -33,7 +33,6 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.LongAdder;
import javax.ws.rs.WebApplicationException;
import io.micrometer.core.instrument.Tags;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -50,7 +49,6 @@ import org.whispersystems.textsecuregcm.storage.MessageAvailabilityListener;
import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.util.Constants;
import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil;
import org.whispersystems.textsecuregcm.util.Util;
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException;
import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil;
@ -314,33 +312,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
for (int i = 0; i < messages.messages().size(); i++) {
final OutgoingMessageEntity message = messages.messages().get(i);
final Envelope.Builder builder = Envelope.newBuilder()
.setType(Envelope.Type.forNumber(message.type()))
.setTimestamp(message.timestamp())
.setServerTimestamp(message.serverTimestamp());
if (!Util.isEmpty(message.source())) {
builder.setSource(message.source())
.setSourceDevice(message.sourceDevice());
if (message.sourceUuid() != null) {
builder.setSourceUuid(message.sourceUuid().toString());
}
}
if (message.content() != null) {
builder.setContent(ByteString.copyFrom(message.content()));
}
builder.setDestinationUuid(message.destinationUuid().toString());
if (message.updatedPni() != null) {
builder.setUpdatedPni(message.updatedPni().toString());
}
builder.setServerGuid(message.guid().toString());
final Envelope envelope = builder.build();
final Envelope envelope = message.toEnvelope();
if (envelope.getSerializedSize() > MAX_DESKTOP_MESSAGE_SIZE && isDesktopClient) {
messagesManager.delete(auth.getAccount().getUuid(), device.getId(), message.guid(), message.serverTimestamp());
@ -348,7 +320,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
sendFutures[i] = CompletableFuture.completedFuture(null);
} else {
sendFutures[i] = sendMessage(builder.build(), Optional.of(new StoredMessageInfo(message.guid(), message.serverTimestamp())));
sendFutures[i] = sendMessage(envelope, Optional.of(new StoredMessageInfo(message.guid(), message.serverTimestamp())));
}
}