From a06a663b940daf5ce0597fa01cc402206962a5ad Mon Sep 17 00:00:00 2001 From: Chris Eager Date: Fri, 29 Jul 2022 16:05:49 -0500 Subject: [PATCH] =?UTF-8?q?Use=20the=20envelope=E2=80=99s=20destination=20?= =?UTF-8?q?UUID=20for=20receipt=20source=20UUID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/MessageController.java | 4 +- .../textsecuregcm/push/ReceiptSender.java | 11 +++--- .../websocket/WebSocketConnection.java | 4 +- .../controllers/MessageControllerTest.java | 3 +- .../websocket/WebSocketConnectionTest.java | 39 ++++++++++++------- 5 files changed, 37 insertions(+), 24 deletions(-) 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 319e94be5..a3b850bfa 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/MessageController.java @@ -467,7 +467,9 @@ public class MessageController { if (deletedMessage.hasSourceUuid() && deletedMessage.getType() != Type.SERVER_DELIVERY_RECEIPT) { try { - receiptSender.sendReceipt(auth, UUID.fromString(deletedMessage.getSourceUuid()), deletedMessage.getTimestamp()); + receiptSender.sendReceipt( + UUID.fromString(deletedMessage.getDestinationUuid()), auth.getAuthenticatedDevice().getId(), + UUID.fromString(deletedMessage.getSourceUuid()), deletedMessage.getTimestamp()); } catch (Exception e) { logger.warn("Failed to send delivery receipt", e); } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java b/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java index f21fa8645..7169c17e5 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java @@ -12,7 +12,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount; import org.whispersystems.textsecuregcm.controllers.NoSuchUserException; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.metrics.MetricsUtil; @@ -38,9 +37,9 @@ public class ReceiptSender { MetricsUtil.name(ReceiptSender.class, "executor")); } - public CompletableFuture sendReceipt(AuthenticatedAccount source, UUID destinationUuid, long messageId) throws NoSuchUserException { - final Account sourceAccount = source.getAccount(); - if (sourceAccount.getUuid().equals(destinationUuid)) { + public CompletableFuture sendReceipt(UUID sourceUuid, long sourceDeviceId, UUID destinationUuid, long messageId) + throws NoSuchUserException { + if (sourceUuid.equals(destinationUuid)) { return CompletableFuture.completedFuture(null); } @@ -49,8 +48,8 @@ public class ReceiptSender { final Envelope.Builder message = Envelope.newBuilder() .setServerTimestamp(System.currentTimeMillis()) - .setSourceUuid(sourceAccount.getUuid().toString()) - .setSourceDevice((int) source.getAuthenticatedDevice().getId()) + .setSourceUuid(sourceUuid.toString()) + .setSourceDevice((int) sourceDeviceId) .setDestinationUuid(destinationUuid.toString()) .setTimestamp(messageId) .setType(Envelope.Type.SERVER_DELIVERY_RECEIPT); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java b/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java index 31c73f65a..89466c63e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnection.java @@ -231,7 +231,9 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac } try { - receiptSender.sendReceipt(auth, UUID.fromString(message.getSourceUuid()), message.getTimestamp()); + receiptSender.sendReceipt(UUID.fromString(message.getDestinationUuid()), + auth.getAuthenticatedDevice().getId(), UUID.fromString(message.getSourceUuid()), + message.getTimestamp()); } catch (NoSuchUserException e) { logger.info("No longer registered: {}", e.getMessage()); } catch (WebApplicationException e) { diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java index 182f0c514..14c94d647 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/MessageControllerTest.java @@ -465,7 +465,8 @@ class MessageControllerTest { .delete(); assertThat("Good Response Code", response.getStatus(), is(equalTo(204))); - verify(receiptSender).sendReceipt(any(AuthenticatedAccount.class), eq(sourceUuid), eq(timestamp)); + verify(receiptSender).sendReceipt(eq(AuthHelper.VALID_UUID), eq(1L), + eq(sourceUuid), eq(timestamp)); response = resources.getJerseyTest() .target(String.format("/v1/messages/uuid/%s", uuid2)) diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java index 4830e629e..8f0d98221 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/websocket/WebSocketConnectionTest.java @@ -68,10 +68,12 @@ import org.whispersystems.websocket.session.WebSocketSessionContext; class WebSocketConnectionTest { - private static final String VALID_USER = "+14152222222"; + private static final String VALID_USER = "+14152222222"; private static final String INVALID_USER = "+14151111111"; - private static final String VALID_PASSWORD = "secure"; + private static final int SOURCE_DEVICE_ID = 1; + + private static final String VALID_PASSWORD = "secure"; private static final String INVALID_PASSWORD = "insecure"; private AccountAuthenticator accountAuthenticator; @@ -138,15 +140,16 @@ class WebSocketConnectionTest { void testOpen() throws Exception { MessagesManager storedMessages = mock(MessagesManager.class); - UUID accountUuid = UUID.randomUUID(); + UUID accountUuid = UUID.randomUUID(); UUID senderOneUuid = UUID.randomUUID(); UUID senderTwoUuid = UUID.randomUUID(); - List outgoingMessages = List.of(createMessage("sender1", senderOneUuid, UUID.randomUUID(), 1111, "first"), - createMessage("sender1", senderOneUuid, UUID.randomUUID(), 2222, "second"), - createMessage("sender2", senderTwoUuid, UUID.randomUUID(), 3333, "third")); + List outgoingMessages = List.of(createMessage("sender1", senderOneUuid, accountUuid, 1111, "first"), + createMessage("sender1", senderOneUuid, accountUuid, 2222, "second"), + createMessage("sender2", senderTwoUuid, accountUuid, 3333, "third")); - when(device.getId()).thenReturn(2L); + final long deviceId = 2L; + when(device.getId()).thenReturn(deviceId); when(account.getNumber()).thenReturn("+14152222222"); when(account.getUuid()).thenReturn(accountUuid); @@ -196,8 +199,10 @@ class WebSocketConnectionTest { futures.get(0).completeExceptionally(new IOException()); futures.get(2).completeExceptionally(new IOException()); - verify(storedMessages, times(1)).delete(eq(accountUuid), eq(2L), eq(UUID.fromString(outgoingMessages.get(1).getServerGuid())), eq(outgoingMessages.get(1).getServerTimestamp())); - verify(receiptSender, times(1)).sendReceipt(eq(auth), eq(senderOneUuid), eq(2222L)); + verify(storedMessages, times(1)).delete(eq(accountUuid), eq(deviceId), + eq(UUID.fromString(outgoingMessages.get(1).getServerGuid())), eq(outgoingMessages.get(1).getServerTimestamp())); + verify(receiptSender, times(1)).sendReceipt(eq(accountUuid), eq(deviceId), eq(senderOneUuid), + eq(2222L)); connection.stop(); verify(client).close(anyInt(), anyString()); @@ -268,12 +273,13 @@ class WebSocketConnectionTest { void testPendingSend() throws Exception { MessagesManager storedMessages = mock(MessagesManager.class); + final UUID accountUuid = UUID.randomUUID(); final UUID senderTwoUuid = UUID.randomUUID(); final Envelope firstMessage = Envelope.newBuilder() .setServerGuid(UUID.randomUUID().toString()) .setSourceUuid(UUID.randomUUID().toString()) - .setDestinationUuid(UUID.randomUUID().toString()) + .setDestinationUuid(accountUuid.toString()) .setUpdatedPni(UUID.randomUUID().toString()) .setTimestamp(System.currentTimeMillis()) .setSourceDevice(1) @@ -283,7 +289,7 @@ class WebSocketConnectionTest { final Envelope secondMessage = Envelope.newBuilder() .setServerGuid(UUID.randomUUID().toString()) .setSourceUuid(senderTwoUuid.toString()) - .setDestinationUuid(UUID.randomUUID().toString()) + .setDestinationUuid(accountUuid.toString()) .setTimestamp(System.currentTimeMillis()) .setSourceDevice(2) .setType(Envelope.Type.CIPHERTEXT) @@ -291,10 +297,11 @@ class WebSocketConnectionTest { final List pendingMessages = List.of(firstMessage, secondMessage); - when(device.getId()).thenReturn(2L); + final long deviceId = 2L; + when(device.getId()).thenReturn(deviceId); when(account.getNumber()).thenReturn("+14152222222"); - when(account.getUuid()).thenReturn(UUID.randomUUID()); + when(account.getUuid()).thenReturn(accountUuid); final Device sender1device = mock(Device.class); @@ -336,7 +343,8 @@ class WebSocketConnectionTest { futures.get(1).complete(response); futures.get(0).completeExceptionally(new IOException()); - verify(receiptSender, times(1)).sendReceipt(eq(auth), eq(senderTwoUuid), eq(secondMessage.getTimestamp())); + verify(receiptSender, times(1)).sendReceipt(eq(account.getUuid()), eq(deviceId), eq(senderTwoUuid), + eq(secondMessage.getTimestamp())); connection.stop(); verify(client).close(anyInt(), anyString()); @@ -627,6 +635,7 @@ class WebSocketConnectionTest { when(account.getNumber()).thenReturn("+18005551234"); when(account.getUuid()).thenReturn(accountUuid); when(device.getId()).thenReturn(1L); + when(client.isOpen()).thenReturn(true); when(client.getUserAgent()).thenReturn("Test-UA"); when(messagesManager.getMessagesForDevice(eq(accountUuid), eq(1L), eq("Test-UA"), anyBoolean())) @@ -853,7 +862,7 @@ class WebSocketConnectionTest { .setTimestamp(timestamp) .setServerTimestamp(0) .setSourceUuid(senderUuid.toString()) - .setSourceDevice(1) + .setSourceDevice(SOURCE_DEVICE_ID) .setDestinationUuid(destinationUuid.toString()) .setContent(ByteString.copyFrom(content.getBytes(StandardCharsets.UTF_8))) .build();