Compare commits

..

8 Commits

920 changed files with 15788 additions and 45468 deletions

View File

@@ -31,8 +31,6 @@
</value> </value>
</option> </option>
<option name="RIGHT_MARGIN" value="100" /> <option name="RIGHT_MARGIN" value="100" />
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
<AndroidXmlCodeStyleSettings> <AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" /> <option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings> </AndroidXmlCodeStyleSettings>
@@ -70,12 +68,6 @@
<XML> <XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML> </XML>
<codeStyleSettings language="Groovy">
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JAVA"> <codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="80" /> <option name="RIGHT_MARGIN" value="80" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" /> <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />

View File

@@ -13,6 +13,23 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------
All files under the directories briar-android/src, briar-api/src,
briar-core/src, briar-desktop/src and briar-test/src are licensed
under the Apache License, version 2.0 (the "License"); you may not
use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
------------------------------------------------------------------------- -------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE

View File

@@ -1,4 +1,5 @@
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'witness'
apply plugin: 'com.neenbedankt.android-apt' apply plugin: 'com.neenbedankt.android-apt'
android { android {
@@ -6,11 +7,20 @@ android {
buildToolsVersion "23.0.3" buildToolsVersion "23.0.3"
defaultConfig { defaultConfig {
minSdkVersion 14 minSdkVersion 9
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt' targetSdkVersion 22
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt' versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dexOptions {
incremental true
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7 sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7
@@ -18,12 +28,23 @@ android {
} }
dependencies { dependencies {
testCompile project(':briar-api') compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile project(':briar-core') compile project(':briar-api')
compile project(':briar-core')
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'net.jodah:concurrentunit:0.4.2' testCompile 'net.jodah:concurrentunit:0.4.2'
testCompile 'com.android.support:appcompat-v7:23.2.1' compile 'com.android.support:appcompat-v7:23.2.1'
testApt 'com.google.dagger:dagger-compiler:2.0.2' testApt 'com.google.dagger:dagger-compiler:2.0.2'
provided 'javax.annotation:jsr250-api:1.0' provided 'javax.annotation:jsr250-api:1.0'
testCompile project(':briar-tests') testCompile project(':briar-tests')
} }
dependencyVerification {
verify = [
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
]
}

17
briar-android-tests/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/ernir/dev/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

View File

@@ -3,7 +3,6 @@ package org.briarproject;
import net.jodah.concurrentunit.Waiter; import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.blogs.Blog; import org.briarproject.api.blogs.Blog;
import org.briarproject.api.blogs.BlogCommentHeader;
import org.briarproject.api.blogs.BlogFactory; import org.briarproject.api.blogs.BlogFactory;
import org.briarproject.api.blogs.BlogManager; import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPost; import org.briarproject.api.blogs.BlogPost;
@@ -12,6 +11,7 @@ import org.briarproject.api.blogs.BlogPostHeader;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
@@ -33,9 +33,7 @@ import org.briarproject.sync.SyncModule;
import org.briarproject.transport.TransportModule; import org.briarproject.transport.TransportModule;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@@ -50,17 +48,15 @@ import javax.inject.Inject;
import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertFalse;
import static org.briarproject.TestPluginsModule.MAX_LATENCY; import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.blogs.MessageType.COMMENT;
import static org.briarproject.api.blogs.MessageType.POST;
import static org.briarproject.api.blogs.MessageType.WRAPPED_COMMENT;
import static org.briarproject.api.blogs.MessageType.WRAPPED_POST;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID; import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING; import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.api.sync.ValidationManager.State.VALID;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class BlogManagerTest extends BriarIntegrationTest { public class BlogManagerTest {
private LifecycleManager lifecycleManager0, lifecycleManager1; private LifecycleManager lifecycleManager0, lifecycleManager1;
private SyncSessionFactory sync0, sync1; private SyncSessionFactory sync0, sync1;
@@ -91,15 +87,13 @@ public class BlogManagerTest extends BriarIntegrationTest {
private final int TIMEOUT = 15000; private final int TIMEOUT = 15000;
private final String AUTHOR1 = "Author 1"; private final String AUTHOR1 = "Author 1";
private final String AUTHOR2 = "Author 2"; private final String AUTHOR2 = "Author 2";
private final String CONTENT_TYPE = "text/plain";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(BlogManagerTest.class.getName()); Logger.getLogger(ForumSharingIntegrationTest.class.getName());
private BlogManagerTestComponent t0, t1; private BlogManagerTestComponent t0, t1;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
BlogManagerTestComponent component = BlogManagerTestComponent component =
@@ -173,15 +167,15 @@ public class BlogManagerTest extends BriarIntegrationTest {
defaultInit(); defaultInit();
// check that blog0 has no posts // check that blog0 has no posts
final String body = TestUtils.getRandomString(42); final byte[] body = TestUtils.getRandomBytes(42);
Collection<BlogPostHeader> headers0 = Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog0.getId()); blogManager0.getPostHeaders(blog0.getId());
assertEquals(0, headers0.size()); assertEquals(0, headers0.size());
// add a post to blog0 // add a post to blog0
BlogPost p = blogPostFactory BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null, .createBlogPost(blog0.getId(), null, clock.currentTimeMillis(),
author0, body); null, author0, CONTENT_TYPE, body);
blogManager0.addLocalPost(p); blogManager0.addLocalPost(p);
// check that post is now in blog0 // check that post is now in blog0
@@ -189,7 +183,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
assertEquals(1, headers0.size()); assertEquals(1, headers0.size());
// check that body is there // check that body is there
assertEquals(body, blogManager0.getPostBody(p.getMessage().getId())); assertArrayEquals(body,
blogManager0.getPostBody(p.getMessage().getId()));
// make sure that blog0 at author1 doesn't have the post yet // make sure that blog0 at author1 doesn't have the post yet
Collection<BlogPostHeader> headers1 = Collection<BlogPostHeader> headers1 =
@@ -203,10 +198,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
// make sure post arrived // make sure post arrived
headers1 = blogManager1.getPostHeaders(blog0.getId()); headers1 = blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size()); assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// check that body is there // check that body is there
assertEquals(body, blogManager1.getPostBody(p.getMessage().getId())); assertArrayEquals(body,
blogManager1.getPostBody(p.getMessage().getId()));
stopLifecycles(); stopLifecycles();
} }
@@ -217,10 +212,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
defaultInit(); defaultInit();
// add a post to blog1 // add a post to blog1
final String body = TestUtils.getRandomString(42); final byte[] body = TestUtils.getRandomBytes(42);
BlogPost p = blogPostFactory BlogPost p = blogPostFactory
.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null, .createBlogPost(blog1.getId(), null, clock.currentTimeMillis(),
author0, body); null, author0, CONTENT_TYPE, body);
blogManager0.addLocalPost(p); blogManager0.addLocalPost(p);
// check that post is now in blog1 // check that post is now in blog1
@@ -241,264 +236,26 @@ public class BlogManagerTest extends BriarIntegrationTest {
} }
@Test @Test
public void testCanNotRemoveContactsPersonalBlog() throws Exception { public void testAddAndRemoveBlog() throws Exception {
startLifecycles(); startLifecycles();
defaultInit(); defaultInit();
assertFalse(blogManager0.canBeRemoved(blog1.getId())); String name = "Test Blog";
assertFalse(blogManager1.canBeRemoved(blog0.getId())); String desc = "Description";
// the following two calls should throw a DbException now // add blog
thrown.expect(DbException.class); Blog blog = blogManager0.addBlog(author0, name, desc);
Collection<Blog> blogs0 = blogManager0.getBlogs();
assertEquals(3, blogs0.size());
assertTrue(blogs0.contains(blog));
assertEquals(2, blogManager0.getBlogs(author0).size());
blogManager0.removeBlog(blog1); // remove blog
blogManager1.removeBlog(blog0); blogManager0.removeBlog(blog);
blogs0 = blogManager0.getBlogs();
// blogs have not been removed assertEquals(2, blogs0.size());
assertEquals(2, blogManager0.getBlogs().size()); assertFalse(blogs0.contains(blog));
assertEquals(2, blogManager1.getBlogs().size()); assertEquals(1, blogManager0.getBlogs(author0).size());
stopLifecycles();
}
@Test
public void testBlogComment() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// sync the post over
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// 1 adds a comment to that blog post
String comment = "This is a comment on a blog post!";
blogManager1
.addLocalComment(author1, blog1.getId(), comment,
headers1.iterator().next());
// sync comment over
sync1To0();
deliveryWaiter.await(TIMEOUT, 2);
// make sure comment and wrapped post arrived
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(1, headers0.size());
assertEquals(COMMENT, headers0.iterator().next().getType());
BlogCommentHeader h = (BlogCommentHeader) headers0.iterator().next();
assertEquals(author0, h.getParent().getAuthor());
// ensure that body can be retrieved from wrapped post
assertEquals(body, blogManager0.getPostBody(h.getParentId()));
// 1 has only their own comment in their blog
headers1 = blogManager1.getPostHeaders(blog1.getId());
assertEquals(1, headers1.size());
stopLifecycles();
}
@Test
public void testBlogCommentOnOwnPost() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// get header of own post
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog0.getId());
assertEquals(1, headers0.size());
BlogPostHeader header = headers0.iterator().next();
// add a comment on own post
String comment = "This is a comment on my own blog post!";
blogManager0
.addLocalComment(author0, blog0.getId(), comment, header);
// sync the post and comment over
sync0To1();
deliveryWaiter.await(TIMEOUT, 2);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(2, headers1.size());
for (BlogPostHeader h : headers1) {
if (h.getType() == POST) {
assertEquals(body, blogManager1.getPostBody(h.getId()));
} else {
assertEquals(comment, ((BlogCommentHeader)h).getComment());
}
}
stopLifecycles();
}
@Test
public void testCommentOnComment() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// sync the post over
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// 1 reblogs that blog post
blogManager1
.addLocalComment(author1, blog1.getId(), null,
headers1.iterator().next());
// sync comment over
sync1To0();
deliveryWaiter.await(TIMEOUT, 2);
// make sure comment and wrapped post arrived
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(1, headers0.size());
// get header of comment
BlogPostHeader cHeader = headers0.iterator().next();
assertEquals(COMMENT, cHeader.getType());
// comment on the comment
String comment = "This is a comment on a reblogged post.";
blogManager0
.addLocalComment(author0, blog0.getId(), comment, cHeader);
// sync comment over
sync0To1();
deliveryWaiter.await(TIMEOUT, 3);
// check that comment arrived
headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(2, headers1.size());
// get header of comment
cHeader = null;
for (BlogPostHeader h : headers1) {
if (h.getType() == COMMENT) {
cHeader = h;
}
}
assertTrue(cHeader != null);
// another comment on the comment
String comment2 = "This is a comment on a comment.";
blogManager1.addLocalComment(author1, blog1.getId(), comment2, cHeader);
// sync comment over
sync1To0();
deliveryWaiter.await(TIMEOUT, 4);
// make sure new comment arrived
headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(2, headers0.size());
boolean satisfied = false;
for (BlogPostHeader h : headers0) {
assertEquals(COMMENT, h.getType());
BlogCommentHeader c = (BlogCommentHeader) h;
if (c.getComment() != null && c.getComment().equals(comment2)) {
assertEquals(author0, c.getParent().getAuthor());
assertEquals(WRAPPED_COMMENT, c.getParent().getType());
assertEquals(comment,
((BlogCommentHeader) c.getParent()).getComment());
assertEquals(WRAPPED_COMMENT,
((BlogCommentHeader) c.getParent()).getParent()
.getType());
assertEquals(WRAPPED_POST,
((BlogCommentHeader) ((BlogCommentHeader) c
.getParent()).getParent()).getParent()
.getType());
satisfied = true;
}
}
assertTrue(satisfied);
stopLifecycles();
}
@Test
public void testCommentOnOwnComment() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// sync the post over
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// 1 reblogs that blog post with a comment
String comment = "This is a comment on a post.";
blogManager1
.addLocalComment(author1, blog1.getId(), comment,
headers1.iterator().next());
// get comment from own blog
headers1 = blogManager1.getPostHeaders(blog1.getId());
assertEquals(1, headers1.size());
assertEquals(COMMENT, headers1.iterator().next().getType());
BlogCommentHeader ch = (BlogCommentHeader) headers1.iterator().next();
assertEquals(comment, ch.getComment());
comment = "This is a comment on a post with a comment.";
blogManager1.addLocalComment(author1, blog1.getId(), comment, ch);
// sync both comments over (2 comments + 1 wrapped post)
sync1To0();
deliveryWaiter.await(TIMEOUT, 3);
// make sure both comments arrived
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(2, headers0.size());
stopLifecycles(); stopLifecycles();
} }
@@ -509,14 +266,14 @@ public class BlogManagerTest extends BriarIntegrationTest {
} }
private class Listener implements EventListener { private class Listener implements EventListener {
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) { if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e; MessageStateChangedEvent event = (MessageStateChangedEvent) e;
if (!event.isLocal()) { if (!event.isLocal()) {
if (event.getState() == DELIVERED) { if (event.getState() == DELIVERED) {
deliveryWaiter.resume(); deliveryWaiter.resume();
} else if (event.getState() == INVALID || } else if (event.getState() == VALID ||
event.getState() == INVALID ||
event.getState() == PENDING) { event.getState() == PENDING) {
validationWaiter.resume(); validationWaiter.resume();
} }
@@ -526,28 +283,39 @@ public class BlogManagerTest extends BriarIntegrationTest {
} }
private void defaultInit() throws DbException { private void defaultInit() throws DbException {
getDefaultIdentities(); addDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
listenToEvents(); listenToEvents();
} }
private void getDefaultIdentities() throws DbException { private void addDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor(); KeyPair keyPair0 = crypto.generateSignatureKeyPair();
author1 = identityManager1.getLocalAuthor(); byte[] publicKey0 = keyPair0.getPublic().getEncoded();
blog0 = blogFactory.createBlog(author0); byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
blog1 = blogFactory.createBlog(author1); author0 = authorFactory
.createLocalAuthor(AUTHOR1, publicKey0, privateKey0);
identityManager0.addLocalAuthor(author0);
blog0 = blogFactory.createPersonalBlog(author0);
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(AUTHOR2, publicKey1, privateKey1);
identityManager1.addLocalAuthor(author1);
blog1 = blogFactory.createPersonalBlog(author1);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {
// sharer adds invitee as contact // sharer adds invitee as contact
contactId1 = contactManager0.addContact(author1, contactId1 = contactManager0.addContact(author1,
author0.getId(), master, clock.currentTimeMillis(), true, author0.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
// invitee adds sharer back // invitee adds sharer back
contactId0 = contactManager1.addContact(author0, contactId0 = contactManager1.addContact(author0,
author1.getId(), master, clock.currentTimeMillis(), true, author1.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
} }
@@ -592,8 +360,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish // Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(AUTHOR1); lifecycleManager0.startServices();
lifecycleManager1.startServices(AUTHOR2); lifecycleManager1.startServices();
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
} }

View File

@@ -1,743 +0,0 @@
package org.briarproject;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.blogs.Blog;
import org.briarproject.api.blogs.BlogInvitationRequest;
import org.briarproject.api.blogs.BlogInvitationResponse;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPostFactory;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.BlogInvitationReceivedEvent;
import org.briarproject.api.event.BlogInvitationResponseReceivedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageStateChangedEvent;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.sync.ValidationManager.State;
import org.briarproject.api.system.Clock;
import org.briarproject.blogs.BlogsModule;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.transport.TransportModule;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.blogs.BlogSharingManager.CLIENT_ID;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BlogSharingIntegrationTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
private SyncSessionFactory sync0, sync1;
private BlogManager blogManager0, blogManager1;
private MessageTracker messageTracker0, messageTracker1;
private ContactManager contactManager0, contactManager1, contactManager2;
private Contact contact1, contact2, contact01, contact02;
private ContactId contactId1, contactId01;
private IdentityManager identityManager0, identityManager1,
identityManager2;
private LocalAuthor author0, author1, author2;
private Blog blog0, blog1, blog2;
private SharerListener listener0;
private InviteeListener listener1;
@Inject
Clock clock;
@Inject
AuthorFactory authorFactory;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
BlogPostFactory blogPostFactory;
@Inject
CryptoComponent cryptoComponent;
// objects accessed from background threads need to be volatile
private volatile BlogSharingManager blogSharingManager0;
private volatile BlogSharingManager blogSharingManager1;
private volatile BlogSharingManager blogSharingManager2;
private volatile Waiter eventWaiter;
private volatile Waiter msgWaiter;
private final File testDir = TestUtils.getTestDirectory();
private final SecretKey master = TestUtils.getSecretKey();
private final int TIMEOUT = 15000;
private final String SHARER = "Sharer";
private final String INVITEE = "Invitee";
private final String CONTACT2 = "Contact2";
private static final Logger LOG =
Logger.getLogger(BlogSharingIntegrationTest.class.getName());
private BlogSharingIntegrationTestComponent t0, t1, t2;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setUp() {
BlogSharingIntegrationTestComponent component =
DaggerBlogSharingIntegrationTestComponent.builder().build();
component.inject(this);
injectEagerSingletons(component);
assertTrue(testDir.mkdirs());
File t0Dir = new File(testDir, SHARER);
t0 = DaggerBlogSharingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
injectEagerSingletons(t0);
File t1Dir = new File(testDir, INVITEE);
t1 = DaggerBlogSharingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
injectEagerSingletons(t1);
File t2Dir = new File(testDir, CONTACT2);
t2 = DaggerBlogSharingIntegrationTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t2Dir)).build();
injectEagerSingletons(t2);
identityManager0 = t0.getIdentityManager();
identityManager1 = t1.getIdentityManager();
identityManager2 = t2.getIdentityManager();
contactManager0 = t0.getContactManager();
contactManager1 = t1.getContactManager();
contactManager2 = t2.getContactManager();
blogManager0 = t0.getBlogManager();
blogManager1 = t1.getBlogManager();
messageTracker0 = t0.getMessageTracker();
messageTracker1 = t1.getMessageTracker();
blogSharingManager0 = t0.getBlogSharingManager();
blogSharingManager1 = t1.getBlogSharingManager();
blogSharingManager2 = t2.getBlogSharingManager();
sync0 = t0.getSyncSessionFactory();
sync1 = t1.getSyncSessionFactory();
// initialize waiters fresh for each test
eventWaiter = new Waiter();
msgWaiter = new Waiter();
}
@Test
public void testPersonalBlogCannotBeSharedWithOwner() throws Exception {
startLifecycles();
defaultInit(true);
assertFalse(blogSharingManager0.canBeShared(blog1.getId(), contact1));
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact2));
assertFalse(blogSharingManager1.canBeShared(blog0.getId(), contact01));
assertFalse(blogSharingManager2.canBeShared(blog0.getId(), contact02));
// create invitation
blogSharingManager0
.sendInvitation(blog1.getId(), contactId1, "Hi!");
// sync invitation
sync0To1();
// make sure the invitee ignored the request for their own blog
assertFalse(listener1.requestReceived);
stopLifecycles();
}
@Test
public void testSuccessfulSharing() throws Exception {
startLifecycles();
// initialize and let invitee accept all requests
defaultInit(true);
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1, "Hi!");
// invitee has own blog and that of the sharer
assertEquals(2, blogManager1.getBlogs().size());
// get sharing group and assert group message count
GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID, contact1)
.getId();
assertGroupCount(messageTracker0, g, 1, 0);
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
assertGroupCount(messageTracker1, g, 2, 1);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
assertGroupCount(messageTracker0, g, 2, 1);
// blog was added successfully
assertEquals(0, blogSharingManager0.getInvitations().size());
assertEquals(3, blogManager1.getBlogs().size());
// invitee has one invitation message from sharer
List<InvitationMessage> list =
new ArrayList<>(blogSharingManager1
.getInvitationMessages(contactId01));
assertEquals(2, list.size());
// check other things are alright with the message
for (InvitationMessage m : list) {
if (m instanceof BlogInvitationRequest) {
BlogInvitationRequest invitation =
(BlogInvitationRequest) m;
assertFalse(invitation.isAvailable());
assertEquals(blog2.getAuthor().getName(),
invitation.getBlogAuthorName());
assertEquals(contactId1, invitation.getContactId());
assertEquals("Hi!", invitation.getMessage());
} else {
BlogInvitationResponse response =
(BlogInvitationResponse) m;
assertEquals(contactId01, response.getContactId());
assertTrue(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
blogSharingManager0.getInvitationMessages(contactId1)
.size());
// blog can not be shared again
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1));
assertFalse(blogSharingManager1.canBeShared(blog2.getId(), contact01));
// group message count is still correct
assertGroupCount(messageTracker0, g, 2, 1);
assertGroupCount(messageTracker1, g, 2, 1);
stopLifecycles();
}
@Test
public void testDeclinedSharing() throws Exception {
startLifecycles();
// initialize and let invitee deny all requests
defaultInit(false);
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1, null);
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
// blog was not added
assertEquals(0, blogSharingManager0.getInvitations().size());
assertEquals(2, blogManager1.getBlogs().size());
// blog is no longer available to invitee who declined
assertEquals(0, blogSharingManager1.getInvitations().size());
// invitee has one invitation message from sharer and one response
List<InvitationMessage> list =
new ArrayList<>(blogSharingManager1
.getInvitationMessages(contactId01));
assertEquals(2, list.size());
// check things are alright with the message
for (InvitationMessage m : list) {
if (m instanceof BlogInvitationRequest) {
BlogInvitationRequest invitation =
(BlogInvitationRequest) m;
assertFalse(invitation.isAvailable());
assertEquals(blog2.getAuthor().getName(),
invitation.getBlogAuthorName());
assertEquals(contactId1, invitation.getContactId());
assertEquals(null, invitation.getMessage());
} else {
BlogInvitationResponse response =
(BlogInvitationResponse) m;
assertEquals(contactId01, response.getContactId());
assertFalse(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
blogSharingManager0.getInvitationMessages(contactId1)
.size());
// blog can be shared again
assertTrue(blogSharingManager0.canBeShared(blog2.getId(), contact1));
stopLifecycles();
}
@Test
public void testInviteeLeavesAfterFinished() throws Exception {
startLifecycles();
// initialize and let invitee accept all requests
defaultInit(true);
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1, "Hi!");
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
// blog was added successfully
assertEquals(0, blogSharingManager0.getInvitations().size());
assertEquals(3, blogManager1.getBlogs().size());
assertTrue(blogManager1.getBlogs().contains(blog2));
// sharer shares blog with invitee
assertTrue(blogSharingManager0.getSharedWith(blog2.getId())
.contains(contact1));
// invitee gets blog shared by sharer
assertTrue(blogSharingManager1.getSharedBy(blog2.getId())
.contains(contact01));
// invitee un-subscribes from blog
blogManager1.removeBlog(blog2);
// send leave message to sharer
sync1To0();
// blog is gone
assertEquals(0, blogSharingManager0.getInvitations().size());
assertEquals(2, blogManager1.getBlogs().size());
// sharer no longer shares blog with invitee
assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
.contains(contact1));
// invitee no longer gets blog shared by sharer
assertFalse(blogSharingManager1.getSharedBy(blog2.getId())
.contains(contact01));
// blog can be shared again
assertTrue(blogSharingManager0.canBeShared(blog2.getId(), contact1));
assertTrue(blogSharingManager1.canBeShared(blog2.getId(), contact01));
stopLifecycles();
}
@Test
public void testInvitationForExistingBlog() throws Exception {
startLifecycles();
// initialize and let invitee accept all requests
defaultInit(true);
// 1 and 2 are adding each other
contactManager1.addContact(author2,
author1.getId(), master, clock.currentTimeMillis(), true,
true, true
);
contactManager2.addContact(author1,
author2.getId(), master, clock.currentTimeMillis(), true,
true, true
);
assertEquals(3, blogManager1.getBlogs().size());
// sharer sends invitation for 2's blog to 1
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1, "Hi!");
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// make sure blog2 is shared by 0
Collection<Contact> contacts =
blogSharingManager1.getSharedBy(blog2.getId());
assertEquals(1, contacts.size());
assertTrue(contacts.contains(contact01));
// make sure 1 knows that they have blog2 already
Collection<InvitationMessage> messages =
blogSharingManager1.getInvitationMessages(contactId01);
assertEquals(2, messages.size());
assertEquals(blog2, blogManager1.getBlog(blog2.getId()));
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
// blog was not added, because it was there already
assertEquals(0, blogSharingManager0.getInvitations().size());
assertEquals(3, blogManager1.getBlogs().size());
stopLifecycles();
}
@Test
public void testRemovingSharedBlog() throws Exception {
startLifecycles();
// initialize and let invitee accept all requests
defaultInit(true);
// send invitation
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1, "Hi!");
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
// blog was added successfully and is shared both ways
assertEquals(3, blogManager1.getBlogs().size());
Collection<Contact> sharedWith =
blogSharingManager0.getSharedWith(blog2.getId());
assertEquals(1, sharedWith.size());
assertEquals(contact1, sharedWith.iterator().next());
Collection<Contact> sharedBy =
blogSharingManager1.getSharedBy(blog2.getId());
assertEquals(1, sharedBy.size());
assertEquals(contact01, sharedBy.iterator().next());
// shared blog can be removed
assertTrue(blogManager1.canBeRemoved(blog2.getId()));
// invitee removes blog again
blogManager1.removeBlog(blog2);
// sync LEAVE message
sync1To0();
// sharer does not share this blog anymore with invitee
sharedWith =
blogSharingManager0.getSharedWith(blog2.getId());
assertEquals(0, sharedWith.size());
stopLifecycles();
}
@Test
public void testSharedBlogBecomesPermanent() throws Exception {
startLifecycles();
// initialize and let invitee accept all requests
defaultInit(true);
// invitee only sees two blogs
assertEquals(2, blogManager1.getBlogs().size());
// sharer sends invitation for 2's blog to 1
blogSharingManager0
.sendInvitation(blog2.getId(), contactId1, "Hi!");
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// make sure blog2 is shared by 0
Collection<Contact> contacts =
blogSharingManager1.getSharedBy(blog2.getId());
assertEquals(1, contacts.size());
assertTrue(contacts.contains(contact01));
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
// blog was added and can be removed
assertEquals(3, blogManager1.getBlogs().size());
assertTrue(blogManager1.canBeRemoved(blog2.getId()));
// 1 and 2 are adding each other
contactManager1.addContact(author2,
author1.getId(), master, clock.currentTimeMillis(), true,
true, true
);
contactManager2.addContact(author1,
author2.getId(), master, clock.currentTimeMillis(), true,
true, true
);
assertEquals(3, blogManager1.getBlogs().size());
// now blog can not be removed anymore
assertFalse(blogManager1.canBeRemoved(blog2.getId()));
stopLifecycles();
}
@After
public void tearDown() throws InterruptedException {
TestUtils.deleteTestDirectory(testDir);
}
private class SharerListener implements EventListener {
private volatile boolean responseReceived = false;
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
LOG.info("TEST: Sharer received message");
msgWaiter.resume();
}
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
BlogInvitationResponseReceivedEvent event =
(BlogInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId());
responseReceived = true;
eventWaiter.resume();
}
// this is only needed for tests where a blog is re-shared
else if (e instanceof BlogInvitationReceivedEvent) {
BlogInvitationReceivedEvent event =
(BlogInvitationReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId());
Blog b = event.getShareable();
try {
Contact c = contactManager0.getContact(contactId1);
blogSharingManager0.respondToInvitation(b, c, true);
} catch (DbException ex) {
eventWaiter.rethrow(ex);
} finally {
eventWaiter.resume();
}
}
}
}
private class InviteeListener implements EventListener {
private volatile boolean requestReceived = false;
private final boolean accept, answer;
private InviteeListener(boolean accept, boolean answer) {
this.accept = accept;
this.answer = answer;
}
private InviteeListener(boolean accept) {
this(accept, true);
}
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
LOG.info("TEST: Invitee received message");
msgWaiter.resume();
}
} else if (e instanceof BlogInvitationReceivedEvent) {
BlogInvitationReceivedEvent event =
(BlogInvitationReceivedEvent) e;
requestReceived = true;
if (!answer) return;
Blog b = event.getShareable();
try {
eventWaiter.assertEquals(1,
blogSharingManager1.getInvitations().size());
Contact c =
contactManager1.getContact(event.getContactId());
blogSharingManager1.respondToInvitation(b, c, accept);
} catch (DbException ex) {
eventWaiter.rethrow(ex);
} finally {
eventWaiter.resume();
}
}
// this is only needed for tests where a blog is re-shared
else if (e instanceof BlogInvitationResponseReceivedEvent) {
BlogInvitationResponseReceivedEvent event =
(BlogInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId01, event.getContactId());
eventWaiter.resume();
}
}
}
private void startLifecycles() throws InterruptedException {
// Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(INVITEE);
lifecycleManager2.startServices(CONTACT2);
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup();
}
private void stopLifecycles() throws InterruptedException {
// Clean up
lifecycleManager0.stopServices();
lifecycleManager1.stopServices();
lifecycleManager2.stopServices();
lifecycleManager0.waitForShutdown();
lifecycleManager1.waitForShutdown();
lifecycleManager2.waitForShutdown();
}
private void defaultInit(boolean accept) throws DbException {
getDefaultIdentities();
addDefaultContacts();
getPersonalBlogOfSharer();
listenToEvents(accept);
}
private void getDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor();
author1 = identityManager1.getLocalAuthor();
author2 = identityManager2.getLocalAuthor();
}
private void addDefaultContacts() throws DbException {
// sharer adds invitee as contact
contactId1 = contactManager0.addContact(author1,
author0.getId(), master, clock.currentTimeMillis(), true,
true, true
);
contact1 = contactManager0.getContact(contactId1);
// sharer adds second contact
ContactId contactId2 = contactManager0.addContact(author2,
author0.getId(), master, clock.currentTimeMillis(), true,
true, true
);
contact2 = contactManager0.getContact(contactId2);
// contacts add sharer back
contactId01 = contactManager1.addContact(author0,
author1.getId(), master, clock.currentTimeMillis(), true,
true, true
);
contact01 = contactManager1.getContact(contactId01);
ContactId contactId02 = contactManager2.addContact(author0,
author2.getId(), master, clock.currentTimeMillis(), true,
true, true
);
contact02 = contactManager2.getContact(contactId02);
}
private void getPersonalBlogOfSharer() throws DbException {
blog0 = blogManager0.getPersonalBlog(author0);
blog1 = blogManager0.getPersonalBlog(author1);
blog2 = blogManager0.getPersonalBlog(author2);
}
private void listenToEvents(boolean accept) {
listener0 = new SharerListener();
t0.getEventBus().addListener(listener0);
listener1 = new InviteeListener(accept);
t1.getEventBus().addListener(listener1);
SharerListener listener2 = new SharerListener();
t2.getEventBus().addListener(listener2);
}
private void sync0To1() throws IOException, TimeoutException {
deliverMessage(sync0, contactId01, sync1, contactId1,
"Sharer to Invitee");
}
private void sync1To0() throws IOException, TimeoutException {
deliverMessage(sync1, contactId1, sync0, contactId01,
"Invitee to Sharer");
}
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
SyncSessionFactory toSync, ContactId toId, String debug)
throws IOException, TimeoutException {
if (debug != null) LOG.info("TEST: Sending message from " + debug);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// Create an outgoing sync session
SyncSession sessionFrom =
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
// Write whatever needs to be written
sessionFrom.run();
out.close();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
// Create an incoming sync session
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
// Read whatever needs to be read
sessionTo.run();
in.close();
// wait for message to actually arrive
msgWaiter.await(TIMEOUT, 1);
}
private void injectEagerSingletons(
BlogSharingIntegrationTestComponent component) {
component.inject(new LifecycleModule.EagerSingletons());
component.inject(new BlogsModule.EagerSingletons());
component.inject(new CryptoModule.EagerSingletons());
component.inject(new ContactModule.EagerSingletons());
component.inject(new TransportModule.EagerSingletons());
component.inject(new SharingModule.EagerSingletons());
component.inject(new SyncModule.EagerSingletons());
component.inject(new PropertiesModule.EagerSingletons());
}
}

