From d40a058ef5edf08d200351951c5963b4f1f7e13c Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 10 Apr 2017 18:57:14 -0300 Subject: [PATCH] Change blog descriptor format to include RSS feed flag This now also handles the case where an RSS blog is deleted via the blog deletion option and not the feed management. --- .../briarproject/bramble/db/JdbcDatabase.java | 4 +-- .../org/briarproject/briar/api/blog/Blog.java | 8 ++++- .../briar/api/blog/BlogFactory.java | 5 +++ .../org/briarproject/briar/api/feed/Feed.java | 14 +------- .../briar/blog/BlogFactoryImpl.java | 16 ++++++++-- .../briar/feed/FeedFactoryImpl.java | 4 +-- .../briar/feed/FeedManagerImpl.java | 32 ++++++++++++------- .../briarproject/briar/feed/FeedModule.java | 5 ++- .../briar/sharing/BlogSharingValidator.java | 10 ++++-- .../briar/blog/BlogManagerImplTest.java | 2 +- .../briar/blog/BlogPostValidatorTest.java | 2 +- .../sharing/BlogSharingValidatorTest.java | 23 ++++++------- 12 files changed, 77 insertions(+), 48 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java index 54238266b..7ae01fe47 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java @@ -68,8 +68,8 @@ import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry; @NotNullByDefault abstract class JdbcDatabase implements Database { - private static final int SCHEMA_VERSION = 29; - private static final int MIN_SCHEMA_VERSION = 29; + private static final int SCHEMA_VERSION = 30; + private static final int MIN_SCHEMA_VERSION = 30; private static final String CREATE_SETTINGS = "CREATE TABLE settings" diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/Blog.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/Blog.java index b7e1d240f..a0e4fff02 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/Blog.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/Blog.java @@ -13,16 +13,22 @@ import javax.annotation.concurrent.Immutable; public class Blog extends BaseGroup implements Shareable { private final Author author; + private final boolean rssFeed; - public Blog(Group group, Author author) { + public Blog(Group group, Author author, boolean rssFeed) { super(group); this.author = author; + this.rssFeed = rssFeed; } public Author getAuthor() { return author; } + public boolean isRssFeed() { + return rssFeed; + } + @Override public boolean equals(Object o) { return o instanceof Blog && super.equals(o); diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogFactory.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogFactory.java index 4b0a89cf3..a9d057501 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogFactory.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogFactory.java @@ -13,6 +13,11 @@ public interface BlogFactory { */ Blog createBlog(Author author); + /** + * Creates a RSS feed blog for a given author. + */ + Blog createFeedBlog(Author author); + /** * Parses a blog with the given Group */ diff --git a/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java b/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java index 51f53f10c..4932ecab7 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/feed/Feed.java @@ -93,21 +93,9 @@ public class Feed { if (this == o) return true; if (o instanceof Feed) { Feed f = (Feed) o; - return url.equals(f.url) && blog.equals(f.blog) && - equalsWithNull(title, f.title) && - equalsWithNull(description, f.description) && - equalsWithNull(author, f.author) && - added == f.added && - updated == f.updated && - lastEntryTime == f.lastEntryTime; + return blog.equals(f.blog); } return false; } - private boolean equalsWithNull(@Nullable Object a, @Nullable Object b) { - if (a == b) return true; - if (a == null || b == null) return false; - return a.equals(b); - } - } diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogFactoryImpl.java index 26c1eb108..deaae2cfe 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogFactoryImpl.java @@ -33,15 +33,25 @@ class BlogFactoryImpl implements BlogFactory { @Override public Blog createBlog(Author a) { + return createBlog(a, false); + } + + @Override + public Blog createFeedBlog(Author a) { + return createBlog(a, true); + } + + private Blog createBlog(Author a, boolean rssFeed) { try { BdfList blog = BdfList.of( a.getName(), - a.getPublicKey() + a.getPublicKey(), + rssFeed ); byte[] descriptor = clientHelper.toByteArray(blog); Group g = groupFactory .createGroup(BlogManagerImpl.CLIENT_ID, descriptor); - return new Blog(g, a); + return new Blog(g, a, rssFeed); } catch (FormatException e) { throw new RuntimeException(e); } @@ -54,7 +64,7 @@ class BlogFactoryImpl implements BlogFactory { BdfList blog = clientHelper.toList(descriptor); Author a = authorFactory.createAuthor(blog.getString(0), blog.getRaw(1)); - return new Blog(g, a); + return new Blog(g, a, blog.getBoolean(2)); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java index 531f169ef..14aca1559 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java @@ -52,7 +52,7 @@ class FeedFactoryImpl implements FeedFactory { .createLocalAuthor(syndFeed.getTitle(), keyPair.getPublic().getEncoded(), keyPair.getPrivate().getEncoded()); - Blog blog = blogFactory.createBlog(localAuthor); + Blog blog = blogFactory.createFeedBlog(localAuthor); long added = clock.currentTimeMillis(); return new Feed(url, blog, localAuthor, added); @@ -75,7 +75,7 @@ class FeedFactoryImpl implements FeedFactory { byte[] privateKey = d.getRaw(KEY_PRIVATE_KEY); LocalAuthor localAuthor = authorFactory .createLocalAuthor(blogTitle, publicKey, privateKey); - Blog blog = blogFactory.createBlog(localAuthor); + Blog blog = blogFactory.createFeedBlog(localAuthor); String title = d.getOptionalString(KEY_FEED_TITLE); String desc = d.getOptionalString(KEY_FEED_DESC); diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java index 8db542e8b..969de52a3 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java @@ -30,6 +30,7 @@ import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.util.StringUtils; +import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.blog.BlogPost; import org.briarproject.briar.api.blog.BlogPostFactory; @@ -74,7 +75,8 @@ import static org.briarproject.briar.util.HtmlUtils.clean; @ThreadSafe @NotNullByDefault -class FeedManagerImpl implements FeedManager, Client, EventListener { +class FeedManagerImpl implements FeedManager, Client, EventListener, + BlogManager.RemoveBlogHook { private static final Logger LOG = Logger.getLogger(FeedManagerImpl.class.getName()); @@ -158,7 +160,6 @@ class FeedManagerImpl implements FeedManager, Client, EventListener { @Override public void addFeed(String url) throws DbException, IOException { - // TODO check for existing feed? // fetch syndication feed to get its metadata SyndFeed f; try { @@ -207,15 +208,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener { LOG.info("Removing RSS feed..."); Transaction txn = db.startTransaction(false); try { - List feeds = getFeeds(txn); - for (Feed f : feeds) { - if (f.getBlogId().equals(feed.getBlogId())) { - feed = f; - feeds.remove(f); - break; - } - } - storeFeeds(txn, feeds); + // this will call removingBlog() where the feed itself gets removed blogManager.removeBlog(txn, feed.getBlog()); db.commitTransaction(txn); } finally { @@ -223,6 +216,23 @@ class FeedManagerImpl implements FeedManager, Client, EventListener { } } + @Override + public void removingBlog(Transaction txn, Blog b) throws DbException { + if (!b.isRssFeed()) return; + + // delete blog's RSS feed if we have it + boolean found = false; + List feeds = getFeeds(txn); + for (Feed f : feeds) { + if (f.getBlogId().equals(b.getId())) { + found = true; + feeds.remove(f); + break; + } + } + if (found) storeFeeds(txn, feeds); + } + @Override public List getFeeds() throws DbException { List feeds; diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java index ab8dfbc29..c4b567c18 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java @@ -2,6 +2,7 @@ package org.briarproject.briar.feed; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.briar.api.blog.BlogManager; import org.briarproject.briar.api.feed.FeedManager; import javax.inject.Inject; @@ -21,10 +22,12 @@ public class FeedModule { @Provides @Singleton FeedManager provideFeedManager(FeedManagerImpl feedManager, - LifecycleManager lifecycleManager, EventBus eventBus) { + LifecycleManager lifecycleManager, EventBus eventBus, + BlogManager blogManager) { lifecycleManager.registerClient(feedManager); eventBus.addListener(feedManager); + blogManager.registerRemoveBlogHook(feedManager); return feedManager; } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingValidator.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingValidator.java index 6f0df8e47..f9b378ef7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingValidator.java @@ -39,14 +39,20 @@ class BlogSharingValidator extends SharingValidator { @Override protected GroupId validateDescriptor(BdfList descriptor) throws FormatException { - checkSize(descriptor, 2); + checkSize(descriptor, 3); String name = descriptor.getString(0); checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH); byte[] publicKey = descriptor.getRaw(1); checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH); + boolean rssFeed = descriptor.getBoolean(2); Author author = authorFactory.createAuthor(name, publicKey); - Blog blog = blogFactory.createBlog(author); + Blog blog; + if (rssFeed) { + blog = blogFactory.createFeedBlog(author); + } else { + blog = blogFactory.createBlog(author); + } return blog.getId(); } 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 e2b5e8ef5..4ff1bb75c 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 @@ -297,7 +297,7 @@ public class BlogManagerImplTest extends BriarTestCase { final LocalAuthor localAuthor = new LocalAuthor(authorId, "Author", publicKey, privateKey, created); - return new Blog(group, localAuthor); + return new Blog(group, localAuthor, false); } private BdfDictionary authorToBdfDictionary(Author a) { diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java index 1ac77a550..d3731d19d 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogPostValidatorTest.java @@ -79,7 +79,7 @@ public class BlogPostValidatorTest extends BriarTestCase { new BdfEntry(KEY_AUTHOR_NAME, author.getName()), new BdfEntry(KEY_PUBLIC_KEY, author.getPublicKey()) ); - blog = new Blog(group, author); + blog = new Blog(group, author, false); MessageId messageId = new MessageId(TestUtils.getRandomId()); long timestamp = System.currentTimeMillis(); diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java index c67360d64..7c4c96ab2 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingValidatorTest.java @@ -23,8 +23,8 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { private final byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH); private final Author author = new Author(authorId, authorName, publicKey); - private final Blog blog = new Blog(group, author); - private final BdfList descriptor = BdfList.of(authorName, publicKey); + private final Blog blog = new Blog(group, author, false); + private final BdfList descriptor = BdfList.of(authorName, publicKey, false); private final String content = TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH); @@ -64,7 +64,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test(expected = FormatException.class) public void testRejectsNullBlogName() throws Exception { - BdfList invalidDescriptor = BdfList.of(null, publicKey); + BdfList invalidDescriptor = BdfList.of(null, publicKey, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -72,7 +72,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test(expected = FormatException.class) public void testRejectsNonStringBlogName() throws Exception { - BdfList invalidDescriptor = BdfList.of(123, publicKey); + BdfList invalidDescriptor = BdfList.of(123, publicKey, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -80,7 +80,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test(expected = FormatException.class) public void testRejectsTooShortBlogName() throws Exception { - BdfList invalidDescriptor = BdfList.of("", publicKey); + BdfList invalidDescriptor = BdfList.of("", publicKey, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -89,7 +89,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test public void testAcceptsMinLengthBlogName() throws Exception { String shortBlogName = TestUtils.getRandomString(1); - BdfList validDescriptor = BdfList.of(shortBlogName, publicKey); + BdfList validDescriptor = BdfList.of(shortBlogName, publicKey, false); expectCreateBlog(shortBlogName, publicKey); expectEncodeMetadata(INVITE); BdfMessageContext messageContext = v.validateMessage(message, group, @@ -102,7 +102,8 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { public void testRejectsTooLongBlogName() throws Exception { String invalidBlogName = TestUtils.getRandomString(MAX_BLOG_NAME_LENGTH + 1); - BdfList invalidDescriptor = BdfList.of(invalidBlogName, publicKey); + BdfList invalidDescriptor = + BdfList.of(invalidBlogName, publicKey, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -110,7 +111,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test(expected = FormatException.class) public void testRejectsNullPublicKey() throws Exception { - BdfList invalidDescriptor = BdfList.of(authorName, null); + BdfList invalidDescriptor = BdfList.of(authorName, null, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -118,7 +119,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test(expected = FormatException.class) public void testRejectsNonRawPublicKey() throws Exception { - BdfList invalidDescriptor = BdfList.of(authorName, 123); + BdfList invalidDescriptor = BdfList.of(authorName, 123, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -127,7 +128,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test(expected = FormatException.class) public void testRejectsTooLongPublicKey() throws Exception { byte[] invalidKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1); - BdfList invalidDescriptor = BdfList.of(authorName, invalidKey); + BdfList invalidDescriptor = BdfList.of(authorName, invalidKey, false); v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor, null)); @@ -136,7 +137,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest { @Test public void testAcceptsMinLengthPublicKey() throws Exception { byte[] key = TestUtils.getRandomBytes(1); - BdfList validDescriptor = BdfList.of(authorName, key); + BdfList validDescriptor = BdfList.of(authorName, key, false); expectCreateBlog(authorName, key); expectEncodeMetadata(INVITE);