Generate SignedPreKey records, improve SignedPreKey cleanup.

This commit is contained in:
Moxie Marlinspike
2014-07-12 18:06:22 -07:00
parent 144f269059
commit 5f5ddd7c26
11 changed files with 287 additions and 66 deletions

View File

@@ -0,0 +1,118 @@
package org.thoughtcrime.securesms.database;
import android.test.InstrumentationTestCase;
import static org.fest.assertions.api.Assertions.assertThat;
public class CanonicalAddressDatabaseTest extends InstrumentationTestCase {
private static final String AMBIGUOUS_NUMBER = "222-3333";
private static final String SPECIFIC_NUMBER = "+49 444 222 3333";
private static final String EMAIL = "a@b.fom";
private static final String SIMILAR_EMAIL = "a@b.com";
private static final String GROUP = "__textsecure_group__!000111222333";
private static final String SIMILAR_GROUP = "__textsecure_group__!100111222333";
private static final String ALPHA = "T-Mobile";
private static final String SIMILAR_ALPHA = "T-Mobila";
private CanonicalAddressDatabase db;
public void setUp() throws Exception {
super.setUp();
this.db = CanonicalAddressDatabase.getInstance(getInstrumentation().getTargetContext());
}
public void tearDown() throws Exception {
}
/**
* Throw two equivalent numbers (one without locale info, one with full info) at the canonical
* address db and see that the caching and DB operations work properly in revealing the right
* addresses. This is run twice to ensure cache logic is hit.
*
* @throws Exception
*/
public void testNumberAddressUpdates() throws Exception {
final long id = db.getCanonicalAddressId(AMBIGUOUS_NUMBER);
assertThat(db.getAddressFromId(id)).isEqualTo(AMBIGUOUS_NUMBER);
assertThat(db.getCanonicalAddressId(SPECIFIC_NUMBER)).isEqualTo(id);
assertThat(db.getAddressFromId(id)).isEqualTo(SPECIFIC_NUMBER);
assertThat(db.getCanonicalAddressId(AMBIGUOUS_NUMBER)).isEqualTo(id);
assertThat(db.getCanonicalAddressId(AMBIGUOUS_NUMBER)).isEqualTo(id);
assertThat(db.getAddressFromId(id)).isEqualTo(AMBIGUOUS_NUMBER);
assertThat(db.getCanonicalAddressId(SPECIFIC_NUMBER)).isEqualTo(id);
assertThat(db.getAddressFromId(id)).isEqualTo(SPECIFIC_NUMBER);
assertThat(db.getCanonicalAddressId(AMBIGUOUS_NUMBER)).isEqualTo(id);
}
public void testSimilarNumbers() throws Exception {
assertThat(db.getCanonicalAddressId("This is a phone number 222-333-444"))
.isNotEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("222-333-444"))
.isNotEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("222-333-44"))
.isNotEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("222-333-4"))
.isNotEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("+49 222-333-4444"))
.isNotEqualTo(db.getCanonicalAddressId("+1 222-333-4444"));
assertThat(db.getCanonicalAddressId("1 222-333-4444"))
.isEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("1 (222) 333-4444"))
.isEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("+12223334444"))
.isEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("+1 (222) 333.4444"))
.isEqualTo(db.getCanonicalAddressId("222-333-4444"));
assertThat(db.getCanonicalAddressId("+49 (222) 333.4444"))
.isEqualTo(db.getCanonicalAddressId("222-333-4444"));
}
public void testEmailAddresses() throws Exception {
final long emailId = db.getCanonicalAddressId(EMAIL);
final long similarEmailId = db.getCanonicalAddressId(SIMILAR_EMAIL);
assertThat(emailId).isNotEqualTo(similarEmailId);
assertThat(db.getAddressFromId(emailId)).isEqualTo(EMAIL);
assertThat(db.getAddressFromId(similarEmailId)).isEqualTo(SIMILAR_EMAIL);
}
public void testGroups() throws Exception {
final long groupId = db.getCanonicalAddressId(GROUP);
final long similarGroupId = db.getCanonicalAddressId(SIMILAR_GROUP);
assertThat(groupId).isNotEqualTo(similarGroupId);
assertThat(db.getAddressFromId(groupId)).isEqualTo(GROUP);
assertThat(db.getAddressFromId(similarGroupId)).isEqualTo(SIMILAR_GROUP);
}
public void testAlpha() throws Exception {
final long id = db.getCanonicalAddressId(ALPHA);
final long similarId = db.getCanonicalAddressId(SIMILAR_ALPHA);
assertThat(id).isNotEqualTo(similarId);
assertThat(db.getAddressFromId(id)).isEqualTo(ALPHA);
assertThat(db.getAddressFromId(similarId)).isEqualTo(SIMILAR_ALPHA);
}
public void testIsNumber() throws Exception {
assertThat(CanonicalAddressDatabase.isNumberAddress("+495556666777")).isTrue();
assertThat(CanonicalAddressDatabase.isNumberAddress("(222) 333-4444")).isTrue();
assertThat(CanonicalAddressDatabase.isNumberAddress("1 (222) 333-4444")).isTrue();
assertThat(CanonicalAddressDatabase.isNumberAddress("T-Mobile123")).isTrue();
assertThat(CanonicalAddressDatabase.isNumberAddress("333-4444")).isTrue();
assertThat(CanonicalAddressDatabase.isNumberAddress("12345")).isTrue();
assertThat(CanonicalAddressDatabase.isNumberAddress("T-Mobile")).isFalse();
assertThat(CanonicalAddressDatabase.isNumberAddress("T-Mobile1")).isFalse();
assertThat(CanonicalAddressDatabase.isNumberAddress("Wherever bank")).isFalse();
assertThat(CanonicalAddressDatabase.isNumberAddress("__textsecure_group__!afafafafafaf")).isFalse();
assertThat(CanonicalAddressDatabase.isNumberAddress("email@domain.com")).isFalse();
}
}

