Remove content-type and parentId from private messages

and turn them into a regular string.
This commit is contained in:
Torsten Grote
2016-10-27 13:30:34 -02:00
parent a18317e912
commit 78740a6942
18 changed files with 81 additions and 112 deletions

View File

@@ -8,12 +8,12 @@ import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.forum.ForumPostFactory; import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.messaging.MessagingConstants;
import org.briarproject.api.messaging.PrivateMessage; import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.briarproject.system.SystemModule; import org.briarproject.system.SystemModule;
import org.briarproject.util.StringUtils;
import org.junit.Test; import org.junit.Test;
import javax.inject.Inject; import javax.inject.Inject;
@@ -48,17 +48,14 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
// Create a maximum-length private message // Create a maximum-length private message
GroupId groupId = new GroupId(TestUtils.getRandomId()); GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE; long timestamp = Long.MAX_VALUE;
MessageId parent = new MessageId(TestUtils.getRandomId()); String body =
String contentType = TestUtils.getRandomString( StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
MessagingConstants.MAX_CONTENT_TYPE_LENGTH);
byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH];
PrivateMessage message = privateMessageFactory.createPrivateMessage( PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, parent, contentType, body); groupId, timestamp, body);
// Check the size of the serialised message // Check the size of the serialised message
int length = message.getMessage().getRaw().length; int length = message.getMessage().getRaw().length;
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH assertTrue(
+ MessagingConstants.MAX_CONTENT_TYPE_LENGTH length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH); assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
} }

View File

