Return actual private group message headers and bodies to the UI

This commit is contained in:
Torsten Grote
2016-10-20 17:54:52 -02:00
parent 2c8aaa215c
commit 349a34ffd8
6 changed files with 148 additions and 20 deletions

View File

@@ -3,19 +3,23 @@ package org.briarproject.api.privategroup;
import org.briarproject.api.clients.PostHeader;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class GroupMessageHeader extends PostHeader {
private final GroupId groupId;
public GroupMessageHeader(@NotNull GroupId groupId, @NotNull MessageId id,
public GroupMessageHeader(GroupId groupId, MessageId id,
@Nullable MessageId parentId, long timestamp,
@NotNull Author author, @NotNull Status authorStatus,
boolean read) {
Author author, Status authorStatus, boolean read) {
super(id, parentId, timestamp, author, authorStatus, read);
this.groupId = groupId;
}

View File

@@ -0,0 +1,21 @@
package org.briarproject.api.privategroup;
import org.briarproject.api.identity.Author;
import org.briarproject.api.nullsafety.NotNullByDefault;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
public class JoinMessageHeader extends GroupMessageHeader {
public JoinMessageHeader(GroupId groupId, MessageId id,
@Nullable MessageId parentId, long timestamp, Author author,
Author.Status authorStatus, boolean read) {
super(groupId, id, parentId, timestamp, author, authorStatus, read);
}
}

View File

@@ -8,6 +8,8 @@ interface Constants {
String KEY_TYPE = "type";
String KEY_TIMESTAMP = "timestamp";
String KEY_READ = MSG_KEY_READ;
String KEY_PARENT_ID = "parentId";
String KEY_AUTHOR_ID = "authorId";
String KEY_AUTHOR_NAME = "authorName";
String KEY_AUTHOR_PUBLIC_KEY = "authorPublicKey";

View File

@@ -6,6 +6,8 @@ import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.privategroup.MessageType;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
@@ -24,8 +26,10 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENG
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_ID;
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_NAME;
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_PUBLIC_KEY;
import static org.briarproject.privategroup.Constants.KEY_PARENT_ID;
import static org.briarproject.privategroup.Constants.KEY_READ;
import static org.briarproject.privategroup.Constants.KEY_TIMESTAMP;
import static org.briarproject.privategroup.Constants.KEY_TYPE;
@@ -33,12 +37,14 @@ import static org.briarproject.privategroup.Constants.KEY_TYPE;
class GroupMessageValidator extends BdfMessageValidator {
private final PrivateGroupFactory groupFactory;
private final AuthorFactory authorFactory;
GroupMessageValidator(PrivateGroupFactory groupFactory,
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
Clock clock) {
Clock clock, AuthorFactory authorFactory) {
super(clientHelper, metadataEncoder, clock);
this.groupFactory = groupFactory;
this.authorFactory = authorFactory;
}
@Override
@@ -179,6 +185,7 @@ class GroupMessageValidator extends BdfMessageValidator {
// Return the metadata and dependencies
BdfDictionary meta = new BdfDictionary();
if (parent_id != null) meta.put(KEY_PARENT_ID, parent_id);
return new BdfMessageContext(meta, dependencies);
}
@@ -186,6 +193,8 @@ class GroupMessageValidator extends BdfMessageValidator {
byte[] pubKey, long time) {
c.getDictionary().put(KEY_TIMESTAMP, time);
c.getDictionary().put(KEY_READ, false);
Author a = authorFactory.createAuthor(authorName, pubKey);
c.getDictionary().put(KEY_AUTHOR_ID, a.getId());
c.getDictionary().put(KEY_AUTHOR_NAME, authorName);
c.getDictionary().put(KEY_AUTHOR_PUBLIC_KEY, pubKey);
}

View File

@@ -9,9 +9,13 @@ import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.Author.Status;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.MessageType;
import org.briarproject.api.privategroup.JoinMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.PrivateGroupManager;
@@ -26,14 +30,23 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.api.identity.Author.Status.OURSELVES;
import static org.briarproject.api.privategroup.MessageType.JOIN;
import static org.briarproject.api.privategroup.MessageType.NEW_MEMBER;
import static org.briarproject.api.privategroup.MessageType.POST;
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_ID;
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_NAME;
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_PUBLIC_KEY;
import static org.briarproject.privategroup.Constants.KEY_PARENT_ID;
import static org.briarproject.privategroup.Constants.KEY_PREVIOUS_MSG_ID;
import static org.briarproject.privategroup.Constants.KEY_READ;
import static org.briarproject.privategroup.Constants.KEY_TIMESTAMP;
@@ -49,17 +62,19 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
+ "67657220627920546f727374656e2047"));
private final PrivateGroupFactory privateGroupFactory;
private final IdentityManager identityManager;
@Inject
PrivateGroupManagerImpl(ClientHelper clientHelper,
MetadataParser metadataParser, DatabaseComponent db,
PrivateGroupFactory privateGroupFactory) {
PrivateGroupFactory privateGroupFactory,
IdentityManager identityManager) {
super(db, clientHelper, metadataParser);
this.privateGroupFactory = privateGroupFactory;
this.identityManager = identityManager;
}
@NotNull
@Override
public ClientId getClientId() {
return CLIENT_ID;
@@ -85,14 +100,14 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
private void announceNewMember(Transaction txn, GroupMessage m)
throws DbException, FormatException {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TYPE, MessageType.NEW_MEMBER.getInt());
meta.put(KEY_TYPE, NEW_MEMBER.getInt());
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
}
private void joinPrivateGroup(Transaction txn, GroupMessage m)
throws DbException, FormatException {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TYPE, MessageType.JOIN.getInt());
meta.put(KEY_TYPE, JOIN.getInt());
addMessageMetadata(meta, m, true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
trackOutgoingMessage(txn, m.getMessage());
@@ -135,6 +150,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
clientHelper.mergeGroupMetadata(txn, g, d);
}
@Override
public long getMessageTimestamp(MessageId id) throws DbException {
try {
BdfDictionary d = clientHelper.getMessageMetadataAsDictionary(id);
@@ -150,7 +166,8 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
Transaction txn = db.startTransaction(false);
try {
BdfDictionary meta = new BdfDictionary();
meta.put(KEY_TYPE, MessageType.POST.getInt());
meta.put(KEY_TYPE, POST.getInt());
if (m.getParent() != null) meta.put(KEY_PARENT_ID, m.getParent());
addMessageMetadata(meta, m, true);
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
trackOutgoingMessage(txn, m.getMessage());
@@ -165,7 +182,6 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
m.getMessage().getTimestamp(), m.getMember(), OURSELVES, true);
}
@NotNull
@Override
public PrivateGroup getPrivateGroup(GroupId g) throws DbException {
PrivateGroup privateGroup;
@@ -179,7 +195,6 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
return privateGroup;
}
@NotNull
@Override
public PrivateGroup getPrivateGroup(Transaction txn, GroupId g)
throws DbException {
@@ -191,7 +206,6 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
}
}
@NotNull
@Override
public Collection<PrivateGroup> getPrivateGroups() throws DbException {
Collection<Group> groups;
@@ -219,18 +233,90 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
return false;
}
@NotNull
@Override
public String getMessageBody(MessageId m) throws DbException {
return "empty";
try {
// TODO remove
if (clientHelper.getMessageMetadataAsDictionary(m).getLong(KEY_TYPE) != POST.getInt())
return "new member joined";
// type(0), member_name(1), member_public_key(2), parent_id(3),
// previous_message_id(4), content(5), signature(6)
return clientHelper.getMessageAsList(m).getString(5);
} catch (FormatException e) {
throw new DbException(e);
}
}
@NotNull
@Override
public Collection<GroupMessageHeader> getHeaders(GroupId g)
throws DbException {
Collection<GroupMessageHeader> headers =
new ArrayList<GroupMessageHeader>();
Transaction txn = db.startTransaction(true);
try {
Map<MessageId, BdfDictionary> metadata =
clientHelper.getMessageMetadataAsDictionary(txn, g);
// get all authors we need to get the status for
Set<AuthorId> authors = new HashSet<AuthorId>();
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
BdfDictionary meta = entry.getValue();
if (meta.getLong(KEY_TYPE) == NEW_MEMBER.getInt())
continue;
byte[] idBytes = meta.getRaw(KEY_AUTHOR_ID);
authors.add(new AuthorId(idBytes));
}
// get statuses for all authors
Map<AuthorId, Status> statuses = new HashMap<AuthorId, Status>();
for (AuthorId id : authors) {
statuses.put(id, identityManager.getAuthorStatus(txn, id));
}
// Parse the metadata
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
BdfDictionary meta = entry.getValue();
if (meta.getLong(KEY_TYPE) == NEW_MEMBER.getInt())
continue;
headers.add(getGroupMessageHeader(txn, g, entry.getKey(), meta,
statuses));
}
txn.setComplete();
return headers;
} catch (FormatException e) {
throw new DbException(e);
} finally {
db.endTransaction(txn);
}
}
return Collections.emptyList();
private GroupMessageHeader getGroupMessageHeader(Transaction txn, GroupId g,
MessageId id, BdfDictionary meta, Map<AuthorId, Status> statuses)
throws DbException, FormatException {
MessageId parentId = null;
if (meta.containsKey(KEY_PARENT_ID)) {
parentId = new MessageId(meta.getRaw(KEY_PARENT_ID));
}
long timestamp = meta.getLong(KEY_TIMESTAMP);
AuthorId authorId = new AuthorId(meta.getRaw(KEY_AUTHOR_ID));
String name = meta.getString(KEY_AUTHOR_NAME);
byte[] publicKey = meta.getRaw(KEY_AUTHOR_PUBLIC_KEY);
Author author = new Author(authorId, name, publicKey);
Status status;
if (statuses.containsKey(authorId)) {
status = statuses.get(authorId);
} else {
status = identityManager.getAuthorStatus(txn, author.getId());
}
boolean read = meta.getBoolean(KEY_READ);
if (meta.getLong(KEY_TYPE) == JOIN.getInt()) {
return new JoinMessageHeader(g, id, parentId, timestamp, author,
status, read);
}
return new GroupMessageHeader(g, id, parentId, timestamp, author,
status, read);
}
@Override
@@ -251,6 +337,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
boolean read) {
meta.put(KEY_TIMESTAMP, m.getMessage().getTimestamp());
meta.put(KEY_READ, read);
meta.put(KEY_AUTHOR_ID, m.getMember().getId());
meta.put(KEY_AUTHOR_NAME, m.getMember().getName());
meta.put(KEY_AUTHOR_PUBLIC_KEY, m.getMember().getPublicKey());
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.privategroup;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.messaging.ConversationManager;
import org.briarproject.api.privategroup.GroupMessageFactory;
@@ -59,11 +60,15 @@ public class PrivateGroupModule {
GroupMessageValidator provideGroupMessageValidator(
PrivateGroupFactory groupFactory,
ValidationManager validationManager, ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock) {
MetadataEncoder metadataEncoder, Clock clock,
AuthorFactory authorFactory) {
GroupMessageValidator validator = new GroupMessageValidator(
groupFactory, clientHelper, metadataEncoder, clock);
groupFactory, clientHelper, metadataEncoder, clock,
authorFactory);
validationManager.registerMessageValidator(
PrivateGroupManagerImpl.CLIENT_ID, validator);
return validator;
}