mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-24 11:07:58 +01:00
Secret sender
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package org.whispersystems.dispatch;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import java.util.Optional;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExternalResource;
|
||||
@@ -42,7 +42,7 @@ public class DispatchManagerTest {
|
||||
}
|
||||
});
|
||||
|
||||
dispatchManager = new DispatchManager(socketFactory, Optional.<DispatchChannel>absent());
|
||||
dispatchManager = new DispatchManager(socketFactory, Optional.empty());
|
||||
dispatchManager.start();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class DispatchManagerTest {
|
||||
public void testSubscribe() throws IOException {
|
||||
DispatchChannel dispatchChannel = mock(DispatchChannel.class);
|
||||
dispatchManager.subscribe("foo", dispatchChannel);
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "foo", Optional.<byte[]>absent()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "foo", Optional.empty()));
|
||||
|
||||
verify(dispatchChannel, timeout(1000)).onDispatchSubscribed(eq("foo"));
|
||||
}
|
||||
@@ -72,8 +72,8 @@ public class DispatchManagerTest {
|
||||
dispatchManager.subscribe("foo", dispatchChannel);
|
||||
dispatchManager.unsubscribe("foo", dispatchChannel);
|
||||
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "foo", Optional.<byte[]>absent()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.UNSUBSCRIBE, "foo", Optional.<byte[]>absent()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "foo", Optional.empty()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.UNSUBSCRIBE, "foo", Optional.empty()));
|
||||
|
||||
verify(dispatchChannel, timeout(1000)).onDispatchUnsubscribed(eq("foo"));
|
||||
}
|
||||
@@ -86,8 +86,8 @@ public class DispatchManagerTest {
|
||||
dispatchManager.subscribe("foo", fooChannel);
|
||||
dispatchManager.subscribe("bar", barChannel);
|
||||
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "foo", Optional.<byte[]>absent()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "bar", Optional.<byte[]>absent()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "foo", Optional.empty()));
|
||||
pubSubReplyInputStream.write(new PubSubReply(PubSubReply.Type.SUBSCRIBE, "bar", Optional.empty()));
|
||||
|
||||
verify(fooChannel, timeout(1000)).onDispatchSubscribed(eq("foo"));
|
||||
verify(barChannel, timeout(1000)).onDispatchSubscribed(eq("bar"));
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
package org.whispersystems.textsecuregcm.tests.auth;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.textsecuregcm.auth.Anonymous;
|
||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import java.util.Optional;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class OptionalAccessTest {
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedMissingTarget() {
|
||||
try {
|
||||
OptionalAccess.verify(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
throw new AssertionError("should fail");
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 401);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedMissingTargetDevice() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
when(account.getDevice(eq(10))).thenReturn(Optional.empty());
|
||||
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
|
||||
|
||||
try {
|
||||
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("1234".getBytes()))), Optional.of(account), "10");
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 401);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedBadTargetDevice() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
when(account.getDevice(eq(10))).thenReturn(Optional.empty());
|
||||
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
|
||||
|
||||
try {
|
||||
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("1234".getBytes()))), Optional.of(account), "$$");
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 422);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedBadCode() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
|
||||
|
||||
try {
|
||||
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("5678".getBytes()))), Optional.of(account));
|
||||
throw new AssertionError("should fail");
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 401);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentifiedMissingTarget() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
|
||||
try {
|
||||
OptionalAccess.verify(Optional.of(account), Optional.empty(), Optional.empty());
|
||||
throw new AssertionError("should fail");
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 404);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsolicitedBadTarget() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(false);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
|
||||
try {
|
||||
OptionalAccess.verify(Optional.empty(), Optional.empty(), Optional.of(account));
|
||||
throw new AssertionError("shold fai");
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 401);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsolicitedGoodTarget() {
|
||||
Account account = mock(Account.class);
|
||||
Anonymous random = mock(Anonymous.class);
|
||||
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(true);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
OptionalAccess.verify(Optional.empty(), Optional.of(random), Optional.of(account));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedGoodTarget() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
|
||||
when(account.isActive()).thenReturn(true);
|
||||
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("1234".getBytes()))), Optional.of(account));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedInactive() {
|
||||
Account account = mock(Account.class);
|
||||
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
|
||||
when(account.isActive()).thenReturn(false);
|
||||
|
||||
try {
|
||||
OptionalAccess.verify(Optional.empty(), Optional.of(new Anonymous(Base64.encodeBytes("1234".getBytes()))), Optional.of(account));
|
||||
throw new AssertionError();
|
||||
} catch (WebApplicationException e) {
|
||||
assertEquals(e.getResponse().getStatus(), 401);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentifiedGoodTarget() {
|
||||
Account source = mock(Account.class);
|
||||
Account target = mock(Account.class);
|
||||
when(target.isActive()).thenReturn(true);
|
||||
OptionalAccess.verify(Optional.of(source), Optional.empty(), Optional.of(target));;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
|
||||
import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator;
|
||||
import org.whispersystems.textsecuregcm.controllers.AccountController;
|
||||
@@ -30,8 +28,10 @@ import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
@@ -59,7 +59,7 @@ public class AccountControllerTest {
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.addProvider(new RateLimitExceededExceptionMapper())
|
||||
.setMapper(SystemMapper.getMapper())
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
@@ -94,8 +94,8 @@ public class AccountControllerTest {
|
||||
|
||||
when(accountsManager.get(eq(SENDER_PIN))).thenReturn(Optional.of(senderPinAccount));
|
||||
when(accountsManager.get(eq(SENDER_OVER_PIN))).thenReturn(Optional.of(senderPinAccount));
|
||||
when(accountsManager.get(eq(SENDER))).thenReturn(Optional.absent());
|
||||
when(accountsManager.get(eq(SENDER_OLD))).thenReturn(Optional.absent());
|
||||
when(accountsManager.get(eq(SENDER))).thenReturn(Optional.empty());
|
||||
when(accountsManager.get(eq(SENDER_OLD))).thenReturn(Optional.empty());
|
||||
|
||||
doThrow(new RateLimitExceededException(SENDER_OVER_PIN)).when(pinLimiter).validate(eq(SENDER_OVER_PIN));
|
||||
}
|
||||
@@ -110,7 +110,7 @@ public class AccountControllerTest {
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
|
||||
verify(smsSender).deliverSmsVerification(eq(SENDER), eq(Optional.absent()), anyString());
|
||||
verify(smsSender).deliverSmsVerification(eq(SENDER), eq(Optional.empty()), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -270,6 +270,17 @@ public class AccountControllerTest {
|
||||
verify(AuthHelper.VALID_ACCOUNT).setPin(eq("31337"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPinUnauthorized() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target("/v1/accounts/pin/")
|
||||
.request()
|
||||
.put(Entity.json(new RegistrationLock("31337")));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetShortPin() throws Exception {
|
||||
Response response =
|
||||
|
||||
@@ -3,20 +3,20 @@ package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.configuration.AttachmentsConfiguration;
|
||||
import org.whispersystems.textsecuregcm.controllers.AttachmentController;
|
||||
import org.whispersystems.textsecuregcm.entities.AttachmentDescriptor;
|
||||
import org.whispersystems.textsecuregcm.entities.AttachmentUri;
|
||||
import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.s3.UrlSigner;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -24,10 +24,9 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
public class AttachmentControllerTest {
|
||||
|
||||
private static AttachmentsConfiguration configuration = mock(AttachmentsConfiguration.class);
|
||||
private static FederatedClientManager federatedClientManager = mock(FederatedClientManager.class );
|
||||
private static RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private static RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private static AttachmentsConfiguration configuration = mock(AttachmentsConfiguration.class);
|
||||
private static RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private static RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
|
||||
private static UrlSigner urlSigner;
|
||||
|
||||
@@ -43,10 +42,10 @@ public class AttachmentControllerTest {
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setMapper(SystemMapper.getMapper())
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new AttachmentController(rateLimiters, federatedClientManager, urlSigner))
|
||||
.addResource(new AttachmentController(rateLimiters, urlSigner))
|
||||
.build();
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.textsecuregcm.auth.CertificateGenerator;
|
||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||
import org.whispersystems.textsecuregcm.controllers.CertificateController;
|
||||
import org.whispersystems.textsecuregcm.crypto.Curve;
|
||||
import org.whispersystems.textsecuregcm.entities.DeliveryCertificate;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.SenderCertificate;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.ServerCertificate;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class CertificateControllerTest {
|
||||
|
||||
private static final String caPublicKey = "BWh+UOhT1hD8bkb+MFRvb6tVqhoG8YYGCzOd7mgjo8cV";
|
||||
private static final String caPrivateKey = "EO3Mnf0kfVlVnwSaqPoQnAxhnnGL1JTdXqktCKEe9Eo=";
|
||||
|
||||
private static final String signingCertificate = "CiUIDBIhBbTz4h1My+tt+vw+TVscgUe/DeHS0W02tPWAWbTO2xc3EkD+go4bJnU0AcnFfbOLKoiBfCzouZtDYMOVi69rE7r4U9cXREEqOkUmU2WJBjykAxWPCcSTmVTYHDw7hkSp/puG";
|
||||
private static final String signingKey = "ABOxG29xrfq4E7IrW11Eg7+HBbtba9iiS0500YoBjn4=";
|
||||
|
||||
private static CertificateGenerator certificateGenerator;
|
||||
|
||||
static {
|
||||
try {
|
||||
certificateGenerator = new CertificateGenerator(Base64.decode(signingCertificate), Curve.decodePrivatePoint(Base64.decode(signingKey)), 1);
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setMapper(SystemMapper.getMapper())
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new CertificateController(certificateGenerator))
|
||||
.build();
|
||||
|
||||
|
||||
@Test
|
||||
public void testValidCertificate() throws Exception {
|
||||
DeliveryCertificate certificateObject = resources.getJerseyTest()
|
||||
.target("/v1/certificate/delivery")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
|
||||
.get(DeliveryCertificate.class);
|
||||
|
||||
|
||||
SenderCertificate certificateHolder = SenderCertificate.parseFrom(certificateObject.getCertificate());
|
||||
SenderCertificate.Certificate certificate = SenderCertificate.Certificate.parseFrom(certificateHolder.getCertificate());
|
||||
|
||||
ServerCertificate serverCertificateHolder = certificate.getSigner();
|
||||
ServerCertificate.Certificate serverCertificate = ServerCertificate.Certificate.parseFrom(serverCertificateHolder.getCertificate());
|
||||
|
||||
assertTrue(Curve.verifySignature(Curve.decodePoint(serverCertificate.getKey().toByteArray(), 0), certificateHolder.getCertificate().toByteArray(), certificateHolder.getSignature().toByteArray()));
|
||||
assertTrue(Curve.verifySignature(Curve.decodePoint(Base64.decode(caPublicKey), 0), serverCertificateHolder.getCertificate().toByteArray(), serverCertificateHolder.getSignature().toByteArray()));
|
||||
|
||||
assertEquals(certificate.getSender(), AuthHelper.VALID_NUMBER);
|
||||
assertEquals(certificate.getSenderDevice(), 1L);
|
||||
assertTrue(Arrays.equals(certificate.getIdentityKey().toByteArray(), Base64.decode(AuthHelper.VALID_IDENTITY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadAuthentication() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/certificate/delivery")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
|
||||
.get();
|
||||
|
||||
assertEquals(response.getStatus(), 401);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoAuthentication() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/certificate/delivery")
|
||||
.request()
|
||||
.get();
|
||||
|
||||
assertEquals(response.getStatus(), 401);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedAuthentication() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/certificate/delivery")
|
||||
.request()
|
||||
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("1234".getBytes()))
|
||||
.get();
|
||||
|
||||
assertEquals(response.getStatus(), 401);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,12 +16,10 @@
|
||||
*/
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
|
||||
import org.whispersystems.textsecuregcm.controllers.DeviceController;
|
||||
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
@@ -40,8 +38,10 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -83,7 +83,7 @@ public class DeviceControllerTest {
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addProvider(new DeviceLimitExceededExceptionMapper())
|
||||
.addResource(new DumbVerificationDeviceController(pendingDevicesManager,
|
||||
@@ -202,15 +202,4 @@ public class DeviceControllerTest {
|
||||
verifyNoMoreInteractions(messagesManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeDeviceTest() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/devices/12345")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
|
||||
.delete();
|
||||
|
||||
assertEquals(204, response.getStatus());
|
||||
verify(directoryQueue).deleteRegisteredUser(eq(AuthHelper.VALID_NUMBER));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.DirectoryCredentials;
|
||||
import org.whispersystems.textsecuregcm.auth.DirectoryCredentialsGenerator;
|
||||
import org.whispersystems.textsecuregcm.configuration.DirectoryConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.DirectoryClientConfiguration;
|
||||
import org.whispersystems.textsecuregcm.controllers.DirectoryController;
|
||||
import org.whispersystems.textsecuregcm.entities.ClientContactTokens;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.DirectoryManager;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
@@ -26,11 +23,11 @@ import javax.ws.rs.core.Response;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyListOf;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Matchers.anyList;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -46,7 +43,7 @@ public class DirectoryControllerTest {
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new DirectoryController(rateLimiters,
|
||||
directoryManager,
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.controllers.FederationControllerV1;
|
||||
import org.whispersystems.textsecuregcm.controllers.FederationControllerV2;
|
||||
import org.whispersystems.textsecuregcm.controllers.KeysController;
|
||||
import org.whispersystems.textsecuregcm.controllers.MessageController;
|
||||
import org.whispersystems.textsecuregcm.entities.IncomingMessageList;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKeyResponseItem;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKeyResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.push.ApnFallbackManager;
|
||||
import org.whispersystems.textsecuregcm.push.PushSender;
|
||||
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
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 javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.jsonFixture;
|
||||
|
||||
public class FederatedControllerTest {
|
||||
|
||||
private static final String SINGLE_DEVICE_RECIPIENT = "+14151111111";
|
||||
private static final String MULTI_DEVICE_RECIPIENT = "+14152222222";
|
||||
|
||||
private PushSender pushSender = mock(PushSender.class );
|
||||
private ReceiptSender receiptSender = mock(ReceiptSender.class);
|
||||
private FederatedClientManager federatedClientManager = mock(FederatedClientManager.class);
|
||||
private AccountsManager accountsManager = mock(AccountsManager.class );
|
||||
private MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
private RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private ApnFallbackManager apnFallbackManager = mock(ApnFallbackManager.class);
|
||||
|
||||
private final SignedPreKey signedPreKey = new SignedPreKey(3333, "foo", "baar");
|
||||
private final PreKeyResponse preKeyResponseV2 = new PreKeyResponse("foo", new LinkedList<PreKeyResponseItem>());
|
||||
|
||||
private final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
private final MessageController messageController = new MessageController(rateLimiters, pushSender, receiptSender, accountsManager, messagesManager, federatedClientManager, apnFallbackManager);
|
||||
private final KeysController keysControllerV2 = mock(KeysController.class);
|
||||
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new FederationControllerV1(accountsManager, null, messageController))
|
||||
.addResource(new FederationControllerV2(accountsManager, null, messageController, keysControllerV2))
|
||||
.build();
|
||||
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Set<Device> singleDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis(), false, false, "Test"));
|
||||
}};
|
||||
|
||||
Set<Device> multiDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(222, "baz", "boop"), System.currentTimeMillis(), System.currentTimeMillis(), false, false, "Test"));
|
||||
add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(333, "rad", "mad"), System.currentTimeMillis(), System.currentTimeMillis(), false, false, "Test"));
|
||||
}};
|
||||
|
||||
Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, singleDeviceList);
|
||||
Account multiDeviceAccount = new Account(MULTI_DEVICE_RECIPIENT, multiDeviceList);
|
||||
|
||||
when(accountsManager.get(eq(SINGLE_DEVICE_RECIPIENT))).thenReturn(Optional.of(singleDeviceAccount));
|
||||
when(accountsManager.get(eq(MULTI_DEVICE_RECIPIENT))).thenReturn(Optional.of(multiDeviceAccount));
|
||||
|
||||
when(rateLimiters.getMessagesLimiter()).thenReturn(rateLimiter);
|
||||
|
||||
when(keysControllerV2.getSignedKey(any(Account.class))).thenReturn(Optional.of(signedPreKey));
|
||||
when(keysControllerV2.getDeviceKeys(any(Account.class), anyString(), anyString(), any(Optional.class)))
|
||||
.thenReturn(Optional.of(preKeyResponseV2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleDeviceCurrent() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/federation/messages/+14152223333/1/%s", SINGLE_DEVICE_RECIPIENT))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader("cyanogen", "foofoo"))
|
||||
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat("Good Response", response.getStatus(), is(equalTo(204)));
|
||||
|
||||
verify(pushSender).sendMessage(any(Account.class), any(Device.class), any(MessageProtos.Envelope.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignedPreKeyV2() throws Exception {
|
||||
PreKeyResponse response =
|
||||
resources.getJerseyTest()
|
||||
.target("/v2/federation/key/+14152223333/1")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader("cyanogen", "foofoo"))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat("good response", response.getIdentityKey().equals(preKeyResponseV2.getIdentityKey()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||
import org.whispersystems.textsecuregcm.controllers.KeysController;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKey;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKeyCount;
|
||||
@@ -28,8 +27,10 @@ import javax.ws.rs.core.Response;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
@@ -63,9 +64,9 @@ public class KeyControllerTest {
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new KeysController(rateLimiters, keys, accounts, null))
|
||||
.addResource(new KeysController(rateLimiters, keys, accounts))
|
||||
.build();
|
||||
|
||||
@Before
|
||||
@@ -103,14 +104,15 @@ public class KeyControllerTest {
|
||||
when(existsAccount.getDevice(2L)).thenReturn(Optional.of(sampleDevice2));
|
||||
when(existsAccount.getDevice(3L)).thenReturn(Optional.of(sampleDevice3));
|
||||
when(existsAccount.getDevice(4L)).thenReturn(Optional.of(sampleDevice4));
|
||||
when(existsAccount.getDevice(22L)).thenReturn(Optional.<Device>absent());
|
||||
when(existsAccount.getDevice(22L)).thenReturn(Optional.<Device>empty());
|
||||
when(existsAccount.getDevices()).thenReturn(allDevices);
|
||||
when(existsAccount.isActive()).thenReturn(true);
|
||||
when(existsAccount.getIdentityKey()).thenReturn("existsidentitykey");
|
||||
when(existsAccount.getNumber()).thenReturn(EXISTS_NUMBER);
|
||||
when(existsAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of("1337".getBytes()));
|
||||
|
||||
when(accounts.get(EXISTS_NUMBER)).thenReturn(Optional.of(existsAccount));
|
||||
when(accounts.get(NOT_EXISTS_NUMBER)).thenReturn(Optional.<Account>absent());
|
||||
when(accounts.get(NOT_EXISTS_NUMBER)).thenReturn(Optional.<Account>empty());
|
||||
|
||||
when(rateLimiters.getPreKeysLimiter()).thenReturn(rateLimiter);
|
||||
|
||||
@@ -118,7 +120,7 @@ public class KeyControllerTest {
|
||||
singleDevice.add(SAMPLE_KEY);
|
||||
when(keys.get(eq(EXISTS_NUMBER), eq(1L))).thenReturn(Optional.of(singleDevice));
|
||||
|
||||
when(keys.get(eq(NOT_EXISTS_NUMBER), eq(1L))).thenReturn(Optional.<List<KeyRecord>>absent());
|
||||
when(keys.get(eq(NOT_EXISTS_NUMBER), eq(1L))).thenReturn(Optional.<List<KeyRecord>>empty());
|
||||
|
||||
List<KeyRecord> multiDevice = new LinkedList<>();
|
||||
multiDevice.add(SAMPLE_KEY);
|
||||
@@ -191,6 +193,49 @@ public class KeyControllerTest {
|
||||
verifyNoMoreInteractions(keys);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnidentifiedRequest() throws Exception {
|
||||
PreKeyResponse result = resources.getJerseyTest()
|
||||
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
|
||||
.request()
|
||||
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("1337".getBytes()))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertThat(result.getDevice(1).getPreKey().getKeyId()).isEqualTo(SAMPLE_KEY.getKeyId());
|
||||
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
|
||||
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
|
||||
|
||||
verify(keys).get(eq(EXISTS_NUMBER), eq(1L));
|
||||
verifyNoMoreInteractions(keys);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnauthorizedUnidentifiedRequest() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
|
||||
.request()
|
||||
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("9999".getBytes()))
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
verifyNoMoreInteractions(keys);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMalformedUnidentifiedRequest() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
|
||||
.request()
|
||||
.header(OptionalAccess.UNIDENTIFIED, "$$$$$$$$$")
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
verifyNoMoreInteractions(keys);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void validMultiRequestTestV2() throws Exception {
|
||||
PreKeyResponse results = resources.getJerseyTest()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
|
||||
import org.whispersystems.textsecuregcm.controllers.MessageController;
|
||||
import org.whispersystems.textsecuregcm.entities.IncomingMessageList;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope;
|
||||
@@ -15,7 +15,6 @@ import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntity;
|
||||
import org.whispersystems.textsecuregcm.entities.OutgoingMessageEntityList;
|
||||
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.entities.StaleDevices;
|
||||
import org.whispersystems.textsecuregcm.federation.FederatedClientManager;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.push.ApnFallbackManager;
|
||||
@@ -26,6 +25,7 @@ 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.Base64;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
@@ -33,14 +33,17 @@ import javax.ws.rs.core.Response;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
@@ -54,7 +57,6 @@ public class MessageControllerTest {
|
||||
|
||||
private final PushSender pushSender = mock(PushSender.class );
|
||||
private final ReceiptSender receiptSender = mock(ReceiptSender.class);
|
||||
private final FederatedClientManager federatedClientManager = mock(FederatedClientManager.class);
|
||||
private final AccountsManager accountsManager = mock(AccountsManager.class );
|
||||
private final MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
private final RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
@@ -66,27 +68,27 @@ public class MessageControllerTest {
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new MessageController(rateLimiters, pushSender, receiptSender, accountsManager,
|
||||
messagesManager, federatedClientManager, apnFallbackManager))
|
||||
messagesManager, apnFallbackManager))
|
||||
.build();
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Set<Device> singleDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, new SignedPreKey(333, "baz", "boop"), System.currentTimeMillis(), System.currentTimeMillis(), false, false, "Test"));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, new SignedPreKey(333, "baz", "boop"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", true));
|
||||
}};
|
||||
|
||||
Set<Device> multiDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis(), false, false, "Test"));
|
||||
add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(), System.currentTimeMillis(), false, false, "Test"));
|
||||
add(new Device(3, null, "foo", "bar", "baz", "isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31), System.currentTimeMillis(), false, false, "Test"));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", true));
|
||||
add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", true));
|
||||
add(new Device(3, null, "foo", "bar", "baz", "isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31), System.currentTimeMillis(), "Test", true));
|
||||
}};
|
||||
|
||||
Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, singleDeviceList);
|
||||
Account multiDeviceAccount = new Account(MULTI_DEVICE_RECIPIENT, multiDeviceList);
|
||||
Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, singleDeviceList, "1234".getBytes());
|
||||
Account multiDeviceAccount = new Account(MULTI_DEVICE_RECIPIENT, multiDeviceList, "1234".getBytes());
|
||||
|
||||
when(accountsManager.get(eq(SINGLE_DEVICE_RECIPIENT))).thenReturn(Optional.of(singleDeviceAccount));
|
||||
when(accountsManager.get(eq(MULTI_DEVICE_RECIPIENT))).thenReturn(Optional.of(multiDeviceAccount));
|
||||
@@ -106,7 +108,43 @@ public class MessageControllerTest {
|
||||
|
||||
assertThat("Good Response", response.getStatus(), is(equalTo(200)));
|
||||
|
||||
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), any(Envelope.class));
|
||||
ArgumentCaptor<Envelope> captor = ArgumentCaptor.forClass(Envelope.class);
|
||||
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture());
|
||||
|
||||
assertTrue(captor.getValue().hasSource());
|
||||
assertTrue(captor.getValue().hasSourceDevice());
|
||||
}
|
||||
|
||||
@Test
|
||||
public synchronized void testSingleDeviceCurrentUnidentified() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
|
||||
.request()
|
||||
.header(OptionalAccess.UNIDENTIFIED, Base64.encodeBytes("1234".getBytes()))
|
||||
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat("Good Response", response.getStatus(), is(equalTo(200)));
|
||||
|
||||
ArgumentCaptor<Envelope> captor = ArgumentCaptor.forClass(Envelope.class);
|
||||
verify(pushSender, times(1)).sendMessage(any(Account.class), any(Device.class), captor.capture());
|
||||
|
||||
assertFalse(captor.getValue().hasSource());
|
||||
assertFalse(captor.getValue().hasSourceDevice());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public synchronized void testSendBadAuth() throws Exception {
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
|
||||
.request()
|
||||
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
|
||||
MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat("Good Response", response.getStatus(), is(equalTo(401)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -187,9 +225,11 @@ public class MessageControllerTest {
|
||||
final long timestampOne = 313377;
|
||||
final long timestampTwo = 313388;
|
||||
|
||||
final UUID uuidOne = UUID.randomUUID();
|
||||
|
||||
List<OutgoingMessageEntity> messages = new LinkedList<OutgoingMessageEntity>() {{
|
||||
add(new OutgoingMessageEntity(1L, false, Envelope.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes(), null));
|
||||
add(new OutgoingMessageEntity(2L, false, Envelope.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null, null));
|
||||
add(new OutgoingMessageEntity(1L, false, uuidOne, Envelope.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes(), null, 0));
|
||||
add(new OutgoingMessageEntity(2L, false, null, Envelope.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null, null, 0));
|
||||
}};
|
||||
|
||||
OutgoingMessageEntityList messagesList = new OutgoingMessageEntityList(messages, false);
|
||||
@@ -211,6 +251,9 @@ public class MessageControllerTest {
|
||||
|
||||
assertEquals(response.getMessages().get(0).getTimestamp(), timestampOne);
|
||||
assertEquals(response.getMessages().get(1).getTimestamp(), timestampTwo);
|
||||
|
||||
assertEquals(response.getMessages().get(0).getGuid(), uuidOne);
|
||||
assertEquals(response.getMessages().get(1).getGuid(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -219,8 +262,8 @@ public class MessageControllerTest {
|
||||
final long timestampTwo = 313388;
|
||||
|
||||
List<OutgoingMessageEntity> messages = new LinkedList<OutgoingMessageEntity>() {{
|
||||
add(new OutgoingMessageEntity(1L, false, Envelope.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes(), null));
|
||||
add(new OutgoingMessageEntity(2L, false, Envelope.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null, null));
|
||||
add(new OutgoingMessageEntity(1L, false, UUID.randomUUID(), Envelope.Type.CIPHERTEXT_VALUE, null, timestampOne, "+14152222222", 2, "hi there".getBytes(), null, 0));
|
||||
add(new OutgoingMessageEntity(2L, false, UUID.randomUUID(), Envelope.Type.RECEIPT_VALUE, null, timestampTwo, "+14152222222", 2, null, null, 0));
|
||||
}};
|
||||
|
||||
OutgoingMessageEntityList messagesList = new OutgoingMessageEntityList(messages, false);
|
||||
@@ -240,21 +283,22 @@ public class MessageControllerTest {
|
||||
@Test
|
||||
public synchronized void testDeleteMessages() throws Exception {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
when(messagesManager.delete(AuthHelper.VALID_NUMBER, 1, "+14152222222", 31337))
|
||||
.thenReturn(Optional.of(new OutgoingMessageEntity(31337L, true,
|
||||
.thenReturn(Optional.of(new OutgoingMessageEntity(31337L, true, null,
|
||||
Envelope.Type.CIPHERTEXT_VALUE,
|
||||
null, timestamp,
|
||||
"+14152222222", 1, "hi".getBytes(), null)));
|
||||
"+14152222222", 1, "hi".getBytes(), null, 0)));
|
||||
|
||||
when(messagesManager.delete(AuthHelper.VALID_NUMBER, 1, "+14152222222", 31338))
|
||||
.thenReturn(Optional.of(new OutgoingMessageEntity(31337L, true,
|
||||
.thenReturn(Optional.of(new OutgoingMessageEntity(31337L, true, null,
|
||||
Envelope.Type.RECEIPT_VALUE,
|
||||
null, System.currentTimeMillis(),
|
||||
"+14152222222", 1, null, null)));
|
||||
"+14152222222", 1, null, null, 0)));
|
||||
|
||||
|
||||
when(messagesManager.delete(AuthHelper.VALID_NUMBER, 1, "+14152222222", 31339))
|
||||
.thenReturn(Optional.<OutgoingMessageEntity>absent());
|
||||
.thenReturn(Optional.empty());
|
||||
|
||||
Response response = resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/%s/%d", "+14152222222", 31337))
|
||||
@@ -263,7 +307,7 @@ public class MessageControllerTest {
|
||||
.delete();
|
||||
|
||||
assertThat("Good Response Code", response.getStatus(), is(equalTo(204)));
|
||||
verify(receiptSender).sendReceipt(any(Account.class), eq("+14152222222"), eq(timestamp), eq(Optional.<String>absent()));
|
||||
verify(receiptSender).sendReceipt(any(Account.class), eq("+14152222222"), eq(timestamp));
|
||||
|
||||
response = resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/%s/%d", "+14152222222", 31338))
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider;
|
||||
import org.whispersystems.textsecuregcm.configuration.ProfilesConfiguration;
|
||||
import org.whispersystems.textsecuregcm.controllers.ProfileController;
|
||||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
@@ -17,6 +15,10 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Optional;
|
||||
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
@@ -38,7 +40,7 @@ public class ProfileControllerTest {
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthFilter())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder())
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(Account.class))
|
||||
.setMapper(SystemMapper.getMapper())
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new ProfileController(rateLimiters,
|
||||
@@ -53,9 +55,10 @@ public class ProfileControllerTest {
|
||||
Account profileAccount = mock(Account.class);
|
||||
|
||||
when(profileAccount.getIdentityKey()).thenReturn("bar");
|
||||
when(profileAccount.getName()).thenReturn("baz");
|
||||
when(profileAccount.getProfileName()).thenReturn("baz");
|
||||
when(profileAccount.getAvatar()).thenReturn("profiles/bang");
|
||||
when(profileAccount.getAvatarDigest()).thenReturn("buh");
|
||||
when(profileAccount.isActive()).thenReturn(true);
|
||||
|
||||
when(accountsManager.get(AuthHelper.VALID_NUMBER_TWO)).thenReturn(Optional.of(profileAccount));
|
||||
}
|
||||
@@ -78,5 +81,14 @@ public class ProfileControllerTest {
|
||||
verify(rateLimiter, times(1)).validate(AuthHelper.VALID_NUMBER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProfileGetUnauthorized() throws Exception {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
|
||||
.request()
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.whispersystems.textsecuregcm.tests.push;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.relayrides.pushy.apns.ApnsClient;
|
||||
import com.relayrides.pushy.apns.ApnsServerException;
|
||||
@@ -22,6 +21,7 @@ import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.netty.util.concurrent.DefaultEventExecutor;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.whispersystems.textsecuregcm.tests.push;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Matchers;
|
||||
@@ -15,6 +14,8 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -49,21 +50,21 @@ public class AccountTest {
|
||||
Account recentAccount = new Account("+14152222222", new HashSet<Device>() {{
|
||||
add(recentMasterDevice);
|
||||
add(recentSecondaryDevice);
|
||||
}});
|
||||
}}, "1234".getBytes());
|
||||
|
||||
assertTrue(recentAccount.isActive());
|
||||
|
||||
Account oldSecondaryAccount = new Account("+14152222222", new HashSet<Device>() {{
|
||||
add(recentMasterDevice);
|
||||
add(agingSecondaryDevice);
|
||||
}});
|
||||
}}, "1234".getBytes());
|
||||
|
||||
assertTrue(oldSecondaryAccount.isActive());
|
||||
|
||||
Account agingPrimaryAccount = new Account("+14152222222", new HashSet<Device>() {{
|
||||
add(oldMasterDevice);
|
||||
add(agingSecondaryDevice);
|
||||
}});
|
||||
}}, "1234".getBytes());
|
||||
|
||||
assertTrue(agingPrimaryAccount.isActive());
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public class AccountTest {
|
||||
Account oldPrimaryAccount = new Account("+14152222222", new HashSet<Device>() {{
|
||||
add(oldMasterDevice);
|
||||
add(oldSecondaryDevice);
|
||||
}});
|
||||
}}, "1234".getBytes());
|
||||
|
||||
assertFalse(oldPrimaryAccount.isActive());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.whispersystems.textsecuregcm.tests.storage;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -18,17 +17,14 @@ import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class DirectoryReconcilerTest {
|
||||
|
||||
@@ -53,8 +49,6 @@ public class DirectoryReconcilerTest {
|
||||
public void setup() {
|
||||
when(account.getNumber()).thenReturn(VALID_NUMBER);
|
||||
when(account.isActive()).thenReturn(true);
|
||||
when(account.isVideoSupported()).thenReturn(true);
|
||||
when(account.isVoiceSupported()).thenReturn(true);
|
||||
when(inactiveAccount.getNumber()).thenReturn(INACTIVE_NUMBER);
|
||||
when(inactiveAccount.isActive()).thenReturn(false);
|
||||
|
||||
@@ -66,7 +60,7 @@ public class DirectoryReconcilerTest {
|
||||
|
||||
when(reconciliationClient.sendChunk(any())).thenReturn(successResponse);
|
||||
|
||||
when(reconciliationCache.getLastNumber()).thenReturn(Optional.absent());
|
||||
when(reconciliationCache.getLastNumber()).thenReturn(Optional.empty());
|
||||
when(reconciliationCache.claimActiveWork(any(), anyLong())).thenReturn(true);
|
||||
when(reconciliationCache.isAccelerated()).thenReturn(false);
|
||||
}
|
||||
@@ -155,7 +149,7 @@ public class DirectoryReconcilerTest {
|
||||
assertThat(request.getValue().getNumbers()).isEqualTo(Collections.emptyList());
|
||||
|
||||
verify(reconciliationCache, times(1)).getLastNumber();
|
||||
verify(reconciliationCache, times(1)).setLastNumber(eq(Optional.absent()));
|
||||
verify(reconciliationCache, times(1)).setLastNumber(eq(Optional.empty()));
|
||||
verify(reconciliationCache, times(1)).clearAccelerate();
|
||||
verify(reconciliationCache, times(1)).isAccelerated();
|
||||
verify(reconciliationCache, times(2)).claimActiveWork(any(), anyLong());
|
||||
@@ -192,7 +186,7 @@ public class DirectoryReconcilerTest {
|
||||
assertThat(addedContact.getValue().getToken()).isEqualTo(Util.getContactToken(VALID_NUMBER));
|
||||
|
||||
verify(reconciliationCache, times(1)).getLastNumber();
|
||||
verify(reconciliationCache, times(1)).setLastNumber(eq(Optional.absent()));
|
||||
verify(reconciliationCache, times(1)).setLastNumber(eq(Optional.empty()));
|
||||
verify(reconciliationCache, times(1)).clearAccelerate();
|
||||
verify(reconciliationCache, times(1)).claimActiveWork(any(), anyLong());
|
||||
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
package org.whispersystems.textsecuregcm.tests.util;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import org.whispersystems.dropwizard.simpleauth.AuthDynamicFeature;
|
||||
import org.whispersystems.dropwizard.simpleauth.BasicCredentialAuthFilter;
|
||||
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
|
||||
import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.configuration.FederationConfiguration;
|
||||
import org.whispersystems.textsecuregcm.federation.FederatedPeer;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.util.Base64;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import io.dropwizard.auth.AuthDynamicFeature;
|
||||
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -31,6 +26,8 @@ public class AuthHelper {
|
||||
public static final String INVVALID_NUMBER = "+14151111111";
|
||||
public static final String INVALID_PASSWORD = "bar";
|
||||
|
||||
public static final String VALID_IDENTITY = "BcxxDU9FGMda70E7+Uvm7pnQcEdXQ64aJCpPUeRSfcFo";
|
||||
|
||||
public static AccountsManager ACCOUNTS_MANAGER = mock(AccountsManager.class );
|
||||
public static Account VALID_ACCOUNT = mock(Account.class );
|
||||
public static Account VALID_ACCOUNT_TWO = mock(Account.class);
|
||||
@@ -53,29 +50,24 @@ public class AuthHelper {
|
||||
when(VALID_ACCOUNT_TWO.getNumber()).thenReturn(VALID_NUMBER_TWO);
|
||||
when(VALID_ACCOUNT.getAuthenticatedDevice()).thenReturn(Optional.of(VALID_DEVICE));
|
||||
when(VALID_ACCOUNT_TWO.getAuthenticatedDevice()).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
||||
when(VALID_ACCOUNT.getRelay()).thenReturn(Optional.<String>absent());
|
||||
when(VALID_ACCOUNT_TWO.getRelay()).thenReturn(Optional.<String>absent());
|
||||
when(VALID_ACCOUNT.getRelay()).thenReturn(Optional.<String>empty());
|
||||
when(VALID_ACCOUNT_TWO.getRelay()).thenReturn(Optional.<String>empty());
|
||||
when(VALID_ACCOUNT.isActive()).thenReturn(true);
|
||||
when(VALID_ACCOUNT_TWO.isActive()).thenReturn(true);
|
||||
when(VALID_ACCOUNT.getIdentityKey()).thenReturn(VALID_IDENTITY);
|
||||
when(ACCOUNTS_MANAGER.get(VALID_NUMBER)).thenReturn(Optional.of(VALID_ACCOUNT));
|
||||
when(ACCOUNTS_MANAGER.get(VALID_NUMBER_TWO)).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
|
||||
|
||||
List<FederatedPeer> peer = new LinkedList<FederatedPeer>() {{
|
||||
add(new FederatedPeer("cyanogen", "https://foo", "foofoo", "bazzzzz"));
|
||||
}};
|
||||
|
||||
FederationConfiguration federationConfiguration = mock(FederationConfiguration.class);
|
||||
when(federationConfiguration.getPeers()).thenReturn(peer);
|
||||
|
||||
return new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<Account>()
|
||||
.setAuthenticator(new AccountAuthenticator(ACCOUNTS_MANAGER))
|
||||
.setPrincipal(Account.class)
|
||||
.buildAuthFilter(),
|
||||
new BasicCredentialAuthFilter.Builder<FederatedPeer>()
|
||||
.setAuthenticator(new FederatedPeerAuthenticator(federationConfiguration))
|
||||
.setPrincipal(FederatedPeer.class)
|
||||
.buildAuthFilter());
|
||||
}
|
||||
|
||||
public static String getAuthHeader(String number, String password) {
|
||||
return "Basic " + Base64.encodeBytes((number + ":" + password).getBytes());
|
||||
}
|
||||
|
||||
public static String getUnidentifiedAccessHeader(byte[] key) {
|
||||
return Base64.encodeBytes(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.whispersystems.textsecuregcm.tests.websocket;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.eclipse.jetty.websocket.api.UpgradeRequest;
|
||||
@@ -27,6 +26,8 @@ import org.whispersystems.textsecuregcm.websocket.WebSocketAccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.websocket.WebSocketConnection;
|
||||
import org.whispersystems.textsecuregcm.websocket.WebsocketAddress;
|
||||
import org.whispersystems.websocket.WebSocketClient;
|
||||
import org.whispersystems.websocket.auth.WebSocketAuthenticator;
|
||||
import org.whispersystems.websocket.auth.WebSocketAuthenticator.AuthenticationResult;
|
||||
import org.whispersystems.websocket.messages.WebSocketResponseMessage;
|
||||
import org.whispersystems.websocket.session.WebSocketSessionContext;
|
||||
|
||||
@@ -35,7 +36,9 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.dropwizard.auth.basic.BasicCredentials;
|
||||
import static org.junit.Assert.*;
|
||||
@@ -72,7 +75,7 @@ public class WebSocketConnectionTest {
|
||||
.thenReturn(Optional.of(account));
|
||||
|
||||
when(accountAuthenticator.authenticate(eq(new BasicCredentials(INVALID_USER, INVALID_PASSWORD))))
|
||||
.thenReturn(Optional.<Account>absent());
|
||||
.thenReturn(Optional.<Account>empty());
|
||||
|
||||
when(account.getAuthenticatedDevice()).thenReturn(Optional.of(device));
|
||||
|
||||
@@ -81,8 +84,8 @@ public class WebSocketConnectionTest {
|
||||
put("password", new LinkedList<String>() {{add(VALID_PASSWORD);}});
|
||||
}});
|
||||
|
||||
Optional<Account> account = webSocketAuthenticator.authenticate(upgradeRequest);
|
||||
when(sessionContext.getAuthenticated(Account.class)).thenReturn(account.get());
|
||||
AuthenticationResult<Account> account = webSocketAuthenticator.authenticate(upgradeRequest);
|
||||
when(sessionContext.getAuthenticated(Account.class)).thenReturn(account.getUser().orElse(null));
|
||||
|
||||
connectListener.onWebSocketConnect(sessionContext);
|
||||
|
||||
@@ -94,7 +97,8 @@ public class WebSocketConnectionTest {
|
||||
}});
|
||||
|
||||
account = webSocketAuthenticator.authenticate(upgradeRequest);
|
||||
assertFalse(account.isPresent());
|
||||
assertFalse(account.getUser().isPresent());
|
||||
assertTrue(account.isRequired());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,7 +129,7 @@ public class WebSocketConnectionTest {
|
||||
when(sender1.getDevices()).thenReturn(sender1devices);
|
||||
|
||||
when(accountsManager.get("sender1")).thenReturn(Optional.of(sender1));
|
||||
when(accountsManager.get("sender2")).thenReturn(Optional.<Account>absent());
|
||||
when(accountsManager.get("sender2")).thenReturn(Optional.empty());
|
||||
|
||||
when(storedMessages.getMessagesForDevice(account.getNumber(), device.getId()))
|
||||
.thenReturn(outgoingMessagesList);
|
||||
@@ -160,7 +164,7 @@ public class WebSocketConnectionTest {
|
||||
futures.get(2).setException(new IOException());
|
||||
|
||||
verify(storedMessages, times(1)).delete(eq(account.getNumber()), eq(2L), eq(2L), eq(false));
|
||||
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender1"), eq(2222L), eq(Optional.<String>absent()));
|
||||
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender1"), eq(2222L));
|
||||
|
||||
connection.onDispatchUnsubscribed(websocketAddress.serialize());
|
||||
verify(client).close(anyInt(), anyString());
|
||||
@@ -208,7 +212,7 @@ public class WebSocketConnectionTest {
|
||||
when(sender1.getDevices()).thenReturn(sender1devices);
|
||||
|
||||
when(accountsManager.get("sender1")).thenReturn(Optional.of(sender1));
|
||||
when(accountsManager.get("sender2")).thenReturn(Optional.<Account>absent());
|
||||
when(accountsManager.get("sender2")).thenReturn(Optional.<Account>empty());
|
||||
|
||||
when(storedMessages.getMessagesForDevice(account.getNumber(), device.getId()))
|
||||
.thenReturn(pendingMessagesList);
|
||||
@@ -250,7 +254,7 @@ public class WebSocketConnectionTest {
|
||||
futures.get(1).set(response);
|
||||
futures.get(0).setException(new IOException());
|
||||
|
||||
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()), eq(Optional.<String>absent()));
|
||||
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()));
|
||||
verify(websocketSender, times(1)).queueMessage(eq(account), eq(device), any(Envelope.class));
|
||||
verify(pushSender, times(1)).sendQueuedNotification(eq(account), eq(device));
|
||||
|
||||
@@ -285,14 +289,14 @@ public class WebSocketConnectionTest {
|
||||
.build();
|
||||
|
||||
List<OutgoingMessageEntity> pendingMessages = new LinkedList<OutgoingMessageEntity>() {{
|
||||
add(new OutgoingMessageEntity(1, true, firstMessage.getType().getNumber(), firstMessage.getRelay(),
|
||||
add(new OutgoingMessageEntity(1, true, UUID.randomUUID(), firstMessage.getType().getNumber(), firstMessage.getRelay(),
|
||||
firstMessage.getTimestamp(), firstMessage.getSource(),
|
||||
firstMessage.getSourceDevice(), firstMessage.getLegacyMessage().toByteArray(),
|
||||
firstMessage.getContent().toByteArray()));
|
||||
add(new OutgoingMessageEntity(2, false, secondMessage.getType().getNumber(), secondMessage.getRelay(),
|
||||
firstMessage.getContent().toByteArray(), 0));
|
||||
add(new OutgoingMessageEntity(2, false, UUID.randomUUID(), secondMessage.getType().getNumber(), secondMessage.getRelay(),
|
||||
secondMessage.getTimestamp(), secondMessage.getSource(),
|
||||
secondMessage.getSourceDevice(), secondMessage.getLegacyMessage().toByteArray(),
|
||||
secondMessage.getContent().toByteArray()));
|
||||
secondMessage.getContent().toByteArray(), 0));
|
||||
}};
|
||||
|
||||
OutgoingMessageEntityList pendingMessagesList = new OutgoingMessageEntityList(pendingMessages, false);
|
||||
@@ -313,7 +317,7 @@ public class WebSocketConnectionTest {
|
||||
when(sender1.getDevices()).thenReturn(sender1devices);
|
||||
|
||||
when(accountsManager.get("sender1")).thenReturn(Optional.of(sender1));
|
||||
when(accountsManager.get("sender2")).thenReturn(Optional.<Account>absent());
|
||||
when(accountsManager.get("sender2")).thenReturn(Optional.<Account>empty());
|
||||
|
||||
when(storedMessages.getMessagesForDevice(account.getNumber(), device.getId()))
|
||||
.thenReturn(pendingMessagesList);
|
||||
@@ -346,7 +350,7 @@ public class WebSocketConnectionTest {
|
||||
futures.get(1).set(response);
|
||||
futures.get(0).setException(new IOException());
|
||||
|
||||
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()), eq(Optional.<String>absent()));
|
||||
verify(receiptSender, times(1)).sendReceipt(eq(account), eq("sender2"), eq(secondMessage.getTimestamp()));
|
||||
verifyNoMoreInteractions(websocketSender);
|
||||
verifyNoMoreInteractions(pushSender);
|
||||
|
||||
@@ -356,8 +360,8 @@ public class WebSocketConnectionTest {
|
||||
|
||||
|
||||
private OutgoingMessageEntity createMessage(long id, boolean cached, String sender, long timestamp, boolean receipt, String content) {
|
||||
return new OutgoingMessageEntity(id, cached, receipt ? Envelope.Type.RECEIPT_VALUE : Envelope.Type.CIPHERTEXT_VALUE,
|
||||
null, timestamp, sender, 1, content.getBytes(), null);
|
||||
return new OutgoingMessageEntity(id, cached, UUID.randomUUID(), receipt ? Envelope.Type.RECEIPT_VALUE : Envelope.Type.CIPHERTEXT_VALUE,
|
||||
null, timestamp, sender, 1, content.getBytes(), null, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user