From 6a07d8f2c9c6df030f1cde2c1cc4cd4efd28a99e Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Wed, 26 Apr 2017 18:51:08 -0300 Subject: [PATCH] Allow to remove pre-shared blogs of our contacts --- .../android/blog/BlogControllerImpl.java | 2 +- .../briar/api/blog/BlogManager.java | 2 +- .../briar/blog/BlogManagerImpl.java | 30 +++------- .../briar/sharing/BlogSharingManagerImpl.java | 25 ++++----- .../briar/sharing/SharingManagerImpl.java | 13 ++++- .../briar/blog/BlogManagerImplTest.java | 55 ++++--------------- .../blog/BlogManagerIntegrationTest.java | 17 +++--- .../sharing/BlogSharingIntegrationTest.java | 55 ++++++++----------- 8 files changed, 76 insertions(+), 123 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java index ae666f691a..414420dbd2 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BlogControllerImpl.java @@ -169,7 +169,7 @@ class BlogControllerImpl extends BaseControllerImpl LocalAuthor a = identityManager.getLocalAuthor(); Blog b = blogManager.getBlog(groupId); boolean ours = a.getId().equals(b.getAuthor().getId()); - boolean removable = blogManager.canBeRemoved(groupId); + boolean removable = blogManager.canBeRemoved(b); BlogItem blog = new BlogItem(b, ours, removable); long duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java index 041d474a4e..cc7dc13fc3 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java @@ -34,7 +34,7 @@ public interface BlogManager { /** * Returns true if a blog can be removed. */ - boolean canBeRemoved(GroupId g) throws DbException; + boolean canBeRemoved(Blog b) throws DbException; /** * Removes and deletes a blog. diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java index b27a3bf116..02e4f1eae7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java @@ -3,7 +3,6 @@ package org.briarproject.briar.blog; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.contact.Contact; -import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfList; @@ -76,7 +75,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, AddContactHook, RemoveContactHook, Client { private final IdentityManager identityManager; - private final ContactManager contactManager; private final BlogFactory blogFactory; private final BlogPostFactory blogPostFactory; private final List<RemoveBlogHook> removeHooks; @@ -84,12 +82,10 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, @Inject BlogManagerImpl(DatabaseComponent db, IdentityManager identityManager, ClientHelper clientHelper, MetadataParser metadataParser, - ContactManager contactManager, BlogFactory blogFactory, - BlogPostFactory blogPostFactory) { + BlogFactory blogFactory, BlogPostFactory blogPostFactory) { super(db, clientHelper, metadataParser); this.identityManager = identityManager; - this.contactManager = contactManager; this.blogFactory = blogFactory; this.blogPostFactory = blogPostFactory; removeHooks = new CopyOnWriteArrayList<RemoveBlogHook>(); @@ -120,7 +116,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, @Override public void removingContact(Transaction txn, Contact c) throws DbException { Blog b = blogFactory.createBlog(c.getAuthor()); - removeBlog(txn, b, true); + removeBlog(txn, b); } @Override @@ -191,10 +187,10 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, } @Override - public boolean canBeRemoved(GroupId g) throws DbException { + public boolean canBeRemoved(Blog b) throws DbException { Transaction txn = db.startTransaction(true); try { - boolean canBeRemoved = canBeRemoved(txn, g); + boolean canBeRemoved = canBeRemoved(txn, b); db.commitTransaction(txn); return canBeRemoved; } finally { @@ -202,23 +198,18 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, } } - private boolean canBeRemoved(Transaction txn, GroupId g) + private boolean canBeRemoved(Transaction txn, Blog b) throws DbException { - boolean canBeRemoved; - Blog b = getBlog(txn, g); AuthorId authorId = b.getAuthor().getId(); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); - if (localAuthor.getId().equals(authorId)) return false; - canBeRemoved = !contactManager - .contactExists(txn, authorId, localAuthor.getId()); - return canBeRemoved; + return !localAuthor.getId().equals(authorId); } @Override public void removeBlog(Blog b) throws DbException { Transaction txn = db.startTransaction(false); try { - removeBlog(txn, b, false); + removeBlog(txn, b); db.commitTransaction(txn); } finally { db.endTransaction(txn); @@ -227,12 +218,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, @Override public void removeBlog(Transaction txn, Blog b) throws DbException { - removeBlog(txn, b, false); - } - - private void removeBlog(Transaction txn, Blog b, boolean forced) - throws DbException { - if (!forced && !canBeRemoved(txn, b.getId())) + if (!canBeRemoved(txn, b)) throw new IllegalArgumentException(); for (RemoveBlogHook hook : removeHooks) hook.removingBlog(txn, b); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java index 26da642ba2..6664c67dcd 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java @@ -1,5 +1,6 @@ package org.briarproject.briar.sharing; +import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.contact.Contact; @@ -11,7 +12,6 @@ import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.ClientId; -import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.BlogInvitationResponse; import org.briarproject.briar.api.blog.BlogManager; @@ -52,18 +52,17 @@ class BlogSharingManagerImpl extends SharingManagerImpl<Blog> } @Override - protected boolean canBeShared(Transaction txn, GroupId shareableId, - Contact c) throws DbException { - // check if shareableId belongs to our personal blog - LocalAuthor author = identityManager.getLocalAuthor(txn); - Blog b = blogManager.getPersonalBlog(author); - if (b.getId().equals(shareableId)) return false; - - // check if shareableId belongs to c's personal blog - b = blogManager.getPersonalBlog(c.getAuthor()); - if (b.getId().equals(shareableId)) return false; - - return super.canBeShared(txn, shareableId, c); + public void addingContact(Transaction txn, Contact c) throws DbException { + super.addingContact(txn, c); + LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); + Blog ourBlog = blogManager.getPersonalBlog(localAuthor); + Blog theirBlog = blogManager.getPersonalBlog(c.getAuthor()); + try { + initializeSharedSession(txn, c, ourBlog); + initializeSharedSession(txn, c, theirBlog); + } catch (FormatException e) { + throw new DbException(e); + } } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java index fc61bf49df..0b99d75bf6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java @@ -48,6 +48,7 @@ import static org.briarproject.briar.sharing.MessageType.DECLINE; import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.LEAVE; import static org.briarproject.briar.sharing.SharingConstants.GROUP_KEY_CONTACT_ID; +import static org.briarproject.briar.sharing.State.SHARING; @NotNullByDefault abstract class SharingManagerImpl<S extends Shareable> @@ -138,6 +139,16 @@ abstract class SharingManagerImpl<S extends Shareable> return false; } + protected void initializeSharedSession(Transaction txn, Contact c, + S shareable) throws DbException, FormatException { + GroupId contactGroupId = getContactGroup(c).getId(); + Session session = + new Session(SHARING, contactGroupId, shareable.getId(), null, + null, 0, 0); + MessageId storageId = createStorageId(txn, contactGroupId); + storeSession(txn, storageId, session); + } + private SessionId getSessionId(GroupId shareableId) { return new SessionId(shareableId.getBytes()); } @@ -414,7 +425,7 @@ abstract class SharingManagerImpl<S extends Shareable> } } - protected boolean canBeShared(Transaction txn, GroupId g, Contact c) + private boolean canBeShared(Transaction txn, GroupId g, Contact c) throws DbException { GroupId contactGroupId = getContactGroup(c).getId(); SessionId sessionId = getSessionId(g); diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java index 1ff6404811..5b9cee48cc 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java @@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfList; @@ -62,8 +61,6 @@ public class BlogManagerImplTest extends BriarTestCase { private final IdentityManager identityManager = context.mock(IdentityManager.class); private final ClientHelper clientHelper = context.mock(ClientHelper.class); - private final ContactManager contactManager = - context.mock(ContactManager.class); private final BlogFactory blogFactory = context.mock(BlogFactory.class); private final Blog blog1, blog2; @@ -74,7 +71,7 @@ public class BlogManagerImplTest extends BriarTestCase { MetadataParser metadataParser = context.mock(MetadataParser.class); BlogPostFactory blogPostFactory = context.mock(BlogPostFactory.class); blogManager = new BlogManagerImpl(db, identityManager, clientHelper, - metadataParser, contactManager, blogFactory, blogPostFactory); + metadataParser, blogFactory, blogPostFactory); blog1 = createBlog(); blog2 = createBlog(); @@ -126,6 +123,8 @@ public class BlogManagerImplTest extends BriarTestCase { context.checking(new Expectations() {{ oneOf(blogFactory).createBlog(blog2.getAuthor()); will(returnValue(blog2)); + oneOf(identityManager).getLocalAuthor(txn); + will(returnValue(blog1.getAuthor())); oneOf(db).removeGroup(txn, blog2.getGroup()); }}); @@ -173,13 +172,11 @@ public class BlogManagerImplTest extends BriarTestCase { public void testRemoveBlog() throws Exception { final Transaction txn = new Transaction(null, false); - checkGetBlogExpectations(txn, false, blog1); context.checking(new Expectations() {{ + oneOf(db).startTransaction(false); + will(returnValue(txn)); oneOf(identityManager).getLocalAuthor(txn); will(returnValue(blog2.getAuthor())); - oneOf(contactManager).contactExists(txn, blog1.getAuthor().getId(), - blog2.getAuthor().getId()); - will(returnValue(false)); oneOf(db).removeGroup(txn, blog1.getGroup()); oneOf(db).commitTransaction(txn); oneOf(db).endTransaction(txn); @@ -240,57 +237,29 @@ public class BlogManagerImplTest extends BriarTestCase { public void testBlogCanBeRemoved() throws Exception { // check that own personal blogs can not be removed final Transaction txn = new Transaction(null, true); - checkGetBlogExpectations(txn, true, blog1); context.checking(new Expectations() {{ + oneOf(db).startTransaction(true); + will(returnValue(txn)); oneOf(identityManager).getLocalAuthor(txn); will(returnValue(blog1.getAuthor())); oneOf(db).commitTransaction(txn); oneOf(db).endTransaction(txn); }}); - assertFalse(blogManager.canBeRemoved(blog1.getId())); + assertFalse(blogManager.canBeRemoved(blog1)); context.assertIsSatisfied(); - // check that blogs of contacts can not be removed + // check that blogs of contacts can be removed final Transaction txn2 = new Transaction(null, true); - checkGetBlogExpectations(txn2, true, blog1); context.checking(new Expectations() {{ + oneOf(db).startTransaction(true); + will(returnValue(txn2)); oneOf(identityManager).getLocalAuthor(txn2); will(returnValue(blog2.getAuthor())); - oneOf(contactManager).contactExists(txn2, blog1.getAuthor().getId(), - blog2.getAuthor().getId()); - will(returnValue(true)); oneOf(db).commitTransaction(txn2); oneOf(db).endTransaction(txn2); }}); - assertFalse(blogManager.canBeRemoved(blog1.getId())); + assertTrue(blogManager.canBeRemoved(blog1)); context.assertIsSatisfied(); - - // check that blogs can be removed if they don't belong to a contact - final Transaction txn3 = new Transaction(null, true); - checkGetBlogExpectations(txn3, true, blog1); - context.checking(new Expectations() {{ - oneOf(identityManager).getLocalAuthor(txn3); - will(returnValue(blog2.getAuthor())); - oneOf(contactManager).contactExists(txn3, blog1.getAuthor().getId(), - blog2.getAuthor().getId()); - will(returnValue(false)); - oneOf(db).commitTransaction(txn3); - oneOf(db).endTransaction(txn3); - }}); - assertTrue(blogManager.canBeRemoved(blog1.getId())); - context.assertIsSatisfied(); - } - - private void checkGetBlogExpectations(final Transaction txn, - final boolean readOnly, final Blog blog) throws Exception { - context.checking(new Expectations() {{ - oneOf(db).startTransaction(readOnly); - will(returnValue(txn)); - oneOf(db).getGroup(txn, blog.getId()); - will(returnValue(blog.getGroup())); - oneOf(blogFactory).parseBlog(blog.getGroup()); - will(returnValue(blog)); - }}); } private Blog createBlog() { diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java index 289f3c0991..6c88846cf3 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java @@ -21,7 +21,6 @@ import org.junit.rules.ExpectedException; import java.util.Collection; import java.util.Iterator; -import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; @@ -185,19 +184,19 @@ public class BlogManagerIntegrationTest } @Test - public void testCanNotRemoveContactsPersonalBlog() throws Exception { - assertFalse(blogManager0.canBeRemoved(blog1.getId())); - assertFalse(blogManager1.canBeRemoved(blog0.getId())); + public void testCanRemoveContactsPersonalBlog() throws Exception { + assertTrue(blogManager0.canBeRemoved(blog1)); + assertTrue(blogManager1.canBeRemoved(blog0)); - // the following two calls should throw a DbException now - thrown.expect(IllegalArgumentException.class); + assertEquals(4, blogManager0.getBlogs().size()); + assertEquals(2, blogManager1.getBlogs().size()); blogManager0.removeBlog(blog1); blogManager1.removeBlog(blog0); - // blogs have not been removed - assertEquals(2, blogManager0.getBlogs().size()); - assertEquals(2, blogManager1.getBlogs().size()); + // blogs have been removed + assertEquals(3, blogManager0.getBlogs().size()); + assertEquals(1, blogManager1.getBlogs().size()); } @Test diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java index 31608a0261..e13718352e 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingIntegrationTest.java @@ -41,7 +41,7 @@ import static org.junit.Assert.fail; public class BlogSharingIntegrationTest extends BriarIntegrationTest<BriarIntegrationTestComponent> { - private BlogManager blogManager1; + private BlogManager blogManager0, blogManager1; private Blog blog0, blog1, blog2; private SharerListener listener0; private InviteeListener listener1; @@ -60,7 +60,7 @@ public class BlogSharingIntegrationTest public void setUp() throws Exception { super.setUp(); - BlogManager blogManager0 = c0.getBlogManager(); + blogManager0 = c0.getBlogManager(); blogManager1 = c1.getBlogManager(); blogSharingManager0 = c0.getBlogSharingManager(); blogSharingManager1 = c1.getBlogSharingManager(); @@ -370,7 +370,7 @@ public class BlogSharingIntegrationTest assertEquals(contact0From1, sharedBy.iterator().next()); // shared blog can be removed - assertTrue(blogManager1.canBeRemoved(blog2.getId())); + assertTrue(blogManager1.canBeRemoved(blog2)); // invitee removes blog again blogManager1.removeBlog(blog2); @@ -386,44 +386,33 @@ public class BlogSharingIntegrationTest } @Test - public void testSharedBlogBecomesPermanent() throws Exception { + public void testRemovePreSharedBlog() throws Exception { // let invitee accept all requests listenToEvents(true); - // invitee only sees two blogs - assertEquals(2, blogManager1.getBlogs().size()); + // 0 and 1 are sharing blog 1 with each other + assertTrue(blogSharingManager0.getSharedWith(blog1.getId()) + .contains(contact1From0)); + assertTrue(blogSharingManager1.getSharedWith(blog1.getId()) + .contains(contact0From1)); - // sharer sends invitation for 2's blog to 1 - blogSharingManager0 - .sendInvitation(blog2.getId(), contactId1From0, "Hi!", - clock.currentTimeMillis()); + // 0 removes blog 1 + assertTrue(blogManager0.getBlogs().contains(blog1)); + blogManager0.removeBlog(blog1); + assertFalse(blogManager0.getBlogs().contains(blog1)); - // sync first request message + // sync leave message to 0 sync0To1(1, true); - eventWaiter.await(TIMEOUT, 1); - assertTrue(listener1.requestReceived); - // make sure blog2 is shared by 0 - Collection<Contact> contacts = - blogSharingManager1.getSharedWith(blog2.getId()); - assertEquals(1, contacts.size()); - assertTrue(contacts.contains(contact0From1)); - - // sync response back - sync1To0(1, true); - 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 - addContacts1And2(); - assertEquals(3, blogManager1.getBlogs().size()); + // 0 and 1 are no longer sharing blog 1 with each other + assertFalse(blogSharingManager0.getSharedWith(blog1.getId()) + .contains(contact1From0)); + assertFalse(blogSharingManager1.getSharedWith(blog1.getId()) + .contains(contact0From1)); - // now blog can not be removed anymore - assertFalse(blogManager1.canBeRemoved(blog2.getId())); + // 1 can again share blog 1 with 0 + assertTrue( + blogSharingManager1.canBeShared(blog1.getId(), contact0From1)); } @Test -- GitLab