Squashed History

This commit is contained in:
Moxie Marlinspike
2013-12-08 23:11:09 -08:00
commit 4ad0dad3d9
103 changed files with 9737 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
package org.whispersystems.textsecuregcm.tests;
/**
* Created with IntelliJ IDEA.
* User: moxie
* Date: 10/28/13
* Time: 12:53 PM
* To change this template use File | Settings | File Templates.
*/
public class BaseTest {
}

View File

@@ -0,0 +1,91 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.google.common.base.Optional;
import com.sun.jersey.api.client.ClientResponse;
import com.yammer.dropwizard.testing.ResourceTest;
import org.junit.Test;
import org.whispersystems.textsecuregcm.controllers.AccountController;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.sms.SenderFactory;
import org.whispersystems.textsecuregcm.sms.TwilioSmsSender;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.PendingAccountsManager;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import javax.ws.rs.core.MediaType;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
public class AccountControllerTest extends ResourceTest {
private static final String SENDER = "+14152222222";
private PendingAccountsManager pendingAccountsManager = mock(PendingAccountsManager.class);
private AccountsManager accountsManager = mock(AccountsManager.class );
private RateLimiters rateLimiters = mock(RateLimiters.class );
private RateLimiter rateLimiter = mock(RateLimiter.class );
private TwilioSmsSender twilioSmsSender = mock(TwilioSmsSender.class );
private SenderFactory senderFactory = mock(SenderFactory.class );
@Override
protected void setUpResources() throws Exception {
addProvider(AuthHelper.getAuthenticator());
when(rateLimiters.getSmsDestinationLimiter()).thenReturn(rateLimiter);
when(rateLimiters.getVoiceDestinationLimiter()).thenReturn(rateLimiter);
when(rateLimiters.getVerifyLimiter()).thenReturn(rateLimiter);
when(pendingAccountsManager.getCodeForNumber(SENDER)).thenReturn(Optional.of("1234"));
when(senderFactory.getSmsSender(SENDER)).thenReturn(twilioSmsSender);
addResource(new AccountController(pendingAccountsManager,
accountsManager,
rateLimiters,
senderFactory));
}
@Test
public void testSendCode() throws Exception {
ClientResponse response =
client().resource(String.format("/v1/accounts/sms/code/%s", SENDER))
.get(ClientResponse.class);
assertThat(response.getStatus()).isEqualTo(200);
verify(twilioSmsSender).deliverSmsVerification(eq(SENDER), anyString());
}
@Test
public void testVerifyCode() throws Exception {
ClientResponse response =
client().resource(String.format("/v1/accounts/code/%s", "1234"))
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
.entity(new AccountAttributes("keykeykeykey", false))
.type(MediaType.APPLICATION_JSON_TYPE)
.put(ClientResponse.class);
assertThat(response.getStatus()).isEqualTo(204);
verify(accountsManager).create(isA(Account.class));
}
@Test
public void testVerifyBadCode() throws Exception {
ClientResponse response =
client().resource(String.format("/v1/accounts/code/%s", "1111"))
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
.entity(new AccountAttributes("keykeykeykey", false))
.type(MediaType.APPLICATION_JSON_TYPE)
.put(ClientResponse.class);
assertThat(response.getStatus()).isEqualTo(403);
verifyNoMoreInteractions(accountsManager);
}
}

View File

