mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 02:18:08 +01:00
Detect message delivery loops
This commit is contained in:
@@ -103,6 +103,7 @@ import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.PniServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.limits.CardinalityEstimator;
|
||||
import org.whispersystems.textsecuregcm.limits.MessageDeliveryLoopMonitor;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper;
|
||||
@@ -205,7 +206,8 @@ class MessageControllerTest {
|
||||
new MessageController(rateLimiters, cardinalityEstimator, messageSender, receiptSender, accountsManager,
|
||||
messagesManager, pushNotificationManager, pushNotificationScheduler, reportMessageManager, multiRecipientMessageExecutor,
|
||||
messageDeliveryScheduler, ReportSpamTokenProvider.noop(), mock(ClientReleaseManager.class), dynamicConfigurationManager,
|
||||
serverSecretParams, SpamChecker.noop(), new MessageMetrics(), clock))
|
||||
serverSecretParams, SpamChecker.noop(), new MessageMetrics(), mock(MessageDeliveryLoopMonitor.class),
|
||||
clock))
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.whispersystems.textsecuregcm.limits;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
|
||||
class MessageDeliveryLoopMonitorTest {
|
||||
|
||||
private MessageDeliveryLoopMonitor messageDeliveryLoopMonitor;
|
||||
|
||||
@RegisterExtension
|
||||
static final RedisClusterExtension REDIS_CLUSTER_EXTENSION = RedisClusterExtension.builder().build();
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
messageDeliveryLoopMonitor = new MessageDeliveryLoopMonitor(REDIS_CLUSTER_EXTENSION.getRedisCluster());
|
||||
}
|
||||
|
||||
@Test
|
||||
void incrementDeliveryAttemptCount() {
|
||||
final UUID accountIdentifier = UUID.randomUUID();
|
||||
final byte deviceId = Device.PRIMARY_ID;
|
||||
|
||||
assertEquals(1, messageDeliveryLoopMonitor.incrementDeliveryAttemptCount(accountIdentifier, deviceId, UUID.randomUUID()).join());
|
||||
assertEquals(1, messageDeliveryLoopMonitor.incrementDeliveryAttemptCount(accountIdentifier, deviceId, UUID.randomUUID()).join());
|
||||
|
||||
final UUID repeatedDeliveryGuid = UUID.randomUUID();
|
||||
|
||||
for (int i = 1; i < 10; i++) {
|
||||
assertEquals(i, messageDeliveryLoopMonitor.incrementDeliveryAttemptCount(accountIdentifier, deviceId, repeatedDeliveryGuid).join());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import org.mockito.stubbing.Answer;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
|
||||
import org.whispersystems.textsecuregcm.limits.MessageDeliveryLoopMonitor;
|
||||
import org.whispersystems.textsecuregcm.metrics.MessageMetrics;
|
||||
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
||||
import org.whispersystems.textsecuregcm.push.PushNotificationScheduler;
|
||||
@@ -133,7 +134,8 @@ class WebSocketConnectionIntegrationTest {
|
||||
webSocketClient,
|
||||
scheduledExecutorService,
|
||||
messageDeliveryScheduler,
|
||||
clientReleaseManager);
|
||||
clientReleaseManager,
|
||||
mock(MessageDeliveryLoopMonitor.class));
|
||||
|
||||
final List<MessageProtos.Envelope> expectedMessages = new ArrayList<>(persistedMessageCount + cachedMessageCount);
|
||||
|
||||
@@ -220,7 +222,8 @@ class WebSocketConnectionIntegrationTest {
|
||||
webSocketClient,
|
||||
scheduledExecutorService,
|
||||
messageDeliveryScheduler,
|
||||
clientReleaseManager);
|
||||
clientReleaseManager,
|
||||
mock(MessageDeliveryLoopMonitor.class));
|
||||
|
||||
final int persistedMessageCount = 207;
|
||||
final int cachedMessageCount = 173;
|
||||
@@ -289,7 +292,8 @@ class WebSocketConnectionIntegrationTest {
|
||||
100, // use a very short timeout, so that this test completes quickly
|
||||
scheduledExecutorService,
|
||||
messageDeliveryScheduler,
|
||||
clientReleaseManager);
|
||||
clientReleaseManager,
|
||||
mock(MessageDeliveryLoopMonitor.class));
|
||||
|
||||
final int persistedMessageCount = 207;
|
||||
final int cachedMessageCount = 173;
|
||||
|
||||
@@ -56,6 +56,7 @@ import org.mockito.stubbing.Answer;
|
||||
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
|
||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.limits.MessageDeliveryLoopMonitor;
|
||||
import org.whispersystems.textsecuregcm.metrics.MessageMetrics;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
||||
@@ -124,7 +125,8 @@ class WebSocketConnectionTest {
|
||||
new WebSocketAccountAuthenticator(accountAuthenticator, mock(PrincipalSupplier.class));
|
||||
AuthenticatedConnectListener connectListener = new AuthenticatedConnectListener(receiptSender, messagesManager,
|
||||
new MessageMetrics(), mock(PushNotificationManager.class), mock(PushNotificationScheduler.class),
|
||||
mock(ClientPresenceManager.class), retrySchedulingExecutor, messageDeliveryScheduler, clientReleaseManager);
|
||||
mock(ClientPresenceManager.class), retrySchedulingExecutor, messageDeliveryScheduler, clientReleaseManager,
|
||||
mock(MessageDeliveryLoopMonitor.class));
|
||||
WebSocketSessionContext sessionContext = mock(WebSocketSessionContext.class);
|
||||
|
||||
when(accountAuthenticator.authenticate(eq(new BasicCredentials(VALID_USER, VALID_PASSWORD))))
|
||||
@@ -628,7 +630,7 @@ class WebSocketConnectionTest {
|
||||
private @NotNull WebSocketConnection webSocketConnection(final WebSocketClient client) {
|
||||
return new WebSocketConnection(receiptSender, messagesManager, new MessageMetrics(),
|
||||
mock(PushNotificationManager.class), mock(PushNotificationScheduler.class), auth, client,
|
||||
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager);
|
||||
retrySchedulingExecutor, Schedulers.immediate(), clientReleaseManager, mock(MessageDeliveryLoopMonitor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user