mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Store correct original parent ID when rewrapping blog posts.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user