mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Merge branch '494-implement-backend-for-reblogging-and-blog-comments' into 'master'
Add support for comments and reblogging to Blog Client Comments and reblogs need to depend on the post they refer to. Since message dependencies are limited to one group, the post and also the comments need to be wrapped when commented on or reblogged to another blog (and group). For this reason, in addition to comments, two new wrapping message types are introduced. They retain all data of the original messages and allow for reconstruction and signature verification. This MR breaks backwards compatibility with old blog posts. It removes the content type, title and parent ID from the post. Furthermore, it includes one commit that replaces the `Message` in `MessageSharedEvent` with a `MessageId`. Closes #494 See merge request !285
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package org.briarproject.api.blogs;
|
||||
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.Author.Status;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static org.briarproject.api.blogs.MessageType.COMMENT;
|
||||
import static org.briarproject.api.blogs.MessageType.WRAPPED_COMMENT;
|
||||
|
||||
public class BlogCommentHeader extends BlogPostHeader {
|
||||
|
||||
private final String comment;
|
||||
private final BlogPostHeader parent;
|
||||
|
||||
public BlogCommentHeader(@NotNull MessageType type,
|
||||
@NotNull GroupId groupId, @Nullable String comment,
|
||||
@NotNull BlogPostHeader parent, @NotNull MessageId id,
|
||||
long timestamp, long timeReceived, @NotNull Author author,
|
||||
@NotNull Status authorStatus, boolean read) {
|
||||
|
||||
super(type, groupId, id, parent.getId(), timestamp,
|
||||
timeReceived, author, authorStatus, read);
|
||||
|
||||
if (type != COMMENT && type != WRAPPED_COMMENT)
|
||||
throw new IllegalArgumentException("Incompatible Message Type");
|
||||
|
||||
this.comment = comment;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public BlogPostHeader getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
@@ -10,12 +10,6 @@ public interface BlogConstants {
|
||||
/** The length of a blogs's description in UTF-8 bytes. */
|
||||
int MAX_BLOG_DESC_LENGTH = 240;
|
||||
|
||||
/** The maximum length of a blog post's content type in UTF-8 bytes. */
|
||||
int MAX_CONTENT_TYPE_LENGTH = 50;
|
||||
|
||||
/** The length of a blog post's title in UTF-8 bytes. */
|
||||
int MAX_BLOG_POST_TITLE_LENGTH = 100;
|
||||
|
||||
/** The maximum length of a blog post's body in bytes. */
|
||||
int MAX_BLOG_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
|
||||
|
||||
@@ -31,17 +25,20 @@ public interface BlogConstants {
|
||||
// Metadata keys
|
||||
String KEY_TYPE = "type";
|
||||
String KEY_DESCRIPTION = "description";
|
||||
String KEY_TITLE = "title";
|
||||
String KEY_TIMESTAMP = "timestamp";
|
||||
String KEY_TIME_RECEIVED = "timeReceived";
|
||||
String KEY_AUTHOR_ID = "id";
|
||||
String KEY_AUTHOR_NAME = "name";
|
||||
String KEY_PUBLIC_KEY = "publicKey";
|
||||
String KEY_AUTHOR = "author";
|
||||
String KEY_CONTENT_TYPE = "contentType";
|
||||
String KEY_READ = "read";
|
||||
String KEY_COMMENT = "comment";
|
||||
String KEY_ORIGINAL_MSG_ID = "originalMessageId";
|
||||
String KEY_CURRENT_MSG_ID = "currentMessageId";
|
||||
String KEY_ORIGINAL_PARENT_MSG_ID = "originalParentMessageId";
|
||||
/**
|
||||
* This is the ID of either a message wrapped from a different group
|
||||
* or of a message from the same group that therefore needed no wrapping.
|
||||
*/
|
||||
String KEY_PARENT_MSG_ID = "parentMessageId";
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -31,6 +32,11 @@ public interface BlogManager {
|
||||
/** Stores a local blog post. */
|
||||
void addLocalPost(Transaction txn, BlogPost p) throws DbException;
|
||||
|
||||
/** Add a comment to an existing blog post or reblog it. */
|
||||
void addLocalComment(LocalAuthor author, GroupId groupId,
|
||||
@Nullable String comment, BlogPostHeader wHeader)
|
||||
throws DbException;
|
||||
|
||||
/** Returns the blog with the given ID. */
|
||||
Blog getBlog(GroupId g) throws DbException;
|
||||
|
||||
@@ -47,7 +53,7 @@ public interface BlogManager {
|
||||
Collection<Blog> getBlogs() throws DbException;
|
||||
|
||||
/** Returns the header of the blog post with the given ID. */
|
||||
BlogPostHeader getPostHeader(MessageId m) throws DbException;
|
||||
BlogPostHeader getPostHeader(GroupId g, MessageId m) throws DbException;
|
||||
|
||||
/** Returns the body of the blog post with the given ID. */
|
||||
byte[] getPostBody(MessageId m) throws DbException;
|
||||
|
||||
@@ -9,19 +9,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlogPost extends ForumPost {
|
||||
|
||||
@Nullable
|
||||
private final String title;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTitle() {
|
||||
return title;
|
||||
public BlogPost(@NotNull Message message, @Nullable MessageId parent,
|
||||
@NotNull Author author) {
|
||||
super(message, parent, author);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.briarproject.api.blogs;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.data.BdfList;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -11,9 +13,30 @@ import java.security.GeneralSecurityException;
|
||||
|
||||
public interface BlogPostFactory {
|
||||
|
||||
BlogPost createBlogPost(@NotNull GroupId groupId, @Nullable String title,
|
||||
long timestamp, @Nullable MessageId parent,
|
||||
@NotNull LocalAuthor author, @NotNull String contentType,
|
||||
@NotNull byte[] body)
|
||||
BlogPost createBlogPost(@NotNull GroupId groupId, long timestamp,
|
||||
@Nullable MessageId parent, @NotNull LocalAuthor author,
|
||||
@NotNull String body)
|
||||
throws FormatException, GeneralSecurityException;
|
||||
|
||||
Message createBlogComment(GroupId groupId, LocalAuthor author,
|
||||
@Nullable String comment, MessageId originalId, MessageId wrappedId)
|
||||
throws FormatException, GeneralSecurityException;
|
||||
|
||||
/** Wraps a blog post */
|
||||
Message wrapPost(GroupId groupId, byte[] descriptor,
|
||||
long timestamp, BdfList body)
|
||||
throws FormatException;
|
||||
|
||||
/** Re-wraps a previously wrapped post */
|
||||
Message rewrapWrappedPost(GroupId groupId, BdfList body)
|
||||
throws FormatException;
|
||||
|
||||
/** Wraps a blog comment */
|
||||
Message wrapComment(GroupId groupId, byte[] descriptor,
|
||||
long timestamp, BdfList body, MessageId currentId)
|
||||
throws FormatException;
|
||||
|
||||
/** Re-wraps a previously wrapped comment */
|
||||
Message rewrapWrappedComment(GroupId groupId, BdfList body,
|
||||
MessageId currentId) throws FormatException;
|
||||
}
|
||||
|
||||
@@ -3,33 +3,45 @@ package org.briarproject.api.blogs;
|
||||
import org.briarproject.api.clients.PostHeader;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.Author.Status;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlogPostHeader extends PostHeader {
|
||||
|
||||
@Nullable
|
||||
private final String title;
|
||||
private final MessageType type;
|
||||
private final GroupId groupId;
|
||||
private final long timeReceived;
|
||||
|
||||
public BlogPostHeader(@Nullable String title, @NotNull MessageId id,
|
||||
long timestamp, long timeReceived, @NotNull Author author,
|
||||
@NotNull Status authorStatus, @NotNull String contentType,
|
||||
boolean read) {
|
||||
super(id, null, timestamp, author, authorStatus, contentType, read);
|
||||
public BlogPostHeader(@NotNull MessageType type, @NotNull GroupId groupId,
|
||||
@NotNull MessageId id, @Nullable MessageId parentId, long timestamp,
|
||||
long timeReceived, @NotNull Author author,
|
||||
@NotNull Status authorStatus, boolean read) {
|
||||
super(id, parentId, timestamp, author, authorStatus, read);
|
||||
|
||||
this.title = title;
|
||||
this.type = type;
|
||||
this.groupId = groupId;
|
||||
this.timeReceived = timeReceived;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTitle() {
|
||||
return title;
|
||||
public BlogPostHeader(@NotNull MessageType type, @NotNull GroupId groupId,
|
||||
@NotNull MessageId id, long timestamp, long timeReceived,
|
||||
@NotNull Author author, @NotNull Status authorStatus,
|
||||
boolean read) {
|
||||
this(type, groupId, id, null, timestamp, timeReceived, author,
|
||||
authorStatus, read);
|
||||
}
|
||||
|
||||
public MessageType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public long getTimeReceived() {
|
||||
return timeReceived;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ClientHelper {
|
||||
@@ -72,7 +73,7 @@ public interface ClientHelper {
|
||||
/**
|
||||
* Marks the given message as shared or unshared with other contacts.
|
||||
*/
|
||||
void setMessageShared(Transaction txn, Message m, boolean shared)
|
||||
void setMessageShared(Transaction txn, MessageId m, boolean shared)
|
||||
throws DbException;
|
||||
|
||||
byte[] toByteArray(BdfDictionary dictionary) throws FormatException;
|
||||
@@ -83,4 +84,9 @@ public interface ClientHelper {
|
||||
throws FormatException;
|
||||
|
||||
BdfList toList(byte[] b, int off, int len) throws FormatException;
|
||||
|
||||
BdfList toList(byte[] b) throws FormatException;
|
||||
|
||||
byte[] sign(BdfList toSign, byte[] privateKey)
|
||||
throws FormatException, GeneralSecurityException;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.briarproject.api.clients;
|
||||
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.Author.Status;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
public abstract class PostHeader {
|
||||
@@ -9,19 +10,16 @@ public abstract class PostHeader {
|
||||
private final MessageId parentId;
|
||||
private final long timestamp;
|
||||
private final Author author;
|
||||
private final Author.Status authorStatus;
|
||||
private final String contentType;
|
||||
private final Status authorStatus;
|
||||
private final boolean read;
|
||||
|
||||
public PostHeader(MessageId id, MessageId parentId, long timestamp,
|
||||
Author author, Author.Status authorStatus, String contentType,
|
||||
boolean read) {
|
||||
Author author, Status authorStatus, boolean read) {
|
||||
this.id = id;
|
||||
this.parentId = parentId;
|
||||
this.timestamp = timestamp;
|
||||
this.author = author;
|
||||
this.authorStatus = authorStatus;
|
||||
this.contentType = contentType;
|
||||
this.read = read;
|
||||
}
|
||||
|
||||
@@ -33,14 +31,10 @@ public abstract class PostHeader {
|
||||
return author;
|
||||
}
|
||||
|
||||
public Author.Status getAuthorStatus() {
|
||||
public Status getAuthorStatus() {
|
||||
return authorStatus;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ public interface DatabaseComponent {
|
||||
/**
|
||||
* Marks the given message as shared or unshared.
|
||||
*/
|
||||
void setMessageShared(Transaction txn, Message m, boolean shared)
|
||||
void setMessageShared(Transaction txn, MessageId m, boolean shared)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package org.briarproject.api.event;
|
||||
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
|
||||
/** An event that is broadcast when a message is shared. */
|
||||
public class MessageSharedEvent extends Event {
|
||||
|
||||
private final Message message;
|
||||
private final MessageId messageId;
|
||||
|
||||
public MessageSharedEvent(Message message) {
|
||||
this.message = message;
|
||||
public MessageSharedEvent(MessageId message) {
|
||||
this.messageId = message;
|
||||
}
|
||||
|
||||
public Message getMessage() {
|
||||
return message;
|
||||
public MessageId getMessageId() {
|
||||
return messageId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ public interface ForumConstants {
|
||||
String KEY_NAME = "name";
|
||||
String KEY_PUBLIC_NAME = "publicKey";
|
||||
String KEY_AUTHOR = "author";
|
||||
String KEY_CONTENT_TYPE = "contentType";
|
||||
String KEY_LOCAL = "local";
|
||||
String KEY_READ = "read";
|
||||
|
||||
|
||||
@@ -9,14 +9,11 @@ public class ForumPost {
|
||||
private final Message message;
|
||||
private final MessageId parent;
|
||||
private final Author author;
|
||||
private final String contentType;
|
||||
|
||||
public ForumPost(Message message, MessageId parent, Author author,
|
||||
String contentType) {
|
||||
public ForumPost(Message message, MessageId parent, Author author) {
|
||||
this.message = message;
|
||||
this.parent = parent;
|
||||
this.author = author;
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public Message getMessage() {
|
||||
@@ -30,8 +27,4 @@ public class ForumPost {
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,8 @@ public class ForumPostHeader extends PostHeader
|
||||
implements MessageTree.MessageNode {
|
||||
|
||||
public ForumPostHeader(MessageId id, MessageId parentId, long timestamp,
|
||||
Author author, Author.Status authorStatus, String contentType,
|
||||
boolean read) {
|
||||
super(id, parentId, timestamp, author, authorStatus, contentType, read);
|
||||
Author author, Author.Status authorStatus, boolean read) {
|
||||
super(id, parentId, timestamp, author, authorStatus, read);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user