@@ -0,0 +1,82 @@
package org.whispersystems.textsecuregcm.tests.controllers;
import com.sun.jersey.api.client.ClientResponse;
import com.yammer.dropwizard.testing.ResourceTest;
import org.junit.Test;
import org.whispersystems.textsecuregcm.controllers.KeysController;
import org.whispersystems.textsecuregcm.entities.PreKey;
import org.whispersystems.textsecuregcm.limits.RateLimiter;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.storage.Keys;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
public class KeyControllerTest extends ResourceTest {
private final String EXISTS_NUMBER = "+14152222222";
private final String NOT_EXISTS_NUMBER = "+14152222220";
private final PreKey SAMPLE_KEY = new PreKey(1, EXISTS_NUMBER, 1234, "test1", "test2", false);
private final Keys keys = mock(Keys.class);
@Override
protected void setUpResources() {
addProvider(AuthHelper.getAuthenticator());
RateLimiters rateLimiters = mock(RateLimiters.class);
RateLimiter rateLimiter = mock(RateLimiter.class );
when(rateLimiters.getPreKeysLimiter()).thenReturn(rateLimiter);
when(keys.get(EXISTS_NUMBER)).thenReturn(SAMPLE_KEY);
when(keys.get(NOT_EXISTS_NUMBER)).thenReturn(null);
addResource(new KeysController(rateLimiters, keys, null));
}
@Test
public void validRequestTest() throws Exception {
PreKey result = client().resource(String.format("/v1/keys/%s", EXISTS_NUMBER))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(PreKey.class);
assertThat(result.getKeyId()).isEqualTo(SAMPLE_KEY.getKeyId());
assertThat(result.getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
assertThat(result.getIdentityKey()).isEqualTo(SAMPLE_KEY.getIdentityKey());
assertThat(result.getId() == 0);
assertThat(result.getNumber() == null);
verify(keys).get(EXISTS_NUMBER);
}
@Test
public void invalidRequestTest() throws Exception {
ClientResponse response = client().resource(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(ClientResponse.class);
assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(404);
verify(keys).get(NOT_EXISTS_NUMBER);
}
@Test
public void unauthorizedRequestTest() throws Exception {
ClientResponse response =
client().resource(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.get(ClientResponse.class);
assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(401);
response =
client().resource(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER))
.get(ClientResponse.class);
assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(401);
}
}

View File

@@ -0,0 +1,44 @@
package org.whispersystems.textsecuregcm.tests.entities;
import org.junit.Test;
import org.whispersystems.textsecuregcm.entities.ClientContact;
import org.whispersystems.textsecuregcm.util.Util;
import static com.yammer.dropwizard.testing.JsonHelpers.*;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class ClientContactTest {
@Test
public void serializeToJSON() throws Exception {
byte[] token = Util.getContactToken("+14152222222");
ClientContact contact = new ClientContact(token, null, false);
ClientContact contactWithRelay = new ClientContact(token, "whisper", false);
ClientContact contactWithRelaySms = new ClientContact(token, "whisper", true );
assertThat("Basic Contact Serialization works",
asJson(contact),
is(equalTo(jsonFixture("fixtures/contact.json"))));
assertThat("Contact Relay Serialization works",
asJson(contactWithRelay),
is(equalTo(jsonFixture("fixtures/contact.relay.json"))));
assertThat("Contact Relay+SMS Serialization works",
asJson(contactWithRelaySms),
is(equalTo(jsonFixture("fixtures/contact.relay.sms.json"))));
}
@Test
public void deserializeFromJSON() throws Exception {
ClientContact contact = new ClientContact(Util.getContactToken("+14152222222"),
"whisper", true);
assertThat("a ClientContact can be deserialized from JSON",
fromJson(jsonFixture("fixtures/contact.relay.sms.json"), ClientContact.class),
is(contact));
}
}

View File

@@ -0,0 +1,34 @@
package org.whispersystems.textsecuregcm.tests.entities;
import org.junit.Test;
import org.whispersystems.textsecuregcm.entities.ClientContact;
import org.whispersystems.textsecuregcm.entities.PreKey;
import org.whispersystems.textsecuregcm.util.Util;
import static com.yammer.dropwizard.testing.JsonHelpers.*;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class PreKeyTest {
@Test
public void serializeToJSON() throws Exception {
PreKey preKey = new PreKey(1, "+14152222222", 1234, "test", "identityTest", false);
assertThat("Basic Contact Serialization works",
asJson(preKey),
is(equalTo(jsonFixture("fixtures/prekey.json"))));
}
@Test
public void deserializeFromJSON() throws Exception {
ClientContact contact = new ClientContact(Util.getContactToken("+14152222222"),
"whisper", true);
assertThat("a ClientContact can be deserialized from JSON",
fromJson(jsonFixture("fixtures/contact.relay.sms.json"), ClientContact.class),
is(contact));
}
}

View File

@@ -0,0 +1,44 @@
package org.whispersystems.textsecuregcm.tests.util;
import com.google.common.base.Optional;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator;
import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider;
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.util.Base64;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class AuthHelper {
public static final String VALID_NUMBER = "+14150000000";
public static final String VALID_PASSWORD = "foo";
public static final String INVVALID_NUMBER = "+14151111111";
public static final String INVALID_PASSWORD = "bar";
public static MultiBasicAuthProvider<FederatedPeer, Account> getAuthenticator() {
AccountsManager accounts = mock(AccountsManager.class);
Account account = mock(Account.class);
AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(credentials.verify("foo")).thenReturn(true);
when(account.getAuthenticationCredentials()).thenReturn(credentials);
when(accounts.get(VALID_NUMBER)).thenReturn(Optional.of(account));
return new MultiBasicAuthProvider<>(new FederatedPeerAuthenticator(new FederationConfiguration()),
FederatedPeer.class,
new AccountAuthenticator(accounts),
Account.class, "WhisperServer");
}
public static String getAuthHeader(String number, String password) {
return "Basic " + Base64.encodeBytes((number + ":" + password).getBytes());
}
}

View File

@@ -0,0 +1,3 @@
{
"token" : "BQVVHxMt5zAFXA"
}

View File

@@ -0,0 +1,4 @@
{
"token" : "BQVVHxMt5zAFXA",
"relay" : "whisper"
}

View File

@@ -0,0 +1,5 @@
{
"token" : "BQVVHxMt5zAFXA",
"relay" : "whisper",
"supportsSms" : true
}

View File

@@ -0,0 +1,5 @@
{
"keyId" : 1234,
"publicKey" : "test",
"identityKey" : "identityTest"
}