diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/Bytes.java b/bramble-api/src/main/java/org/briarproject/bramble/api/Bytes.java index 5c9b61f40873694903dfb9a393ede6af72069fcb..1a862bbd87b28d70d0d5121f08a2d1378c95a27d 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/Bytes.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/Bytes.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.api; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.util.StringUtils; import java.util.Arrays; import java.util.Comparator; @@ -53,6 +54,12 @@ public class Bytes implements Comparable<Bytes> { return aBytes.length - bBytes.length; } + @Override + public String toString() { + return getClass().getSimpleName() + + "(" + StringUtils.toHexString(getBytes()) + ")"; + } + public static class BytesComparator implements Comparator<Bytes> { @Override 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 041d474a4eca490b8444c47a9feac2c652792800..cce628fcb4e6f0092c60937ac227e2377c35c764 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 @@ -60,7 +60,7 @@ public interface BlogManager { * Adds a comment to an existing blog post or reblogs it. */ void addLocalComment(LocalAuthor author, GroupId groupId, - @Nullable String comment, BlogPostHeader wHeader) + @Nullable String comment, BlogPostHeader parentHeader) throws DbException; /** diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogPostFactory.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogPostFactory.java index 4a64c27323232acff7bf2d957ecbdc4c2f4432f8..6a07a18c22f4dcee7a275e010bc598cd5d5c5a6a 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogPostFactory.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogPostFactory.java @@ -25,7 +25,8 @@ public interface BlogPostFactory { throws FormatException, GeneralSecurityException; Message createBlogComment(GroupId groupId, LocalAuthor author, - @Nullable String comment, MessageId originalId, MessageId wrappedId) + @Nullable String comment, MessageId parentOriginalId, + MessageId parentCurrentId) throws FormatException, GeneralSecurityException; /** @@ -44,11 +45,11 @@ public interface BlogPostFactory { * Wraps a blog comment */ Message wrapComment(GroupId groupId, byte[] descriptor, long timestamp, - BdfList body, MessageId currentId) throws FormatException; + BdfList body, MessageId parentCurrentId) throws FormatException; /** * Re-wraps a previously wrapped comment */ Message rewrapWrappedComment(GroupId groupId, BdfList body, - MessageId currentId) throws FormatException; + MessageId parentCurrentId) throws FormatException; } 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 b27a3bf116b71a22ed1bb6b020b30cf10bf288e9..84f3724dafc341eec8391d56fa4535b47502c44f 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 @@ -246,7 +246,6 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, addLocalPost(txn, p); db.commitTransaction(txn); } finally { - //noinspection ThrowFromFinallyBlock db.endTransaction(txn); } } @@ -269,8 +268,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, MessageId postId = p.getMessage().getId(); BlogPostHeader h = getPostHeaderFromMetadata(txn, groupId, postId, meta); - BlogPostAddedEvent event = - new BlogPostAddedEvent(groupId, h, true); + BlogPostAddedEvent event = new BlogPostAddedEvent(groupId, h, true); txn.attach(event); } catch (FormatException e) { throw new DbException(e); @@ -279,42 +277,39 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, @Override public void addLocalComment(LocalAuthor author, GroupId groupId, - @Nullable String comment, BlogPostHeader pOriginalHeader) + @Nullable String comment, BlogPostHeader parentHeader) throws DbException { - MessageType type = pOriginalHeader.getType(); + MessageType type = parentHeader.getType(); if (type != POST && type != COMMENT) throw new IllegalArgumentException("Comment on unknown type!"); Transaction txn = db.startTransaction(false); try { // Wrap post that we are commenting on - MessageId parentId = wrapMessage(txn, groupId, pOriginalHeader); - - // Get ID of new parent's original message. - // Assumes that pOriginalHeader is a POST or COMMENT - MessageId pOriginalId = pOriginalHeader.getId(); + MessageId parentOriginalId = + getOriginalMessageId(txn, parentHeader); + MessageId parentCurrentId = + wrapMessage(txn, groupId, parentHeader, parentOriginalId); // Create actual comment - Message message = blogPostFactory - .createBlogComment(groupId, author, comment, pOriginalId, - parentId); + Message message = blogPostFactory.createBlogComment(groupId, author, + comment, parentOriginalId, parentCurrentId); BdfDictionary meta = new BdfDictionary(); meta.put(KEY_TYPE, COMMENT.getInt()); if (comment != null) meta.put(KEY_COMMENT, comment); meta.put(KEY_TIMESTAMP, message.getTimestamp()); meta.put(KEY_ORIGINAL_MSG_ID, message.getId()); - meta.put(KEY_ORIGINAL_PARENT_MSG_ID, pOriginalId); - meta.put(KEY_PARENT_MSG_ID, parentId); + meta.put(KEY_ORIGINAL_PARENT_MSG_ID, parentOriginalId); + meta.put(KEY_PARENT_MSG_ID, parentCurrentId); meta.put(KEY_AUTHOR, authorToBdfDictionary(author)); // Send comment clientHelper.addLocalMessage(txn, message, meta, true); // broadcast event - BlogPostHeader h = - getPostHeaderFromMetadata(txn, groupId, message.getId(), - meta); + BlogPostHeader h = getPostHeaderFromMetadata(txn, groupId, + message.getId(), meta); BlogPostAddedEvent event = new BlogPostAddedEvent(groupId, h, true); txn.attach(event); db.commitTransaction(txn); @@ -323,81 +318,94 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, } catch (GeneralSecurityException e) { throw new IllegalArgumentException("Invalid key of author", e); } finally { - //noinspection ThrowFromFinallyBlock db.endTransaction(txn); } } + private MessageId getOriginalMessageId(Transaction txn, BlogPostHeader h) + throws DbException, FormatException { + MessageType type = h.getType(); + if (type == POST || type == COMMENT) return h.getId(); + BdfDictionary meta = clientHelper.getMessageMetadataAsDictionary(txn, + h.getId()); + return new MessageId(meta.getRaw(KEY_ORIGINAL_MSG_ID)); + } + private MessageId wrapMessage(Transaction txn, GroupId groupId, - BlogPostHeader pOriginalHeader) + BlogPostHeader header, MessageId originalId) throws DbException, FormatException { - if (groupId.equals(pOriginalHeader.getGroupId())) { + if (groupId.equals(header.getGroupId())) { // We are trying to wrap a post that is already in our group. // This is unnecessary, so just return the post's MessageId - return pOriginalHeader.getId(); + return header.getId(); } // Get body of message to be wrapped - BdfList body = - clientHelper.getMessageAsList(txn, pOriginalHeader.getId()); + BdfList body = clientHelper.getMessageAsList(txn, header.getId()); if (body == null) throw new DbException(); - long wTimestamp = pOriginalHeader.getTimestamp(); - Message wMessage; + long timestamp = header.getTimestamp(); + Message wrappedMessage; BdfDictionary meta = new BdfDictionary(); - MessageType type = pOriginalHeader.getType(); + MessageType type = header.getType(); if (type == POST) { - Group wGroup = db.getGroup(txn, pOriginalHeader.getGroupId()); - byte[] wDescriptor = wGroup.getDescriptor(); // Wrap post - wMessage = blogPostFactory - .wrapPost(groupId, wDescriptor, wTimestamp, body); + Group group = db.getGroup(txn, header.getGroupId()); + byte[] descriptor = group.getDescriptor(); + wrappedMessage = blogPostFactory.wrapPost(groupId, descriptor, + timestamp, body); meta.put(KEY_TYPE, WRAPPED_POST.getInt()); - meta.put(KEY_RSS_FEED, pOriginalHeader.isRssFeed()); + meta.put(KEY_RSS_FEED, header.isRssFeed()); } else if (type == COMMENT) { - Group wGroup = db.getGroup(txn, pOriginalHeader.getGroupId()); - byte[] wDescriptor = wGroup.getDescriptor(); - BlogCommentHeader wComment = (BlogCommentHeader) pOriginalHeader; - MessageId wrappedId = - wrapMessage(txn, groupId, wComment.getParent()); + // Recursively wrap parent + BlogCommentHeader commentHeader = (BlogCommentHeader) header; + BlogPostHeader parentHeader = commentHeader.getParent(); + MessageId parentOriginalId = + getOriginalMessageId(txn, parentHeader); + MessageId parentCurrentId = + wrapMessage(txn, groupId, parentHeader, parentOriginalId); // Wrap comment - wMessage = blogPostFactory - .wrapComment(groupId, wDescriptor, wTimestamp, - body, wrappedId); + Group group = db.getGroup(txn, header.getGroupId()); + byte[] descriptor = group.getDescriptor(); + wrappedMessage = blogPostFactory.wrapComment(groupId, descriptor, + timestamp, body, parentCurrentId); meta.put(KEY_TYPE, WRAPPED_COMMENT.getInt()); - if (wComment.getComment() != null) - meta.put(KEY_COMMENT, wComment.getComment()); - meta.put(KEY_PARENT_MSG_ID, wrappedId); + if (commentHeader.getComment() != null) + meta.put(KEY_COMMENT, commentHeader.getComment()); + meta.put(KEY_PARENT_MSG_ID, parentCurrentId); } else if (type == WRAPPED_POST) { // Re-wrap wrapped post without adding another wrapping layer - wMessage = blogPostFactory.rewrapWrappedPost(groupId, body); + wrappedMessage = blogPostFactory.rewrapWrappedPost(groupId, body); meta.put(KEY_TYPE, WRAPPED_POST.getInt()); - meta.put(KEY_RSS_FEED, pOriginalHeader.isRssFeed()); + meta.put(KEY_RSS_FEED, header.isRssFeed()); } else if (type == WRAPPED_COMMENT) { - BlogCommentHeader wComment = (BlogCommentHeader) pOriginalHeader; - MessageId wrappedId = - wrapMessage(txn, groupId, wComment.getParent()); + // Recursively wrap parent + BlogCommentHeader commentHeader = (BlogCommentHeader) header; + BlogPostHeader parentHeader = commentHeader.getParent(); + MessageId parentOriginalId = + getOriginalMessageId(txn, parentHeader); + MessageId parentCurrentId = + wrapMessage(txn, groupId, parentHeader, parentOriginalId); // Re-wrap wrapped comment - wMessage = blogPostFactory - .rewrapWrappedComment(groupId, body, wrappedId); + wrappedMessage = blogPostFactory.rewrapWrappedComment(groupId, body, + parentCurrentId); meta.put(KEY_TYPE, WRAPPED_COMMENT.getInt()); - if (wComment.getComment() != null) - meta.put(KEY_COMMENT, wComment.getComment()); - meta.put(KEY_PARENT_MSG_ID, wrappedId); + if (commentHeader.getComment() != null) + meta.put(KEY_COMMENT, commentHeader.getComment()); + meta.put(KEY_PARENT_MSG_ID, parentCurrentId); } else { throw new IllegalArgumentException( "Unknown Message Type: " + type); } - meta.put(KEY_ORIGINAL_MSG_ID, pOriginalHeader.getId()); - meta.put(KEY_AUTHOR, - authorToBdfDictionary(pOriginalHeader.getAuthor())); - meta.put(KEY_TIMESTAMP, pOriginalHeader.getTimestamp()); - meta.put(KEY_TIME_RECEIVED, pOriginalHeader.getTimeReceived()); + meta.put(KEY_ORIGINAL_MSG_ID, originalId); + meta.put(KEY_AUTHOR, authorToBdfDictionary(header.getAuthor())); + meta.put(KEY_TIMESTAMP, header.getTimestamp()); + meta.put(KEY_TIME_RECEIVED, header.getTimeReceived()); // Send wrapped message and store metadata - clientHelper.addLocalMessage(txn, wMessage, meta, true); - return wMessage.getId(); + clientHelper.addLocalMessage(txn, wrappedMessage, meta, true); + return wrappedMessage.getId(); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java index b8fd8b7e32e85c816ec766921d043dcbd4b58b08..bd89a0ba81930ea31b2416f1386a642938d1e0f3 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogPostFactoryImpl.java @@ -65,7 +65,8 @@ class BlogPostFactoryImpl implements BlogPostFactory { @Override public Message createBlogComment(GroupId groupId, LocalAuthor author, - @Nullable String comment, MessageId pOriginalId, MessageId parentId) + @Nullable String comment, MessageId parentOriginalId, + MessageId parentCurrentId) throws FormatException, GeneralSecurityException { if (comment != null) { @@ -78,22 +79,20 @@ class BlogPostFactoryImpl implements BlogPostFactory { long timestamp = clock.currentTimeMillis(); // Generate the signature - BdfList signed = - BdfList.of(groupId, timestamp, comment, pOriginalId, parentId); + BdfList signed = BdfList.of(groupId, timestamp, comment, + parentOriginalId, parentCurrentId); byte[] sig = clientHelper .sign(SIGNING_LABEL_COMMENT, signed, author.getPrivateKey()); // Serialise the signed message - BdfList message = - BdfList.of(COMMENT.getInt(), comment, pOriginalId, parentId, - sig); + BdfList message = BdfList.of(COMMENT.getInt(), comment, + parentOriginalId, parentCurrentId, sig); return clientHelper.createMessage(groupId, timestamp, message); } @Override public Message wrapPost(GroupId groupId, byte[] descriptor, - long timestamp, BdfList body) - throws FormatException { + long timestamp, BdfList body) throws FormatException { if (getType(body) != POST) throw new IllegalArgumentException("Needs to wrap a POST"); @@ -101,9 +100,8 @@ class BlogPostFactoryImpl implements BlogPostFactory { // Serialise the message String content = body.getString(1); byte[] signature = body.getRaw(2); - BdfList message = - BdfList.of(WRAPPED_POST.getInt(), descriptor, timestamp, - content, signature); + BdfList message = BdfList.of(WRAPPED_POST.getInt(), descriptor, + timestamp, content, signature); return clientHelper .createMessage(groupId, clock.currentTimeMillis(), message); } @@ -120,16 +118,15 @@ class BlogPostFactoryImpl implements BlogPostFactory { long timestamp = body.getLong(2); String content = body.getString(3); byte[] signature = body.getRaw(4); - BdfList message = - BdfList.of(WRAPPED_POST.getInt(), descriptor, timestamp, - content, signature); + BdfList message = BdfList.of(WRAPPED_POST.getInt(), descriptor, + timestamp, content, signature); return clientHelper .createMessage(groupId, clock.currentTimeMillis(), message); } @Override public Message wrapComment(GroupId groupId, byte[] descriptor, - long timestamp, BdfList body, MessageId parentId) + long timestamp, BdfList body, MessageId parentCurrentId) throws FormatException { if (getType(body) != COMMENT) @@ -140,16 +137,16 @@ class BlogPostFactoryImpl implements BlogPostFactory { byte[] pOriginalId = body.getRaw(2); byte[] oldParentId = body.getRaw(3); byte[] signature = body.getRaw(4); - BdfList message = - BdfList.of(WRAPPED_COMMENT.getInt(), descriptor, timestamp, - comment, pOriginalId, oldParentId, signature, parentId); + BdfList message = BdfList.of(WRAPPED_COMMENT.getInt(), descriptor, + timestamp, comment, pOriginalId, oldParentId, signature, + parentCurrentId); return clientHelper .createMessage(groupId, clock.currentTimeMillis(), message); } @Override public Message rewrapWrappedComment(GroupId groupId, BdfList body, - MessageId parentId) throws FormatException { + MessageId parentCurrentId) throws FormatException { if (getType(body) != WRAPPED_COMMENT) throw new IllegalArgumentException( @@ -162,9 +159,9 @@ class BlogPostFactoryImpl implements BlogPostFactory { byte[] pOriginalId = body.getRaw(4); byte[] oldParentId = body.getRaw(5); byte[] signature = body.getRaw(6); - BdfList message = - BdfList.of(WRAPPED_COMMENT.getInt(), descriptor, timestamp, - comment, pOriginalId, oldParentId, signature, parentId); + BdfList message = BdfList.of(WRAPPED_COMMENT.getInt(), descriptor, + timestamp, comment, pOriginalId, oldParentId, signature, + parentCurrentId); return clientHelper .createMessage(groupId, clock.currentTimeMillis(), message); }