From 6906336dfb9d94f8810adc288c642685b49f7a24 Mon Sep 17 00:00:00 2001 From: Ehren Kret Date: Fri, 14 May 2021 14:45:12 -0500 Subject: [PATCH] Include the uuid with the list of mismatched devices --- .../controllers/MessageController.java | 69 ++++++++++--------- .../entities/AccountMismatchedDevices.java | 22 ++++++ 2 files changed, 59 insertions(+), 32 deletions(-) create mode 100644 service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountMismatchedDevices.java diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java index 444947a0c..0c1ee9e75 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java @@ -38,7 +38,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.stream.Collectors; -import javax.annotation.Nullable; import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -62,6 +61,7 @@ import org.whispersystems.textsecuregcm.auth.Anonymous; import org.whispersystems.textsecuregcm.auth.CombinedUnidentifiedSenderAccessKeys; import org.whispersystems.textsecuregcm.auth.OptionalAccess; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicMessageRateConfiguration; +import org.whispersystems.textsecuregcm.entities.AccountMismatchedDevices; import org.whispersystems.textsecuregcm.entities.IncomingMessage; import org.whispersystems.textsecuregcm.entities.IncomingMessageList; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; @@ -359,42 +359,47 @@ public class MessageController { })); checkAccessKeys(accessKeys, uuidToAccountMap); - try { - for (Account account : uuidToAccountMap.values()) { - Set deviceIds = Arrays.stream(multiRecipientMessage.getRecipients()) - .filter(recipient -> recipient.getUuid().equals(account.getUuid())) - .map(Recipient::getDeviceId) - .collect(Collectors.toSet()); + List accountMismatchedDevices = new ArrayList<>(); + for (Account account : uuidToAccountMap.values()) { + Set deviceIds = Arrays.stream(multiRecipientMessage.getRecipients()) + .filter(recipient -> recipient.getUuid().equals(account.getUuid())) + .map(Recipient::getDeviceId) + .collect(Collectors.toSet()); + try { validateCompleteDeviceList(account, deviceIds, false); + } catch (MismatchedDevicesException e) { + accountMismatchedDevices.add(new AccountMismatchedDevices(account.getUuid(), + new MismatchedDevices(e.getMissingDevices(), e.getExtraDevices()))); } - - List tags = List.of( - UserAgentTagUtil.getPlatformTag(userAgent), - Tag.of(EPHEMERAL_TAG_NAME, String.valueOf(online)), - Tag.of(SENDER_TYPE_TAG_NAME, "unidentified")); - List uuids404 = new ArrayList<>(); - for (Recipient recipient : multiRecipientMessage.getRecipients()) { - - Account destinationAccount = uuidToAccountMap.get(recipient.getUuid()); - // we asserted this must be true in validateCompleteDeviceList - //noinspection OptionalGetWithoutIsPresent - Device destinationDevice = destinationAccount.getDevice(recipient.getDeviceId()).get(); - Metrics.counter(SENT_MESSAGE_COUNTER_NAME, tags).increment(); - try { - sendMessage(destinationAccount, destinationDevice, timestamp, online, recipient, - multiRecipientMessage.getCommonPayload()); - } catch (NoSuchUserException e) { - uuids404.add(destinationAccount.getUuid()); - } - } - return Response.ok(new SendMessageResponse(uuids404)).build(); - } catch (MismatchedDevicesException e) { - throw new WebApplicationException(Response + } + if (!accountMismatchedDevices.isEmpty()) { + return Response .status(409) .type(MediaType.APPLICATION_JSON_TYPE) - .entity(new MismatchedDevices(e.getMissingDevices(), e.getExtraDevices())) - .build()); + .entity(accountMismatchedDevices) + .build(); } + + List tags = List.of( + UserAgentTagUtil.getPlatformTag(userAgent), + Tag.of(EPHEMERAL_TAG_NAME, String.valueOf(online)), + Tag.of(SENDER_TYPE_TAG_NAME, "unidentified")); + List uuids404 = new ArrayList<>(); + for (Recipient recipient : multiRecipientMessage.getRecipients()) { + + Account destinationAccount = uuidToAccountMap.get(recipient.getUuid()); + // we asserted this must be true in validateCompleteDeviceList + //noinspection OptionalGetWithoutIsPresent + Device destinationDevice = destinationAccount.getDevice(recipient.getDeviceId()).get(); + Metrics.counter(SENT_MESSAGE_COUNTER_NAME, tags).increment(); + try { + sendMessage(destinationAccount, destinationDevice, timestamp, online, recipient, + multiRecipientMessage.getCommonPayload()); + } catch (NoSuchUserException e) { + uuids404.add(destinationAccount.getUuid()); + } + } + return Response.ok(new SendMessageResponse(uuids404)).build(); } private void checkAccessKeys(CombinedUnidentifiedSenderAccessKeys accessKeys, Map uuidToAccountMap) { diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountMismatchedDevices.java b/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountMismatchedDevices.java new file mode 100644 index 000000000..992c6d0ab --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountMismatchedDevices.java @@ -0,0 +1,22 @@ +/* + * Copyright 2021 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.whispersystems.textsecuregcm.entities; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.UUID; + +public class AccountMismatchedDevices { + @JsonProperty + public final UUID uuid; + + @JsonProperty + public final MismatchedDevices devices; + + public AccountMismatchedDevices(final UUID uuid, final MismatchedDevices devices) { + this.uuid = uuid; + this.devices = devices; + } +}