mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
Address review comments
This commit is contained in:
@@ -72,6 +72,7 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
|||||||
private LocalAuthor author0, author1;
|
private LocalAuthor author0, author1;
|
||||||
private PrivateGroup privateGroup0;
|
private PrivateGroup privateGroup0;
|
||||||
private GroupId groupId0;
|
private GroupId groupId0;
|
||||||
|
private GroupMessage newMemberMsg0;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Clock clock;
|
Clock clock;
|
||||||
@@ -221,6 +222,20 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
|||||||
|
|
||||||
// assert that message did not arrive
|
// assert that message did not arrive
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
||||||
|
|
||||||
|
// create and add test message with previousMsgId of newMemberMsg
|
||||||
|
previousMsgId = newMemberMsg0.getMessage().getId();
|
||||||
|
msg = groupMessageFactory
|
||||||
|
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
|
||||||
|
author0, "test", previousMsgId);
|
||||||
|
groupManager0.addLocalMessage(msg);
|
||||||
|
|
||||||
|
// sync test message
|
||||||
|
sync0To1();
|
||||||
|
validationWaiter.await(TIMEOUT, 1);
|
||||||
|
|
||||||
|
// assert that message did not arrive
|
||||||
|
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -437,13 +452,13 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
|||||||
private void addGroup() throws Exception {
|
private void addGroup() throws Exception {
|
||||||
// author0 joins privateGroup0
|
// author0 joins privateGroup0
|
||||||
long joinTime = clock.currentTimeMillis();
|
long joinTime = clock.currentTimeMillis();
|
||||||
GroupMessage newMemberMsg = groupMessageFactory
|
newMemberMsg0 = groupMessageFactory
|
||||||
.createNewMemberMessage(privateGroup0.getId(), joinTime,
|
.createNewMemberMessage(privateGroup0.getId(), joinTime,
|
||||||
author0, author0);
|
author0, author0);
|
||||||
GroupMessage joinMsg = groupMessageFactory
|
GroupMessage joinMsg = groupMessageFactory
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
|
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
|
||||||
newMemberMsg.getMessage().getId());
|
newMemberMsg0.getMessage().getId());
|
||||||
groupManager0.addPrivateGroup(privateGroup0, newMemberMsg, joinMsg);
|
groupManager0.addPrivateGroup(privateGroup0, newMemberMsg0, joinMsg);
|
||||||
assertEquals(joinMsg.getMessage().getId(),
|
assertEquals(joinMsg.getMessage().getId(),
|
||||||
groupManager0.getPreviousMsgId(groupId0));
|
groupManager0.getPreviousMsgId(groupId0));
|
||||||
|
|
||||||
@@ -457,13 +472,13 @@ public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
|||||||
|
|
||||||
// author1 joins privateGroup0
|
// author1 joins privateGroup0
|
||||||
joinTime = clock.currentTimeMillis();
|
joinTime = clock.currentTimeMillis();
|
||||||
newMemberMsg = groupMessageFactory
|
GroupMessage newMemberMsg1 = groupMessageFactory
|
||||||
.createNewMemberMessage(privateGroup0.getId(), joinTime,
|
.createNewMemberMessage(privateGroup0.getId(), joinTime,
|
||||||
author0, author1);
|
author0, author1);
|
||||||
joinMsg = groupMessageFactory
|
joinMsg = groupMessageFactory
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
|
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
|
||||||
newMemberMsg.getMessage().getId());
|
newMemberMsg1.getMessage().getId());
|
||||||
groupManager1.addPrivateGroup(privateGroup0, newMemberMsg, joinMsg);
|
groupManager1.addPrivateGroup(privateGroup0, newMemberMsg1, joinMsg);
|
||||||
assertEquals(joinMsg.getMessage().getId(),
|
assertEquals(joinMsg.getMessage().getId(),
|
||||||
groupManager1.getPreviousMsgId(groupId0));
|
groupManager1.getPreviousMsgId(groupId0));
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.briarproject.db.DatabaseModule;
|
|||||||
import org.briarproject.event.EventModule;
|
import org.briarproject.event.EventModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.privategroup.PrivateGroupModule;
|
import org.briarproject.privategroup.PrivateGroupModule;
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
@@ -37,6 +38,7 @@ import dagger.Component;
|
|||||||
DataModule.class,
|
DataModule.class,
|
||||||
DatabaseModule.class,
|
DatabaseModule.class,
|
||||||
EventModule.class,
|
EventModule.class,
|
||||||
|
MessagingModule.class,
|
||||||
PrivateGroupModule.class,
|
PrivateGroupModule.class,
|
||||||
IdentityModule.class,
|
IdentityModule.class,
|
||||||
LifecycleModule.class,
|
LifecycleModule.class,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.briarproject.android.privategroup.conversation;
|
|||||||
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.briarproject.R;
|
|
||||||
import org.briarproject.android.api.AndroidNotificationManager;
|
import org.briarproject.android.api.AndroidNotificationManager;
|
||||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||||
import org.briarproject.android.threaded.ThreadListControllerImpl;
|
import org.briarproject.android.threaded.ThreadListControllerImpl;
|
||||||
@@ -95,8 +94,8 @@ public class GroupControllerImpl extends
|
|||||||
protected String loadMessageBody(GroupMessageHeader header)
|
protected String loadMessageBody(GroupMessageHeader header)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
if (header instanceof JoinMessageHeader) {
|
if (header instanceof JoinMessageHeader) {
|
||||||
return listener.getApplicationContext()
|
// will be looked up later
|
||||||
.getString(R.string.groups_member_joined);
|
return "";
|
||||||
}
|
}
|
||||||
return privateGroupManager.getMessageBody(header.getId());
|
return privateGroupManager.getMessageBody(header.getId());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.android.privategroup.conversation;
|
package org.briarproject.android.privategroup.conversation;
|
||||||
|
|
||||||
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -19,12 +20,11 @@ public class GroupMessageAdapter extends ThreadItemAdapter<GroupMessageItem> {
|
|||||||
super(listener, layoutManager);
|
super(listener, layoutManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@LayoutRes
|
||||||
@Override
|
@Override
|
||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
GroupMessageItem item = getVisibleItem(position);
|
GroupMessageItem item = getVisibleItem(position);
|
||||||
if (item instanceof JoinMessageItem) {
|
if (item != null) return item.getLayout();
|
||||||
return R.layout.list_item_thread_notice;
|
|
||||||
}
|
|
||||||
return R.layout.list_item_thread;
|
return R.layout.list_item_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class GroupMessageAdapter extends ThreadItemAdapter<GroupMessageItem> {
|
|||||||
View v = LayoutInflater.from(parent.getContext())
|
View v = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(type, parent, false);
|
.inflate(type, parent, false);
|
||||||
if (type == R.layout.list_item_thread_notice) {
|
if (type == R.layout.list_item_thread_notice) {
|
||||||
return new BaseThreadItemViewHolder<>(v);
|
return new JoinMessageItemHolder(v);
|
||||||
}
|
}
|
||||||
return new ThreadItemViewHolder<>(v);
|
return new ThreadItemViewHolder<>(v);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
package org.briarproject.android.privategroup.conversation;
|
package org.briarproject.android.privategroup.conversation;
|
||||||
|
|
||||||
|
import android.support.annotation.LayoutRes;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.threaded.ThreadItem;
|
import org.briarproject.android.threaded.ThreadItem;
|
||||||
import org.briarproject.api.identity.Author;
|
import org.briarproject.api.identity.Author;
|
||||||
import org.briarproject.api.identity.Author.Status;
|
import org.briarproject.api.identity.Author.Status;
|
||||||
import org.briarproject.api.privategroup.GroupMessageHeader;
|
import org.briarproject.api.privategroup.GroupMessageHeader;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotThreadSafe
|
||||||
class GroupMessageItem extends ThreadItem {
|
class GroupMessageItem extends ThreadItem {
|
||||||
|
|
||||||
private GroupMessageItem(MessageId messageId, MessageId parentId,
|
private GroupMessageItem(MessageId messageId, MessageId parentId,
|
||||||
@@ -19,4 +27,9 @@ class GroupMessageItem extends ThreadItem {
|
|||||||
h.getAuthorStatus(), h.isRead());
|
h.getAuthorStatus(), h.isRead());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@LayoutRes
|
||||||
|
public int getLayout() {
|
||||||
|
return R.layout.list_item_thread;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
package org.briarproject.android.privategroup.conversation;
|
package org.briarproject.android.privategroup.conversation;
|
||||||
|
|
||||||
|
import android.support.annotation.LayoutRes;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
import org.briarproject.api.privategroup.GroupMessageHeader;
|
import org.briarproject.api.privategroup.GroupMessageHeader;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotThreadSafe
|
||||||
class JoinMessageItem extends GroupMessageItem {
|
class JoinMessageItem extends GroupMessageItem {
|
||||||
|
|
||||||
JoinMessageItem(GroupMessageHeader h,
|
JoinMessageItem(GroupMessageHeader h,
|
||||||
@@ -19,4 +27,9 @@ class JoinMessageItem extends GroupMessageItem {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@LayoutRes
|
||||||
|
public int getLayout() {
|
||||||
|
return R.layout.list_item_thread_notice;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package org.briarproject.android.privategroup.conversation;
|
||||||
|
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.threaded.BaseThreadItemViewHolder;
|
||||||
|
import org.briarproject.android.threaded.ThreadItemAdapter;
|
||||||
|
import org.briarproject.android.threaded.ThreadItemAdapter.ThreadItemListener;
|
||||||
|
import org.briarproject.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
public class JoinMessageItemHolder
|
||||||
|
extends BaseThreadItemViewHolder<GroupMessageItem> {
|
||||||
|
|
||||||
|
public JoinMessageItemHolder(View v) {
|
||||||
|
super(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(final ThreadItemAdapter<GroupMessageItem> adapter,
|
||||||
|
final ThreadItemListener<GroupMessageItem> listener,
|
||||||
|
final GroupMessageItem item, int pos) {
|
||||||
|
super.bind(adapter, listener, item, pos);
|
||||||
|
|
||||||
|
textView.setText(getContext().getString(R.string.groups_member_joined));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,13 +21,13 @@ import org.briarproject.util.StringUtils;
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class BaseThreadItemViewHolder<I extends ThreadItem>
|
public abstract class BaseThreadItemViewHolder<I extends ThreadItem>
|
||||||
extends RecyclerView.ViewHolder {
|
extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
private final static int ANIMATION_DURATION = 5000;
|
private final static int ANIMATION_DURATION = 5000;
|
||||||
|
|
||||||
|
protected final TextView textView;
|
||||||
private final ViewGroup layout;
|
private final ViewGroup layout;
|
||||||
private final TextView textView;
|
|
||||||
private final AuthorView author;
|
private final AuthorView author;
|
||||||
private final View topDivider;
|
private final View topDivider;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package org.briarproject.android.threaded;
|
package org.briarproject.android.threaded;
|
||||||
|
|
||||||
import android.support.annotation.UiThread;
|
|
||||||
|
|
||||||
import org.briarproject.api.clients.MessageTree.MessageNode;
|
import org.briarproject.api.clients.MessageTree.MessageNode;
|
||||||
import org.briarproject.api.identity.Author;
|
import org.briarproject.api.identity.Author;
|
||||||
import org.briarproject.api.identity.Author.Status;
|
import org.briarproject.api.identity.Author.Status;
|
||||||
@@ -11,7 +9,6 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
|
|
||||||
import static org.briarproject.android.threaded.ThreadItemAdapter.UNDEFINED;
|
import static org.briarproject.android.threaded.ThreadItemAdapter.UNDEFINED;
|
||||||
|
|
||||||
@UiThread
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
public abstract class ThreadItem implements MessageNode {
|
public abstract class ThreadItem implements MessageNode {
|
||||||
|
|
||||||
@@ -97,4 +94,5 @@ public abstract class ThreadItem implements MessageNode {
|
|||||||
public void setDescendantCount(int descendantCount) {
|
public void setDescendantCount(int descendantCount) {
|
||||||
this.descendantCount = descendantCount;
|
this.descendantCount = descendantCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ public class ThreadItemAdapter<I extends ThreadItem>
|
|||||||
revision++;
|
revision++;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected interface ThreadItemListener<I> {
|
public interface ThreadItemListener<I> {
|
||||||
|
|
||||||
void onItemVisible(I item);
|
void onItemVisible(I item);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.android.threaded;
|
package org.briarproject.android.threaded;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
@@ -40,8 +39,6 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void onGroupRemoved();
|
void onGroupRemoved();
|
||||||
|
|
||||||
Context getApplicationContext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
Logger.getLogger(ThreadListControllerImpl.class.getName());
|
Logger.getLogger(ThreadListControllerImpl.class.getName());
|
||||||
|
|
||||||
protected final IdentityManager identityManager;
|
protected final IdentityManager identityManager;
|
||||||
@CryptoExecutor
|
|
||||||
protected final Executor cryptoExecutor;
|
protected final Executor cryptoExecutor;
|
||||||
protected final AndroidNotificationManager notificationManager;
|
protected final AndroidNotificationManager notificationManager;
|
||||||
protected final Clock clock;
|
protected final Clock clock;
|
||||||
|
|||||||
@@ -84,6 +84,6 @@ public interface ClientHelper {
|
|||||||
throws FormatException, GeneralSecurityException;
|
throws FormatException, GeneralSecurityException;
|
||||||
|
|
||||||
void verifySignature(byte[] sig, byte[] publicKey, BdfList signed)
|
void verifySignature(byte[] sig, byte[] publicKey, BdfList signed)
|
||||||
throws InvalidMessageException;
|
throws FormatException, GeneralSecurityException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,16 +12,8 @@ public enum MessageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MessageType valueOf(int value) {
|
public static MessageType valueOf(int value) {
|
||||||
switch (value) {
|
for (MessageType m : values()) if (m.value == value) return m;
|
||||||
case 0:
|
throw new IllegalArgumentException();
|
||||||
return NEW_MEMBER;
|
|
||||||
case 1:
|
|
||||||
return JOIN;
|
|
||||||
case 2:
|
|
||||||
return POST;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt() {
|
public int getInt() {
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ public interface PrivateGroupManager extends MessageTracker {
|
|||||||
* Adds a new private group and joins it.
|
* Adds a new private group and joins it.
|
||||||
*
|
*
|
||||||
* @param group The private group to add
|
* @param group The private group to add
|
||||||
* @param newMemberMsg The creator's message announcing the first new member
|
* @param newMemberMsg The creator's message announcing herself as
|
||||||
* @param joinMsg The first new member's join message
|
* first new member
|
||||||
|
* @param joinMsg The creator's own join message
|
||||||
*/
|
*/
|
||||||
void addPrivateGroup(PrivateGroup group, GroupMessage newMemberMsg,
|
void addPrivateGroup(PrivateGroup group, GroupMessage newMemberMsg,
|
||||||
GroupMessage joinMsg) throws DbException;
|
GroupMessage joinMsg) throws DbException;
|
||||||
@@ -27,10 +28,11 @@ public interface PrivateGroupManager extends MessageTracker {
|
|||||||
/** Removes a dissolved private group. */
|
/** Removes a dissolved private group. */
|
||||||
void removePrivateGroup(GroupId g) throws DbException;
|
void removePrivateGroup(GroupId g) throws DbException;
|
||||||
|
|
||||||
/** Gets the MessageId of the */
|
/** Gets the MessageId of your previous message sent to the group */
|
||||||
MessageId getPreviousMsgId(GroupId g) throws DbException;
|
MessageId getPreviousMsgId(GroupId g) throws DbException;
|
||||||
|
|
||||||
/** Returns the timestamp of the message with the given ID */
|
/** Returns the timestamp of the message with the given ID */
|
||||||
|
// TODO change to getPreviousMessageHeader()
|
||||||
long getMessageTimestamp(MessageId id) throws DbException;
|
long getMessageTimestamp(MessageId id) throws DbException;
|
||||||
|
|
||||||
/** Stores (and sends) a local group message. */
|
/** Stores (and sends) a local group message. */
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.briarproject.api.sync.MessageId;
|
|||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.clients.BdfMessageValidator;
|
import org.briarproject.clients.BdfMessageValidator;
|
||||||
|
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@@ -101,7 +102,11 @@ class BlogPostValidator extends BdfMessageValidator {
|
|||||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), postBody);
|
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), postBody);
|
||||||
Blog b = blogFactory.parseBlog(g, ""); // description doesn't matter
|
Blog b = blogFactory.parseBlog(g, ""); // description doesn't matter
|
||||||
Author a = b.getAuthor();
|
Author a = b.getAuthor();
|
||||||
clientHelper.verifySignature(sig, a.getPublicKey(), signed);
|
try {
|
||||||
|
clientHelper.verifySignature(sig, a.getPublicKey(), signed);
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new InvalidMessageException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the metadata and dependencies
|
// Return the metadata and dependencies
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
@@ -142,7 +147,11 @@ class BlogPostValidator extends BdfMessageValidator {
|
|||||||
currentId);
|
currentId);
|
||||||
Blog b = blogFactory.parseBlog(g, ""); // description doesn't matter
|
Blog b = blogFactory.parseBlog(g, ""); // description doesn't matter
|
||||||
Author a = b.getAuthor();
|
Author a = b.getAuthor();
|
||||||
clientHelper.verifySignature(sig, a.getPublicKey(), signed);
|
try {
|
||||||
|
clientHelper.verifySignature(sig, a.getPublicKey(), signed);
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new InvalidMessageException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the metadata and dependencies
|
// Return the metadata and dependencies
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import org.briarproject.api.db.DbException;
|
|||||||
import org.briarproject.api.db.Metadata;
|
import org.briarproject.api.db.Metadata;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.InvalidMessageException;
|
|
||||||
import org.briarproject.api.sync.Message;
|
import org.briarproject.api.sync.Message;
|
||||||
import org.briarproject.api.sync.MessageFactory;
|
import org.briarproject.api.sync.MessageFactory;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
@@ -325,22 +324,16 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void verifySignature(byte[] sig, byte[] publicKey, BdfList signed)
|
public void verifySignature(byte[] sig, byte[] publicKey, BdfList signed)
|
||||||
throws InvalidMessageException {
|
throws FormatException, GeneralSecurityException {
|
||||||
try {
|
// Parse the public key
|
||||||
// Parse the public key
|
KeyParser keyParser = cryptoComponent.getSignatureKeyParser();
|
||||||
KeyParser keyParser = cryptoComponent.getSignatureKeyParser();
|
PublicKey key = keyParser.parsePublicKey(publicKey);
|
||||||
PublicKey key = keyParser.parsePublicKey(publicKey);
|
// Verify the signature
|
||||||
// Verify the signature
|
Signature signature = cryptoComponent.getSignature();
|
||||||
Signature signature = cryptoComponent.getSignature();
|
signature.initVerify(key);
|
||||||
signature.initVerify(key);
|
signature.update(toByteArray(signed));
|
||||||
signature.update(toByteArray(signed));
|
if (!signature.verify(sig)) {
|
||||||
if (!signature.verify(sig)) {
|
throw new GeneralSecurityException("Invalid signature");
|
||||||
throw new InvalidMessageException("Invalid signature");
|
|
||||||
}
|
|
||||||
} catch (GeneralSecurityException e) {
|
|
||||||
throw new InvalidMessageException("Invalid public key");
|
|
||||||
} catch (FormatException e) {
|
|
||||||
throw new InvalidMessageException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.briarproject.api.sync.MessageId;
|
|||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.clients.BdfMessageValidator;
|
import org.briarproject.clients.BdfMessageValidator;
|
||||||
|
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@@ -73,10 +74,15 @@ class ForumPostValidator extends BdfMessageValidator {
|
|||||||
}
|
}
|
||||||
// Verify the signature, if any
|
// Verify the signature, if any
|
||||||
if (author != null) {
|
if (author != null) {
|
||||||
// Serialise the data to be signed
|
// Serialise the data to be verified
|
||||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), parent,
|
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), parent,
|
||||||
authorList, contentType, forumPostBody);
|
authorList, contentType, forumPostBody);
|
||||||
clientHelper.verifySignature(sig, author.getPublicKey(), signed);
|
try {
|
||||||
|
clientHelper
|
||||||
|
.verifySignature(sig, author.getPublicKey(), signed);
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new InvalidMessageException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Return the metadata and dependencies
|
// Return the metadata and dependencies
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ interface Constants {
|
|||||||
String KEY_PARENT_MSG_ID = "parentMsgId";
|
String KEY_PARENT_MSG_ID = "parentMsgId";
|
||||||
String KEY_NEW_MEMBER_MSG_ID = "newMemberMsgId";
|
String KEY_NEW_MEMBER_MSG_ID = "newMemberMsgId";
|
||||||
String KEY_PREVIOUS_MSG_ID = "previousMsgId";
|
String KEY_PREVIOUS_MSG_ID = "previousMsgId";
|
||||||
String KEY_AUTHOR_ID = "authorId";
|
String KEY_MEMBER_ID = "memberId";
|
||||||
String KEY_AUTHOR_NAME = "authorName";
|
String KEY_MEMBER_NAME = "memberName";
|
||||||
String KEY_AUTHOR_PUBLIC_KEY = "authorPublicKey";
|
String KEY_MEMBER_PUBLIC_KEY = "memberPublicKey";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,14 +36,15 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
|
|||||||
LocalAuthor creator, Author member) {
|
LocalAuthor creator, Author member) {
|
||||||
try {
|
try {
|
||||||
// Generate the signature
|
// Generate the signature
|
||||||
BdfList toSign = BdfList.of(groupId, timestamp, member.getName(),
|
int type = NEW_MEMBER.getInt();
|
||||||
member.getPublicKey());
|
BdfList toSign = BdfList.of(groupId, timestamp, type,
|
||||||
|
member.getName(), member.getPublicKey());
|
||||||
byte[] signature =
|
byte[] signature =
|
||||||
clientHelper.sign(toSign, creator.getPrivateKey());
|
clientHelper.sign(toSign, creator.getPrivateKey());
|
||||||
|
|
||||||
// Compose the message
|
// Compose the message
|
||||||
BdfList body =
|
BdfList body =
|
||||||
BdfList.of(NEW_MEMBER.getInt(), member.getName(),
|
BdfList.of(type, member.getName(),
|
||||||
member.getPublicKey(), signature);
|
member.getPublicKey(), signature);
|
||||||
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||||
|
|
||||||
@@ -60,14 +61,15 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
|
|||||||
LocalAuthor member, MessageId newMemberId) {
|
LocalAuthor member, MessageId newMemberId) {
|
||||||
try {
|
try {
|
||||||
// Generate the signature
|
// Generate the signature
|
||||||
BdfList toSign = BdfList.of(groupId, timestamp, member.getName(),
|
int type = JOIN.getInt();
|
||||||
member.getPublicKey(), newMemberId);
|
BdfList toSign = BdfList.of(groupId, timestamp, type,
|
||||||
|
member.getName(), member.getPublicKey(), newMemberId);
|
||||||
byte[] signature =
|
byte[] signature =
|
||||||
clientHelper.sign(toSign, member.getPrivateKey());
|
clientHelper.sign(toSign, member.getPrivateKey());
|
||||||
|
|
||||||
// Compose the message
|
// Compose the message
|
||||||
BdfList body =
|
BdfList body =
|
||||||
BdfList.of(JOIN.getInt(), member.getName(),
|
BdfList.of(type, member.getName(),
|
||||||
member.getPublicKey(), newMemberId, signature);
|
member.getPublicKey(), newMemberId, signature);
|
||||||
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||||
|
|
||||||
@@ -85,14 +87,16 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
|
|||||||
MessageId previousMsgId) {
|
MessageId previousMsgId) {
|
||||||
try {
|
try {
|
||||||
// Generate the signature
|
// Generate the signature
|
||||||
BdfList toSign = BdfList.of(groupId, timestamp, author.getName(),
|
int type = POST.getInt();
|
||||||
author.getPublicKey(), parentId, previousMsgId, content);
|
BdfList toSign = BdfList.of(groupId, timestamp, type,
|
||||||
|
author.getName(), author.getPublicKey(), parentId,
|
||||||
|
previousMsgId, content);
|
||||||
byte[] signature =
|
byte[] signature =
|
||||||
clientHelper.sign(toSign, author.getPrivateKey());
|
clientHelper.sign(toSign, author.getPrivateKey());
|
||||||
|
|
||||||
// Compose the message
|
// Compose the message
|
||||||
BdfList body =
|
BdfList body =
|
||||||
BdfList.of(POST.getInt(), author.getName(),
|
BdfList.of(type, author.getName(),
|
||||||
author.getPublicKey(), parentId, previousMsgId,
|
author.getPublicKey(), parentId, previousMsgId,
|
||||||
content, signature);
|
content, signature);
|
||||||
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.briarproject.api.sync.MessageId;
|
|||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.clients.BdfMessageValidator;
|
import org.briarproject.clients.BdfMessageValidator;
|
||||||
|
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -25,10 +26,13 @@ import java.util.Collections;
|
|||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
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.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||||
|
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.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_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_MEMBER_ID;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_NAME;
|
import static org.briarproject.privategroup.Constants.KEY_MEMBER_NAME;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_PUBLIC_KEY;
|
import static org.briarproject.privategroup.Constants.KEY_MEMBER_PUBLIC_KEY;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_NEW_MEMBER_MSG_ID;
|
import static org.briarproject.privategroup.Constants.KEY_NEW_MEMBER_MSG_ID;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_PARENT_MSG_ID;
|
import static org.briarproject.privategroup.Constants.KEY_PARENT_MSG_ID;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_PREVIOUS_MSG_ID;
|
import static org.briarproject.privategroup.Constants.KEY_PREVIOUS_MSG_ID;
|
||||||
@@ -60,29 +64,29 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
body.removeElementAt(0);
|
body.removeElementAt(0);
|
||||||
|
|
||||||
// member_name (string)
|
// member_name (string)
|
||||||
String member_name = body.getString(0);
|
String memberName = body.getString(0);
|
||||||
checkLength(member_name, 1, MAX_AUTHOR_NAME_LENGTH);
|
checkLength(memberName, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||||
|
|
||||||
// member_public_key (raw)
|
// member_public_key (raw)
|
||||||
byte[] member_public_key = body.getRaw(1);
|
byte[] memberPublicKey = body.getRaw(1);
|
||||||
checkLength(member_public_key, 1, MAX_PUBLIC_KEY_LENGTH);
|
checkLength(memberPublicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||||
|
|
||||||
BdfMessageContext c;
|
BdfMessageContext c;
|
||||||
switch (MessageType.valueOf(type)) {
|
switch (MessageType.valueOf(type)) {
|
||||||
case NEW_MEMBER:
|
case NEW_MEMBER:
|
||||||
c = validateNewMember(m, g, body, member_name,
|
c = validateNewMember(m, g, body, memberName,
|
||||||
member_public_key);
|
memberPublicKey);
|
||||||
addMessageMetadata(c, member_name, member_public_key,
|
addMessageMetadata(c, memberName, memberPublicKey,
|
||||||
m.getTimestamp());
|
m.getTimestamp());
|
||||||
break;
|
break;
|
||||||
case JOIN:
|
case JOIN:
|
||||||
c = validateJoin(m, g, body, member_name, member_public_key);
|
c = validateJoin(m, g, body, memberName, memberPublicKey);
|
||||||
addMessageMetadata(c, member_name, member_public_key,
|
addMessageMetadata(c, memberName, memberPublicKey,
|
||||||
m.getTimestamp());
|
m.getTimestamp());
|
||||||
break;
|
break;
|
||||||
case POST:
|
case POST:
|
||||||
c = validatePost(m, g, body, member_name, member_public_key);
|
c = validatePost(m, g, body, memberName, memberPublicKey);
|
||||||
addMessageMetadata(c, member_name, member_public_key,
|
addMessageMetadata(c, memberName, memberPublicKey,
|
||||||
m.getTimestamp());
|
m.getTimestamp());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -93,7 +97,7 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BdfMessageContext validateNewMember(Message m, Group g,
|
private BdfMessageContext validateNewMember(Message m, Group g,
|
||||||
BdfList body, String member_name, byte[] member_public_key)
|
BdfList body, String memberName, byte[] memberPublicKey)
|
||||||
throws InvalidMessageException, FormatException {
|
throws InvalidMessageException, FormatException {
|
||||||
|
|
||||||
// The content is a BDF list with three elements
|
// The content is a BDF list with three elements
|
||||||
@@ -105,11 +109,16 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
||||||
|
|
||||||
// Verify Signature
|
// Verify Signature
|
||||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), member_name,
|
BdfList signed =
|
||||||
member_public_key);
|
BdfList.of(g.getId(), m.getTimestamp(), NEW_MEMBER.getInt(),
|
||||||
|
memberName, memberPublicKey);
|
||||||
PrivateGroup group = groupFactory.parsePrivateGroup(g);
|
PrivateGroup group = groupFactory.parsePrivateGroup(g);
|
||||||
byte[] creatorPublicKey = group.getAuthor().getPublicKey();
|
byte[] creatorPublicKey = group.getAuthor().getPublicKey();
|
||||||
clientHelper.verifySignature(signature, creatorPublicKey, signed);
|
try {
|
||||||
|
clientHelper.verifySignature(signature, creatorPublicKey, signed);
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new InvalidMessageException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the metadata and no dependencies
|
// Return the metadata and no dependencies
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
@@ -117,7 +126,7 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BdfMessageContext validateJoin(Message m, Group g, BdfList body,
|
private BdfMessageContext validateJoin(Message m, Group g, BdfList body,
|
||||||
String member_name, byte[] member_public_key)
|
String memberName, byte[] memberPublicKey)
|
||||||
throws InvalidMessageException, FormatException {
|
throws InvalidMessageException, FormatException {
|
||||||
|
|
||||||
// The content is a BDF list with four elements
|
// The content is a BDF list with four elements
|
||||||
@@ -126,8 +135,8 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
// new_member_id (raw)
|
// new_member_id (raw)
|
||||||
// the identifier of a new member message
|
// the identifier of a new member message
|
||||||
// with the same member_name and member_public_key
|
// with the same member_name and member_public_key
|
||||||
byte[] new_member_id = body.getRaw(2);
|
byte[] newMemberId = body.getRaw(2);
|
||||||
checkLength(new_member_id, MessageId.LENGTH);
|
checkLength(newMemberId, MessageId.LENGTH);
|
||||||
|
|
||||||
// signature (raw)
|
// signature (raw)
|
||||||
// a signature with the member's private key over a list with 5 elements
|
// a signature with the member's private key over a list with 5 elements
|
||||||
@@ -135,22 +144,26 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
||||||
|
|
||||||
// Verify Signature
|
// Verify Signature
|
||||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), member_name,
|
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), JOIN.getInt(),
|
||||||
member_public_key, new_member_id);
|
memberName, memberPublicKey, newMemberId);
|
||||||
clientHelper.verifySignature(signature, member_public_key, signed);
|
try {
|
||||||
|
clientHelper.verifySignature(signature, memberPublicKey, signed);
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new InvalidMessageException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// The new member message is a dependency
|
// The new member message is a dependency
|
||||||
Collection<MessageId> dependencies =
|
Collection<MessageId> dependencies =
|
||||||
Collections.singleton(new MessageId(new_member_id));
|
Collections.singleton(new MessageId(newMemberId));
|
||||||
|
|
||||||
// Return the metadata and dependencies
|
// Return the metadata and dependencies
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
meta.put(KEY_NEW_MEMBER_MSG_ID, new_member_id);
|
meta.put(KEY_NEW_MEMBER_MSG_ID, newMemberId);
|
||||||
return new BdfMessageContext(meta, dependencies);
|
return new BdfMessageContext(meta, dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BdfMessageContext validatePost(Message m, Group g, BdfList body,
|
private BdfMessageContext validatePost(Message m, Group g, BdfList body,
|
||||||
String member_name, byte[] member_public_key)
|
String memberName, byte[] memberPublicKey)
|
||||||
throws InvalidMessageException, FormatException {
|
throws InvalidMessageException, FormatException {
|
||||||
|
|
||||||
// The content is a BDF list with six elements
|
// The content is a BDF list with six elements
|
||||||
@@ -158,15 +171,13 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
// parent_id (raw or null)
|
// parent_id (raw or null)
|
||||||
// the identifier of the post to which this is a reply, if any
|
// the identifier of the post to which this is a reply, if any
|
||||||
byte[] parent_id = body.getOptionalRaw(2);
|
byte[] parentId = body.getOptionalRaw(2);
|
||||||
if (parent_id != null) {
|
checkLength(parentId, MessageId.LENGTH);
|
||||||
checkLength(parent_id, MessageId.LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
// previous_message_id (raw)
|
// previous_message_id (raw)
|
||||||
// the identifier of the member's previous post or join message
|
// the identifier of the member's previous post or join message
|
||||||
byte[] previous_message_id = body.getRaw(3);
|
byte[] previousMessageId = body.getRaw(3);
|
||||||
checkLength(previous_message_id, MessageId.LENGTH);
|
checkLength(previousMessageId, MessageId.LENGTH);
|
||||||
|
|
||||||
// content (string)
|
// content (string)
|
||||||
String content = body.getString(4);
|
String content = body.getString(4);
|
||||||
@@ -178,20 +189,25 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
||||||
|
|
||||||
// Verify Signature
|
// Verify Signature
|
||||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), member_name,
|
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), POST.getInt(),
|
||||||
member_public_key, parent_id, previous_message_id, content);
|
memberName, memberPublicKey, parentId, previousMessageId,
|
||||||
clientHelper.verifySignature(signature, member_public_key, signed);
|
content);
|
||||||
|
try {
|
||||||
|
clientHelper.verifySignature(signature, memberPublicKey, signed);
|
||||||
|
} catch (GeneralSecurityException e) {
|
||||||
|
throw new InvalidMessageException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// The parent post, if any,
|
// The parent post, if any,
|
||||||
// and the member's previous message are dependencies
|
// and the member's previous message are dependencies
|
||||||
Collection<MessageId> dependencies = new ArrayList<MessageId>();
|
Collection<MessageId> dependencies = new ArrayList<MessageId>();
|
||||||
if (parent_id != null) dependencies.add(new MessageId(parent_id));
|
if (parentId != null) dependencies.add(new MessageId(parentId));
|
||||||
dependencies.add(new MessageId(previous_message_id));
|
dependencies.add(new MessageId(previousMessageId));
|
||||||
|
|
||||||
// Return the metadata and dependencies
|
// Return the metadata and dependencies
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
if (parent_id != null) meta.put(KEY_PARENT_MSG_ID, parent_id);
|
if (parentId != null) meta.put(KEY_PARENT_MSG_ID, parentId);
|
||||||
meta.put(KEY_PREVIOUS_MSG_ID, previous_message_id);
|
meta.put(KEY_PREVIOUS_MSG_ID, previousMessageId);
|
||||||
return new BdfMessageContext(meta, dependencies);
|
return new BdfMessageContext(meta, dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,9 +216,9 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
c.getDictionary().put(KEY_TIMESTAMP, time);
|
c.getDictionary().put(KEY_TIMESTAMP, time);
|
||||||
c.getDictionary().put(KEY_READ, false);
|
c.getDictionary().put(KEY_READ, false);
|
||||||
Author a = authorFactory.createAuthor(authorName, pubKey);
|
Author a = authorFactory.createAuthor(authorName, pubKey);
|
||||||
c.getDictionary().put(KEY_AUTHOR_ID, a.getId());
|
c.getDictionary().put(KEY_MEMBER_ID, a.getId());
|
||||||
c.getDictionary().put(KEY_AUTHOR_NAME, authorName);
|
c.getDictionary().put(KEY_MEMBER_NAME, authorName);
|
||||||
c.getDictionary().put(KEY_AUTHOR_PUBLIC_KEY, pubKey);
|
c.getDictionary().put(KEY_MEMBER_PUBLIC_KEY, pubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ import static org.briarproject.api.identity.Author.Status.OURSELVES;
|
|||||||
import static org.briarproject.api.privategroup.MessageType.JOIN;
|
import static org.briarproject.api.privategroup.MessageType.JOIN;
|
||||||
import static org.briarproject.api.privategroup.MessageType.NEW_MEMBER;
|
import static org.briarproject.api.privategroup.MessageType.NEW_MEMBER;
|
||||||
import static org.briarproject.api.privategroup.MessageType.POST;
|
import static org.briarproject.api.privategroup.MessageType.POST;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_ID;
|
import static org.briarproject.privategroup.Constants.KEY_MEMBER_ID;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_NAME;
|
import static org.briarproject.privategroup.Constants.KEY_MEMBER_NAME;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_AUTHOR_PUBLIC_KEY;
|
import static org.briarproject.privategroup.Constants.KEY_MEMBER_PUBLIC_KEY;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_NEW_MEMBER_MSG_ID;
|
import static org.briarproject.privategroup.Constants.KEY_NEW_MEMBER_MSG_ID;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_PARENT_MSG_ID;
|
import static org.briarproject.privategroup.Constants.KEY_PARENT_MSG_ID;
|
||||||
import static org.briarproject.privategroup.Constants.KEY_PREVIOUS_MSG_ID;
|
import static org.briarproject.privategroup.Constants.KEY_PREVIOUS_MSG_ID;
|
||||||
@@ -141,8 +141,7 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
private MessageId getPreviousMsgId(Transaction txn, GroupId g)
|
private MessageId getPreviousMsgId(Transaction txn, GroupId g)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||||
byte[] previousMsgIdBytes = d.getOptionalRaw(KEY_PREVIOUS_MSG_ID);
|
byte[] previousMsgIdBytes = d.getRaw(KEY_PREVIOUS_MSG_ID);
|
||||||
if (previousMsgIdBytes == null) throw new DbException();
|
|
||||||
return new MessageId(previousMsgIdBytes);
|
return new MessageId(previousMsgIdBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,9 +190,9 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
boolean read) {
|
boolean read) {
|
||||||
meta.put(KEY_TIMESTAMP, m.getMessage().getTimestamp());
|
meta.put(KEY_TIMESTAMP, m.getMessage().getTimestamp());
|
||||||
meta.put(KEY_READ, read);
|
meta.put(KEY_READ, read);
|
||||||
meta.put(KEY_AUTHOR_ID, m.getMember().getId());
|
meta.put(KEY_MEMBER_ID, m.getMember().getId());
|
||||||
meta.put(KEY_AUTHOR_NAME, m.getMember().getName());
|
meta.put(KEY_MEMBER_NAME, m.getMember().getName());
|
||||||
meta.put(KEY_AUTHOR_PUBLIC_KEY, m.getMember().getPublicKey());
|
meta.put(KEY_MEMBER_PUBLIC_KEY, m.getMember().getPublicKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -269,11 +268,10 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||||
// get all authors we need to get the status for
|
// get all authors we need to get the status for
|
||||||
Set<AuthorId> authors = new HashSet<AuthorId>();
|
Set<AuthorId> authors = new HashSet<AuthorId>();
|
||||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
for (BdfDictionary meta : metadata.values()) {
|
||||||
BdfDictionary meta = entry.getValue();
|
|
||||||
if (meta.getLong(KEY_TYPE) == NEW_MEMBER.getInt())
|
if (meta.getLong(KEY_TYPE) == NEW_MEMBER.getInt())
|
||||||
continue;
|
continue;
|
||||||
byte[] idBytes = meta.getRaw(KEY_AUTHOR_ID);
|
byte[] idBytes = meta.getRaw(KEY_MEMBER_ID);
|
||||||
authors.add(new AuthorId(idBytes));
|
authors.add(new AuthorId(idBytes));
|
||||||
}
|
}
|
||||||
// get statuses for all authors
|
// get statuses for all authors
|
||||||
@@ -308,9 +306,9 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
}
|
}
|
||||||
long timestamp = meta.getLong(KEY_TIMESTAMP);
|
long timestamp = meta.getLong(KEY_TIMESTAMP);
|
||||||
|
|
||||||
AuthorId authorId = new AuthorId(meta.getRaw(KEY_AUTHOR_ID));
|
AuthorId authorId = new AuthorId(meta.getRaw(KEY_MEMBER_ID));
|
||||||
String name = meta.getString(KEY_AUTHOR_NAME);
|
String name = meta.getString(KEY_MEMBER_NAME);
|
||||||
byte[] publicKey = meta.getRaw(KEY_AUTHOR_PUBLIC_KEY);
|
byte[] publicKey = meta.getRaw(KEY_MEMBER_PUBLIC_KEY);
|
||||||
Author author = new Author(authorId, name, publicKey);
|
Author author = new Author(authorId, name, publicKey);
|
||||||
|
|
||||||
Status status;
|
Status status;
|
||||||
@@ -361,8 +359,8 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// NEW_MEMBER must have same member_name and member_public_key
|
// NEW_MEMBER must have same member_name and member_public_key
|
||||||
if (!Arrays.equals(meta.getRaw(KEY_AUTHOR_ID),
|
if (!Arrays.equals(meta.getRaw(KEY_MEMBER_ID),
|
||||||
newMemberMeta.getRaw(KEY_AUTHOR_ID))) {
|
newMemberMeta.getRaw(KEY_MEMBER_ID))) {
|
||||||
// FIXME throw new InvalidMessageException() (#643)
|
// FIXME throw new InvalidMessageException() (#643)
|
||||||
db.deleteMessage(txn, m.getId());
|
db.deleteMessage(txn, m.getId());
|
||||||
return false;
|
return false;
|
||||||
@@ -401,8 +399,16 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// previous message must be from same member
|
// previous message must be from same member
|
||||||
if (!Arrays.equals(meta.getRaw(KEY_AUTHOR_ID),
|
if (!Arrays.equals(meta.getRaw(KEY_MEMBER_ID),
|
||||||
previousMeta.getRaw(KEY_AUTHOR_ID))) {
|
previousMeta.getRaw(KEY_MEMBER_ID))) {
|
||||||
|
// FIXME throw new InvalidMessageException() (#643)
|
||||||
|
db.deleteMessage(txn, m.getId());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// previous message must be a POST or JOIN
|
||||||
|
MessageType previousType = MessageType
|
||||||
|
.valueOf(previousMeta.getLong(KEY_TYPE).intValue());
|
||||||
|
if (previousType != JOIN && previousType != POST) {
|
||||||
// FIXME throw new InvalidMessageException() (#643)
|
// FIXME throw new InvalidMessageException() (#643)
|
||||||
db.deleteMessage(txn, m.getId());
|
db.deleteMessage(txn, m.getId());
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user