View File

@@ -1,90 +0,0 @@
package org.briarproject;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.blogs.BlogsModule;
import org.briarproject.clients.ClientsModule;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {
TestDatabaseModule.class,
TestPluginsModule.class,
TestSeedProviderModule.class,
ClientsModule.class,
ContactModule.class,
CryptoModule.class,
DataModule.class,
DatabaseModule.class,
EventModule.class,
BlogsModule.class,
ForumModule.class,
IdentityModule.class,
LifecycleModule.class,
PropertiesModule.class,
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class,
MessagingModule.class
})
interface BlogSharingIntegrationTestComponent {
void inject(BlogSharingIntegrationTest testCase);
void inject(ContactModule.EagerSingletons init);
void inject(CryptoModule.EagerSingletons init);
void inject(BlogsModule.EagerSingletons init);
void inject(LifecycleModule.EagerSingletons init);
void inject(PropertiesModule.EagerSingletons init);
void inject(SharingModule.EagerSingletons init);
void inject(SyncModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init);
LifecycleManager getLifecycleManager();
EventBus getEventBus();
IdentityManager getIdentityManager();
ContactManager getContactManager();
BlogSharingManager getBlogSharingManager();
BlogManager getBlogManager();
MessageTracker getMessageTracker();
SyncSessionFactory getSyncSessionFactory();
}