@@ -97,9 +97,9 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
// Send Bob a message // Send Bob a message
GroupId groupId = messagingManager.getConversationId(contactId); GroupId groupId = messagingManager.getConversationId(contactId);
byte[] body = "Hi Bob!".getBytes("UTF-8"); String body = "Hi Bob!";
PrivateMessage message = privateMessageFactory.createPrivateMessage( PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, null, "text/plain", body); groupId, timestamp, body);
messagingManager.addLocalMessage(message); messagingManager.addLocalMessage(message);
// Get a stream context // Get a stream context
StreamContext ctx = keyManager.getStreamContext(contactId, StreamContext ctx = keyManager.getStreamContext(contactId,

View File

@@ -450,11 +450,11 @@ public class ConversationActivity extends BriarActivity
public void run() { public void run() {
try { try {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
byte[] body = messagingManager.getMessageBody(m); String body = messagingManager.getMessageBody(m);
long duration = System.currentTimeMillis() - now; long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Loading body took " + duration + " ms"); LOG.info("Loading body took " + duration + " ms");
displayMessageBody(m, StringUtils.fromUtf8(body)); displayMessageBody(m, body);
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
@@ -656,8 +656,7 @@ public class ConversationActivity extends BriarActivity
public void run() { public void run() {
try { try {
storeMessage(privateMessageFactory.createPrivateMessage( storeMessage(privateMessageFactory.createPrivateMessage(
groupId, timestamp, null, "text/plain", groupId, timestamp, body), body);
StringUtils.toUtf8(body)), body);
} catch (FormatException e) { } catch (FormatException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@@ -676,9 +675,10 @@ public class ConversationActivity extends BriarActivity
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info("Storing message took " + duration + " ms"); LOG.info("Storing message took " + duration + " ms");
MessageId id = m.getMessage().getId(); MessageId id = m.getMessage().getId();
PrivateMessageHeader h = new PrivateMessageHeader(id, PrivateMessageHeader h =
groupId, m.getMessage().getTimestamp(), new PrivateMessageHeader(id, groupId,
m.getContentType(), true, false, false, false); m.getMessage().getTimestamp(), true, false,
false, false);
ConversationItem item = ConversationItem.from(h); ConversationItem item = ConversationItem.from(h);
item.setBody(body); item.setBody(body);
bodyCache.put(id, body); bodyCache.put(id, body);

View File

@@ -64,7 +64,7 @@ public abstract class BaseMessageFragment extends BaseFragment
@Override @Override
public void onSendClick(String msg) { public void onSendClick(String msg) {
if (StringUtils.isTooLong(msg, listener.getMaximumMessageLength())) { if (StringUtils.utf8IsTooLong(msg, listener.getMaximumMessageLength())) {
Snackbar.make(message, R.string.text_too_long, LENGTH_SHORT).show(); Snackbar.make(message, R.string.text_too_long, LENGTH_SHORT).show();
return; return;
} }

View File

@@ -232,7 +232,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
public void onSendClick(String text) { public void onSendClick(String text) {
if (text.trim().length() == 0) if (text.trim().length() == 0)
return; return;
if (StringUtils.isTooLong(text, getMaxBodyLength())) { if (StringUtils.utf8IsTooLong(text, getMaxBodyLength())) {
displaySnackbarShort(R.string.text_too_long); displaySnackbarShort(R.string.text_too_long);
return; return;
} }

View File

@@ -6,7 +6,7 @@ import android.support.annotation.CallSuper;
import org.briarproject.android.api.AndroidNotificationManager; import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.DbControllerImpl; import org.briarproject.android.controller.DbControllerImpl;
import org.briarproject.android.controller.handler.ResultExceptionHandler; import org.briarproject.android.controller.handler.ResultExceptionHandler;
import org.briarproject.api.clients.BaseMessage; import org.briarproject.api.clients.ThreadedMessage;
import org.briarproject.api.clients.NamedGroup; import org.briarproject.api.clients.NamedGroup;
import org.briarproject.api.clients.PostHeader; import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.crypto.CryptoExecutor; import org.briarproject.api.crypto.CryptoExecutor;
@@ -34,7 +34,7 @@ import java.util.logging.Logger;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends BaseMessage> public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends ThreadItem, H extends PostHeader, M extends ThreadedMessage>
extends DbControllerImpl extends DbControllerImpl
implements ThreadListController<G, I, H>, EventListener { implements ThreadListController<G, I, H>, EventListener {

View File

@@ -1,5 +1,7 @@
package org.briarproject.api.clients; package org.briarproject.api.clients;
import org.briarproject.api.identity.Author;
import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
@@ -9,19 +11,17 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public abstract class BaseMessage { public abstract class ThreadedMessage extends PrivateMessage {
private final Message message;
@Nullable @Nullable
private final MessageId parent; private final MessageId parent;
private final Author author;
public BaseMessage(Message message, @Nullable MessageId parent) { public ThreadedMessage(Message message, @Nullable MessageId parent,
this.message = message; Author author) {
super(message);
this.parent = parent; this.parent = parent;
} this.author = author;
public Message getMessage() {
return message;
} }
@Nullable @Nullable
@@ -29,4 +29,8 @@ public abstract class BaseMessage {
return parent; return parent;
} }
public Author getAuthor() {
return author;
}
} }

View File

@@ -1,26 +1,21 @@
package org.briarproject.api.forum; package org.briarproject.api.forum;
import org.briarproject.api.clients.BaseMessage; import org.briarproject.api.clients.ThreadedMessage;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class ForumPost extends BaseMessage { import javax.annotation.concurrent.Immutable;
@Nullable @Immutable
private final Author author; @NotNullByDefault
public class ForumPost extends ThreadedMessage {
public ForumPost(@NotNull Message message, @Nullable MessageId parent, public ForumPost(Message message, @Nullable MessageId parent,
@Nullable Author author) { Author author) {
super(message, parent); super(message, parent, author);
this.author = author;
}
@Nullable
public Author getAuthor() {
return author;
} }
} }

View File

@@ -30,6 +30,6 @@ public interface MessagingManager extends MessageTracker {
throws DbException; throws DbException;
/** Returns the body of the private message with the given ID. */ /** Returns the body of the private message with the given ID. */
byte[] getMessageBody(MessageId m) throws DbException; String getMessageBody(MessageId m) throws DbException;
} }

View File

@@ -1,23 +1,22 @@
package org.briarproject.api.messaging; package org.briarproject.api.messaging;
import org.briarproject.api.clients.BaseMessage; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PrivateMessage extends BaseMessage { import javax.annotation.concurrent.Immutable;
private final String contentType; @Immutable
@NotNullByDefault
public class PrivateMessage {
public PrivateMessage(@NotNull Message message, @Nullable MessageId parent, private final Message message;
@NotNull String contentType) {
super(message, parent); public PrivateMessage(Message message) {
this.contentType = contentType; this.message = message;
} }
public String getContentType() { public Message getMessage() {
return contentType; return message;
} }
} }

View File

@@ -1,12 +1,13 @@
package org.briarproject.api.messaging; package org.briarproject.api.messaging;
import org.briarproject.api.FormatException; import org.briarproject.api.FormatException;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
@NotNullByDefault
public interface PrivateMessageFactory { public interface PrivateMessageFactory {
PrivateMessage createPrivateMessage(GroupId groupId, long timestamp, PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
MessageId parent, String contentType, byte[] body) String body) throws FormatException;
throws FormatException;
} }

View File

@@ -6,17 +6,10 @@ import org.briarproject.api.sync.MessageId;
public class PrivateMessageHeader extends BaseMessageHeader { public class PrivateMessageHeader extends BaseMessageHeader {
private final String contentType;
public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp, public PrivateMessageHeader(MessageId id, GroupId groupId, long timestamp,
String contentType, boolean local, boolean read, boolean sent, boolean local, boolean read, boolean sent, boolean seen) {
boolean seen) {
super(id, groupId, timestamp, local, read, sent, seen); super(id, groupId, timestamp, local, read, sent, seen);
this.contentType = contentType;
} }
public String getContentType() {
return contentType;
}
} }

View File

@@ -1,6 +1,6 @@
package org.briarproject.api.privategroup; package org.briarproject.api.privategroup;
import org.briarproject.api.clients.BaseMessage; import org.briarproject.api.clients.ThreadedMessage;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.nullsafety.NotNullByDefault; import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
@@ -11,18 +11,15 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class GroupMessage extends BaseMessage { public class GroupMessage extends ThreadedMessage {
private final Author member;
public GroupMessage(Message message, @Nullable MessageId parent, public GroupMessage(Message message, @Nullable MessageId parent,
Author member) { Author member) {
super(message, parent); super(message, parent, member);
this.member = member;
} }
public Author getMember() { public Author getMember() {
return member; return super.getAuthor();
} }
} }

View File

@@ -31,7 +31,7 @@ class ForumPostFactoryImpl implements ForumPostFactory {
MessageId parent, LocalAuthor author, String body) MessageId parent, LocalAuthor author, String body)
throws FormatException, GeneralSecurityException { throws FormatException, GeneralSecurityException {
// Validate the arguments // Validate the arguments
if (StringUtils.isTooLong(body, MAX_FORUM_POST_BODY_LENGTH)) if (StringUtils.utf8IsTooLong(body, MAX_FORUM_POST_BODY_LENGTH))
throw new IllegalArgumentException(); throw new IllegalArgumentException();
// Serialise the data to be signed // Serialise the data to be signed
BdfList authorList = BdfList authorList =

View File

@@ -98,12 +98,10 @@ class MessagingManagerImpl extends ConversationClientImpl
GroupId groupId = m.getGroupId(); GroupId groupId = m.getGroupId();
long timestamp = meta.getLong("timestamp"); long timestamp = meta.getLong("timestamp");
String contentType = meta.getString("contentType");
boolean local = meta.getBoolean("local"); boolean local = meta.getBoolean("local");
boolean read = meta.getBoolean(MSG_KEY_READ); boolean read = meta.getBoolean(MSG_KEY_READ);
PrivateMessageHeader header = new PrivateMessageHeader( PrivateMessageHeader header = new PrivateMessageHeader(
m.getId(), groupId, timestamp, contentType, local, read, m.getId(), groupId, timestamp, local, read, false, false);
false, false);
ContactId contactId = getContactId(txn, groupId); ContactId contactId = getContactId(txn, groupId);
PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent( PrivateMessageReceivedEvent event = new PrivateMessageReceivedEvent(
header, contactId, groupId); header, contactId, groupId);
@@ -120,8 +118,6 @@ class MessagingManagerImpl extends ConversationClientImpl
try { try {
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put("timestamp", m.getMessage().getTimestamp()); meta.put("timestamp", m.getMessage().getTimestamp());
if (m.getParent() != null) meta.put("parent", m.getParent());
meta.put("contentType", m.getContentType());
meta.put("local", true); meta.put("local", true);
meta.put("read", true); meta.put("read", true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true); clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
@@ -193,11 +189,11 @@ class MessagingManagerImpl extends ConversationClientImpl
if (meta == null) continue; if (meta == null) continue;
try { try {
long timestamp = meta.getLong("timestamp"); long timestamp = meta.getLong("timestamp");
String contentType = meta.getString("contentType");
boolean local = meta.getBoolean("local"); boolean local = meta.getBoolean("local");
boolean read = meta.getBoolean("read"); boolean read = meta.getBoolean("read");
headers.add(new PrivateMessageHeader(id, g, timestamp, headers.add(
contentType, local, read, s.isSent(), s.isSeen())); new PrivateMessageHeader(id, g, timestamp, local, read,
s.isSent(), s.isSeen()));
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }
@@ -206,11 +202,11 @@ class MessagingManagerImpl extends ConversationClientImpl
} }
@Override @Override
public byte[] getMessageBody(MessageId m) throws DbException { public String getMessageBody(MessageId m) throws DbException {
try { try {
// Parent ID, content type, private message body // 0: private message body
BdfList message = clientHelper.getMessageAsList(m); BdfList message = clientHelper.getMessageAsList(m);
return message.getRaw(2); return message.getString(0);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -5,16 +5,16 @@ import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfList; import org.briarproject.api.data.BdfList;
import org.briarproject.api.messaging.PrivateMessage; import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message; import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageId;
import org.briarproject.util.StringUtils;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
import static org.briarproject.util.StringUtils.utf8IsTooLong;
@NotNullByDefault
class PrivateMessageFactoryImpl implements PrivateMessageFactory { class PrivateMessageFactoryImpl implements PrivateMessageFactory {
private final ClientHelper clientHelper; private final ClientHelper clientHelper;
@@ -26,16 +26,13 @@ class PrivateMessageFactoryImpl implements PrivateMessageFactory {
@Override @Override
public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp, public PrivateMessage createPrivateMessage(GroupId groupId, long timestamp,
MessageId parent, String contentType, byte[] body) String body) throws FormatException {
throws FormatException {
// Validate the arguments // Validate the arguments
if (StringUtils.toUtf8(contentType).length > MAX_CONTENT_TYPE_LENGTH) if (utf8IsTooLong(body, MAX_PRIVATE_MESSAGE_BODY_LENGTH))
throw new IllegalArgumentException();
if (body.length > MAX_PRIVATE_MESSAGE_BODY_LENGTH)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
// Serialise the message // Serialise the message
BdfList message = BdfList.of(parent, contentType, body); BdfList message = BdfList.of(body);
Message m = clientHelper.createMessage(groupId, timestamp, message); Message m = clientHelper.createMessage(groupId, timestamp, message);
return new PrivateMessage(m, parent, contentType); return new PrivateMessage(m);
} }
} }

View File

@@ -1,9 +1,8 @@
package org.briarproject.messaging; package org.briarproject.messaging;
import org.briarproject.api.FormatException; import org.briarproject.api.FormatException;
import org.briarproject.api.UniqueId;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.BdfMessageContext; import org.briarproject.api.clients.BdfMessageContext;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList; import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder; import org.briarproject.api.data.MetadataEncoder;
@@ -12,7 +11,6 @@ import org.briarproject.api.sync.Message;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.clients.BdfMessageValidator; import org.briarproject.clients.BdfMessageValidator;
import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE_LENGTH;
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH; import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
import static org.briarproject.clients.BdfConstants.MSG_KEY_READ; import static org.briarproject.clients.BdfConstants.MSG_KEY_READ;
@@ -26,22 +24,14 @@ class PrivateMessageValidator extends BdfMessageValidator {
@Override @Override
protected BdfMessageContext validateMessage(Message m, Group g, protected BdfMessageContext validateMessage(Message m, Group g,
BdfList body) throws FormatException { BdfList body) throws FormatException {
// Parent ID, content type, private message body // private message body
checkSize(body, 3); checkSize(body, 1);
// Parent ID is optional
byte[] parentId = body.getOptionalRaw(0);
checkLength(parentId, UniqueId.LENGTH);
// Content type
String contentType = body.getString(1);
checkLength(contentType, 0, MAX_CONTENT_TYPE_LENGTH);
// Private message body // Private message body
byte[] privateMessageBody = body.getRaw(2); String privateMessageBody = body.getString(0);
checkLength(privateMessageBody, 0, MAX_PRIVATE_MESSAGE_BODY_LENGTH); checkLength(privateMessageBody, 0, MAX_PRIVATE_MESSAGE_BODY_LENGTH);
// Return the metadata // Return the metadata
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put("timestamp", m.getTimestamp()); meta.put("timestamp", m.getTimestamp());
if (parentId != null) meta.put("parent", parentId);
meta.put("contentType", contentType);
meta.put("local", false); meta.put("local", false);
meta.put(MSG_KEY_READ, false); meta.put(MSG_KEY_READ, false);
return new BdfMessageContext(meta); return new BdfMessageContext(meta);

View File

@@ -104,7 +104,7 @@ public class StringUtils {
/** /**
* Returns true if the string is longer than maxLength * Returns true if the string is longer than maxLength
*/ */
public static boolean isTooLong(String s, int maxLength) { public static boolean utf8IsTooLong(String s, int maxLength) {
return toUtf8(s).length > maxLength; return toUtf8(s).length > maxLength;
} }
} }