Skip to content
Snippets Groups Projects
Commit 1ad3a664 authored by akwizgran's avatar akwizgran
Browse files

Merge branch '941-store-correct-parent-id' into 'master'

Store correct original parent ID when rewrapping blog posts

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