View File

@@ -1,30 +0,0 @@
package org.briarproject;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import static org.junit.Assert.assertEquals;
public abstract class BriarIntegrationTest extends BriarTestCase {
protected static void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount, long latestMsg)
throws DbException {
GroupCount groupCount = tracker.getGroupCount(g);
assertEquals(msgCount, groupCount.getMsgCount());
assertEquals(unreadCount, groupCount.getUnreadCount());
assertEquals(latestMsg, groupCount.getLatestMsgTime());
}
protected static void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount) throws DbException {
GroupCount c1 = tracker.getGroupCount(g);
assertEquals(msgCount, c1.getMsgCount());
assertEquals(unreadCount, c1.getUnreadCount());
}
}

View File

@@ -4,11 +4,9 @@ import junit.framework.Assert;
import net.jodah.concurrentunit.Waiter; import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
@@ -36,7 +34,7 @@ import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule; import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.transport.TransportModule; import org.briarproject.transport.TransportModule;
import org.jetbrains.annotations.Nullable; import org.briarproject.util.StringUtils;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -55,18 +53,19 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertNull;
import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertFalse;
import static org.briarproject.TestPluginsModule.MAX_LATENCY; import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID; import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING; import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.briarproject.api.sync.ValidationManager.State.VALID;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class ForumManagerTest extends BriarIntegrationTest { public class ForumManagerTest {
private LifecycleManager lifecycleManager0, lifecycleManager1; private LifecycleManager lifecycleManager0, lifecycleManager1;
private SyncSessionFactory sync0, sync1; private SyncSessionFactory sync0, sync1;
private ForumManager forumManager0, forumManager1; private ForumManager forumManager0, forumManager1;
private ContactManager contactManager0, contactManager1; private ContactManager contactManager0, contactManager1;
private MessageTracker messageTracker0, messageTracker1;
private ContactId contactId0,contactId1; private ContactId contactId0,contactId1;
private IdentityManager identityManager0, identityManager1; private IdentityManager identityManager0, identityManager1;
private LocalAuthor author0, author1; private LocalAuthor author0, author1;
@@ -77,8 +76,6 @@ public class ForumManagerTest extends BriarIntegrationTest {
@Inject @Inject
AuthorFactory authorFactory; AuthorFactory authorFactory;
@Inject @Inject
CryptoComponent crypto;
@Inject
ForumPostFactory forumPostFactory; ForumPostFactory forumPostFactory;
// objects accessed from background threads need to be volatile // objects accessed from background threads need to be volatile
@@ -119,8 +116,6 @@ public class ForumManagerTest extends BriarIntegrationTest {
identityManager1 = t1.getIdentityManager(); identityManager1 = t1.getIdentityManager();
contactManager0 = t0.getContactManager(); contactManager0 = t0.getContactManager();
contactManager1 = t1.getContactManager(); contactManager1 = t1.getContactManager();
messageTracker0 = t0.getMessageTracker();
messageTracker1 = t1.getMessageTracker();
forumManager0 = t0.getForumManager(); forumManager0 = t0.getForumManager();
forumManager1 = t1.getForumManager(); forumManager1 = t1.getForumManager();
forumSharingManager0 = t0.getForumSharingManager(); forumSharingManager0 = t0.getForumSharingManager();
@@ -133,17 +128,16 @@ public class ForumManagerTest extends BriarIntegrationTest {
deliveryWaiter = new Waiter(); deliveryWaiter = new Waiter();
} }
private ForumPost createForumPost(GroupId groupId, private ForumPost createForumPost(GroupId groupId, ForumPost parent,
@Nullable ForumPost parent, String body, long ms) throws Exception { String body, long ms) throws Exception {
return forumPostFactory.createPost(groupId, ms, return forumPostFactory.createAnonymousPost(groupId, ms,
parent == null ? null : parent.getMessage().getId(), parent == null ? null : parent.getMessage().getId(),
author0, body); "text/plain", StringUtils.toUtf8(body));
} }
@Test @Test
public void testForumPost() throws Exception { public void testForumPost() throws Exception {
startLifecycles(); startLifecycles();
getDefaultIdentities();
Forum forum = forumManager0.addForum("TestForum"); Forum forum = forumManager0.addForum("TestForum");
assertEquals(1, forumManager0.getForums().size()); assertEquals(1, forumManager0.getForums().size());
final long ms1 = clock.currentTimeMillis() - 1000L; final long ms1 = clock.currentTimeMillis() - 1000L;
@@ -157,24 +151,15 @@ public class ForumManagerTest extends BriarIntegrationTest {
createForumPost(forum.getGroup().getId(), post1, body2, ms2); createForumPost(forum.getGroup().getId(), post1, body2, ms2);
assertEquals(ms2, post2.getMessage().getTimestamp()); assertEquals(ms2, post2.getMessage().getTimestamp());
forumManager0.addLocalPost(post1); forumManager0.addLocalPost(post1);
forumManager0.setReadFlag(forum.getGroup().getId(), forumManager0.setReadFlag(post1.getMessage().getId(), true);
post1.getMessage().getId(), true);
assertGroupCount(messageTracker0, forum.getGroup().getId(), 1, 0,
post1.getMessage().getTimestamp());
forumManager0.addLocalPost(post2); forumManager0.addLocalPost(post2);
forumManager0.setReadFlag(forum.getGroup().getId(), forumManager0.setReadFlag(post2.getMessage().getId(), false);
post2.getMessage().getId(), false);
assertGroupCount(messageTracker0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(messageTracker0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
Collection<ForumPostHeader> headers = Collection<ForumPostHeader> headers =
forumManager0.getPostHeaders(forum.getGroup().getId()); forumManager0.getPostHeaders(forum.getGroup().getId());
assertEquals(2, headers.size()); assertEquals(2, headers.size());
for (ForumPostHeader h : headers) { for (ForumPostHeader h : headers) {
final String hBody = forumManager0.getPostBody(h.getId()); final String hBody =
StringUtils.fromUtf8(forumManager0.getPostBody(h.getId()));
boolean isPost1 = h.getId().equals(post1.getMessage().getId()); boolean isPost1 = h.getId().equals(post1.getMessage().getId());
boolean isPost2 = h.getId().equals(post2.getMessage().getId()); boolean isPost2 = h.getId().equals(post2.getMessage().getId());
@@ -218,29 +203,23 @@ public class ForumManagerTest extends BriarIntegrationTest {
forumManager0.addLocalPost(post1); forumManager0.addLocalPost(post1);
assertEquals(1, forumManager0.getPostHeaders(g).size()); assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(0, forumManager1.getPostHeaders(g).size()); assertEquals(0, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker0, g, 1, 0, time);
assertGroupCount(messageTracker1, g, 0, 0, 0);
// send post to 1 // send post to 1
sync0To1(); sync0To1();
deliveryWaiter.await(TIMEOUT, 1); deliveryWaiter.await(TIMEOUT, 1);
assertEquals(1, forumManager1.getPostHeaders(g).size()); assertEquals(1, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker1, g, 1, 1, time);
// add another forum post // add another forum post
long time2 = clock.currentTimeMillis(); time = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time2); ForumPost post2 = createForumPost(g, null, "b", time);
forumManager1.addLocalPost(post2); forumManager1.addLocalPost(post2);
assertEquals(1, forumManager0.getPostHeaders(g).size()); assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(2, forumManager1.getPostHeaders(g).size()); assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker0, g, 1, 0, time);
assertGroupCount(messageTracker1, g, 2, 1, time2);
// send post to 0 // send post to 0
sync1To0(); sync1To0();
deliveryWaiter.await(TIMEOUT, 1); deliveryWaiter.await(TIMEOUT, 1);
assertEquals(2, forumManager1.getPostHeaders(g).size()); assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker0, g, 2, 1, time2);
stopLifecycles(); stopLifecycles();
} }
@@ -319,7 +298,7 @@ public class ForumManagerTest extends BriarIntegrationTest {
assertEquals(1, forumManager0.getPostHeaders(g).size()); assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(0, forumManager1.getPostHeaders(g).size()); assertEquals(0, forumManager1.getPostHeaders(g).size());
// send the child post to 1 // send posts to 1
sync0To1(); sync0To1();
validationWaiter.await(TIMEOUT, 1); validationWaiter.await(TIMEOUT, 1);
assertEquals(1, forumManager0.getPostHeaders(g).size()); assertEquals(1, forumManager0.getPostHeaders(g).size());
@@ -348,14 +327,14 @@ public class ForumManagerTest extends BriarIntegrationTest {
} }
private class Listener implements EventListener { private class Listener implements EventListener {
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) { if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e; MessageStateChangedEvent event = (MessageStateChangedEvent) e;
if (!event.isLocal()) { if (!event.isLocal()) {
if (event.getState() == DELIVERED) { if (event.getState() == DELIVERED) {
deliveryWaiter.resume(); deliveryWaiter.resume();
} else if (event.getState() == INVALID || } else if (event.getState() == VALID ||
event.getState() == INVALID ||
event.getState() == PENDING) { event.getState() == PENDING) {
validationWaiter.resume(); validationWaiter.resume();
} }
@@ -365,27 +344,33 @@ public class ForumManagerTest extends BriarIntegrationTest {
} }
private void defaultInit() throws DbException { private void defaultInit() throws DbException {
getDefaultIdentities(); addDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addForum(); addForum();
listenToEvents(); listenToEvents();
} }
private void getDefaultIdentities() throws DbException { private void addDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor(); author0 = authorFactory.createLocalAuthor(SHARER,
author1 = identityManager1.getLocalAuthor(); TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123));
identityManager0.addLocalAuthor(author0);
author1 = authorFactory.createLocalAuthor(INVITEE,
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123));
identityManager1.addLocalAuthor(author1);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {
// sharer adds invitee as contact // sharer adds invitee as contact
contactId1 = contactManager0.addContact(author1, contactId1 = contactManager0.addContact(author1,
author0.getId(), master, clock.currentTimeMillis(), true, author0.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
// invitee adds sharer back // invitee adds sharer back
contactId0 = contactManager1.addContact(author0, contactId0 = contactManager1.addContact(author0,
author1.getId(), master, clock.currentTimeMillis(), true, author1.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
} }
@@ -434,8 +419,8 @@ public class ForumManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish // Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(SHARER); lifecycleManager0.startServices();
lifecycleManager1.startServices(INVITEE); lifecycleManager1.startServices();
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject; package org.briarproject;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumManager;
@@ -8,7 +7,6 @@ import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.SyncSessionFactory; import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.blogs.BlogsModule;
import org.briarproject.clients.ClientsModule; import org.briarproject.clients.ClientsModule;
import org.briarproject.contact.ContactModule; import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule; import org.briarproject.crypto.CryptoModule;
@@ -18,7 +16,6 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule; import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule; import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule; import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule; import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule; import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
@@ -41,17 +38,15 @@ import dagger.Component;
DatabaseModule.class, DatabaseModule.class,
EventModule.class, EventModule.class,
ForumModule.class, ForumModule.class,
BlogsModule.class,
IdentityModule.class, IdentityModule.class,
LifecycleModule.class, LifecycleModule.class,
PropertiesModule.class, PropertiesModule.class,
SharingModule.class, SharingModule.class,
SyncModule.class, SyncModule.class,
SystemModule.class, SystemModule.class,
TransportModule.class, TransportModule.class
MessagingModule.class
}) })
interface ForumManagerTestComponent { public interface ForumManagerTestComponent {
void inject(ForumManagerTest testCase); void inject(ForumManagerTest testCase);
@@ -79,8 +74,6 @@ interface ForumManagerTestComponent {
ContactManager getContactManager(); ContactManager getContactManager();
MessageTracker getMessageTracker();
ForumSharingManager getForumSharingManager(); ForumSharingManager getForumSharingManager();
ForumManager getForumManager(); ForumManager getForumManager();

View File

@@ -3,13 +3,16 @@ package org.briarproject;
import net.jodah.concurrentunit.Waiter; import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.Bytes; import org.briarproject.api.Bytes;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager; import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.SessionId; import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.KeyParser;
import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.data.BdfList; import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
@@ -22,8 +25,7 @@ import org.briarproject.api.event.ForumInvitationReceivedEvent;
import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; import org.briarproject.api.event.ForumInvitationResponseReceivedEvent;
import org.briarproject.api.event.MessageStateChangedEvent; import org.briarproject.api.event.MessageStateChangedEvent;
import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumInvitationRequest; import org.briarproject.api.forum.ForumInvitationMessage;
import org.briarproject.api.forum.ForumInvitationResponse;
import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPost; import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.forum.ForumPostFactory; import org.briarproject.api.forum.ForumPostFactory;
@@ -33,8 +35,7 @@ import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sharing.SharingInvitationItem; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.SyncSession; import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory; import org.briarproject.api.sync.SyncSessionFactory;
@@ -68,7 +69,6 @@ import javax.inject.Inject;
import static org.briarproject.TestPluginsModule.MAX_LATENCY; import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.api.forum.ForumSharingManager.CLIENT_ID;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED; import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID; import static org.briarproject.api.sync.ValidationManager.State.INVALID;
@@ -111,7 +111,6 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
private final String SHARER = "Sharer"; private final String SHARER = "Sharer";
private final String INVITEE = "Invitee"; private final String INVITEE = "Invitee";
private final String SHARER2 = "Sharer2"; private final String SHARER2 = "Sharer2";
private boolean respond = true;
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(ForumSharingIntegrationTest.class.getName()); Logger.getLogger(ForumSharingIntegrationTest.class.getName());
@@ -184,33 +183,22 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertTrue(listener0.responseReceived); assertTrue(listener0.responseReceived);
// forum was added successfully // forum was added successfully
assertEquals(0, forumSharingManager0.getInvitations().size()); assertEquals(0, forumSharingManager0.getInvited().size());
assertEquals(1, forumManager1.getForums().size()); assertEquals(1, forumManager1.getForums().size());
// invitee has one invitation message from sharer // invitee has one invitation message from sharer
List<InvitationMessage> list = List<ForumInvitationMessage> list =
new ArrayList<>(forumSharingManager1 new ArrayList<>(forumSharingManager1
.getInvitationMessages(contactId0)); .getInvitationMessages(contactId0));
assertEquals(2, list.size()); assertEquals(1, list.size());
// check other things are alright with the forum message // check other things are alright with the forum message
for (InvitationMessage m : list) { ForumInvitationMessage invitation = list.get(0);
if (m instanceof ForumInvitationRequest) { assertFalse(invitation.isAvailable());
ForumInvitationRequest invitation = assertEquals(forum0.getName(), invitation.getForumName());
(ForumInvitationRequest) m; assertEquals(contactId1, invitation.getContactId());
assertFalse(invitation.isAvailable()); assertEquals("Hi!", invitation.getMessage());
assertEquals(forum0.getName(), invitation.getForumName()); // sharer has own invitation message
assertEquals(contactId1, invitation.getContactId()); assertEquals(1,
assertEquals("Hi!", invitation.getMessage());
} else {
ForumInvitationResponse response =
(ForumInvitationResponse) m;
assertEquals(contactId0, response.getContactId());
assertTrue(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
forumSharingManager0.getInvitationMessages(contactId1) forumSharingManager0.getInvitationMessages(contactId1)
.size()); .size());
// forum can not be shared again // forum can not be shared again
@@ -245,35 +233,24 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertTrue(listener0.responseReceived); assertTrue(listener0.responseReceived);
// forum was not added // forum was not added
assertEquals(0, forumSharingManager0.getInvitations().size()); assertEquals(0, forumSharingManager0.getInvited().size());
assertEquals(0, forumManager1.getForums().size()); assertEquals(0, forumManager1.getForums().size());
// forum is no longer available to invitee who declined // forum is no longer available to invitee who declined
assertEquals(0, forumSharingManager1.getInvitations().size()); assertEquals(0, forumSharingManager1.getInvited().size());
// invitee has one invitation message from sharer and one response // invitee has one invitation message from sharer
List<InvitationMessage> list = List<ForumInvitationMessage> list =
new ArrayList<>(forumSharingManager1 new ArrayList<>(forumSharingManager1
.getInvitationMessages(contactId0)); .getInvitationMessages(contactId0));
assertEquals(2, list.size()); assertEquals(1, list.size());
// check things are alright with the forum message // check other things are alright with the forum message
for (InvitationMessage m : list) { ForumInvitationMessage invitation = list.get(0);
if (m instanceof ForumInvitationRequest) { assertFalse(invitation.isAvailable());
ForumInvitationRequest invitation = assertEquals(forum0.getName(), invitation.getForumName());
(ForumInvitationRequest) m; assertEquals(contactId1, invitation.getContactId());
assertFalse(invitation.isAvailable()); assertEquals(null, invitation.getMessage());
assertEquals(forum0.getName(), invitation.getForumName()); // sharer has own invitation message
assertEquals(contactId1, invitation.getContactId()); assertEquals(1,
assertEquals(null, invitation.getMessage());
} else {
ForumInvitationResponse response =
(ForumInvitationResponse) m;
assertEquals(contactId0, response.getContactId());
assertFalse(response.wasAccepted());
assertTrue(response.isLocal());
}
}
// sharer has own invitation message and response
assertEquals(2,
forumSharingManager0.getInvitationMessages(contactId1) forumSharingManager0.getInvitationMessages(contactId1)
.size()); .size());
// forum can be shared again // forum can be shared again
@@ -306,7 +283,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertTrue(listener0.responseReceived); assertTrue(listener0.responseReceived);
// forum was added successfully // forum was added successfully
assertEquals(0, forumSharingManager0.getInvitations().size()); assertEquals(0, forumSharingManager0.getInvited().size());
assertEquals(1, forumManager1.getForums().size()); assertEquals(1, forumManager1.getForums().size());
assertTrue(forumManager1.getForums().contains(forum0)); assertTrue(forumManager1.getForums().contains(forum0));
@@ -326,7 +303,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
syncToSharer(); syncToSharer();
// forum is gone // forum is gone
assertEquals(0, forumSharingManager0.getInvitations().size()); assertEquals(0, forumSharingManager0.getInvited().size());
assertEquals(0, forumManager1.getForums().size()); assertEquals(0, forumManager1.getForums().size());
// sharer no longer shares forum with invitee // sharer no longer shares forum with invitee
@@ -366,7 +343,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
assertTrue(listener0.responseReceived); assertTrue(listener0.responseReceived);
// forum was added successfully // forum was added successfully
assertEquals(0, forumSharingManager0.getInvitations().size()); assertEquals(0, forumSharingManager0.getInvited().size());
assertEquals(1, forumManager1.getForums().size()); assertEquals(1, forumManager1.getForums().size());
assertTrue(forumManager1.getForums().contains(forum0)); assertTrue(forumManager1.getForums().contains(forum0));
@@ -407,7 +384,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
public void testSharerLeavesBeforeResponse() throws Exception { public void testSharerLeavesBeforeResponse() throws Exception {
startLifecycles(); startLifecycles();
try { try {
// initialize except event listeners // initialize and let invitee accept all requests
defaultInit(true); defaultInit(true);
// send invitation // send invitation
@@ -417,39 +394,17 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// sharer un-subscribes from forum // sharer un-subscribes from forum
forumManager0.removeForum(forum0); forumManager0.removeForum(forum0);
// prevent invitee response before syncing messages // from here on expect the response to fail with an AssertionError,
respond = false; // because there is in fact no invited forum available anymore
thrown.expect(AssertionError.class);
// sync first request message and leave message // sync first request message and leave message
deliverMessage(sync0, contactId0, sync1, contactId1, 2, syncToInvitee();
"Sharer to Invitee");
eventWaiter.await(TIMEOUT, 1); eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived); assertTrue(listener1.requestReceived);
// ensure that invitee has no forum invitations available // invitee has no forums available
assertEquals(0, forumSharingManager1.getInvitations().size()); assertEquals(0, forumSharingManager1.getInvited().size());
assertEquals(0, forumManager1.getForums().size());
// Try again, this time allow the response
addForumForSharer();
respond = true;
// send invitation
forumSharingManager0
.sendInvitation(forum0.getId(), contactId1, null);
// sharer un-subscribes from forum
forumManager0.removeForum(forum0);
// sync first request message and leave message
deliverMessage(sync0, contactId0, sync1, contactId1, 2,
"Sharer to Invitee");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// ensure that invitee has no forum invitations available
assertEquals(0, forumSharingManager1.getInvitations().size());
assertEquals(1, forumManager1.getForums().size());
} finally { } finally {
stopLifecycles(); stopLifecycles();
} }
@@ -483,20 +438,20 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
listener1.requestReceived = false; listener1.requestReceived = false;
// get SessionId from invitation // get SessionId from invitation
List<InvitationMessage> list = new ArrayList<>( List<ForumInvitationMessage> list = new ArrayList<>(
forumSharingManager1 forumSharingManager1
.getInvitationMessages(contactId0)); .getInvitationMessages(contactId0));
assertEquals(2, list.size()); assertEquals(1, list.size());
InvitationMessage msg = list.get(0); ForumInvitationMessage msg = list.get(0);
SessionId sessionId = msg.getSessionId(); SessionId sessionId = msg.getSessionId();
assertEquals(sessionId, list.get(1).getSessionId());
// get all sorts of stuff needed to send a message // get all sorts of stuff needed to send a message
DatabaseComponent db = t0.getDatabaseComponent(); DatabaseComponent db = t0.getDatabaseComponent();
MessageQueueManager queue = t0.getMessageQueueManager(); MessageQueueManager queue = t0.getMessageQueueManager();
Contact c1 = contactManager0.getContact(contactId1); Contact c1 = contactManager0.getContact(contactId1);
ContactGroupFactory groupFactory = t0.getContactGroupFactory(); PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
Group group = groupFactory.createContactGroup(CLIENT_ID, c1); Group group = groupFactory
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
long time = clock.currentTimeMillis(); long time = clock.currentTimeMillis();
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION, BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
sessionId.getBytes(), sessionId.getBytes(),
@@ -509,7 +464,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
queue.sendMessage(txn, group, time, body, new Metadata()); queue.sendMessage(txn, group, time, body, new Metadata());
db.commitTransaction(txn); txn.setComplete();
} finally { } finally {
db.endTransaction(txn); db.endTransaction(txn);
} }
@@ -546,9 +501,6 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// forum was added successfully // forum was added successfully
assertEquals(1, forumManager1.getForums().size()); assertEquals(1, forumManager1.getForums().size());
assertEquals(2,
forumSharingManager0.getInvitationMessages(contactId1)
.size());
// invitee now shares same forum back // invitee now shares same forum back
forumSharingManager1.sendInvitation(forum0.getId(), forumSharingManager1.sendInvitation(forum0.getId(),
@@ -560,10 +512,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// make sure that no new request was received // make sure that no new request was received
assertFalse(listener0.requestReceived); assertFalse(listener0.requestReceived);
assertEquals(2, assertEquals(1,
forumSharingManager0.getInvitationMessages(contactId1) forumSharingManager0.getInvitationMessages(contactId1)
.size()); .size());
assertEquals(0, forumSharingManager0.getInvitations().size());
} finally { } finally {
stopLifecycles(); stopLifecycles();
} }
@@ -580,7 +531,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db1 = t1.getDatabaseComponent(); DatabaseComponent db1 = t1.getDatabaseComponent();
Transaction txn = db1.startTransaction(false); Transaction txn = db1.startTransaction(false);
db1.addGroup(txn, forum0.getGroup()); db1.addGroup(txn, forum0.getGroup());
db1.commitTransaction(txn); txn.setComplete();
db1.endTransaction(txn); db1.endTransaction(txn);
// send invitation // send invitation
@@ -615,9 +566,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
eventWaiter.await(TIMEOUT, 1); eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived); assertTrue(listener0.responseReceived);
assertEquals(2, forumSharingManager0 assertEquals(1, forumSharingManager0
.getInvitationMessages(contactId1).size()); .getInvitationMessages(contactId1).size());
assertEquals(3, forumSharingManager1 assertEquals(2, forumSharingManager1
.getInvitationMessages(contactId0).size()); .getInvitationMessages(contactId0).size());
} else { } else {
eventWaiter.await(TIMEOUT, 1); eventWaiter.await(TIMEOUT, 1);
@@ -628,9 +579,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
eventWaiter.await(TIMEOUT, 1); eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.responseReceived); assertTrue(listener1.responseReceived);
assertEquals(3, forumSharingManager0 assertEquals(2, forumSharingManager0
.getInvitationMessages(contactId1).size()); .getInvitationMessages(contactId1).size());
assertEquals(2, forumSharingManager1 assertEquals(1, forumSharingManager1
.getInvitationMessages(contactId0).size()); .getInvitationMessages(contactId0).size());
} }
} finally { } finally {
@@ -665,13 +616,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
forumSharingManager0.getSharedWith(forum0.getId()).size()); forumSharingManager0.getSharedWith(forum0.getId()).size());
// remember SessionId from invitation // remember SessionId from invitation
List<InvitationMessage> list = new ArrayList<>( List<ForumInvitationMessage> list = new ArrayList<>(
forumSharingManager1 forumSharingManager1
.getInvitationMessages(contactId0)); .getInvitationMessages(contactId0));
assertEquals(2, list.size()); assertEquals(1, list.size());
InvitationMessage msg = list.get(0); ForumInvitationMessage msg = list.get(0);
SessionId sessionId = msg.getSessionId(); SessionId sessionId = msg.getSessionId();
assertEquals(sessionId, list.get(1).getSessionId());
// contacts now remove each other // contacts now remove each other
contactManager0.removeContact(contactId1); contactManager0.removeContact(contactId1);
@@ -690,8 +640,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db = t0.getDatabaseComponent(); DatabaseComponent db = t0.getDatabaseComponent();
MessageQueueManager queue = t0.getMessageQueueManager(); MessageQueueManager queue = t0.getMessageQueueManager();
Contact c1 = contactManager0.getContact(contactId1); Contact c1 = contactManager0.getContact(contactId1);
ContactGroupFactory groupFactory = t0.getContactGroupFactory(); PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
Group group = groupFactory.createContactGroup(CLIENT_ID, c1); Group group = groupFactory
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
long time = clock.currentTimeMillis(); long time = clock.currentTimeMillis();
// construct a new message re-using the old SessionId // construct a new message re-using the old SessionId
@@ -706,7 +657,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
queue.sendMessage(txn, group, time, body, new Metadata()); queue.sendMessage(txn, group, time, body, new Metadata());
db.commitTransaction(txn); txn.setComplete();
} finally { } finally {
db.endTransaction(txn); db.endTransaction(txn);
} }
@@ -727,7 +678,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
startLifecycles(); startLifecycles();
try { try {
// initialize // initialize
getDefaultIdentities(); addDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addForumForSharer(); addForumForSharer();
@@ -735,7 +686,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db2 = t2.getDatabaseComponent(); DatabaseComponent db2 = t2.getDatabaseComponent();
Transaction txn = db2.startTransaction(false); Transaction txn = db2.startTransaction(false);
db2.addGroup(txn, forum0.getGroup()); db2.addGroup(txn, forum0.getGroup());
db2.commitTransaction(txn); txn.setComplete();
db2.endTransaction(txn); db2.endTransaction(txn);
// add listeners // add listeners
@@ -756,15 +707,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
forumSharingManager2 forumSharingManager2
.sendInvitation(forum0.getId(), contactId1, null); .sendInvitation(forum0.getId(), contactId1, null);
// sync second request message // sync second request message
deliverMessage(sync2, contactId2, sync1, contactId1, 1, deliverMessage(sync2, contactId2, sync1, contactId1,
"Sharer2 to Invitee"); "Sharer2 to Invitee");
// make sure we now have two invitations to the same forum available // make sure we now have two invitations to the same forum available
Collection<SharingInvitationItem> forums = Collection<Forum> forums = forumSharingManager1.getInvited();
forumSharingManager1.getInvitations();
assertEquals(1, forums.size()); assertEquals(1, forums.size());
assertEquals(2, forums.iterator().next().getNewSharers().size());
assertEquals(forum0, forums.iterator().next().getShareable());
assertEquals(2, assertEquals(2,
forumSharingManager1.getSharedBy(forum0.getId()).size()); forumSharingManager1.getSharedBy(forum0.getId()).size());
@@ -777,7 +725,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
Contact c2 = contactManager1.getContact(contactId2); Contact c2 = contactManager1.getContact(contactId2);
forumSharingManager1.respondToInvitation(forum0, c2, true); forumSharingManager1.respondToInvitation(forum0, c2, true);
// sync response // sync response
deliverMessage(sync1, contactId21, sync2, contactId2, 1, deliverMessage(sync1, contactId21, sync2, contactId2,
"Invitee to Sharer2"); "Invitee to Sharer2");
eventWaiter.await(TIMEOUT, 1); eventWaiter.await(TIMEOUT, 1);
assertTrue(listener2.responseReceived); assertTrue(listener2.responseReceived);
@@ -816,10 +764,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// sharer posts into the forum // sharer posts into the forum
long time = clock.currentTimeMillis(); long time = clock.currentTimeMillis();
String body = TestUtils.getRandomString(42); byte[] body = TestUtils.getRandomBytes(42);
KeyParser keyParser = cryptoComponent.getSignatureKeyParser();
PrivateKey key = keyParser.parsePrivateKey(author0.getPrivateKey());
ForumPost p = forumPostFactory ForumPost p = forumPostFactory
.createPost(forum0.getId(), time, null, author0, .createPseudonymousPost(forum0.getId(), time, null, author0,
body); "text/plain", body, key);
forumManager0.addLocalPost(p); forumManager0.addLocalPost(p);
// sync forum post // sync forum post
@@ -835,10 +785,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// now invitee creates a post // now invitee creates a post
time = clock.currentTimeMillis(); time = clock.currentTimeMillis();
body = TestUtils.getRandomString(42); body = TestUtils.getRandomBytes(42);
key = keyParser.parsePrivateKey(author1.getPrivateKey());
p = forumPostFactory p = forumPostFactory
.createPost(forum0.getId(), time, null, author1, .createPseudonymousPost(forum0.getId(), time, null, author1,
body); "text/plain", body, key);
forumManager1.addLocalPost(p); forumManager1.addLocalPost(p);
// sync forum post // sync forum post
@@ -879,10 +830,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// now invitee creates a post // now invitee creates a post
time = clock.currentTimeMillis(); time = clock.currentTimeMillis();
body = TestUtils.getRandomString(42); body = TestUtils.getRandomBytes(42);
key = keyParser.parsePrivateKey(author1.getPrivateKey());
p = forumPostFactory p = forumPostFactory
.createPost(forum0.getId(), time, null, author1, .createPseudonymousPost(forum0.getId(), time, null, author1,
body); "text/plain", body, key);
forumManager1.addLocalPost(p); forumManager1.addLocalPost(p);
// sync forum post // sync forum post
@@ -912,16 +864,23 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
private class SharerListener implements EventListener { private class SharerListener implements EventListener {
private volatile boolean requestReceived = false; volatile boolean requestReceived = false;
private volatile boolean responseReceived = false; volatile boolean responseReceived = false;
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) { if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e; MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState(); State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) { ClientId c = event.getClientId();
LOG.info("TEST: Sharer received message"); if ((s == DELIVERED || s == INVALID) &&
c.equals(forumSharingManager0.getClientId()) &&
!event.isLocal()) {
LOG.info("TEST: Sharer received message in group " +
event.getMessage().getGroupId().hashCode());
msgWaiter.resume();
} else if (s == DELIVERED && !event.isLocal() &&
c.equals(forumManager0.getClientId())) {
LOG.info("TEST: Sharer received forum post");
msgWaiter.resume(); msgWaiter.resume();
} }
} else if (e instanceof ForumInvitationResponseReceivedEvent) { } else if (e instanceof ForumInvitationResponseReceivedEvent) {
@@ -937,7 +896,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
(ForumInvitationReceivedEvent) e; (ForumInvitationReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId()); eventWaiter.assertEquals(contactId1, event.getContactId());
requestReceived = true; requestReceived = true;
Forum f = event.getShareable(); Forum f = event.getForum();
try { try {
Contact c = contactManager0.getContact(contactId1); Contact c = contactManager0.getContact(contactId1);
forumSharingManager0.respondToInvitation(f, c, true); forumSharingManager0.respondToInvitation(f, c, true);
@@ -952,27 +911,34 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
private class InviteeListener implements EventListener { private class InviteeListener implements EventListener {
private volatile boolean requestReceived = false; volatile boolean requestReceived = false;
private volatile boolean responseReceived = false; volatile boolean responseReceived = false;
private final boolean accept, answer; private final boolean accept, answer;
private InviteeListener(boolean accept, boolean answer) { InviteeListener(boolean accept, boolean answer) {
this.accept = accept; this.accept = accept;
this.answer = answer; this.answer = answer;
} }
private InviteeListener(boolean accept) { InviteeListener(boolean accept) {
this(accept, true); this(accept, true);
} }
@Override
public void eventOccurred(Event e) { public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) { if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e; MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState(); State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) { ClientId c = event.getClientId();
LOG.info("TEST: Invitee received message"); if ((s == DELIVERED || s == INVALID) &&
c.equals(forumSharingManager0.getClientId()) &&
!event.isLocal()) {
LOG.info("TEST: Invitee received message in group " +
event.getMessage().getGroupId().hashCode());
msgWaiter.resume();
} else if (s == DELIVERED && !event.isLocal() &&
c.equals(forumManager0.getClientId())) {
LOG.info("TEST: Invitee received forum post");
msgWaiter.resume(); msgWaiter.resume();
} }
} else if (e instanceof ForumInvitationReceivedEvent) { } else if (e instanceof ForumInvitationReceivedEvent) {
@@ -980,19 +946,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
(ForumInvitationReceivedEvent) e; (ForumInvitationReceivedEvent) e;
requestReceived = true; requestReceived = true;
if (!answer) return; if (!answer) return;
Forum f = event.getShareable(); Forum f = event.getForum();
try { try {
eventWaiter.assertEquals(1, eventWaiter.assertEquals(1,
forumSharingManager1.getInvitations().size()); forumSharingManager1.getInvited().size());
SharingInvitationItem invitation =
forumSharingManager1.getInvitations().iterator()
.next();
eventWaiter.assertEquals(f, invitation.getShareable());
if (respond) {
Contact c = Contact c =
contactManager1.getContact(event.getContactId()); contactManager1.getContact(event.getContactId());
forumSharingManager1.respondToInvitation(f, c, accept); forumSharingManager1.respondToInvitation(f, c, accept);
}
} catch (DbException ex) { } catch (DbException ex) {
eventWaiter.rethrow(ex); eventWaiter.rethrow(ex);
} finally { } finally {
@@ -1015,9 +975,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
lifecycleManager0 = t0.getLifecycleManager(); lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager(); lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager(); lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(SHARER); lifecycleManager0.startServices();
lifecycleManager1.startServices(INVITEE); lifecycleManager1.startServices();
lifecycleManager2.startServices(SHARER2); lifecycleManager2.startServices();
lifecycleManager0.waitForStartup(); lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup(); lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup(); lifecycleManager2.waitForStartup();
@@ -1034,37 +994,51 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
} }
private void defaultInit(boolean accept) throws DbException { private void defaultInit(boolean accept) throws DbException {
getDefaultIdentities(); addDefaultIdentities();
addDefaultContacts(); addDefaultContacts();
addForumForSharer(); addForumForSharer();
listenToEvents(accept); listenToEvents(accept);
} }
private void getDefaultIdentities() throws DbException { private void addDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor(); KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
author1 = identityManager1.getLocalAuthor(); author0 = authorFactory.createLocalAuthor(SHARER,
author2 = identityManager2.getLocalAuthor(); keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager0.addLocalAuthor(author0);
keyPair = cryptoComponent.generateSignatureKeyPair();
author1 = authorFactory.createLocalAuthor(INVITEE,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager1.addLocalAuthor(author1);
keyPair = cryptoComponent.generateSignatureKeyPair();
author2 = authorFactory.createLocalAuthor(SHARER2,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager2.addLocalAuthor(author2);
} }
private void addDefaultContacts() throws DbException { private void addDefaultContacts() throws DbException {
// sharer adds invitee as contact // sharer adds invitee as contact
contactId1 = contactManager0.addContact(author1, contactId1 = contactManager0.addContact(author1,
author0.getId(), master, clock.currentTimeMillis(), true, author0.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
// second sharer does the same // second sharer does the same
contactId21 = contactManager2.addContact(author1, contactId21 = contactManager2.addContact(author1,
author2.getId(), master, clock.currentTimeMillis(), true, author2.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
// invitee adds sharers back // invitee adds sharers back
contactId0 = contactManager1.addContact(author0, contactId0 = contactManager1.addContact(author0,
author1.getId(), master, clock.currentTimeMillis(), true, author1.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
contactId2 = contactManager1.addContact(author2, contactId2 = contactManager1.addContact(author2,
author1.getId(), master, clock.currentTimeMillis(), true, author1.getId(), master, clock.currentTimeMillis(), true,
true, true true
); );
} }
@@ -1083,17 +1057,17 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
} }
private void syncToInvitee() throws IOException, TimeoutException { private void syncToInvitee() throws IOException, TimeoutException {
deliverMessage(sync0, contactId0, sync1, contactId1, 1, deliverMessage(sync0, contactId0, sync1, contactId1,
"Sharer to Invitee"); "Sharer to Invitee");
} }
private void syncToSharer() throws IOException, TimeoutException { private void syncToSharer() throws IOException, TimeoutException {
deliverMessage(sync1, contactId1, sync0, contactId0, 1, deliverMessage(sync1, contactId1, sync0, contactId0,
"Invitee to Sharer"); "Invitee to Sharer");
} }
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId, private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
SyncSessionFactory toSync, ContactId toId, int num, String debug) SyncSessionFactory toSync, ContactId toId, String debug)
throws IOException, TimeoutException { throws IOException, TimeoutException {
if (debug != null) LOG.info("TEST: Sending message from " + debug); if (debug != null) LOG.info("TEST: Sending message from " + debug);
@@ -1114,7 +1088,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
in.close(); in.close();
// wait for message to actually arrive // wait for message to actually arrive
msgWaiter.await(TIMEOUT, num); msgWaiter.await(TIMEOUT, 1);
} }
private void injectEagerSingletons( private void injectEagerSingletons(

View File

@@ -2,7 +2,7 @@ package org.briarproject;
import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager; import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.ContactGroupFactory; import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
@@ -11,7 +11,6 @@ import org.briarproject.api.forum.ForumSharingManager;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.SyncSessionFactory; import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.blogs.BlogsModule;
import org.briarproject.clients.ClientsModule; import org.briarproject.clients.ClientsModule;
import org.briarproject.contact.ContactModule; import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule; import org.briarproject.crypto.CryptoModule;
@@ -21,7 +20,6 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule; import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule; import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule; import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule; import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule; import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
@@ -44,17 +42,15 @@ import dagger.Component;
DatabaseModule.class, DatabaseModule.class,
EventModule.class, EventModule.class,
ForumModule.class, ForumModule.class,
BlogsModule.class,
IdentityModule.class, IdentityModule.class,
LifecycleModule.class, LifecycleModule.class,
PropertiesModule.class, PropertiesModule.class,
SharingModule.class, SharingModule.class,
SyncModule.class, SyncModule.class,
SystemModule.class, SystemModule.class,
TransportModule.class, TransportModule.class
MessagingModule.class
}) })
interface ForumSharingIntegrationTestComponent { public interface ForumSharingIntegrationTestComponent {
void inject(ForumSharingIntegrationTest testCase); void inject(ForumSharingIntegrationTest testCase);
@@ -92,7 +88,7 @@ interface ForumSharingIntegrationTestComponent {
DatabaseComponent getDatabaseComponent(); DatabaseComponent getDatabaseComponent();
ContactGroupFactory getContactGroupFactory(); PrivateGroupFactory getPrivateGroupFactory();
ClientHelper getClientHelper(); ClientHelper getClientHelper();

View File

@@ -1,10 +1,5 @@
package org.briarproject.introduction; package org.briarproject;
import org.briarproject.TestDatabaseModule;
import org.briarproject.TestPluginsModule;
import org.briarproject.TestSeedProviderModule;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
@@ -20,8 +15,10 @@ import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule; import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule; import org.briarproject.event.EventModule;
import org.briarproject.identity.IdentityModule; import org.briarproject.identity.IdentityModule;
import org.briarproject.introduction.IntroductionGroupFactory;
import org.briarproject.introduction.IntroductionModule;
import org.briarproject.introduction.MessageSender;
import org.briarproject.lifecycle.LifecycleModule; import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule; import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule; import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule; import org.briarproject.system.SystemModule;
@@ -48,10 +45,9 @@ import dagger.Component;
SyncModule.class, SyncModule.class,
SystemModule.class, SystemModule.class,
DataModule.class, DataModule.class,
PropertiesModule.class, PropertiesModule.class
MessagingModule.class
}) })
interface IntroductionIntegrationTestComponent { public interface IntroductionIntegrationTestComponent {
void inject(IntroductionIntegrationTest testCase); void inject(IntroductionIntegrationTest testCase);
@@ -83,16 +79,12 @@ interface IntroductionIntegrationTestComponent {
TransportPropertyManager getTransportPropertyManager(); TransportPropertyManager getTransportPropertyManager();
MessageTracker getMessageTracker();
SyncSessionFactory getSyncSessionFactory(); SyncSessionFactory getSyncSessionFactory();
/* the following methods are only needed to manually construct messages */ /* the following methods are only needed to manually construct messages */
DatabaseComponent getDatabaseComponent(); DatabaseComponent getDatabaseComponent();
ClientHelper getClientHelper();
MessageSender getMessageSender(); MessageSender getMessageSender();
IntroductionGroupFactory getIntroductionGroupFactory(); IntroductionGroupFactory getIntroductionGroupFactory();

View File

@@ -6,14 +6,14 @@ import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.forum.ForumConstants; import org.briarproject.api.forum.ForumConstants;
import org.briarproject.api.forum.ForumPost; import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.forum.ForumPostFactory; import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.messaging.MessagingConstants;
import org.briarproject.api.messaging.PrivateMessage; import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.briarproject.system.SystemModule; import org.briarproject.system.SystemModule;
import org.briarproject.util.StringUtils;
import org.junit.Test; import org.junit.Test;
import javax.inject.Inject; import javax.inject.Inject;
@@ -48,14 +48,17 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
// Create a maximum-length private message // Create a maximum-length private message
GroupId groupId = new GroupId(TestUtils.getRandomId()); GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE; long timestamp = Long.MAX_VALUE;
String body = MessageId parent = new MessageId(TestUtils.getRandomId());
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]); String contentType = TestUtils.getRandomString(
MessagingConstants.MAX_CONTENT_TYPE_LENGTH);
byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH];
PrivateMessage message = privateMessageFactory.createPrivateMessage( PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, body); groupId, timestamp, parent, contentType, body);
// Check the size of the serialised message // Check the size of the serialised message
int length = message.getMessage().getRaw().length; int length = message.getMessage().getRaw().length;
assertTrue( assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH); + MessagingConstants.MAX_CONTENT_TYPE_LENGTH
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH); assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
} }
@@ -65,17 +68,17 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
String authorName = TestUtils.getRandomString( String authorName = TestUtils.getRandomString(
MAX_AUTHOR_NAME_LENGTH); MAX_AUTHOR_NAME_LENGTH);
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH]; byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate(); Author author = authorFactory.createAuthor(authorName, authorPublic);
LocalAuthor author = authorFactory
.createLocalAuthor(authorName, authorPublic,
privateKey.getEncoded());
// Create a maximum-length forum post // Create a maximum-length forum post
GroupId groupId = new GroupId(TestUtils.getRandomId()); GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE; long timestamp = Long.MAX_VALUE;
MessageId parent = new MessageId(TestUtils.getRandomId()); MessageId parent = new MessageId(TestUtils.getRandomId());
String body = TestUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH); String contentType = TestUtils.getRandomString(
ForumPost post = forumPostFactory.createPost(groupId, ForumConstants.MAX_CONTENT_TYPE_LENGTH);
timestamp, parent, author, body); byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH];
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
ForumPost post = forumPostFactory.createPseudonymousPost(groupId,
timestamp, parent, author, contentType, body, privateKey);
// Check the size of the serialised message // Check the size of the serialised message
int length = post.getMessage().getRaw().length; int length = post.getMessage().getRaw().length;
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH

View File

@@ -1,838 +0,0 @@
package org.briarproject;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageStateChangedEvent;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.GroupMember;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.JoinMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.privategroup.invitation.GroupInvitationFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.privategroup.PrivateGroupModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.transport.TransportModule;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.TestUtils.getRandomBytes;
import static org.briarproject.api.identity.Author.Status.VERIFIED;
import static org.briarproject.api.privategroup.Visibility.INVISIBLE;
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_CONTACT;
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_US;
import static org.briarproject.api.privategroup.Visibility.VISIBLE;
import static org.briarproject.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
import static org.briarproject.api.sync.Group.Visibility.SHARED;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class PrivateGroupManagerTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
private SyncSessionFactory sync0, sync1, sync2;
private PrivateGroupManager groupManager0, groupManager1, groupManager2;
private ContactManager contactManager0, contactManager1, contactManager2;
private ContactId contactId01, contactId02, contactId1, contactId2;
private IdentityManager identityManager0, identityManager1,
identityManager2;
private LocalAuthor author0, author1, author2;
private DatabaseComponent db0, db1, db2;
private PrivateGroup privateGroup0;
private GroupId groupId0;
@Inject
Clock clock;
@Inject
AuthorFactory authorFactory;
@Inject
ClientHelper clientHelper;
@Inject
CryptoComponent crypto;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
PrivateGroupFactory privateGroupFactory;
@Inject
GroupMessageFactory groupMessageFactory;
@Inject
GroupInvitationFactory groupInvitationFactory;
// objects accessed from background threads need to be volatile
private volatile Waiter validationWaiter;
private volatile Waiter deliveryWaiter;
private final File testDir = TestUtils.getTestDirectory();
private final SecretKey master = TestUtils.getSecretKey();
private final int TIMEOUT = 15000;
private final String AUTHOR0 = "Author 0";
private final String AUTHOR1 = "Author 1";
private final String AUTHOR2 = "Author 2";
private static final Logger LOG =
Logger.getLogger(PrivateGroupManagerTest.class.getName());
private PrivateGroupManagerTestComponent t0, t1, t2;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setUp() throws Exception {
PrivateGroupManagerTestComponent component =
DaggerPrivateGroupManagerTestComponent.builder().build();
component.inject(this);
assertTrue(testDir.mkdirs());
File t0Dir = new File(testDir, AUTHOR0);
t0 = DaggerPrivateGroupManagerTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
injectEagerSingletons(t0);
File t1Dir = new File(testDir, AUTHOR1);
t1 = DaggerPrivateGroupManagerTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
injectEagerSingletons(t1);
File t2Dir = new File(testDir, AUTHOR2);
t2 = DaggerPrivateGroupManagerTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t2Dir)).build();
injectEagerSingletons(t2);
identityManager0 = t0.getIdentityManager();
identityManager1 = t1.getIdentityManager();
identityManager2 = t2.getIdentityManager();
contactManager0 = t0.getContactManager();
contactManager1 = t1.getContactManager();
contactManager2 = t2.getContactManager();
db0 = t0.getDatabaseComponent();
db1 = t1.getDatabaseComponent();
db2 = t2.getDatabaseComponent();
groupManager0 = t0.getPrivateGroupManager();
groupManager1 = t1.getPrivateGroupManager();
groupManager2 = t2.getPrivateGroupManager();
sync0 = t0.getSyncSessionFactory();
sync1 = t1.getSyncSessionFactory();
sync2 = t2.getSyncSessionFactory();
// initialize waiters fresh for each test
validationWaiter = new Waiter();
deliveryWaiter = new Waiter();
startLifecycles();
}
@Test
public void testSendingMessage() throws Exception {
defaultInit();
// create and add test message
long time = clock.currentTimeMillis();
String body = "This is a test message!";
MessageId previousMsgId =
groupManager0.getPreviousMsgId(groupId0);
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, time, null, author0, body,
previousMsgId);
groupManager0.addLocalMessage(msg);
assertEquals(msg.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// sync test message
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// assert that message arrived as expected
Collection<GroupMessageHeader> headers =
groupManager1.getHeaders(groupId0);
assertEquals(3, headers.size());
GroupMessageHeader header = null;
for (GroupMessageHeader h : headers) {
if (!(h instanceof JoinMessageHeader)) {
header = h;
}
}
assertTrue(header != null);
assertFalse(header.isRead());
assertEquals(author0, header.getAuthor());
assertEquals(time, header.getTimestamp());
assertEquals(VERIFIED, header.getAuthorStatus());
assertEquals(body, groupManager1.getMessageBody(header.getId()));
GroupCount count = groupManager1.getGroupCount(groupId0);
assertEquals(2, count.getUnreadCount());
assertEquals(time, count.getLatestMsgTime());
assertEquals(3, count.getMsgCount());
}
@Test
public void testMessageWithWrongPreviousMsgId() throws Exception {
defaultInit();
// create and add test message with no previousMsgId
@SuppressWarnings("ConstantConditions")
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
author0, "test", null);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with random previousMsgId
MessageId previousMsgId = new MessageId(TestUtils.getRandomId());
msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with wrong previousMsgId
previousMsgId = groupManager1.getPreviousMsgId(groupId0);
msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
}
@Test
public void testMessageWithWrongParentMsgId() throws Exception {
defaultInit();
// create and add test message with random parentMsgId
MessageId parentMsgId = new MessageId(TestUtils.getRandomId());
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(),
parentMsgId, author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with wrong parentMsgId
parentMsgId = previousMsgId;
msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(),
parentMsgId, author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
}
@Test
public void testMessageWithWrongTimestamp() throws Exception {
defaultInit();
// create and add test message with wrong timestamp
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, 42, null, author0, "test",
previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with good timestamp
long time = clock.currentTimeMillis();
msg = groupMessageFactory
.createGroupMessage(groupId0, time, null, author0, "test",
previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(3, groupManager1.getHeaders(groupId0).size());
// create and add test message with same timestamp as previous message
previousMsgId = msg.getMessage().getId();
msg = groupMessageFactory
.createGroupMessage(groupId0, time, previousMsgId, author0,
"test2", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(3, groupManager1.getHeaders(groupId0).size());
}
@Test
public void testWrongJoinMessages1() throws Exception {
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
// author0 joins privateGroup0 with wrong join message
long joinTime = clock.currentTimeMillis();
GroupMessage joinMsg0 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
joinTime, getRandomBytes(12));
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
assertEquals(joinMsg0.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author1 joins privateGroup0 with wrong timestamp
joinTime = clock.currentTimeMillis();
long inviteTime = joinTime;
Contact c1 = contactManager0.getContact(contactId1);
byte[] creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime,
author0.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature);
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
// sync join messages
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that 0 never joined the group from 1's perspective
assertEquals(1, groupManager1.getHeaders(groupId0).size());
sync1To0();
validationWaiter.await(TIMEOUT, 1);
// assert that 1 never joined the group from 0's perspective
assertEquals(1, groupManager0.getHeaders(groupId0).size());
}
@Test
public void testWrongJoinMessages2() throws Exception {
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
// author0 joins privateGroup0 with wrong member's join message
long joinTime = clock.currentTimeMillis();
long inviteTime = joinTime - 1;
BdfList toSign = groupInvitationFactory
.createInviteToken(author0.getId(), author0.getId(),
privateGroup0.getId(), inviteTime);
byte[] creatorSignature = clientHelper
.sign(SIGNING_LABEL_INVITE, toSign, author0.getPrivateKey());
// join message should not include invite time and creator's signature
GroupMessage joinMsg0 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
inviteTime, creatorSignature);
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
assertEquals(joinMsg0.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author1 joins privateGroup0 with wrong signature in join message
joinTime = clock.currentTimeMillis();
inviteTime = joinTime - 1;
// signature uses joiner's key, not creator's key
Contact c1 = contactManager0.getContact(contactId1);
creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime,
author1.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature);
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(), SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
// sync join messages
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that 0 never joined the group from 1's perspective
assertEquals(1, groupManager1.getHeaders(groupId0).size());
sync1To0();
validationWaiter.await(TIMEOUT, 1);
// assert that 1 never joined the group from 0's perspective
assertEquals(1, groupManager0.getHeaders(groupId0).size());
}
@Test
public void testGetMembers() throws Exception {
defaultInit();
Collection<GroupMember> members0 = groupManager0.getMembers(groupId0);
assertEquals(2, members0.size());
for (GroupMember m : members0) {
if (m.getAuthor().equals(author0)) {
assertEquals(VISIBLE, m.getVisibility());
} else {
assertEquals(author1, m.getAuthor());
assertEquals(VISIBLE, m.getVisibility());
}
}
Collection<GroupMember> members1 = groupManager1.getMembers(groupId0);
assertEquals(2, members1.size());
for (GroupMember m : members1) {
if (m.getAuthor().equals(author1)) {
assertEquals(VISIBLE, m.getVisibility());
} else {
assertEquals(author0, m.getAuthor());
assertEquals(VISIBLE, m.getVisibility());
}
}
}
@Test
public void testJoinMessages() throws Exception {
defaultInit();
Collection<GroupMessageHeader> headers0 =
groupManager0.getHeaders(groupId0);
for (GroupMessageHeader h : headers0) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
// all relationships of the creator are visible
assertEquals(VISIBLE, j.getVisibility());
}
}
Collection<GroupMessageHeader> headers1 =
groupManager1.getHeaders(groupId0);
for (GroupMessageHeader h : headers1) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
if (h.getAuthor().equals(author1))
// we are visible to ourselves
assertEquals(VISIBLE, j.getVisibility());
else
// our relationship to the creator is visible
assertEquals(VISIBLE, j.getVisibility());
}
}
}
@Test
public void testRevealingRelationships() throws Exception {
defaultInit();
// share the group with 2
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId2, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author2 joins privateGroup0
long joinTime = clock.currentTimeMillis();
long inviteTime = joinTime - 1;
Contact c2 = contactManager0.getContact(contactId2);
byte[] creatorSignature = groupInvitationFactory
.signInvitation(c2, privateGroup0.getId(), inviteTime,
author0.getPrivateKey());
GroupMessage joinMsg2 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author2,
inviteTime, creatorSignature);
Transaction txn2 = db2.startTransaction(false);
groupManager2.addPrivateGroup(txn2, privateGroup0, joinMsg2, false);
// share the group with 0
db2.setGroupVisibility(txn2, contactId01, privateGroup0.getId(),
SHARED);
db2.commitTransaction(txn2);
db2.endTransaction(txn2);
// sync join messages
deliverMessage(sync2, contactId2, sync0, contactId02, "2 to 0");
deliveryWaiter.await(TIMEOUT, 1);
deliverMessage(sync0, contactId02, sync2, contactId2, "0 to 2");
deliveryWaiter.await(TIMEOUT, 2);
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// check that everybody sees everybody else as joined
Collection<GroupMember> members0 = groupManager0.getMembers(groupId0);
assertEquals(3, members0.size());
Collection<GroupMember> members1 = groupManager1.getMembers(groupId0);
assertEquals(3, members1.size());
Collection<GroupMember> members2 = groupManager2.getMembers(groupId0);
assertEquals(3, members2.size());
// assert that contact relationship is not revealed initially
for (GroupMember m : members1) {
if (m.getAuthor().equals(author2)) {
assertEquals(INVISIBLE, m.getVisibility());
}
}
for (GroupMember m : members2) {
if (m.getAuthor().equals(author1)) {
assertEquals(INVISIBLE, m.getVisibility());
}
}
// reveal contact relationship
Transaction txn1 = db1.startTransaction(false);
groupManager1
.relationshipRevealed(txn1, groupId0, author2.getId(), false);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
txn2 = db2.startTransaction(false);
groupManager2
.relationshipRevealed(txn2, groupId0, author1.getId(), true);
db2.commitTransaction(txn2);
db2.endTransaction(txn2);
// assert that contact relationship is now revealed properly
members1 = groupManager1.getMembers(groupId0);
for (GroupMember m : members1) {
if (m.getAuthor().equals(author2)) {
assertEquals(REVEALED_BY_US, m.getVisibility());
}
}
members2 = groupManager2.getMembers(groupId0);
for (GroupMember m : members2) {
if (m.getAuthor().equals(author1)) {
assertEquals(REVEALED_BY_CONTACT, m.getVisibility());
}
}
// assert that join messages reflect revealed relationship
Collection<GroupMessageHeader> headers1 =
groupManager1.getHeaders(groupId0);
for (GroupMessageHeader h : headers1) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
if (h.getAuthor().equals(author2))
// 1 revealed the relationship to 2
assertEquals(REVEALED_BY_US, j.getVisibility());
else
// 1's other relationship (to 1 and creator) are visible
assertEquals(VISIBLE, j.getVisibility());
}
}
Collection<GroupMessageHeader> headers2 =
groupManager2.getHeaders(groupId0);
for (GroupMessageHeader h : headers2) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
if (h.getAuthor().equals(author1))
// 2's relationship was revealed by 1
assertEquals(REVEALED_BY_CONTACT, j.getVisibility());
else
// 2's other relationship (to 2 and creator) are visible
assertEquals(VISIBLE, j.getVisibility());
}
}
}
@Test
public void testDissolveGroup() throws Exception {
defaultInit();
// group is not dissolved initially
assertFalse(groupManager1.isDissolved(groupId0));
// creator dissolves group
Transaction txn1 = db1.startTransaction(false);
groupManager1.markGroupDissolved(txn1, groupId0);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
// group is dissolved now
assertTrue(groupManager1.isDissolved(groupId0));
}
@After
public void tearDown() throws Exception {
stopLifecycles();
TestUtils.deleteTestDirectory(testDir);
}
private class Listener implements EventListener {
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
if (!event.isLocal()) {
if (event.getState() == DELIVERED) {
LOG.info("Delivered new message");
deliveryWaiter.resume();
} else if (event.getState() == INVALID ||
event.getState() == PENDING) {
LOG.info("Validated new " + event.getState().name() +
" message");
validationWaiter.resume();
}
}
}
}
}
private void defaultInit() throws Exception {
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
addGroup();
}
private void addDefaultIdentities() throws DbException {
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
author0 = authorFactory
.createLocalAuthor(AUTHOR0, publicKey0, privateKey0);
identityManager0.registerLocalAuthor(author0);
privateGroup0 =
privateGroupFactory.createPrivateGroup("Testgroup", author0);
groupId0 = privateGroup0.getId();
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(AUTHOR1, publicKey1, privateKey1);
identityManager1.registerLocalAuthor(author1);
KeyPair keyPair2 = crypto.generateSignatureKeyPair();
byte[] publicKey2 = keyPair2.getPublic().getEncoded();
byte[] privateKey2 = keyPair2.getPrivate().getEncoded();
author2 = authorFactory
.createLocalAuthor(AUTHOR2, publicKey2, privateKey2);
identityManager2.registerLocalAuthor(author2);
}
private void addDefaultContacts() throws DbException {
// creator adds invitee as contact
contactId1 = contactManager0
.addContact(author1, author0.getId(), master,
clock.currentTimeMillis(), true, true, true);
// invitee adds creator back
contactId01 = contactManager1
.addContact(author0, author1.getId(), master,
clock.currentTimeMillis(), true, true, true);
// creator adds invitee as contact
contactId2 = contactManager0
.addContact(author2, author0.getId(), master,
clock.currentTimeMillis(), true, true, true);
// invitee adds creator back
contactId02 = contactManager2
.addContact(author0, author2.getId(), master,
clock.currentTimeMillis(), true, true, true);
}
private void listenToEvents() {
Listener listener0 = new Listener();
t0.getEventBus().addListener(listener0);
Listener listener1 = new Listener();
t1.getEventBus().addListener(listener1);
Listener listener2 = new Listener();
t2.getEventBus().addListener(listener2);
}
private void addGroup() throws Exception {
// author0 joins privateGroup0
long joinTime = clock.currentTimeMillis();
GroupMessage joinMsg0 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author0);
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
assertEquals(joinMsg0.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author1 joins privateGroup0
joinTime = clock.currentTimeMillis();
long inviteTime = joinTime - 1;
Contact c1 = contactManager0.getContact(contactId1);
byte[] creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime,
author0.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature);
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));
// sync join messages
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
sync1To0();
deliveryWaiter.await(TIMEOUT, 1);
}
private void sync0To1() throws IOException, TimeoutException {
deliverMessage(sync0, contactId01, sync1, contactId1, "0 to 1");
}
private void sync1To0() throws IOException, TimeoutException {
deliverMessage(sync1, contactId1, sync0, contactId01, "1 to 0");
}
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
SyncSessionFactory toSync, ContactId toId, String debug)
throws IOException, TimeoutException {
if (debug != null) LOG.info("TEST: Sending message from " + debug);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// Create an outgoing sync session
SyncSession sessionFrom =
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
// Write whatever needs to be written
sessionFrom.run();
out.close();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
// Create an incoming sync session
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
// Read whatever needs to be read
sessionTo.run();
in.close();
}
private void startLifecycles() throws InterruptedException {
// Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(AUTHOR0);
lifecycleManager1.startServices(AUTHOR1);
lifecycleManager2.startServices(AUTHOR2);
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup();
}
private void stopLifecycles() throws InterruptedException {
// Clean up
lifecycleManager0.stopServices();
lifecycleManager1.stopServices();
lifecycleManager2.stopServices();
lifecycleManager0.waitForShutdown();
lifecycleManager1.waitForShutdown();
lifecycleManager2.waitForShutdown();
}
private void injectEagerSingletons(
PrivateGroupManagerTestComponent component) {
component.inject(new LifecycleModule.EagerSingletons());
component.inject(new PrivateGroupModule.EagerSingletons());
component.inject(new CryptoModule.EagerSingletons());
component.inject(new ContactModule.EagerSingletons());
component.inject(new TransportModule.EagerSingletons());
component.inject(new SyncModule.EagerSingletons());
component.inject(new PropertiesModule.EagerSingletons());
}
}