View File

@@ -0,0 +1,92 @@
package org.thoughtcrime.securesms.service;
import android.test.AndroidTestCase;
import org.whispersystems.libaxolotl.ecc.Curve;
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.SignedPreKeyEntity;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
public class PreKeyServiceTest extends AndroidTestCase {
public void testSignedPreKeyRotationNotRegistered() throws IOException {
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
PushServiceSocket pushServiceSocket = mock(PushServiceSocket.class);
when(pushServiceSocket.getCurrentSignedPreKey()).thenReturn(null);
PreKeyService.CleanSignedPreKeysTask cleanTask = new PreKeyService.CleanSignedPreKeysTask(signedPreKeyStore,
pushServiceSocket);
cleanTask.run();
verify(pushServiceSocket).getCurrentSignedPreKey();
verifyNoMoreInteractions(signedPreKeyStore);
}
public void testSignedPreKeyEviction() throws Exception {
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
PushServiceSocket pushServiceSocket = mock(PushServiceSocket.class);
SignedPreKeyEntity currentSignedPreKeyEntity = mock(SignedPreKeyEntity.class);
when(currentSignedPreKeyEntity.getKeyId()).thenReturn(3133);
when(pushServiceSocket.getCurrentSignedPreKey()).thenReturn(currentSignedPreKeyEntity);
final SignedPreKeyRecord currentRecord = new SignedPreKeyRecord(3133, System.currentTimeMillis(), Curve.generateKeyPair(true), new byte[64]);
List<SignedPreKeyRecord> records = new LinkedList<SignedPreKeyRecord>() {{
add(new SignedPreKeyRecord(1, 10, Curve.generateKeyPair(true), new byte[32]));
add(new SignedPreKeyRecord(2, 11, Curve.generateKeyPair(true), new byte[32]));
add(new SignedPreKeyRecord(3, System.currentTimeMillis() - 90, Curve.generateKeyPair(true), new byte[64]));
add(new SignedPreKeyRecord(4, System.currentTimeMillis() - 100, Curve.generateKeyPair(true), new byte[64]));
add(currentRecord);
}};
when(signedPreKeyStore.loadSignedPreKeys()).thenReturn(records);
when(signedPreKeyStore.loadSignedPreKey(eq(3133))).thenReturn(currentRecord);
PreKeyService.CleanSignedPreKeysTask cleanTask = new PreKeyService.CleanSignedPreKeysTask(signedPreKeyStore, pushServiceSocket);
cleanTask.run();
verify(signedPreKeyStore).removeSignedPreKey(eq(1));
verify(signedPreKeyStore).removeSignedPreKey(eq(2));
verify(signedPreKeyStore, times(2)).removeSignedPreKey(anyInt());
}
public void testSignedPreKeyNoEviction() throws Exception {
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
PushServiceSocket pushServiceSocket = mock(PushServiceSocket.class);
SignedPreKeyEntity currentSignedPreKeyEntity = mock(SignedPreKeyEntity.class);
when(currentSignedPreKeyEntity.getKeyId()).thenReturn(3133);
when(pushServiceSocket.getCurrentSignedPreKey()).thenReturn(currentSignedPreKeyEntity);
final SignedPreKeyRecord currentRecord = new SignedPreKeyRecord(3133, System.currentTimeMillis(), Curve.generateKeyPair(true), new byte[64]);
List<SignedPreKeyRecord> records = new LinkedList<SignedPreKeyRecord>() {{
add(currentRecord);
}};
when(signedPreKeyStore.loadSignedPreKeys()).thenReturn(records);
when(signedPreKeyStore.loadSignedPreKey(eq(3133))).thenReturn(currentRecord);
PreKeyService.CleanSignedPreKeysTask cleanTask = new PreKeyService.CleanSignedPreKeysTask(signedPreKeyStore, pushServiceSocket);
cleanTask.run();
verify(signedPreKeyStore, never()).removeSignedPreKey(anyInt());
}
}

View File

@@ -0,0 +1,33 @@
package org.thoughtcrime.securesms.util;
import android.test.AndroidTestCase;
import junit.framework.AssertionFailedError;
import org.whispersystems.textsecure.util.InvalidNumberException;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
import static org.fest.assertions.api.Assertions.assertThat;
public class PhoneNumberFormatterTest extends AndroidTestCase {
private static final String LOCAL_NUMBER = "+15555555555";
public void testFormatNumberE164() throws Exception, InvalidNumberException {
assertThat(PhoneNumberFormatter.formatNumber("(555) 555-5555", LOCAL_NUMBER)).isEqualTo(LOCAL_NUMBER);
assertThat(PhoneNumberFormatter.formatNumber("555-5555", LOCAL_NUMBER)).isEqualTo(LOCAL_NUMBER);
assertThat(PhoneNumberFormatter.formatNumber("(123) 555-5555", LOCAL_NUMBER)).isNotEqualTo(LOCAL_NUMBER);
}
public void testFormatNumberEmail() throws Exception {
try {
PhoneNumberFormatter.formatNumber("person@domain.com", LOCAL_NUMBER);
throw new AssertionFailedError("should have thrown on email");
} catch (InvalidNumberException ine) {
// success
}
}
@Override
public void setUp() throws Exception {
super.setUp();
}
}

View File

@@ -0,0 +1,9 @@
package org.thoughtcrime.securesms.util;
import android.test.AndroidTestCase;
import static org.fest.assertions.api.Assertions.assertThat;
public class UtilTest extends AndroidTestCase {
}