From 30fe9f6e2ae712e07de2a813320efd6a41f1a2dd Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Mon, 20 Jun 2016 16:00:05 -0300 Subject: [PATCH] Change Blog Paradigm to Short-Form Removes teaser and makes body mandatory. It also adds support for deleting blogs and introduces a getAuthorStatus() method to the IdentityManager that takes a running transaction. --- .../briarproject/api/blogs/BlogConstants.java | 5 - .../briarproject/api/blogs/BlogManager.java | 11 +- .../org/briarproject/api/blogs/BlogPost.java | 24 +--- .../api/blogs/BlogPostFactory.java | 4 +- .../api/blogs/BlogPostHeader.java | 17 +-- .../api/event/BlogPostAddedEvent.java | 32 +++++ .../api/identity/IdentityManager.java | 3 + .../briarproject/blogs/BlogManagerImpl.java | 131 +++++++++++++----- .../blogs/BlogPostFactoryImpl.java | 15 +- .../briarproject/blogs/BlogPostValidator.java | 37 ++--- .../identity/IdentityManagerImpl.java | 25 ++-- .../sharing/BlogSharingManagerImpl.java | 8 +- .../briarproject/sharing/SharingModule.java | 3 + 13 files changed, 202 insertions(+), 113 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/event/BlogPostAddedEvent.java diff --git a/briar-api/src/org/briarproject/api/blogs/BlogConstants.java b/briar-api/src/org/briarproject/api/blogs/BlogConstants.java index 738e012a3e..5e483ffc6e 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogConstants.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogConstants.java @@ -16,9 +16,6 @@ public interface BlogConstants { /** The length of a blog post's title in UTF-8 bytes. */ int MAX_BLOG_POST_TITLE_LENGTH = 100; - /** The length of a blog post's teaser in UTF-8 bytes. */ - int MAX_BLOG_POST_TEASER_LENGTH = 240; - /** The maximum length of a blog post's body in bytes. */ int MAX_BLOG_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024; @@ -31,8 +28,6 @@ public interface BlogConstants { // Metadata keys String KEY_DESCRIPTION = "description"; String KEY_TITLE = "title"; - String KEY_TEASER = "teaser"; - String KEY_HAS_BODY = "hasBody"; String KEY_TIMESTAMP = "timestamp"; String KEY_PARENT = "parent"; String KEY_AUTHOR_ID = "id"; diff --git a/briar-api/src/org/briarproject/api/blogs/BlogManager.java b/briar-api/src/org/briarproject/api/blogs/BlogManager.java index e01fa5efb9..0effcfee4d 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogManager.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogManager.java @@ -1,6 +1,5 @@ package org.briarproject.api.blogs; -import org.briarproject.api.FormatException; import org.briarproject.api.db.DbException; import org.briarproject.api.db.Transaction; import org.briarproject.api.identity.LocalAuthor; @@ -20,6 +19,9 @@ public interface BlogManager { Blog addBlog(LocalAuthor localAuthor, String name, String description) throws DbException; + /** Removes and deletes a blog. */ + void removeBlog(Blog b) throws DbException; + /** Stores a local blog post. */ void addLocalPost(BlogPost p) throws DbException; @@ -45,4 +47,11 @@ public interface BlogManager { /** Marks a blog post as read or unread. */ void setReadFlag(MessageId m, boolean read) throws DbException; + /** Registers a hook to be called whenever a blog is removed. */ + void registerRemoveBlogHook(RemoveBlogHook hook); + + interface RemoveBlogHook { + void removingBlog(Transaction txn, Blog b) throws DbException; + } + } diff --git a/briar-api/src/org/briarproject/api/blogs/BlogPost.java b/briar-api/src/org/briarproject/api/blogs/BlogPost.java index a6aa1167ae..3854c04727 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogPost.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogPost.java @@ -1,43 +1,27 @@ package org.briarproject.api.blogs; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import org.briarproject.api.forum.ForumPost; import org.briarproject.api.identity.Author; import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class BlogPost extends ForumPost { @Nullable private final String title; - @NotNull - private final String teaser; - private final boolean hasBody; - public BlogPost(@Nullable String title, @NotNull String teaser, - boolean hasBody, @NotNull Message message, - @Nullable MessageId parent, @NotNull Author author, + public BlogPost(@Nullable String title, @NotNull Message message, + @Nullable MessageId parent, @NotNull Author author, @NotNull String contentType) { super(message, parent, author, contentType); this.title = title; - this.teaser = teaser; - this.hasBody = hasBody; } @Nullable public String getTitle() { return title; } - - @NotNull - public String getTeaser() { - return teaser; - } - - public boolean hasBody() { - return hasBody; - } } diff --git a/briar-api/src/org/briarproject/api/blogs/BlogPostFactory.java b/briar-api/src/org/briarproject/api/blogs/BlogPostFactory.java index 2565bfb0e7..6ced9ba20f 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogPostFactory.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogPostFactory.java @@ -12,8 +12,8 @@ import java.security.GeneralSecurityException; public interface BlogPostFactory { BlogPost createBlogPost(@NotNull GroupId groupId, @Nullable String title, - @NotNull String teaser, long timestamp, @Nullable MessageId parent, + long timestamp, @Nullable MessageId parent, @NotNull LocalAuthor author, @NotNull String contentType, - @Nullable byte[] body) + @NotNull byte[] body) throws FormatException, GeneralSecurityException; } diff --git a/briar-api/src/org/briarproject/api/blogs/BlogPostHeader.java b/briar-api/src/org/briarproject/api/blogs/BlogPostHeader.java index 24d421c139..b3a740bcb9 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogPostHeader.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogPostHeader.java @@ -11,33 +11,18 @@ public class BlogPostHeader extends PostHeader { @Nullable private final String title; - @NotNull - private final String teaser; - private final boolean hasBody; - public BlogPostHeader(@Nullable String title, @NotNull String teaser, - boolean hasBody, @NotNull MessageId id, + public BlogPostHeader(@Nullable String title, @NotNull MessageId id, @Nullable MessageId parentId, long timestamp, @NotNull Author author, @NotNull Status authorStatus, @NotNull String contentType, boolean read) { super(id, parentId, timestamp, author, authorStatus, contentType, read); this.title = title; - this.teaser = teaser; - this.hasBody = hasBody; } @Nullable public String getTitle() { return title; } - - @NotNull - public String getTeaser() { - return teaser; - } - - public boolean hasBody() { - return hasBody; - } } diff --git a/briar-api/src/org/briarproject/api/event/BlogPostAddedEvent.java b/briar-api/src/org/briarproject/api/event/BlogPostAddedEvent.java new file mode 100644 index 0000000000..c00e4efbff --- /dev/null +++ b/briar-api/src/org/briarproject/api/event/BlogPostAddedEvent.java @@ -0,0 +1,32 @@ +package org.briarproject.api.event; + +import org.briarproject.api.blogs.BlogPostHeader; +import org.briarproject.api.sync.GroupId; + +/** An event that is broadcast when a blog post was added to the database. */ +public class BlogPostAddedEvent extends Event { + + private final GroupId groupId; + private final BlogPostHeader header; + private final boolean local; + + public BlogPostAddedEvent(GroupId groupId, BlogPostHeader header, + boolean local) { + + this.groupId = groupId; + this.header = header; + this.local = local; + } + + public GroupId getGroupId() { + return groupId; + } + + public BlogPostHeader getHeader() { + return header; + } + + public boolean isLocal() { + return local; + } +} diff --git a/briar-api/src/org/briarproject/api/identity/IdentityManager.java b/briar-api/src/org/briarproject/api/identity/IdentityManager.java index e5420a043f..e89f49d8ac 100644 --- a/briar-api/src/org/briarproject/api/identity/IdentityManager.java +++ b/briar-api/src/org/briarproject/api/identity/IdentityManager.java @@ -29,6 +29,9 @@ public interface IdentityManager { /** Returns the trust-level status of the author */ Status getAuthorStatus(AuthorId a) throws DbException; + /** Returns the trust-level status of the author */ + Status getAuthorStatus(Transaction txn, AuthorId a) throws DbException; + interface AddIdentityHook { void addingIdentity(Transaction txn, LocalAuthor a) throws DbException; } diff --git a/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java b/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java index eabfc251e3..70abde036f 100644 --- a/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java +++ b/briar-core/src/org/briarproject/blogs/BlogManagerImpl.java @@ -10,9 +10,11 @@ import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfEntry; import org.briarproject.api.data.BdfList; +import org.briarproject.api.data.MetadataParser; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DbException; import org.briarproject.api.db.Transaction; +import org.briarproject.api.event.BlogPostAddedEvent; import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author.Status; import org.briarproject.api.identity.AuthorId; @@ -21,7 +23,9 @@ import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.Message; import org.briarproject.api.sync.MessageId; +import org.briarproject.clients.BdfIncomingMessageHook; import org.briarproject.util.StringUtils; import org.jetbrains.annotations.Nullable; @@ -31,24 +35,24 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Logger; import javax.inject.Inject; +import static java.util.logging.Level.WARNING; import static org.briarproject.api.blogs.BlogConstants.KEY_AUTHOR; import static org.briarproject.api.blogs.BlogConstants.KEY_AUTHOR_ID; import static org.briarproject.api.blogs.BlogConstants.KEY_AUTHOR_NAME; import static org.briarproject.api.blogs.BlogConstants.KEY_CONTENT_TYPE; import static org.briarproject.api.blogs.BlogConstants.KEY_DESCRIPTION; -import static org.briarproject.api.blogs.BlogConstants.KEY_HAS_BODY; import static org.briarproject.api.blogs.BlogConstants.KEY_PARENT; import static org.briarproject.api.blogs.BlogConstants.KEY_PUBLIC_KEY; import static org.briarproject.api.blogs.BlogConstants.KEY_READ; -import static org.briarproject.api.blogs.BlogConstants.KEY_TEASER; import static org.briarproject.api.blogs.BlogConstants.KEY_TIMESTAMP; import static org.briarproject.api.blogs.BlogConstants.KEY_TITLE; -class BlogManagerImpl implements BlogManager { +class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager { private static final Logger LOG = Logger.getLogger(BlogManagerImpl.class.getName()); @@ -59,17 +63,19 @@ class BlogManagerImpl implements BlogManager { private final DatabaseComponent db; private final IdentityManager identityManager; - private final ClientHelper clientHelper; private final BlogFactory blogFactory; + private final List<RemoveBlogHook> removeHooks; @Inject BlogManagerImpl(DatabaseComponent db, IdentityManager identityManager, - ClientHelper clientHelper, BlogFactory blogFactory) { + ClientHelper clientHelper, MetadataParser metadataParser, + BlogFactory blogFactory) { + super(clientHelper, metadataParser); this.db = db; this.identityManager = identityManager; - this.clientHelper = clientHelper; this.blogFactory = blogFactory; + removeHooks = new CopyOnWriteArrayList<RemoveBlogHook>(); } @Override @@ -77,6 +83,17 @@ class BlogManagerImpl implements BlogManager { return CLIENT_ID; } + @Override + protected void incomingMessage(Transaction txn, Message m, BdfList list, + BdfDictionary meta) throws DbException, FormatException { + + GroupId groupId = m.getGroupId(); + BlogPostHeader h = getPostHeaderFromMetadata(txn, m.getId(), meta); + BlogPostAddedEvent event = + new BlogPostAddedEvent(groupId, h, false); + txn.attach(event); + } + @Override public Blog addBlog(LocalAuthor localAuthor, String name, String description) throws DbException { @@ -100,14 +117,26 @@ class BlogManagerImpl implements BlogManager { return b; } + @Override + public void removeBlog(Blog b) throws DbException { + Transaction txn = db.startTransaction(false); + try { + for (RemoveBlogHook hook : removeHooks) + hook.removingBlog(txn, b); + db.removeGroup(txn, b.getGroup()); + txn.setComplete(); + } finally { + db.endTransaction(txn); + } + } + @Override public void addLocalPost(BlogPost p) throws DbException { + BdfDictionary meta; try { - BdfDictionary meta = new BdfDictionary(); + meta = new BdfDictionary(); if (p.getTitle() != null) meta.put(KEY_TITLE, p.getTitle()); - meta.put(KEY_TEASER, p.getTeaser()); meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp()); - meta.put(KEY_HAS_BODY, p.hasBody()); if (p.getParent() != null) meta.put(KEY_PARENT, p.getParent()); Author a = p.getAuthor(); @@ -123,6 +152,22 @@ class BlogManagerImpl implements BlogManager { } catch (FormatException e) { throw new RuntimeException(e); } + + // broadcast event about new post + Transaction txn = db.startTransaction(true); + try { + GroupId groupId = p.getMessage().getGroupId(); + MessageId postId = p.getMessage().getId(); + BlogPostHeader h = getPostHeaderFromMetadata(txn, postId, meta); + BlogPostAddedEvent event = + new BlogPostAddedEvent(groupId, h, true); + txn.attach(event); + txn.setComplete(); + } catch (FormatException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + } finally { + db.endTransaction(txn); + } } @Override @@ -189,16 +234,20 @@ class BlogManagerImpl implements BlogManager { @Nullable public byte[] getPostBody(MessageId m) throws DbException { try { - // content, signature - // content: parent, contentType, title, teaser, body, attachments BdfList message = clientHelper.getMessageAsList(m); - BdfList content = message.getList(0); - return content.getRaw(4); + return getPostBody(message); } catch (FormatException e) { throw new DbException(e); } } + private byte[] getPostBody(BdfList message) throws FormatException { + // content, signature + // content: parent, contentType, title, body, attachments + BdfList content = message.getList(0); + return content.getRaw(3); + } + @Override public Collection<BlogPostHeader> getPostHeaders(GroupId g) throws DbException { @@ -213,26 +262,9 @@ class BlogManagerImpl implements BlogManager { for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) { try { BdfDictionary meta = entry.getValue(); - String title = meta.getOptionalString(KEY_TITLE); - String teaser = meta.getString(KEY_TEASER); - boolean hasBody = meta.getBoolean(KEY_HAS_BODY); - long timestamp = meta.getLong(KEY_TIMESTAMP); - MessageId parentId = null; - if (meta.containsKey(KEY_PARENT)) - parentId = new MessageId(meta.getRaw(KEY_PARENT)); - - BdfDictionary d = meta.getDictionary(KEY_AUTHOR); - AuthorId authorId = new AuthorId(d.getRaw(KEY_AUTHOR_ID)); - String name = d.getString(KEY_AUTHOR_NAME); - byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY); - Author author = new Author(authorId, name, publicKey); - Status authorStatus = identityManager.getAuthorStatus(authorId); - - String contentType = meta.getString(KEY_CONTENT_TYPE); - boolean read = meta.getBoolean(KEY_READ); - headers.add(new BlogPostHeader(title, teaser, hasBody, - entry.getKey(), parentId, timestamp, author, - authorStatus, contentType, read)); + BlogPostHeader h = + getPostHeaderFromMetadata(null, entry.getKey(), meta); + headers.add(h); } catch (FormatException e) { throw new DbException(e); } @@ -251,10 +283,43 @@ class BlogManagerImpl implements BlogManager { } } + @Override + public void registerRemoveBlogHook(RemoveBlogHook hook) { + removeHooks.add(hook); + } + private String getBlogDescription(Transaction txn, GroupId g) throws DbException, FormatException { BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g); return d.getString(KEY_DESCRIPTION); } + private BlogPostHeader getPostHeaderFromMetadata(@Nullable Transaction txn, + MessageId id, BdfDictionary meta) + throws DbException, FormatException { + + String title = meta.getOptionalString(KEY_TITLE); + long timestamp = meta.getLong(KEY_TIMESTAMP); + MessageId parentId = null; + if (meta.containsKey(KEY_PARENT)) + parentId = new MessageId(meta.getRaw(KEY_PARENT)); + + BdfDictionary d = meta.getDictionary(KEY_AUTHOR); + AuthorId authorId = new AuthorId(d.getRaw(KEY_AUTHOR_ID)); + String name = d.getString(KEY_AUTHOR_NAME); + byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY); + Author author = new Author(authorId, name, publicKey); + Status authorStatus; + if (txn == null) + authorStatus = identityManager.getAuthorStatus(authorId); + else { + authorStatus = identityManager.getAuthorStatus(txn, authorId); + } + + String contentType = meta.getString(KEY_CONTENT_TYPE); + boolean read = meta.getBoolean(KEY_READ); + return new BlogPostHeader(title, id, parentId, timestamp, author, + authorStatus, contentType, read); + } + } diff --git a/briar-core/src/org/briarproject/blogs/BlogPostFactoryImpl.java b/briar-core/src/org/briarproject/blogs/BlogPostFactoryImpl.java index e9ced2d3fe..ce134d33c6 100644 --- a/briar-core/src/org/briarproject/blogs/BlogPostFactoryImpl.java +++ b/briar-core/src/org/briarproject/blogs/BlogPostFactoryImpl.java @@ -22,7 +22,6 @@ import java.security.GeneralSecurityException; import javax.inject.Inject; import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_POST_BODY_LENGTH; -import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_POST_TEASER_LENGTH; import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_POST_TITLE_LENGTH; import static org.briarproject.api.blogs.BlogConstants.MAX_CONTENT_TYPE_LENGTH; @@ -39,25 +38,22 @@ class BlogPostFactoryImpl implements BlogPostFactory { @Override public BlogPost createBlogPost(@NotNull GroupId groupId, - @Nullable String title, @NotNull String teaser, long timestamp, + @Nullable String title, long timestamp, @Nullable MessageId parent, @NotNull LocalAuthor author, - @NotNull String contentType, @Nullable byte[] body) + @NotNull String contentType, @NotNull byte[] body) throws FormatException, GeneralSecurityException { // Validate the arguments if (title != null && StringUtils.toUtf8(title).length > MAX_BLOG_POST_TITLE_LENGTH) throw new IllegalArgumentException(); - if (StringUtils.toUtf8(teaser).length > MAX_BLOG_POST_TEASER_LENGTH) - throw new IllegalArgumentException(); if (StringUtils.toUtf8(contentType).length > MAX_CONTENT_TYPE_LENGTH) throw new IllegalArgumentException(); - if (body != null && body.length > MAX_BLOG_POST_BODY_LENGTH) + if (body.length > MAX_BLOG_POST_BODY_LENGTH) throw new IllegalArgumentException(); // Serialise the data to be signed - BdfList content = - BdfList.of(parent, contentType, title, teaser, body, null); + BdfList content = BdfList.of(parent, contentType, title, body, null); BdfList signed = BdfList.of(groupId, timestamp, content); // Generate the signature @@ -72,7 +68,6 @@ class BlogPostFactoryImpl implements BlogPostFactory { // Serialise the signed message BdfList message = BdfList.of(content, sig); Message m = clientHelper.createMessage(groupId, timestamp, message); - return new BlogPost(title, teaser, body != null, m, parent, author, - contentType); + return new BlogPost(title, m, parent, author, contentType); } } diff --git a/briar-core/src/org/briarproject/blogs/BlogPostValidator.java b/briar-core/src/org/briarproject/blogs/BlogPostValidator.java index bacf02dff6..1ff0e2d461 100644 --- a/briar-core/src/org/briarproject/blogs/BlogPostValidator.java +++ b/briar-core/src/org/briarproject/blogs/BlogPostValidator.java @@ -11,6 +11,7 @@ import org.briarproject.api.crypto.KeyParser; import org.briarproject.api.crypto.PublicKey; import org.briarproject.api.crypto.Signature; import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.data.BdfEntry; import org.briarproject.api.data.BdfList; import org.briarproject.api.data.MetadataEncoder; import org.briarproject.api.identity.Author; @@ -25,15 +26,16 @@ import java.security.GeneralSecurityException; import java.util.Collection; import java.util.Collections; +import static org.briarproject.api.blogs.BlogConstants.KEY_AUTHOR; +import static org.briarproject.api.blogs.BlogConstants.KEY_AUTHOR_ID; +import static org.briarproject.api.blogs.BlogConstants.KEY_AUTHOR_NAME; import static org.briarproject.api.blogs.BlogConstants.KEY_CONTENT_TYPE; -import static org.briarproject.api.blogs.BlogConstants.KEY_HAS_BODY; import static org.briarproject.api.blogs.BlogConstants.KEY_PARENT; +import static org.briarproject.api.blogs.BlogConstants.KEY_PUBLIC_KEY; import static org.briarproject.api.blogs.BlogConstants.KEY_READ; -import static org.briarproject.api.blogs.BlogConstants.KEY_TEASER; import static org.briarproject.api.blogs.BlogConstants.KEY_TIMESTAMP; import static org.briarproject.api.blogs.BlogConstants.KEY_TITLE; import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_POST_BODY_LENGTH; -import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_POST_TEASER_LENGTH; import static org.briarproject.api.blogs.BlogConstants.MAX_BLOG_POST_TITLE_LENGTH; import static org.briarproject.api.blogs.BlogConstants.MAX_CONTENT_TYPE_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH; @@ -60,37 +62,36 @@ class BlogPostValidator extends BdfMessageValidator { checkSize(body, 2); BdfList content = body.getList(0); - // Content: Parent ID, content type, title (optional), teaser, - // post body (optional), attachments (optional) - checkSize(body, 6); + // Content: Parent ID, content type, title (optional), post body, + // attachments (optional) + checkSize(content, 5); // Parent ID is optional byte[] parent = content.getOptionalRaw(0); checkLength(parent, UniqueId.LENGTH); // Content type String contentType = content.getString(1); checkLength(contentType, 0, MAX_CONTENT_TYPE_LENGTH); + if (!contentType.equals("text/plain")) + throw new InvalidMessageException("Invalid content type"); // Blog post title is optional String title = content.getOptionalString(2); checkLength(contentType, 0, MAX_BLOG_POST_TITLE_LENGTH); - // Blog teaser - String teaser = content.getString(3); - // TODO make sure that there is only text in the teaser - checkLength(contentType, 0, MAX_BLOG_POST_TEASER_LENGTH); - // Blog post body is optional - byte[] postBody = content.getOptionalRaw(4); + // Blog post body + byte[] postBody = content.getRaw(3); checkLength(postBody, 0, MAX_BLOG_POST_BODY_LENGTH); // Attachments - BdfDictionary attachments = content.getOptionalDictionary(5); + BdfDictionary attachments = content.getOptionalDictionary(4); // TODO handle attachments somehow // Signature byte[] sig = body.getRaw(1); checkLength(sig, 0, MAX_SIGNATURE_LENGTH); // Verify the signature + Author a; try { // Get the blog author Blog b = blogFactory.parseBlog(g, ""); // description doesn't matter - Author a = b.getAuthor(); + a = b.getAuthor(); // Parse the public key KeyParser keyParser = crypto.getSignatureKeyParser(); PublicKey key = keyParser.parsePublicKey(a.getPublicKey()); @@ -111,8 +112,12 @@ class BlogPostValidator extends BdfMessageValidator { BdfDictionary meta = new BdfDictionary(); Collection<MessageId> dependencies = null; if (title != null) meta.put(KEY_TITLE, title); - meta.put(KEY_TEASER, teaser); - meta.put(KEY_HAS_BODY, postBody != null); + BdfDictionary author = BdfDictionary.of( + new BdfEntry(KEY_AUTHOR_ID, a.getId()), + new BdfEntry(KEY_AUTHOR_NAME, a.getName()), + new BdfEntry(KEY_PUBLIC_KEY, a.getPublicKey()) + ); + meta.put(KEY_AUTHOR, author); meta.put(KEY_TIMESTAMP, m.getTimestamp()); if (parent != null) { meta.put(KEY_PARENT, parent); diff --git a/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java b/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java index e04e206020..5b1434ad1e 100644 --- a/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java +++ b/briar-core/src/org/briarproject/identity/IdentityManagerImpl.java @@ -99,17 +99,24 @@ class IdentityManagerImpl implements IdentityManager { public Status getAuthorStatus(AuthorId authorId) throws DbException { Transaction txn = db.startTransaction(false); try { - // Compare to the IDs of the user's identities - for (LocalAuthor a : db.getLocalAuthors(txn)) - if (a.getId().equals(authorId)) return VERIFIED; - // Compare to the IDs of contacts' identities - for (Contact c : db.getContacts(txn)) - if (c.getAuthor().getId().equals(authorId)) return VERIFIED; - - // TODO also handle UNVERIFIED when #261 is implemented - return UNKNOWN; + return getAuthorStatus(txn, authorId); } finally { db.endTransaction(txn); } } + + @Override + public Status getAuthorStatus(Transaction txn, AuthorId authorId) + throws DbException { + // Compare to the IDs of the user's identities + for (LocalAuthor a : db.getLocalAuthors(txn)) + if (a.getId().equals(authorId)) return VERIFIED; + // Compare to the IDs of contacts' identities + for (Contact c : db.getContacts(txn)) + if (c.getAuthor().getId().equals(authorId)) return VERIFIED; + + // TODO also handle UNVERIFIED when #261 is implemented + return UNKNOWN; + } + } diff --git a/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java index ba67ff635e..a25520fac0 100644 --- a/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java @@ -5,6 +5,7 @@ import org.briarproject.api.blogs.Blog; import org.briarproject.api.blogs.BlogFactory; import org.briarproject.api.blogs.BlogInvitationMessage; import org.briarproject.api.blogs.BlogManager; +import org.briarproject.api.blogs.BlogManager.RemoveBlogHook; import org.briarproject.api.blogs.BlogSharingManager; import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation; import org.briarproject.api.clients.ClientHelper; @@ -40,7 +41,7 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE; class BlogSharingManagerImpl extends SharingManagerImpl<Blog, BlogInvitation, BlogInvitationMessage, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent> - implements BlogSharingManager { + implements BlogSharingManager, RemoveBlogHook { static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString( "bee438b5de0b3a685badc4e49d76e72d" @@ -124,6 +125,11 @@ class BlogSharingManagerImpl extends return irrFactory; } + @Override + public void removingBlog(Transaction txn, Blog b) throws DbException { + removingShareable(txn, b); + } + static class SFactory implements ShareableFactory<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState> { diff --git a/briar-core/src/org/briarproject/sharing/SharingModule.java b/briar-core/src/org/briarproject/sharing/SharingModule.java index d62c7dccf7..3af07e1292 100644 --- a/briar-core/src/org/briarproject/sharing/SharingModule.java +++ b/briar-core/src/org/briarproject/sharing/SharingModule.java @@ -1,5 +1,6 @@ package org.briarproject.sharing; +import org.briarproject.api.blogs.BlogManager; import org.briarproject.api.blogs.BlogSharingManager; import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.MessageQueueManager; @@ -49,6 +50,7 @@ public class SharingModule { LifecycleManager lifecycleManager, ContactManager contactManager, MessageQueueManager messageQueueManager, + BlogManager blogManager, BlogSharingManagerImpl blogSharingManager) { lifecycleManager.registerClient(blogSharingManager); @@ -56,6 +58,7 @@ public class SharingModule { contactManager.registerRemoveContactHook(blogSharingManager); messageQueueManager.registerIncomingMessageHook( BlogSharingManagerImpl.CLIENT_ID, blogSharingManager); + blogManager.registerRemoveBlogHook(blogSharingManager); return blogSharingManager; } -- GitLab