View File

@@ -1,85 +0,0 @@
package org.briarproject;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.clients.ClientsModule;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.privategroup.PrivateGroupModule;
import org.briarproject.privategroup.invitation.GroupInvitationModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {
TestDatabaseModule.class,
TestPluginsModule.class,
TestSeedProviderModule.class,
ClientsModule.class,
ContactModule.class,
CryptoModule.class,
DataModule.class,
DatabaseModule.class,
EventModule.class,
MessagingModule.class,
PrivateGroupModule.class,
GroupInvitationModule.class,
IdentityModule.class,
LifecycleModule.class,
PropertiesModule.class,
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
})
interface PrivateGroupManagerTestComponent {
void inject(PrivateGroupManagerTest testCase);
void inject(ContactModule.EagerSingletons init);
void inject(CryptoModule.EagerSingletons init);
void inject(PrivateGroupModule.EagerSingletons init);
void inject(LifecycleModule.EagerSingletons init);
void inject(PropertiesModule.EagerSingletons init);
void inject(SyncModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init);
LifecycleManager getLifecycleManager();
EventBus getEventBus();
IdentityManager getIdentityManager();
ContactManager getContactManager();
PrivateGroupManager getPrivateGroupManager();
SyncSessionFactory getSyncSessionFactory();
DatabaseComponent getDatabaseComponent();
}

View File

@@ -43,9 +43,6 @@ import static org.junit.Assert.assertTrue;
public class SimplexMessagingIntegrationTest extends BriarTestCase { public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final static String ALICE = "Alice";
private final static String BOB = "Bob";
private final File testDir = TestUtils.getTestDirectory(); private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice"); private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob"); private final File bobDir = new File(testDir, "bob");
@@ -72,7 +69,6 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
read(write()); read(write());
} }
private byte[] write() throws Exception { private byte[] write() throws Exception {
// Instantiate Alice's services // Instantiate Alice's services
LifecycleManager lifecycleManager = alice.getLifecycleManager(); LifecycleManager lifecycleManager = alice.getLifecycleManager();
@@ -87,23 +83,23 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory(); SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory();
// Start the lifecycle manager // Start the lifecycle manager
lifecycleManager.startServices(null); lifecycleManager.startServices();
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
// Add an identity for Alice // Add an identity for Alice
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice", LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.registerLocalAuthor(aliceAuthor); identityManager.addLocalAuthor(aliceAuthor);
// Add Bob as a contact // Add Bob as a contact
Author bobAuthor = new Author(bobId, BOB, Author bobAuthor = new Author(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH]); new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(bobAuthor, ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
aliceAuthor.getId(), master, timestamp, true, true, true); master, timestamp, true, true);
// Send Bob a message // Send Bob a message
GroupId groupId = messagingManager.getConversationId(contactId); GroupId groupId = messagingManager.getConversationId(contactId);
String body = "Hi Bob!"; byte[] body = "Hi Bob!".getBytes("UTF-8");
PrivateMessage message = privateMessageFactory.createPrivateMessage( PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, body); groupId, timestamp, null, "text/plain", body);
messagingManager.addLocalMessage(message); messagingManager.addLocalMessage(message);
// Get a stream context // Get a stream context
StreamContext ctx = keyManager.getStreamContext(contactId, StreamContext ctx = keyManager.getStreamContext(contactId,
@@ -140,17 +136,18 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
bob.getMessagingManager(); bob.getMessagingManager();
// Start the lifecyle manager // Start the lifecyle manager
lifecycleManager.startServices(null); lifecycleManager.startServices();
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
// Add an identity for Bob // Add an identity for Bob
LocalAuthor bobAuthor = new LocalAuthor(bobId, BOB, LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.registerLocalAuthor(bobAuthor); identityManager.addLocalAuthor(bobAuthor);
// Add Alice as a contact // Add Alice as a contact
Author aliceAuthor = new Author(aliceId, ALICE, Author aliceAuthor = new Author(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH]); new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(aliceAuthor, ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
bobAuthor.getId(), master, timestamp, false, true, true); master, timestamp, false, true);
// Set up an event listener // Set up an event listener
MessageListener listener = new MessageListener(); MessageListener listener = new MessageListener();
bob.getEventBus().addListener(listener); bob.getEventBus().addListener(listener);

View File

@@ -74,7 +74,7 @@ public class SyncIntegrationTest extends BriarTestCase {
headerKey = TestUtils.getSecretKey(); headerKey = TestUtils.getSecretKey();
streamNumber = 123; streamNumber = 123;
// Create a group // Create a group
ClientId clientId = new ClientId(TestUtils.getRandomString(5)); ClientId clientId = new ClientId(TestUtils.getRandomId());
byte[] descriptor = new byte[0]; byte[] descriptor = new byte[0];
Group group = groupFactory.createGroup(clientId, descriptor); Group group = groupFactory.createGroup(clientId, descriptor);
// Add two messages to the group // Add two messages to the group
@@ -122,7 +122,7 @@ public class SyncIntegrationTest extends BriarTestCase {
// Create the readers // Create the readers
StreamContext ctx = new StreamContext(contactId, transportId, tagKey, StreamContext ctx = new StreamContext(contactId, transportId, tagKey,
headerKey, streamNumber); headerKey, 0);
InputStream streamReader = streamReaderFactory.createStreamReader(in, InputStream streamReader = streamReaderFactory.createStreamReader(in,
ctx); ctx);
PacketReader packetReader = packetReaderFactory.createPacketReader( PacketReader packetReader = packetReaderFactory.createPacketReader(

View File

@@ -1,6 +1,6 @@
[main] [main]
host = https://www.transifex.com host = https://www.transifex.com
lang_map = pt_BR: pt-rBR, fr_FR: fr lang_map = pt_BR: pt-rBR
[briar.stringsxml-5] [briar.stringsxml-5]
file_filter = res/values-<lang>/strings.xml file_filter = res/values-<lang>/strings.xml

View File

@@ -7,7 +7,8 @@
android:versionName="0.12"> android:versionName="0.12">
<uses-sdk <uses-sdk
android:minSdkVersion="14" android:minSdkVersion="9"
android:targetSdkVersion="22" android:targetSdkVersion="22"
tools:overrideLibrary="android.support.v14.preference" tools:overrideLibrary="android.support.v14.preference"
/> />
@@ -50,9 +51,7 @@
android:finishOnTaskLaunch="true" android:finishOnTaskLaunch="true"
android:label="@string/crash_report_title" android:label="@string/crash_report_title"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:process=":briar_error_handler" android:process=":briar_error_handler">
android:theme="@style/BriarThemeNoActionBar.Default"
android:windowSoftInputMode="stateHidden">
</activity> </activity>
<activity <activity
@@ -93,7 +92,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/BriarThemeNoActionBar.Default" android:theme="@style/BriarThemeNoActionBar.Default"
android:parentActivityName=".android.NavDrawerActivity" android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="stateHidden|adjustResize"> android:windowSoftInputMode="stateHidden">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity" android:value=".android.NavDrawerActivity"
@@ -101,70 +100,7 @@
</activity> </activity>
<activity <activity
android:name=".android.privategroup.creation.CreateGroupActivity" android:name=".android.forum.ForumInvitationsActivity"
android:label="@string/groups_create_group_title"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.privategroup.conversation.GroupActivity"
android:label="@string/app_name"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.privategroup.invitation.GroupInvitationActivity"
android:label="@string/groups_invitations_title"
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"/>
</activity>
<activity
android:name=".android.privategroup.memberlist.GroupMemberListActivity"
android:label="@string/groups_member_list"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"
/>
</activity>
<activity
android:name=".android.privategroup.reveal.RevealContactsActivity"
android:label="@string/groups_reveal_contacts"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"
/>
</activity>
<activity
android:name=".android.privategroup.creation.GroupInviteActivity"
android:label="@string/groups_invite_members"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"/>
</activity>
<activity
android:name=".android.sharing.ForumInvitationActivity"
android:label="@string/forum_invitations_title" android:label="@string/forum_invitations_title"
android:parentActivityName=".android.NavDrawerActivity"> android:parentActivityName=".android.NavDrawerActivity">
<meta-data <meta-data
@@ -173,16 +109,6 @@
/> />
</activity> </activity>
<activity
android:name=".android.sharing.BlogInvitationActivity"
android:label="@string/blogs_sharing_invitations_title"
android:parentActivityName=".android.contact.ConversationActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.contact.ConversationActivity"
/>
</activity>
<activity <activity
android:name=".android.forum.CreateForumActivity" android:name=".android.forum.CreateForumActivity"
android:label="@string/create_forum_title" android:label="@string/create_forum_title"
@@ -197,8 +123,7 @@
<activity <activity
android:name=".android.forum.ForumActivity" android:name=".android.forum.ForumActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:parentActivityName=".android.NavDrawerActivity" android:parentActivityName=".android.NavDrawerActivity">
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity" android:value=".android.NavDrawerActivity"
@@ -206,30 +131,8 @@
</activity> </activity>
<activity <activity
android:name=".android.sharing.ShareForumActivity" android:name=".android.forum.ShareForumActivity"
android:label="@string/activity_share_toolbar_header" android:label="@string/forums_share_toolbar_header"
android:parentActivityName=".android.forum.ForumActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumActivity"
/>
</activity>
<activity
android:name=".android.sharing.ShareBlogActivity"
android:label="@string/activity_share_toolbar_header"
android:parentActivityName=".android.blogs.BlogActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.blogs.BlogActivity"
/>
</activity>
<activity
android:name=".android.sharing.ForumSharingStatusActivity"
android:label="@string/sharing_status"
android:parentActivityName=".android.forum.ForumActivity"> android:parentActivityName=".android.forum.ForumActivity">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
@@ -238,65 +141,19 @@
</activity> </activity>
<activity <activity
android:name=".android.sharing.BlogSharingStatusActivity" android:name=".android.forum.ForumSharingStatusActivity"
android:label="@string/sharing_status" android:label="@string/forum_sharing_status"
android:parentActivityName=".android.blogs.BlogActivity"> android:parentActivityName=".android.forum.ForumActivity">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"
android:value=".android.blogs.BlogActivity" android:value=".android.forum.ForumActivity"
/> />
</activity> </activity>
<activity <activity
android:name=".android.blogs.BlogActivity" android:name=".android.identity.CreateIdentityActivity"
android:parentActivityName=".android.NavDrawerActivity"> android:label="@string/new_identity_title"
<meta-data android:windowSoftInputMode="stateVisible">
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.blogs.WriteBlogPostActivity"
android:label="@string/blogs_write_blog_post"
android:parentActivityName=".android.blogs.BlogActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.blogs.BlogActivity"
/>
</activity>
<activity
android:name=".android.blogs.ReblogActivity"
android:label="@string/blogs_reblog_button"
android:parentActivityName=".android.blogs.BlogActivity"
android:windowSoftInputMode="stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.blogs.BlogActivity"
/>
</activity>
<activity
android:name=".android.blogs.RssFeedImportActivity"
android:label="@string/blogs_rss_feeds_import"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.blogs.RssFeedManageActivity"
android:label="@string/blogs_rss_feeds_manage"
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity> </activity>
<activity <activity
@@ -337,7 +194,7 @@
<activity <activity
android:name=".android.SettingsActivity" android:name=".android.SettingsActivity"
android:label="@string/settings_button" android:label="@string/settings_title"
android:parentActivityName=".android.NavDrawerActivity"> android:parentActivityName=".android.NavDrawerActivity">
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
width="24"
height="24"
viewBox="0 0 24 24"
sodipodi:docname="ic_emoji_emoticons.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1021"
id="namedview4"
showgrid="false"
inkscape:zoom="4.6354778"
inkscape:cx="47.926788"
inkscape:cy="24.127496"
inkscape:window-x="1440"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<path
style="fill:#000000;fill-opacity:1"
d="m 15.483903,3.8556996 c -0.661546,0.040406 -0.536253,1.2125273 -0.08054,1.6240791 1.361771,1.4519837 1.747379,3.5080793 1.895646,5.4253553 0.109142,2.216286 -0.0846,4.555699 -1.171466,6.533591 -0.361828,0.731167 -1.339597,1.273078 -1.15283,2.195835 0.287109,1.037426 1.187031,0.242862 1.620751,-0.183708 1.991711,-1.742024 2.867744,-4.428018 2.93133,-7.013492 0.02009,-1.918049 -0.231841,-3.9213035 -1.212735,-5.6044037 -0.664187,-1.0906817 -1.39072,-2.2339438 -2.497355,-2.9193489 -0.127976,-0.045915 -0.238296,-0.06368 -0.332802,-0.057908 z M 5.9118212,7.6583077 A 1.3631614,1.3631614 0 0 0 4.54866,9.0214691 1.3631614,1.3631614 0 0 0 5.9118212,10.38463 1.3631614,1.3631614 0 0 0 7.2749824,9.0214691 1.3631614,1.3631614 0 0 0 5.9118212,7.6583077 Z m 3.0731032,3.0012183 0,2.044742 4.7710646,0 0,-2.044742 -4.7710646,0 z m -3.1496485,3.471136 a 1.3631614,1.3631614 0 0 0 -1.3631612,1.363161 1.3631614,1.3631614 0 0 0 1.3631612,1.363161 1.3631614,1.3631614 0 0 0 1.3631612,-1.363161 1.3631614,1.3631614 0 0 0 -1.3631612,-1.363161 z"
id="path4142"
inkscape:connector-curvature="0" />
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 901 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

View File

@@ -11,34 +11,35 @@ dependencies {
compile project(':briar-api') compile project(':briar-api')
compile project(':briar-core') compile project(':briar-core')
compile fileTree(dir: 'libs', include: '*.jar') compile fileTree(dir: 'libs', include: '*.jar')
// This shouldn't be necessary; per section 23.4.4 of the Gradle docs:
// "file dependencies are included in transitive project dependencies within the same build".
compile files('../briar-core/libs/jsocks.jar')
compile "com.android.support:support-v4:$supportVersion" compile "com.android.support:support-v4:$supportVersion"
compile("com.android.support:appcompat-v7:$supportVersion") { compile("com.android.support:appcompat-v7:$supportVersion") {
exclude module: 'support-v4' exclude module: 'support-v4'
} }
compile("com.android.support:preference-v7:$supportVersion") {
exclude module: 'support-v4'
}
compile("com.android.support:preference-v14:$supportVersion") { compile("com.android.support:preference-v14:$supportVersion") {
exclude module: 'support-v4' exclude module: 'support-v4'
exclude module: 'preference-v7'
exclude module: 'recyclerview-v7'
} }
compile("com.android.support:design:$supportVersion") { compile("com.android.support:design:$supportVersion") {
exclude module: 'support-v4' exclude module: 'support-v4'
exclude module: 'recyclerview-v7' exclude module: 'recyclerview-v7'
} }
compile "com.android.support:cardview-v7:$supportVersion"
compile 'com.android.support:support-annotations:23.4.0'
compile('ch.acra:acra:4.8.5') { compile('ch.acra:acra:4.8.5') {
exclude module: 'support-v4' exclude module: 'support-v4'
exclude module: 'support-annotations' exclude module: 'support-annotations'
} }
compile 'info.guardianproject.panic:panic:0.5' compile 'info.guardianproject.panic:panic:0.5'
compile 'info.guardianproject.trustedintents:trustedintents:0.2' compile 'info.guardianproject.trustedintents:trustedintents:0.2'
compile 'de.hdodenhof:circleimageview:2.1.0' compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.google.zxing:core:3.2.1' compile 'com.google.zxing:core:3.2.1'
apt 'com.google.dagger:dagger-compiler:2.0.2' apt 'com.google.dagger:dagger-compiler:2.0.2'
provided 'javax.annotation:jsr250-api:1.0' provided 'javax.annotation:jsr250-api:1.0'
compile 'com.jpardogo.materialtabstrip:library:1.1.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'uk.co.samuelwall:material-tap-target-prompt:1.3.0'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
testCompile 'net.jodah:concurrentunit:0.4.2' testCompile 'net.jodah:concurrentunit:0.4.2'
@@ -46,6 +47,11 @@ dependencies {
testCompile project(path: ':briar-tests') testCompile project(path: ':briar-tests')
testCompile 'org.robolectric:robolectric:3.0' testCompile 'org.robolectric:robolectric:3.0'
testCompile 'org.mockito:mockito-core:1.10.19' testCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'org.robolectric:robolectric:3.0'
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestApt 'com.google.dagger:dagger-compiler:2.0.2'
androidTestCompile 'junit:junit:4.12'
} }
dependencyVerification { dependencyVerification {
@@ -53,20 +59,17 @@ dependencyVerification {
'ch.acra:acra:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb', 'ch.acra:acra:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb',
'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2', 'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2',
'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e', 'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
'de.hdodenhof:circleimageview:bcbc588e19e6dcf8c120b1957776bfe229efba5d2fbe5da7156372eeacf65503', 'de.hdodenhof:circleimageview:c76d936395b50705a3f98c9220c22d2599aeb9e609f559f6048975cfc1f686b8',
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259', 'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448', 'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d', 'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
'com.android.support:preference-v7:775101bd07bd052e455761c5c5d9523d7ad59f2f320e3e8cbde241fd6b1d6025',
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7', 'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686', 'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
'com.android.support:support-annotations:e91a88dd0c5e99069b7f09d4a46b5e06f1e9c4c72fc0a8e987e25d86af480f01', 'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1', 'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1', 'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe', 'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe',
'com.android.support:cardview-v7:4595f1c4a28cfa083b6c0920ad4d49e1c2ca4b8302a955e548f68eb63b74931b',
'com.jpardogo.materialtabstrip:library:24d19232b319f8c73e25793432357919a7ed972186f57a3b2c9093ea74ad8311',
'com.github.bumptech.glide:glide:76ef123957b5fbaebb05fcbe6606dd58c3bc3fcdadb257f99811d0ac9ea9b88b',
'uk.co.samuelwall:material-tap-target-prompt:f67e1caead12a914525b32cbf6da52a96b93ff89573f93cb41102ef3130fb64a',
] ]
} }
@@ -74,10 +77,6 @@ android {
compileSdkVersion 23 compileSdkVersion 23
buildToolsVersion "23.0.3" buildToolsVersion "23.0.3"
defaultConfig {
resValue "string", "app_package", "org.briarproject"
}
sourceSets { sourceSets {
main { main {
manifest.srcFile 'AndroidManifest.xml' manifest.srcFile 'AndroidManifest.xml'
@@ -101,16 +100,24 @@ android {
unitTests.returnDefaultValues = true unitTests.returnDefaultValues = true
} }
} }
// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
} }
buildTypes { buildTypes {
debug { debug {
shrinkResources false
minifyEnabled true minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
} }
release { release {
shrinkResources true
minifyEnabled true minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
} }
@@ -122,8 +129,10 @@ android {
} }
lintOptions { lintOptions {
warning 'MissingTranslation' abortOnError false
warning 'ImpliedQuantity' }
dexOptions {
incremental true
} }
} }

View File

@@ -4,16 +4,17 @@
-dontobfuscate -dontobfuscate
-verbose -verbose
-useuniqueclassmembernames -useuniqueclassmembernames
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
# For comfortability in case we do obfuscate # For comfortability in case we do obfuscate
# -renamesourcefileattribute SourceFile # -renamesourcefileattribute SourceFile
-keepattributes SourceFile, LineNumberTable, *Annotation*, Signature, InnerClasses, EnclosingMethod -keepattributes SourceFile,LineNumberTable,*Annotation*,Signature, InnerClasses, EnclosingMethod
-keep public class * extends android.app.Activity -keep public class * extends android.app.Activity
-keep public class * extends android.app.Application -keep public class * extends android.app.Application
-keep public class * extends android.app.Service -keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider -keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembers class * { native <methods>; } -keepclasseswithmembers class * { native <methods>; }
-keepclasseswithmembers class * { -keepclasseswithmembers class * {
public <init> (android.content.Context, android.util.AttributeSet); public <init> (android.content.Context, android.util.AttributeSet);
@@ -31,41 +32,31 @@
-keepclassmembers class * extends android.app.Activity { -keepclassmembers class * extends android.app.Activity {
public void *(android.view.View); public void *(android.view.View);
} }
-keepclassmembers class * {
@com.google.inject.Inject <init>(...);
@com.google.inject.Inject <fields>;
}
# Just in case Roboguice events are used
-keepclassmembers class * {
void *(**On*Event);
}
-keep class org.h2.** { *; } -keep class org.h2.** { *; }
-keep class org.briarproject.** { *; } -keep class org.briarproject.** { *; }
-keep class com.google.inject.** { *; }
-keep class javax.inject.** { *; } -keep class javax.inject.** { *; }
-keep class javax.annotation.** { *; }
-keep class roboguice.** { *; }
-keep class dagger.** { *; } -keep class dagger.** { *; }
-keep class com.google.zxing.Result -keep class com.google.** { *; }
-dontwarn org.h2.** -dontwarn org.h2.**
-dontnote org.h2.** -dontnote org.h2.**
-dontwarn net.sf.cglib.** -dontwarn net.sf.cglib.**
-dontwarn org.briarproject.plugins.tcp.** -dontwarn org.briarproject.plugins.tcp.**
-dontnote org.briarproject.crypto.** -dontwarn roboguice.**
-dontnote org.spongycastle.crypto.parsers.ECIESPublicKeyParser
-dontwarn net.sourceforge.jsocks.** -dontwarn net.sourceforge.jsocks.**
-dontnote android.support.** -dontnote android.support.**
-dontnote dagger.** -dontnote dagger.**
-dontwarn dagger.** -dontwarn dagger.**
-dontnote com.google.common.** -dontwarn com.google.common.**
-dontwarn com.google.common.**
# RSS libraries
-keep class com.rometools.rome.feed.synd.impl.** { *;}
-keep class com.rometools.rome.io.impl.** { *;}
-keep class org.jsoup.safety.Whitelist
-dontnote com.rometools.rome.**
-dontwarn javax.xml.stream.**
-dontwarn org.jaxen.**
-dontwarn java.nio.**
-dontwarn org.codehaus.mojo.animal_sniffer.**
-dontwarn org.slf4j.impl.**
# Emoji
-keep class org.thoughtcrime.securesms.**
-keep class com.astuetz.PagerSlidingTabStrip$OnTabReselectedListener
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
A FAB does not work, because even with fabSize="mini" it will be too big due to shadow drawing
on lower API levels
-->
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/briar_primary_dark">
<item>
<shape android:shape="oval">
<solid android:color="@color/briar_primary"/>
</shape>
</item>
</ripple>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.56"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#000000"
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>

View File

@@ -1,5 +0,0 @@
<vector android:alpha="0.54" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15.73,3L8.27,3L3,8.27v7.46L8.27,21h7.46L21,15.73L21,8.27L15.73,3zM12,17.3c-0.72,0 -1.3,-0.58 -1.3,-1.3 0,-0.72 0.58,-1.3 1.3,-1.3 0.72,0 1.3,0.58 1.3,1.3 0,0.72 -0.58,1.3 -1.3,1.3zM13,13h-2L11,7h2v6z"/>
</vector>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="@android:color/transparent"/>
<stroke
android:width="2dp"
android:color="@color/briar_text_primary"/>
</shape>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="@dimen/unread_bubble_size"/>
<solid
android:color="@color/briar_text_primary_inverse"/>
<stroke
android:color="@color/briar_text_primary"
android:width="1dp"/>
</shape>

View File

@@ -1,9 +1,4 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector android:height="24dp" android:viewportHeight="48.0"
android:width="24dp" android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
android:height="24dp" <path android:fillColor="#FF000000" android:pathData="M9.1,19.3l14.9,11.8l14.9,-11.8l-1.9,-2.4l-13,10.4l-13,-10.4z"/>
android:viewportHeight="48.0"
android:viewportWidth="48.0">
<path
android:fillColor="#06b9ff"
android:pathData="M9.1,19.3l14.9,11.8l14.9,-11.8l-1.9,-2.4l-13,10.4l-13,-10.4z"/>
</vector> </vector>

View File

@@ -1,9 +1,4 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector android:height="24dp" android:viewportHeight="48.0"
android:width="24dp" android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
android:height="24dp" <path android:fillColor="#FF000000" android:pathData="M38.9,28.7l-14.9,-11.8l-14.9,11.8l1.9,2.4l13,-10.4l13,10.4z"/>
android:viewportHeight="48.0"
android:viewportWidth="48.0">
<path
android:fillColor="#06b9ff"
android:pathData="M38.9,28.7l-14.9,-11.8l-14.9,11.8l1.9,2.4l13,-10.4l13,10.4z"/>
</vector> </vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM19,15.59L17.59,17 14,13.41 10.41,17 9,15.59 12.59,12 9,8.41 10.41,7 14,10.59 17.59,7 19,8.41 15.41,12 19,15.59z"/>
</vector>

Some files were not shown because too many files have changed in this diff Show More