Address review comments for new sharing client

This commit is contained in:
Torsten Grote
2017-01-03 11:40:54 -02:00
parent 694e662028
commit 51b78cf9b1
35 changed files with 322 additions and 231 deletions

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@Deprecated
public interface InvitationFactory<I extends SharingMessage.Invitation> { public interface InvitationFactory<I extends SharingMessage.Invitation> {
I build(GroupId groupId, BdfDictionary d) throws FormatException; I build(GroupId groupId, BdfDictionary d) throws FormatException;

View File

@@ -15,34 +15,63 @@ public interface SharingConstants {
*/ */
int MAX_INVITATION_MESSAGE_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024; int MAX_INVITATION_MESSAGE_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
@Deprecated
String CONTACT_ID = "contactId"; String CONTACT_ID = "contactId";
@Deprecated
String GROUP_ID = "groupId"; String GROUP_ID = "groupId";
@Deprecated
String TO_BE_SHARED_BY_US = "toBeSharedByUs"; String TO_BE_SHARED_BY_US = "toBeSharedByUs";
@Deprecated
String SHARED_BY_US = "sharedByUs"; String SHARED_BY_US = "sharedByUs";
@Deprecated
String SHARED_WITH_US = "sharedWithUs"; String SHARED_WITH_US = "sharedWithUs";
@Deprecated
String TYPE = "type"; String TYPE = "type";
@Deprecated
String SESSION_ID = "sessionId"; String SESSION_ID = "sessionId";
@Deprecated
String STORAGE_ID = "storageId"; String STORAGE_ID = "storageId";
@Deprecated
String STATE = "state"; String STATE = "state";
@Deprecated
String LOCAL = "local"; String LOCAL = "local";
@Deprecated
String TIME = "time"; String TIME = "time";
@Deprecated
String IS_SHARER = "isSharer"; String IS_SHARER = "isSharer";
@Deprecated
String SHAREABLE_ID = "shareableId"; String SHAREABLE_ID = "shareableId";
@Deprecated
String INVITATION_MSG = "invitationMsg"; String INVITATION_MSG = "invitationMsg";
@Deprecated
String INVITATION_ID = "invitationId"; String INVITATION_ID = "invitationId";
@Deprecated
String RESPONSE_ID = "responseId"; String RESPONSE_ID = "responseId";
@Deprecated
int SHARE_MSG_TYPE_INVITATION = 1; int SHARE_MSG_TYPE_INVITATION = 1;
@Deprecated
int SHARE_MSG_TYPE_ACCEPT = 2; int SHARE_MSG_TYPE_ACCEPT = 2;
@Deprecated
int SHARE_MSG_TYPE_DECLINE = 3; int SHARE_MSG_TYPE_DECLINE = 3;
@Deprecated
int SHARE_MSG_TYPE_LEAVE = 4; int SHARE_MSG_TYPE_LEAVE = 4;
@Deprecated
int SHARE_MSG_TYPE_ABORT = 5; int SHARE_MSG_TYPE_ABORT = 5;
@Deprecated
int TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US = 0; int TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US = 0;
@Deprecated
int TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US = 1; int TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US = 1;
@Deprecated
int TASK_ADD_SHARED_SHAREABLE = 2; int TASK_ADD_SHARED_SHAREABLE = 2;
@Deprecated
int TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US = 3; int TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US = 3;
@Deprecated
int TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US = 4; int TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US = 4;
@Deprecated
int TASK_SHARE_SHAREABLE = 5; int TASK_SHARE_SHAREABLE = 5;
@Deprecated
int TASK_UNSHARE_SHAREABLE_SHARED_BY_US = 6; int TASK_UNSHARE_SHAREABLE_SHARED_BY_US = 6;
@Deprecated
int TASK_UNSHARE_SHAREABLE_SHARED_WITH_US = 7; int TASK_UNSHARE_SHAREABLE_SHARED_WITH_US = 7;
} }

View File

@@ -21,6 +21,7 @@ import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE
import static org.briarproject.briar.api.sharing.SharingConstants.TIME; import static org.briarproject.briar.api.sharing.SharingConstants.TIME;
import static org.briarproject.briar.api.sharing.SharingConstants.TYPE; import static org.briarproject.briar.api.sharing.SharingConstants.TYPE;
@Deprecated
@NotNullByDefault @NotNullByDefault
public interface SharingMessage { public interface SharingMessage {

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
@@ -177,7 +176,7 @@ abstract class AbstractProtocolEngine<S extends Session>
void subscribeToPrivateGroup(Transaction txn, MessageId inviteId) void subscribeToPrivateGroup(Transaction txn, MessageId inviteId)
throws DbException, FormatException { throws DbException, FormatException {
InviteMessage invite = getInviteMessage(txn, inviteId); InviteMessage invite = messageParser.getInviteMessage(txn, inviteId);
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup( PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
invite.getGroupName(), invite.getCreator(), invite.getSalt()); invite.getGroupName(), invite.getCreator(), invite.getSalt());
long timestamp = long timestamp =
@@ -197,14 +196,6 @@ abstract class AbstractProtocolEngine<S extends Session>
session.getInviteTimestamp()) + 1); session.getInviteTimestamp()) + 1);
} }
private InviteMessage getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException {
Message message = clientHelper.getMessage(txn, m);
if (message == null) throw new DbException();
BdfList body = clientHelper.toList(message);
return messageParser.parseInviteMessage(message, body);
}
private void sendMessage(Transaction txn, Message m, MessageType type, private void sendMessage(Transaction txn, Message m, MessageType type,
GroupId privateGroupId, boolean visibleInConversation) GroupId privateGroupId, boolean visibleInConversation)
throws DbException { throws DbException {

View File

@@ -401,7 +401,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
throws DbException, FormatException { throws DbException, FormatException {
SessionId sessionId = getSessionId(meta.getPrivateGroupId()); SessionId sessionId = getSessionId(meta.getPrivateGroupId());
// Look up the invite message to get the details of the private group // Look up the invite message to get the details of the private group
InviteMessage invite = getInviteMessage(txn, m); InviteMessage invite = messageParser.getInviteMessage(txn, m);
PrivateGroup pg = privateGroupFactory PrivateGroup pg = privateGroupFactory
.createPrivateGroup(invite.getGroupName(), invite.getCreator(), .createPrivateGroup(invite.getGroupName(), invite.getCreator(),
invite.getSalt()); invite.getSalt());
@@ -412,14 +412,6 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
invite.getMessage(), meta.isAvailableToAnswer(), canBeOpened); invite.getMessage(), meta.isAvailableToAnswer(), canBeOpened);
} }
private InviteMessage getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException {
Message message = clientHelper.getMessage(txn, m);
if (message == null) throw new DbException();
BdfList body = clientHelper.toList(message);
return messageParser.parseInviteMessage(message, body);
}
private GroupInvitationResponse parseInvitationResponse(ContactId c, private GroupInvitationResponse parseInvitationResponse(ContactId c,
GroupId contactGroupId, MessageId m, MessageMetadata meta, GroupId contactGroupId, MessageId m, MessageMetadata meta,
MessageStatus status, boolean accept) MessageStatus status, boolean accept)
@@ -479,7 +471,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
private GroupInvitationItem parseGroupInvitationItem(Transaction txn, private GroupInvitationItem parseGroupInvitationItem(Transaction txn,
Contact c, MessageId m) throws DbException, FormatException { Contact c, MessageId m) throws DbException, FormatException {
InviteMessage invite = getInviteMessage(txn, m); InviteMessage invite = messageParser.getInviteMessage(txn, m);
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup( PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
invite.getGroupName(), invite.getCreator(), invite.getSalt()); invite.getGroupName(), invite.getCreator(), invite.getSalt());
return new GroupInvitationItem(privateGroup, c); return new GroupInvitationItem(privateGroup, c);

View File

@@ -3,9 +3,12 @@ package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
@NotNullByDefault @NotNullByDefault
interface MessageParser { interface MessageParser {
@@ -18,6 +21,9 @@ interface MessageParser {
MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException;
InviteMessage getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException;
InviteMessage parseInviteMessage(Message m, BdfList body) InviteMessage parseInviteMessage(Message m, BdfList body)
throws FormatException; throws FormatException;

View File

@@ -1,9 +1,12 @@
package org.briarproject.briar.privategroup.invitation; package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -31,12 +34,14 @@ class MessageParserImpl implements MessageParser {
private final AuthorFactory authorFactory; private final AuthorFactory authorFactory;
private final PrivateGroupFactory privateGroupFactory; private final PrivateGroupFactory privateGroupFactory;
private final ClientHelper clientHelper;
@Inject @Inject
MessageParserImpl(AuthorFactory authorFactory, MessageParserImpl(AuthorFactory authorFactory,
PrivateGroupFactory privateGroupFactory) { PrivateGroupFactory privateGroupFactory, ClientHelper clientHelper) {
this.authorFactory = authorFactory; this.authorFactory = authorFactory;
this.privateGroupFactory = privateGroupFactory; this.privateGroupFactory = privateGroupFactory;
this.clientHelper = clientHelper;
} }
@Override @Override
@@ -78,6 +83,15 @@ class MessageParserImpl implements MessageParser {
visible, available); visible, available);
} }
@Override
public InviteMessage getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException {
Message message = clientHelper.getMessage(txn, m);
if (message == null) throw new DbException();
BdfList body = clientHelper.toList(message);
return parseInviteMessage(message, body);
}
@Override @Override
public InviteMessage parseInviteMessage(Message m, BdfList body) public InviteMessage parseInviteMessage(Message m, BdfList body)
throws FormatException { throws FormatException {

View File

@@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class AbortMessage extends SharingMessage { class AbortMessage extends SharingMessage {
AbortMessage(MessageId id, GroupId contactGroupId, GroupId shareableId, AbortMessage(MessageId id, GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId) { long timestamp, @Nullable MessageId previousMessageId) {

View File

@@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class AcceptMessage extends SharingMessage { class AcceptMessage extends SharingMessage {
AcceptMessage(MessageId id, @Nullable MessageId previousMessageId, AcceptMessage(MessageId id, @Nullable MessageId previousMessageId,
GroupId contactGroupId, GroupId shareableId, long timestamp) { GroupId contactGroupId, GroupId shareableId, long timestamp) {

View File

@@ -159,7 +159,7 @@ class BlogSharingManagerImpl extends
} }
@Override @Override
protected InvitationFactory<BlogInvitation, BlogSharerSessionState> getIFactory() { protected OldInvitationFactory<BlogInvitation, BlogSharerSessionState> getIFactory() {
return iFactory; return iFactory;
} }
@@ -251,7 +251,7 @@ class BlogSharingManagerImpl extends
} }
private static class IFactory implements private static class IFactory implements
InvitationFactory<BlogInvitation, BlogSharerSessionState> { OldInvitationFactory<BlogInvitation, BlogSharerSessionState> {
@Override @Override
public BlogInvitation build(GroupId groupId, BdfDictionary d) public BlogInvitation build(GroupId groupId, BdfDictionary d)
throws FormatException { throws FormatException {

View File

@@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class DeclineMessage extends SharingMessage { class DeclineMessage extends SharingMessage {
DeclineMessage(MessageId id, GroupId contactGroupId, DeclineMessage(MessageId id, GroupId contactGroupId,
GroupId shareableId, long timestamp, GroupId shareableId, long timestamp,

View File

@@ -0,0 +1,39 @@
package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.forum.Forum;
import org.briarproject.briar.api.forum.ForumInvitationRequest;
import org.briarproject.briar.api.forum.ForumInvitationResponse;
import javax.inject.Inject;
public class ForumInvitationFactoryImpl implements InvitationFactory<Forum> {
@Inject
ForumInvitationFactoryImpl() {
}
@Override
public ForumInvitationRequest createInvitationRequest(boolean local,
boolean sent, boolean seen, boolean read, InviteMessage<Forum> m,
ContactId c, boolean available, boolean canBeOpened) {
SessionId sessionId = new SessionId(m.getShareableId().getBytes());
return new ForumInvitationRequest(m.getId(), m.getContactGroupId(),
m.getTimestamp(), local, sent, seen, read, sessionId,
m.getShareable(), c, m.getMessage(), available, canBeOpened);
}
@Override
public ForumInvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, GroupId shareableId,
ContactId contactId, boolean accept) {
SessionId sessionId = new SessionId(shareableId.getBytes());
return new ForumInvitationResponse(id, contactGroupId, time, local,
sent, seen, read, sessionId, shareableId, contactId, accept);
}
}

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.sharing; package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.forum.Forum; import org.briarproject.briar.api.forum.Forum;
@@ -16,8 +17,9 @@ class ForumMessageParserImpl extends MessageParserImpl<Forum> {
private final ForumFactory forumFactory; private final ForumFactory forumFactory;
@Inject @Inject
ForumMessageParserImpl(ForumFactory forumFactory) { ForumMessageParserImpl(ClientHelper clientHelper,
super(); ForumFactory forumFactory) {
super(clientHelper);
this.forumFactory = forumFactory; this.forumFactory = forumFactory;
} }

View File

@@ -3,22 +3,20 @@ package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.forum.Forum; import org.briarproject.briar.api.forum.Forum;
import org.briarproject.briar.api.forum.ForumInvitationRequest; import org.briarproject.briar.api.forum.ForumInvitationRequest;
import org.briarproject.briar.api.forum.ForumInvitationResponse; import org.briarproject.briar.api.forum.ForumInvitationResponse;
import org.briarproject.briar.api.forum.ForumManager; import org.briarproject.briar.api.forum.ForumManager;
import org.briarproject.briar.api.forum.ForumSharingManager;
import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent; import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent;
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent; import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
@@ -30,23 +28,27 @@ import javax.inject.Inject;
class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> { class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
private final ForumManager forumManager; private final ForumManager forumManager;
private final InvitationFactory<Forum> invitationFactory;
@Inject @Inject
ForumProtocolEngineImpl(DatabaseComponent db, ForumProtocolEngineImpl(DatabaseComponent db,
ClientHelper clientHelper, MessageEncoder messageEncoder, ClientHelper clientHelper, MessageEncoder messageEncoder,
MessageParser<Forum> messageParser, MessageTracker messageTracker, MessageParser<Forum> messageParser, MessageTracker messageTracker,
Clock clock, ForumManager forumManager) { Clock clock, ForumManager forumManager,
InvitationFactory<Forum> invitationFactory) {
super(db, clientHelper, messageEncoder, messageParser, messageTracker, super(db, clientHelper, messageEncoder, messageParser, messageTracker,
clock); clock);
this.forumManager = forumManager; this.forumManager = forumManager;
this.invitationFactory = invitationFactory;
} }
@Override @Override
Event getInvitationRequestReceivedEvent(InviteMessage<Forum> m, Event getInvitationRequestReceivedEvent(InviteMessage<Forum> m,
ContactId contactId, boolean available, boolean canBeOpened) { ContactId contactId, boolean available, boolean canBeOpened) {
ForumInvitationRequest request = ForumInvitationRequest request =
createInvitationRequest(false, false, true, false, m, contactId, (ForumInvitationRequest) invitationFactory
available, canBeOpened); .createInvitationRequest(false, false, true, false, m,
contactId, available, canBeOpened);
return new ForumInvitationRequestReceivedEvent(m.getShareable(), return new ForumInvitationRequestReceivedEvent(m.getShareable(),
contactId, request); contactId, request);
} }
@@ -55,9 +57,11 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
Event getInvitationResponseReceivedEvent(AcceptMessage m, Event getInvitationResponseReceivedEvent(AcceptMessage m,
ContactId contactId) { ContactId contactId) {
ForumInvitationResponse response = ForumInvitationResponse response =
createInvitationResponse(m.getId(), m.getContactGroupId(), (ForumInvitationResponse) invitationFactory
m.getTimestamp(), false, false, true, false, .createInvitationResponse(m.getId(),
m.getShareableId(), contactId, true); m.getContactGroupId(), m.getTimestamp(), false,
false, true, false, m.getShareableId(),
contactId, true);
return new ForumInvitationResponseReceivedEvent(contactId, response); return new ForumInvitationResponseReceivedEvent(contactId, response);
} }
@@ -65,45 +69,25 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
Event getInvitationResponseReceivedEvent(DeclineMessage m, Event getInvitationResponseReceivedEvent(DeclineMessage m,
ContactId contactId) { ContactId contactId) {
ForumInvitationResponse response = ForumInvitationResponse response =
createInvitationResponse(m.getId(), m.getContactGroupId(), (ForumInvitationResponse) invitationFactory
m.getTimestamp(), false, false, true, false, .createInvitationResponse(m.getId(),
m.getShareableId(), contactId, true); m.getContactGroupId(), m.getTimestamp(), false,
false, true, false, m.getShareableId(),
contactId, true);
return new ForumInvitationResponseReceivedEvent(contactId, response); return new ForumInvitationResponseReceivedEvent(contactId, response);
} }
@Override
protected ClientId getClientId() {
return ForumSharingManager.CLIENT_ID;
}
@Override @Override
protected void addShareable(Transaction txn, MessageId inviteId) protected void addShareable(Transaction txn, MessageId inviteId)
throws DbException, FormatException { throws DbException, FormatException {
InviteMessage<Forum> invite = getInviteMessage(txn, inviteId); InviteMessage<Forum> invite =
messageParser.getInviteMessage(txn, inviteId);
forumManager.addForum(txn, invite.getShareable()); forumManager.addForum(txn, invite.getShareable());
} }
private InviteMessage<Forum> getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException {
Message message = clientHelper.getMessage(txn, m);
if (message == null) throw new DbException();
BdfList body = clientHelper.toList(message);
return messageParser.parseInviteMessage(message, body);
}
@Override
public ForumInvitationRequest createInvitationRequest(boolean local,
boolean sent, boolean seen, boolean read, InviteMessage<Forum> m,
ContactId c, boolean available, boolean canBeOpened) {
SessionId sessionId = new SessionId(m.getShareableId().getBytes());
return new ForumInvitationRequest(m.getId(), m.getContactGroupId(),
m.getTimestamp(), local, sent, seen, read, sessionId,
m.getShareable(), c, m.getMessage(), available, canBeOpened);
}
@Override
public ForumInvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, GroupId shareableId,
ContactId contactId, boolean accept) {
SessionId sessionId = new SessionId(shareableId.getBytes());
return new ForumInvitationResponse(id, contactGroupId, time, local,
sent, seen, read, sessionId, shareableId, contactId, accept);
}
} }

View File

@@ -25,9 +25,11 @@ class ForumSharingManagerImpl extends SharingManagerImpl<Forum>
SessionEncoder sessionEncoder, SessionParser sessionParser, SessionEncoder sessionEncoder, SessionParser sessionParser,
MessageTracker messageTracker, MessageTracker messageTracker,
ContactGroupFactory contactGroupFactory, ContactGroupFactory contactGroupFactory,
ProtocolEngine<Forum> engine) { ProtocolEngine<Forum> engine,
InvitationFactory<Forum> invitationFactory) {
super(db, clientHelper, metadataParser, messageParser, sessionEncoder, super(db, clientHelper, metadataParser, messageParser, sessionEncoder,
sessionParser, messageTracker, contactGroupFactory, engine); sessionParser, messageTracker, contactGroupFactory, engine,
invitationFactory);
} }
@Override @Override

View File

@@ -1,12 +1,21 @@
package org.briarproject.briar.sharing; package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.briar.api.sharing.SharingMessage; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.sharing.InvitationRequest;
import org.briarproject.briar.api.sharing.InvitationResponse;
import org.briarproject.briar.api.sharing.Shareable;
@Deprecated public interface InvitationFactory<S extends Shareable> {
@NotNullByDefault
interface InvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState> InvitationRequest<S> createInvitationRequest(boolean local, boolean sent,
extends org.briarproject.briar.api.sharing.InvitationFactory<I> { boolean seen, boolean read, InviteMessage<S> m, ContactId c,
boolean available, boolean canBeOpened);
InvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, GroupId shareableId,
ContactId contactId, boolean accept);
I build(SS localState, long time);
} }

View File

@@ -10,7 +10,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class InviteMessage<S extends Shareable> extends SharingMessage { class InviteMessage<S extends Shareable> extends SharingMessage {
private final S shareable; private final S shareable;
@Nullable @Nullable

View File

@@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class LeaveMessage extends SharingMessage { class LeaveMessage extends SharingMessage {
LeaveMessage(MessageId id, GroupId contactGroupId, LeaveMessage(MessageId id, GroupId contactGroupId,
GroupId shareableId, long timestamp, GroupId shareableId, long timestamp,

View File

@@ -12,7 +12,7 @@ import javax.annotation.Nullable;
@NotNullByDefault @NotNullByDefault
interface MessageEncoder { interface MessageEncoder {
BdfDictionary encodeMetadata(MessageType type, GroupId groupId, BdfDictionary encodeMetadata(MessageType type, GroupId shareableId,
long timestamp, boolean local, boolean read, boolean visible, long timestamp, boolean local, boolean read, boolean visible,
boolean available); boolean available);
@@ -24,16 +24,16 @@ interface MessageEncoder {
@Nullable MessageId previousMessageId, BdfList descriptor, @Nullable MessageId previousMessageId, BdfList descriptor,
@Nullable String message); @Nullable String message);
Message encodeAcceptMessage(GroupId contactGroupId, GroupId groupId, Message encodeAcceptMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);
Message encodeDeclineMessage(GroupId contactGroupId, GroupId groupId, Message encodeDeclineMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);
Message encodeLeaveMessage(GroupId contactGroupId, GroupId groupId, Message encodeLeaveMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);
Message encodeAbortMessage(GroupId contactGroupId, GroupId groupId, Message encodeAbortMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);
} }

View File

@@ -43,11 +43,11 @@ class MessageEncoderImpl implements MessageEncoder {
@Override @Override
public BdfDictionary encodeMetadata(MessageType type, public BdfDictionary encodeMetadata(MessageType type,
GroupId groupId, long timestamp, boolean local, boolean read, GroupId shareableId, long timestamp, boolean local, boolean read,
boolean visible, boolean available) { boolean visible, boolean available) {
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue()); meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue());
meta.put(MSG_KEY_SHAREABLE_ID, groupId); meta.put(MSG_KEY_SHAREABLE_ID, shareableId);
meta.put(MSG_KEY_TIMESTAMP, timestamp); meta.put(MSG_KEY_TIMESTAMP, timestamp);
meta.put(MSG_KEY_LOCAL, local); meta.put(MSG_KEY_LOCAL, local);
meta.put(MSG_KEY_READ, read); meta.put(MSG_KEY_READ, read);
@@ -88,42 +88,42 @@ class MessageEncoderImpl implements MessageEncoder {
@Override @Override
public Message encodeAcceptMessage(GroupId contactGroupId, public Message encodeAcceptMessage(GroupId contactGroupId,
GroupId privateGroupId, long timestamp, GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) { @Nullable MessageId previousMessageId) {
return encodeMessage(ACCEPT, contactGroupId, privateGroupId, timestamp, return encodeMessage(ACCEPT, contactGroupId, shareableId, timestamp,
previousMessageId); previousMessageId);
} }
@Override @Override
public Message encodeDeclineMessage(GroupId contactGroupId, public Message encodeDeclineMessage(GroupId contactGroupId,
GroupId privateGroupId, long timestamp, GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) { @Nullable MessageId previousMessageId) {
return encodeMessage(DECLINE, contactGroupId, privateGroupId, timestamp, return encodeMessage(DECLINE, contactGroupId, shareableId, timestamp,
previousMessageId); previousMessageId);
} }
@Override @Override
public Message encodeLeaveMessage(GroupId contactGroupId, public Message encodeLeaveMessage(GroupId contactGroupId,
GroupId privateGroupId, long timestamp, GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) { @Nullable MessageId previousMessageId) {
return encodeMessage(LEAVE, contactGroupId, privateGroupId, timestamp, return encodeMessage(LEAVE, contactGroupId, shareableId, timestamp,
previousMessageId); previousMessageId);
} }
@Override @Override
public Message encodeAbortMessage(GroupId contactGroupId, public Message encodeAbortMessage(GroupId contactGroupId,
GroupId privateGroupId, long timestamp, GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) { @Nullable MessageId previousMessageId) {
return encodeMessage(ABORT, contactGroupId, privateGroupId, timestamp, return encodeMessage(ABORT, contactGroupId, shareableId, timestamp,
previousMessageId); previousMessageId);
} }
private Message encodeMessage(MessageType type, GroupId contactGroupId, private Message encodeMessage(MessageType type, GroupId contactGroupId,
GroupId groupId, long timestamp, GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) { @Nullable MessageId previousMessageId) {
BdfList body = BdfList.of( BdfList body = BdfList.of(
type.getValue(), type.getValue(),
groupId, shareableId,
previousMessageId previousMessageId
); );
try { try {

View File

@@ -3,9 +3,12 @@ package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.sharing.Shareable; import org.briarproject.briar.api.sharing.Shareable;
@NotNullByDefault @NotNullByDefault
@@ -15,10 +18,13 @@ interface MessageParser<S extends Shareable> {
BdfDictionary getInvitesAvailableToAnswerQuery(); BdfDictionary getInvitesAvailableToAnswerQuery();
BdfDictionary getInvitesAvailableToAnswerQuery(GroupId privateGroupId); BdfDictionary getInvitesAvailableToAnswerQuery(GroupId shareableId);
MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException;
InviteMessage<S> getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException;
InviteMessage<S> parseInviteMessage(Message m, BdfList body) InviteMessage<S> parseInviteMessage(Message m, BdfList body)
throws FormatException; throws FormatException;

View File

@@ -1,9 +1,12 @@
package org.briarproject.briar.sharing; package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
@@ -26,7 +29,10 @@ import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_VISIBLE_IN
abstract class MessageParserImpl<S extends Shareable> abstract class MessageParserImpl<S extends Shareable>
implements MessageParser<S> { implements MessageParser<S> {
MessageParserImpl() { private final ClientHelper clientHelper;
MessageParserImpl(ClientHelper clientHelper) {
this.clientHelper = clientHelper;
} }
@Override @Override
@@ -66,6 +72,15 @@ abstract class MessageParserImpl<S extends Shareable>
visible, available); visible, available);
} }
@Override
public InviteMessage<S> getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException {
Message message = clientHelper.getMessage(txn, m);
if (message == null) throw new DbException();
BdfList body = clientHelper.toList(message);
return parseInviteMessage(message, body);
}
@Override @Override
public InviteMessage<S> parseInviteMessage(Message m, BdfList body) public InviteMessage<S> parseInviteMessage(Message m, BdfList body)
throws FormatException { throws FormatException {

View File

@@ -0,0 +1,12 @@
package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.sharing.SharingMessage;
@Deprecated
@NotNullByDefault
interface OldInvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState>
extends org.briarproject.briar.api.sharing.InvitationFactory<I> {
I build(SS localState, long time);
}

View File

@@ -137,7 +137,7 @@ abstract class OldSharingManagerImpl<S extends Shareable, I extends Invitation,
protected abstract ShareableFactory<S, I, IS, SS> getSFactory(); protected abstract ShareableFactory<S, I, IS, SS> getSFactory();
protected abstract InvitationFactory<I, SS> getIFactory(); protected abstract OldInvitationFactory<I, SS> getIFactory();
protected abstract InviteeSessionStateFactory<S, IS> getISFactory(); protected abstract InviteeSessionStateFactory<S, IS> getISFactory();

View File

@@ -1,14 +1,9 @@
package org.briarproject.briar.sharing; package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.sharing.InvitationRequest;
import org.briarproject.briar.api.sharing.InvitationResponse;
import org.briarproject.briar.api.sharing.Shareable; import org.briarproject.briar.api.sharing.Shareable;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -41,13 +36,4 @@ interface ProtocolEngine<S extends Shareable> {
Session onAbortMessage(Transaction txn, Session session, AbortMessage m) Session onAbortMessage(Transaction txn, Session session, AbortMessage m)
throws DbException, FormatException; throws DbException, FormatException;
InvitationRequest<S> createInvitationRequest(boolean local, boolean sent,
boolean seen, boolean read, InviteMessage<S> m, ContactId c,
boolean available, boolean canBeOpened);
InvitationResponse createInvitationResponse(MessageId id, GroupId groupId,
long time, boolean local, boolean sent, boolean seen,
boolean read, GroupId shareableId, ContactId contactId,
boolean accept);
} }

View File

@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.Group.Visibility;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@@ -27,6 +28,7 @@ import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
import static org.briarproject.briar.sharing.MessageType.ABORT; import static org.briarproject.briar.sharing.MessageType.ABORT;
import static org.briarproject.briar.sharing.MessageType.ACCEPT; import static org.briarproject.briar.sharing.MessageType.ACCEPT;
import static org.briarproject.briar.sharing.MessageType.DECLINE; import static org.briarproject.briar.sharing.MessageType.DECLINE;
@@ -91,11 +93,16 @@ abstract class ProtocolEngineImpl<S extends Shareable>
Message sent = sendInviteMessage(txn, s, message, timestamp); Message sent = sendInviteMessage(txn, s, message, timestamp);
// Track the message // Track the message
messageTracker.trackOutgoingMessage(txn, sent); messageTracker.trackOutgoingMessage(txn, sent);
// Make the shareable visible to the contact
try {
setShareableVisibility(txn, s, VISIBLE);
} catch (FormatException e) {
throw new DbException(e); // Invalid group metadata
}
// Move to the REMOTE_INVITED state // Move to the REMOTE_INVITED state
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
return new Session(REMOTE_INVITED, s.getContactGroupId(), return new Session(REMOTE_INVITED, s.getContactGroupId(),
s.getShareableId(), sent.getId(), s.getLastRemoteMessageId(), s.getShareableId(), sent.getId(), s.getLastRemoteMessageId(),
localTimestamp, s.getInviteTimestamp()); sent.getTimestamp(), s.getInviteTimestamp());
} }
private Message sendInviteMessage(Transaction txn, Session s, private Message sendInviteMessage(Transaction txn, Session s,
@@ -107,8 +114,9 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); // Invalid group descriptor throw new DbException(e); // Invalid group descriptor
} }
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
Message m = messageEncoder Message m = messageEncoder
.encodeInviteMessage(s.getContactGroupId(), timestamp, .encodeInviteMessage(s.getContactGroupId(), localTimestamp,
s.getLastLocalMessageId(), descriptor, message); s.getLastLocalMessageId(), descriptor, message);
sendMessage(txn, m, INVITE, s.getShareableId(), true); sendMessage(txn, m, INVITE, s.getShareableId(), true);
return m; return m;
@@ -140,14 +148,14 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (inviteId == null) throw new IllegalStateException(); if (inviteId == null) throw new IllegalStateException();
markMessageAvailableToAnswer(txn, inviteId, false); markMessageAvailableToAnswer(txn, inviteId, false);
// Send a ACCEPT message // Send a ACCEPT message
Message sent = sendAcceptMessage(txn, s, true); Message sent = sendAcceptMessage(txn, s);
// Track the message // Track the message
messageTracker.trackOutgoingMessage(txn, sent); messageTracker.trackOutgoingMessage(txn, sent);
try { try {
// Add and subscribe to the shareable // Add and subscribe to the shareable
addShareable(txn, inviteId); addShareable(txn, inviteId);
// Share the shareable with the contact // Share the shareable with the contact
setPrivateGroupVisibility(txn, s, SHARED); setShareableVisibility(txn, s, SHARED);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); // Invalid group metadata throw new DbException(e); // Invalid group metadata
} }
@@ -160,12 +168,12 @@ abstract class ProtocolEngineImpl<S extends Shareable>
protected abstract void addShareable(Transaction txn, MessageId inviteId) protected abstract void addShareable(Transaction txn, MessageId inviteId)
throws DbException, FormatException; throws DbException, FormatException;
private Message sendAcceptMessage(Transaction txn, Session session, private Message sendAcceptMessage(Transaction txn, Session session)
boolean visibleInUi) throws DbException { throws DbException {
Message m = messageEncoder.encodeAcceptMessage( Message m = messageEncoder.encodeAcceptMessage(
session.getContactGroupId(), session.getShareableId(), session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId()); getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, ACCEPT, session.getShareableId(), visibleInUi); sendMessage(txn, m, ACCEPT, session.getShareableId(), true);
return m; return m;
} }
@@ -195,7 +203,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
if (inviteId == null) throw new IllegalStateException(); if (inviteId == null) throw new IllegalStateException();
markMessageAvailableToAnswer(txn, inviteId, false); markMessageAvailableToAnswer(txn, inviteId, false);
// Send a DECLINE message // Send a DECLINE message
Message sent = sendDeclineMessage(txn, s, true); Message sent = sendDeclineMessage(txn, s);
// Track the message // Track the message
messageTracker.trackOutgoingMessage(txn, sent); messageTracker.trackOutgoingMessage(txn, sent);
// Move to the START state // Move to the START state
@@ -204,12 +212,12 @@ abstract class ProtocolEngineImpl<S extends Shareable>
s.getInviteTimestamp()); s.getInviteTimestamp());
} }
private Message sendDeclineMessage(Transaction txn, Session session, private Message sendDeclineMessage(Transaction txn, Session session)
boolean visibleInUi) throws DbException { throws DbException {
Message m = messageEncoder.encodeDeclineMessage( Message m = messageEncoder.encodeDeclineMessage(
session.getContactGroupId(), session.getShareableId(), session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId()); getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, DECLINE, session.getShareableId(), visibleInUi); sendMessage(txn, m, DECLINE, session.getShareableId(), true);
return m; return m;
} }
@@ -228,7 +236,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
case LOCAL_LEFT: case LOCAL_LEFT:
case REMOTE_HANGING: case REMOTE_HANGING:
case ERROR: case ERROR:
throw new ProtocolStateException(); // Invalid in these states return s; // Ignored in this state
default: default:
throw new AssertionError(); throw new AssertionError();
} }
@@ -237,25 +245,25 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private Session onLocalLeave(Transaction txn, Session s, State nextState) private Session onLocalLeave(Transaction txn, Session s, State nextState)
throws DbException { throws DbException {
try { try {
// Stop sharing the shareable with the contact // Stop sharing the shareable (not actually needed in REMOTE_LEFT)
setPrivateGroupVisibility(txn, s, INVISIBLE); setShareableVisibility(txn, s, INVISIBLE);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); // Invalid group metadata throw new DbException(e); // Invalid group metadata
} }
// Send a LEAVE message // Send a LEAVE message
Message sent = sendLeaveMessage(txn, s, false); Message sent = sendLeaveMessage(txn, s);
// Move to the next state // Move to the next state
return new Session(nextState, s.getContactGroupId(), s.getShareableId(), return new Session(nextState, s.getContactGroupId(), s.getShareableId(),
sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(), sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),
s.getInviteTimestamp()); s.getInviteTimestamp());
} }
private Message sendLeaveMessage(Transaction txn, Session session, private Message sendLeaveMessage(Transaction txn, Session session)
boolean visibleInUi) throws DbException { throws DbException {
Message m = messageEncoder.encodeLeaveMessage( Message m = messageEncoder.encodeLeaveMessage(
session.getContactGroupId(), session.getShareableId(), session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId()); getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, LEAVE, session.getShareableId(), visibleInUi); sendMessage(txn, m, LEAVE, session.getShareableId(), false);
return m; return m;
} }
@@ -286,7 +294,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
throws DbException, FormatException { throws DbException, FormatException {
// The timestamp must be higher than the last invite message, if any // The timestamp must be higher than the last invite message, if any
if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s); if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s);
// Mark the invite message visible in the UI and available to answer // The dependency, if any, must be the last remote message
if (!isValidDependency(s, m.getPreviousMessageId()))
return abort(txn, s);
// Mark the invite message visible in the UI and (un)available to answer
markMessageVisibleInUi(txn, m.getId(), true); markMessageVisibleInUi(txn, m.getId(), true);
markMessageAvailableToAnswer(txn, m.getId(), available); markMessageAvailableToAnswer(txn, m.getId(), available);
// Track the message // Track the message
@@ -309,14 +320,14 @@ abstract class ProtocolEngineImpl<S extends Shareable>
// The dependency, if any, must be the last remote message // The dependency, if any, must be the last remote message
if (!isValidDependency(s, m.getPreviousMessageId())) if (!isValidDependency(s, m.getPreviousMessageId()))
return abort(txn, s); return abort(txn, s);
// Mark the invite message visible in the UI and available to answer // Mark the invite message visible in the UI and unavailable to answer
markMessageVisibleInUi(txn, m.getId(), true); markMessageVisibleInUi(txn, m.getId(), true);
markMessageAvailableToAnswer(txn, m.getId(), false); markMessageAvailableToAnswer(txn, m.getId(), false);
// Track the message // Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(), messageTracker.trackMessage(txn, m.getContactGroupId(),
m.getTimestamp(), false); m.getTimestamp(), false);
// Share the shareable with the contact // Share the shareable with the contact
setPrivateGroupVisibility(txn, s, SHARED); setShareableVisibility(txn, s, SHARED);
// Broadcast an event // Broadcast an event
ContactId contactId = getContactId(txn, s.getContactGroupId()); ContactId contactId = getContactId(txn, s.getContactGroupId());
txn.attach( txn.attach(
@@ -335,9 +346,9 @@ abstract class ProtocolEngineImpl<S extends Shareable>
AcceptMessage m) throws DbException, FormatException { AcceptMessage m) throws DbException, FormatException {
switch (s.getState()) { switch (s.getState()) {
case REMOTE_INVITED: case REMOTE_INVITED:
return onRemoteAccept(txn, s, m); return onRemoteAcceptWhenInvited(txn, s, m);
case REMOTE_HANGING: case REMOTE_HANGING:
return onRemoteAcceptWhenHanging(txn, s, m, LOCAL_LEFT); return onRemoteAccept(txn, s, m, LOCAL_LEFT);
case START: case START:
case LOCAL_INVITED: case LOCAL_INVITED:
case SHARING: case SHARING:
@@ -351,9 +362,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} }
} }
private Session onRemoteAcceptWhenHanging(Transaction txn, Session s, private Session onRemoteAccept(Transaction txn, Session s, AcceptMessage m,
AcceptMessage m, State nextState) State nextState) throws DbException, FormatException {
throws DbException, FormatException {
// The timestamp must be higher than the last invite message // The timestamp must be higher than the last invite message
if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s); if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s);
// The dependency, if any, must be the last remote message // The dependency, if any, must be the last remote message
@@ -373,13 +383,13 @@ abstract class ProtocolEngineImpl<S extends Shareable>
s.getInviteTimestamp()); s.getInviteTimestamp());
} }
private Session onRemoteAccept(Transaction txn, Session s, AcceptMessage m) private Session onRemoteAcceptWhenInvited(Transaction txn, Session s,
throws DbException, FormatException { AcceptMessage m) throws DbException, FormatException {
// Perform normal remote accept validation and operation // Perform normal remote accept validation and operation
Session session = onRemoteAcceptWhenHanging(txn, s, m, SHARING); Session session = onRemoteAccept(txn, s, m, SHARING);
// Share the shareable with the contact // Share the shareable with the contact
if (session.getState() != ERROR) if (session.getState() != ERROR)
setPrivateGroupVisibility(txn, s, SHARED); setShareableVisibility(txn, s, SHARED);
return session; return session;
} }
@@ -392,7 +402,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
switch (s.getState()) { switch (s.getState()) {
case REMOTE_INVITED: case REMOTE_INVITED:
case REMOTE_HANGING: case REMOTE_HANGING:
return onRemoteDecline(txn, s, m, START); return onRemoteDecline(txn, s, m);
case START: case START:
case LOCAL_INVITED: case LOCAL_INVITED:
case SHARING: case SHARING:
@@ -407,8 +417,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} }
private Session onRemoteDecline(Transaction txn, Session s, private Session onRemoteDecline(Transaction txn, Session s,
DeclineMessage m, State nextState) DeclineMessage m) throws DbException, FormatException {
throws DbException, FormatException {
// The timestamp must be higher than the last invite message // The timestamp must be higher than the last invite message
if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s); if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s);
// The dependency, if any, must be the last remote message // The dependency, if any, must be the last remote message
@@ -419,11 +428,17 @@ abstract class ProtocolEngineImpl<S extends Shareable>
// Track the message // Track the message
messageTracker.trackMessage(txn, m.getContactGroupId(), messageTracker.trackMessage(txn, m.getContactGroupId(),
m.getTimestamp(), false); m.getTimestamp(), false);
// Make the shareable invisible (not actually needed in REMOTE_HANGING)
try {
setShareableVisibility(txn, s, INVISIBLE);
} catch (FormatException e) {
throw new DbException(e); // Invalid group metadata
}
// Broadcast an event // Broadcast an event
ContactId contactId = getContactId(txn, m.getContactGroupId()); ContactId contactId = getContactId(txn, m.getContactGroupId());
txn.attach(getInvitationResponseReceivedEvent(m, contactId)); txn.attach(getInvitationResponseReceivedEvent(m, contactId));
// Move to the next state // Move to the next state
return new Session(nextState, s.getContactGroupId(), s.getShareableId(), return new Session(START, s.getContactGroupId(), s.getShareableId(),
s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(), s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(),
s.getInviteTimestamp()); s.getInviteTimestamp());
} }
@@ -440,7 +455,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
case LOCAL_LEFT: case LOCAL_LEFT:
return onRemoteLeave(txn, s, m, START); return onRemoteLeave(txn, s, m, START);
case SHARING: case SHARING:
return onRemoteLeaveWhenSharing(txn, s, m, REMOTE_LEFT); return onRemoteLeaveWhenSharing(txn, s, m);
case START: case START:
case REMOTE_INVITED: case REMOTE_INVITED:
case REMOTE_LEFT: case REMOTE_LEFT:
@@ -478,13 +493,12 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} }
private Session onRemoteLeaveWhenSharing(Transaction txn, Session s, private Session onRemoteLeaveWhenSharing(Transaction txn, Session s,
LeaveMessage m, State nextState) LeaveMessage m) throws DbException, FormatException {
throws DbException, FormatException {
// Carry out normal leave validation and operation // Carry out normal leave validation and operation
Session session = onRemoteLeave(txn, s, m, nextState); Session session = onRemoteLeave(txn, s, m, REMOTE_LEFT);
// Stop sharing the shareable with the contact // Stop sharing the shareable with the contact
if (session.getState() != ERROR) if (session.getState() != ERROR)
setPrivateGroupVisibility(txn, s, INVISIBLE); setShareableVisibility(txn, s, INVISIBLE);
// Move to the next state // Move to the next state
return session; return session;
} }
@@ -503,7 +517,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
markInvitesUnavailableToAnswer(txn, s); markInvitesUnavailableToAnswer(txn, s);
// If we subscribe, make the shareable invisible to the contact // If we subscribe, make the shareable invisible to the contact
if (isSubscribed(txn, s.getShareableId())) if (isSubscribed(txn, s.getShareableId()))
setPrivateGroupVisibility(txn, s, INVISIBLE); setShareableVisibility(txn, s, INVISIBLE);
// Send an ABORT message // Send an ABORT message
Message sent = sendAbortMessage(txn, s); Message sent = sendAbortMessage(txn, s);
// Move to the ERROR state // Move to the ERROR state
@@ -526,9 +540,13 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private boolean isSubscribed(Transaction txn, GroupId g) private boolean isSubscribed(Transaction txn, GroupId g)
throws DbException { throws DbException {
return db.containsGroup(txn, g); if (!db.containsGroup(txn, g)) return false;
Group group = db.getGroup(txn, g);
return group.getClientId().equals(getClientId());
} }
protected abstract ClientId getClientId();
private Message sendAbortMessage(Transaction txn, Session session) private Message sendAbortMessage(Transaction txn, Session session)
throws DbException { throws DbException {
Message m = messageEncoder.encodeAbortMessage( Message m = messageEncoder.encodeAbortMessage(
@@ -572,7 +590,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
} }
} }
private void setPrivateGroupVisibility(Transaction txn, Session session, private void setShareableVisibility(Transaction txn, Session session,
Visibility v) throws DbException, FormatException { Visibility v) throws DbException, FormatException {
ContactId contactId = getContactId(txn, session.getContactGroupId()); ContactId contactId = getContactId(txn, session.getContactGroupId());
db.setGroupVisibility(txn, contactId, session.getShareableId(), v); db.setGroupVisibility(txn, contactId, session.getShareableId(), v);

View File

@@ -32,8 +32,8 @@ class Session {
this.inviteTimestamp = inviteTimestamp; this.inviteTimestamp = inviteTimestamp;
} }
Session(GroupId contactGroupId, GroupId privateGroupId) { Session(GroupId contactGroupId, GroupId shareableId) {
this(START, contactGroupId, privateGroupId, null, null, 0, 0); this(START, contactGroupId, shareableId, null, null, 0, 0);
} }
public State getState() { public State getState() {

View File

@@ -38,12 +38,12 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(SharerEngine.class.getName()); Logger.getLogger(SharerEngine.class.getName());
private final InvitationFactory<I, SS> invitationFactory; private final OldInvitationFactory<I, SS> invitationFactory;
private final InvitationResponseReceivedEventFactory<SS, IRR> private final InvitationResponseReceivedEventFactory<SS, IRR>
invitationResponseReceivedEventFactory; invitationResponseReceivedEventFactory;
private final Clock clock; private final Clock clock;
SharerEngine(InvitationFactory<I, SS> invitationFactory, SharerEngine(OldInvitationFactory<I, SS> invitationFactory,
InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory, InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory,
Clock clock) { Clock clock) {
this.invitationFactory = invitationFactory; this.invitationFactory = invitationFactory;

View File

@@ -35,11 +35,9 @@ import org.briarproject.briar.client.ConversationClientImpl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -62,18 +60,21 @@ abstract class SharingManagerImpl<S extends Shareable>
private final SessionParser sessionParser; private final SessionParser sessionParser;
private final ContactGroupFactory contactGroupFactory; private final ContactGroupFactory contactGroupFactory;
private final ProtocolEngine<S> engine; private final ProtocolEngine<S> engine;
private final InvitationFactory<S> invitationFactory;
SharingManagerImpl(DatabaseComponent db, ClientHelper clientHelper, SharingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
MetadataParser metadataParser, MessageParser<S> messageParser, MetadataParser metadataParser, MessageParser<S> messageParser,
SessionEncoder sessionEncoder, SessionParser sessionParser, SessionEncoder sessionEncoder, SessionParser sessionParser,
MessageTracker messageTracker, MessageTracker messageTracker,
ContactGroupFactory contactGroupFactory, ProtocolEngine<S> engine) { ContactGroupFactory contactGroupFactory, ProtocolEngine<S> engine,
InvitationFactory<S> invitationFactory) {
super(db, clientHelper, metadataParser, messageTracker); super(db, clientHelper, metadataParser, messageTracker);
this.messageParser = messageParser; this.messageParser = messageParser;
this.sessionEncoder = sessionEncoder; this.sessionEncoder = sessionEncoder;
this.sessionParser = sessionParser; this.sessionParser = sessionParser;
this.contactGroupFactory = contactGroupFactory; this.contactGroupFactory = contactGroupFactory;
this.engine = engine; this.engine = engine;
this.invitationFactory = invitationFactory;
} }
protected abstract ClientId getClientId(); protected abstract ClientId getClientId();
@@ -137,8 +138,8 @@ abstract class SharingManagerImpl<S extends Shareable>
return false; return false;
} }
private SessionId getSessionId(GroupId privateGroupId) { private SessionId getSessionId(GroupId shareableId) {
return new SessionId(privateGroupId.getBytes()); return new SessionId(shareableId.getBytes());
} }
@Nullable @Nullable
@@ -222,7 +223,7 @@ abstract class SharingManagerImpl<S extends Shareable>
session = new Session(contactGroupId, shareableId); session = new Session(contactGroupId, shareableId);
storageId = createStorageId(txn, contactGroupId); storageId = createStorageId(txn, contactGroupId);
} else { } else {
// An earlier invite was declined, so we already have a session // We already have a session
session = sessionParser session = sessionParser
.parseSession(contactGroupId, ss.bdfSession); .parseSession(contactGroupId, ss.bdfSession);
storageId = ss.storageId; storageId = ss.storageId;
@@ -315,26 +316,19 @@ abstract class SharingManagerImpl<S extends Shareable>
ContactId c, MessageId m, MessageMetadata meta, ContactId c, MessageId m, MessageMetadata meta,
MessageStatus status) throws DbException, FormatException { MessageStatus status) throws DbException, FormatException {
// Look up the invite message to get the details of the private group // Look up the invite message to get the details of the private group
InviteMessage<S> invite = getInviteMessage(txn, m); InviteMessage<S> invite = messageParser.getInviteMessage(txn, m);
boolean canBeOpened = db.containsGroup(txn, invite.getShareableId()); boolean canBeOpened = db.containsGroup(txn, invite.getShareableId());
return engine.createInvitationRequest(meta.isLocal(), status.isSent(), return invitationFactory
status.isSeen(), meta.isRead(), invite, c, .createInvitationRequest(meta.isLocal(), status.isSent(),
meta.isAvailableToAnswer(), canBeOpened); status.isSeen(), meta.isRead(), invite, c,
} meta.isAvailableToAnswer(), canBeOpened);
private InviteMessage<S> getInviteMessage(Transaction txn, MessageId m)
throws DbException, FormatException {
Message message = clientHelper.getMessage(txn, m);
if (message == null) throw new DbException();
BdfList body = clientHelper.toList(message);
return messageParser.parseInviteMessage(message, body);
} }
private InvitationResponse parseInvitationResponse(ContactId c, private InvitationResponse parseInvitationResponse(ContactId c,
GroupId contactGroupId, MessageId m, MessageMetadata meta, GroupId contactGroupId, MessageId m, MessageMetadata meta,
MessageStatus status, boolean accept) MessageStatus status, boolean accept)
throws DbException, FormatException { throws DbException, FormatException {
return engine.createInvitationResponse(m, contactGroupId, return invitationFactory.createInvitationResponse(m, contactGroupId,
meta.getTimestamp(), meta.isLocal(), status.isSent(), meta.getTimestamp(), meta.isLocal(), status.isSent(),
status.isSeen(), meta.isRead(), meta.getShareableId(), c, status.isSeen(), meta.isRead(), meta.getShareableId(), c,
accept); accept);
@@ -346,9 +340,8 @@ abstract class SharingManagerImpl<S extends Shareable>
List<SharingInvitationItem> items = List<SharingInvitationItem> items =
new ArrayList<SharingInvitationItem>(); new ArrayList<SharingInvitationItem>();
BdfDictionary query = messageParser.getInvitesAvailableToAnswerQuery(); BdfDictionary query = messageParser.getInvitesAvailableToAnswerQuery();
Set<S> shareables = new HashSet<S>(); Map<S, Collection<Contact>> sharers =
Map<GroupId, Collection<Contact>> sharers = new HashMap<S, Collection<Contact>>();
new HashMap<GroupId, Collection<Contact>>();
Transaction txn = db.startTransaction(true); Transaction txn = db.startTransaction(true);
try { try {
// get invitations from each contact // get invitations from each contact
@@ -358,21 +351,22 @@ abstract class SharingManagerImpl<S extends Shareable>
clientHelper.getMessageMetadataAsDictionary(txn, clientHelper.getMessageMetadataAsDictionary(txn,
contactGroupId, query); contactGroupId, query);
for (MessageId m : results.keySet()) { for (MessageId m : results.keySet()) {
InviteMessage<S> invite = getInviteMessage(txn, m); InviteMessage<S> invite =
messageParser.getInviteMessage(txn, m);
S s = invite.getShareable(); S s = invite.getShareable();
shareables.add(s); if (sharers.containsKey(s)) {
if (sharers.containsKey(s.getId())) { sharers.get(s).add(c);
sharers.get(s.getId()).add(c);
} else { } else {
Collection<Contact> contacts = new ArrayList<Contact>(); Collection<Contact> contacts = new ArrayList<Contact>();
contacts.add(c); contacts.add(c);
sharers.put(s.getId(), contacts); sharers.put(s, contacts);
} }
} }
} }
// construct the invitation items // construct the invitation items
for (S s : shareables) { for (Entry<S, Collection<Contact>> e : sharers.entrySet()) {
Collection<Contact> contacts = sharers.get(s.getId()); S s = e.getKey();
Collection<Contact> contacts = e.getValue();
boolean subscribed = db.containsGroup(txn, s.getId()); boolean subscribed = db.containsGroup(txn, s.getId());
SharingInvitationItem invitation = SharingInvitationItem invitation =
new SharingInvitationItem(s, subscribed, contacts); new SharingInvitationItem(s, subscribed, contacts);

View File

@@ -129,4 +129,10 @@ public class SharingModule {
return forumProtocolEngine; return forumProtocolEngine;
} }
@Provides
InvitationFactory<Forum> provideForumInvitationFactory(
ForumInvitationFactoryImpl forumInvitationFactory) {
return forumInvitationFactory;
}
} }

View File

@@ -59,13 +59,13 @@ abstract class SharingValidator extends BdfMessageValidator {
byte[] previousMessageId = body.getOptionalRaw(1); byte[] previousMessageId = body.getOptionalRaw(1);
checkLength(previousMessageId, UniqueId.LENGTH); checkLength(previousMessageId, UniqueId.LENGTH);
BdfList descriptor = body.getList(2); BdfList descriptor = body.getList(2);
GroupId groupId = validateDescriptor(descriptor); GroupId shareableId = validateDescriptor(descriptor);
String msg = body.getOptionalString(3); String msg = body.getOptionalString(3);
checkLength(msg, 1, MAX_INVITATION_MESSAGE_LENGTH); checkLength(msg, 1, MAX_INVITATION_MESSAGE_LENGTH);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder
.encodeMetadata(INVITE, groupId, m.getTimestamp(), false, false, .encodeMetadata(INVITE, shareableId, m.getTimestamp(), false,
false, false); false, false, false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
@@ -81,14 +81,14 @@ abstract class SharingValidator extends BdfMessageValidator {
private BdfMessageContext validateNonInviteMessage(MessageType type, private BdfMessageContext validateNonInviteMessage(MessageType type,
Message m, BdfList body) throws FormatException { Message m, BdfList body) throws FormatException {
checkSize(body, 3); checkSize(body, 3);
byte[] groupId = body.getRaw(1); byte[] shareableId = body.getRaw(1);
checkLength(groupId, UniqueId.LENGTH); checkLength(shareableId, UniqueId.LENGTH);
byte[] previousMessageId = body.getOptionalRaw(2); byte[] previousMessageId = body.getOptionalRaw(2);
checkLength(previousMessageId, UniqueId.LENGTH); checkLength(previousMessageId, UniqueId.LENGTH);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder
.encodeMetadata(type, new GroupId(groupId), m.getTimestamp(), .encodeMetadata(type, new GroupId(shareableId),
false, false, false, false); m.getTimestamp(), false, false, false, false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {

View File

@@ -666,11 +666,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
oneOf(messageParser).parseMetadata(meta); oneOf(messageParser).parseMetadata(meta);
will(returnValue(messageMetadata1)); will(returnValue(messageMetadata1));
oneOf(db).getMessageStatus(txn, contactId, message.getId()); oneOf(db).getMessageStatus(txn, contactId, message.getId());
oneOf(clientHelper).getMessage(txn, message.getId()); oneOf(messageParser).getInviteMessage(txn, message.getId());
will(returnValue(message));
oneOf(clientHelper).toList(message);
will(returnValue(body));
oneOf(messageParser).parseInviteMessage(message, body);
will(returnValue(invite)); will(returnValue(invite));
oneOf(privateGroupFactory).createPrivateGroup(invite.getGroupName(), oneOf(privateGroupFactory).createPrivateGroup(invite.getGroupName(),
invite.getCreator(), invite.getSalt()); invite.getCreator(), invite.getSalt());
@@ -743,21 +739,13 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
contactGroup.getId(), query); contactGroup.getId(), query);
will(returnValue(results)); will(returnValue(results));
// message 1 // message 1
oneOf(clientHelper).getMessage(txn, message.getId()); oneOf(messageParser).getInviteMessage(txn, message.getId());
will(returnValue(message));
oneOf(clientHelper).toList(message);
will(returnValue(body));
oneOf(messageParser).parseInviteMessage(message, body);
will(returnValue(inviteMessage1)); will(returnValue(inviteMessage1));
oneOf(privateGroupFactory).createPrivateGroup(groupName, author, oneOf(privateGroupFactory).createPrivateGroup(groupName, author,
salt); salt);
will(returnValue(pg)); will(returnValue(pg));
// message 2 // message 2
oneOf(clientHelper).getMessage(txn, messageId2); oneOf(messageParser).getInviteMessage(txn, messageId2);
will(returnValue(message2));
oneOf(clientHelper).toList(message2);
will(returnValue(body2));
oneOf(messageParser).parseInviteMessage(message2, body2);
will(returnValue(inviteMessage2)); will(returnValue(inviteMessage2));
oneOf(privateGroupFactory).createPrivateGroup(groupName, author, oneOf(privateGroupFactory).createPrivateGroup(groupName, author,
salt); salt);

View File

@@ -144,11 +144,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
expectSendJoinMessage(properJoinMessage, true); expectSendJoinMessage(properJoinMessage, true);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageTracker).trackOutgoingMessage(txn, message); oneOf(messageTracker).trackOutgoingMessage(txn, message);
oneOf(clientHelper).getMessage(txn, lastRemoteMessageId); oneOf(messageParser).getInviteMessage(txn, lastRemoteMessageId);
will(returnValue(inviteMsg));
oneOf(clientHelper).toList(inviteMsg);
will(returnValue(inviteList));
oneOf(messageParser).parseInviteMessage(inviteMsg, inviteList);
will(returnValue(inviteMessage)); will(returnValue(inviteMessage));
oneOf(privateGroupFactory) oneOf(privateGroupFactory)
.createPrivateGroup(inviteMessage.getGroupName(), .createPrivateGroup(inviteMessage.getGroupName(),

View File

@@ -33,8 +33,6 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import javax.inject.Inject;
import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNotNull;
import static org.briarproject.bramble.test.TestUtils.getRandomString; import static org.briarproject.bramble.test.TestUtils.getRandomString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -49,9 +47,6 @@ public class ForumSharingIntegrationTest
private InviteeListener listener1; private InviteeListener listener1;
private Forum forum0; private Forum forum0;
@Inject
MessageEncoder messageEncoder;
// objects accessed from background threads need to be volatile // objects accessed from background threads need to be volatile
private volatile ForumSharingManager forumSharingManager0; private volatile ForumSharingManager forumSharingManager0;
private volatile ForumSharingManager forumSharingManager1; private volatile ForumSharingManager forumSharingManager1;

View File

@@ -3,6 +3,8 @@ package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.UniqueId; import org.briarproject.bramble.api.UniqueId;
import org.briarproject.bramble.api.client.BdfMessageContext; import org.briarproject.bramble.api.client.BdfMessageContext;
import org.briarproject.bramble.api.data.BdfDictionary;
import org.briarproject.bramble.api.data.BdfEntry;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestUtils; import org.briarproject.bramble.test.TestUtils;
@@ -20,7 +22,6 @@ import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH; import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH; import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH; import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
import static org.briarproject.briar.sharing.MessageType.ABORT; import static org.briarproject.briar.sharing.MessageType.ABORT;
import static org.briarproject.briar.sharing.MessageType.ACCEPT; import static org.briarproject.briar.sharing.MessageType.ACCEPT;
import static org.briarproject.briar.sharing.MessageType.DECLINE; import static org.briarproject.briar.sharing.MessageType.DECLINE;
@@ -46,6 +47,8 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
private final BdfList descriptor = BdfList.of(forumName, salt); private final BdfList descriptor = BdfList.of(forumName, salt);
private final String content = private final String content =
TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH); TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
private final BdfDictionary meta =
BdfDictionary.of(new BdfEntry("meta", "data"));
@Test @Test
public void testAcceptsInvitationWithContent() throws Exception { public void testAcceptsInvitationWithContent() throws Exception {
@@ -121,21 +124,20 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsInvalidMessageType() throws Exception { public void testRejectsInvalidMessageType() throws Exception {
int invalidMessageType = SHARE_MSG_TYPE_ABORT + 1; int invalidMessageType = ABORT.getValue() + 1;
v.validateMessage(message, group, v.validateMessage(message, group,
BdfList.of(invalidMessageType, groupId, previousMsgId)); BdfList.of(invalidMessageType, groupId, previousMsgId));
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsNullGroupId() throws Exception { public void testRejectsNullSessionId() throws Exception {
v.validateMessage(message, group, v.validateMessage(message, group,
BdfList.of(ABORT.getValue(), null, previousMsgId)); BdfList.of(ABORT.getValue(), null, previousMsgId));
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsNonRawSessionId() throws Exception { public void testRejectsNonRawSessionId() throws Exception {
v.validateMessage(message, group, v.validateMessage(message, group, BdfList.of(ABORT.getValue(), 123));
BdfList.of(SHARE_MSG_TYPE_ABORT, 123));
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
@@ -161,13 +163,13 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsTooLongBodyForAbort() throws Exception { public void testRejectsTooLongBodyForAbort() throws Exception {
v.validateMessage(message, group, v.validateMessage(message, group,
BdfList.of(SHARE_MSG_TYPE_ABORT, groupId, previousMsgId, 123)); BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsTooShortBodyForInvitation() throws Exception { public void testRejectsTooShortBodyForInvitation() throws Exception {
v.validateMessage(message, group, v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), groupId, forumName)); BdfList.of(INVITE.getValue(), previousMsgId, descriptor));
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
@@ -207,9 +209,10 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
BdfList validDescriptor = BdfList.of(shortForumName, salt); BdfList validDescriptor = BdfList.of(shortForumName, salt);
expectCreateForum(shortForumName); expectCreateForum(shortForumName);
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE);
v.validateMessage(message, group, BdfMessageContext messageContext = v.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor, BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
null)); null));
assertExpectedContext(messageContext, previousMsgId);
} }
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
@@ -295,6 +298,7 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
oneOf(messageEncoder) oneOf(messageEncoder)
.encodeMetadata(type, groupId, timestamp, false, false, .encodeMetadata(type, groupId, timestamp, false, false,
false, false); false, false);
will(returnValue(meta));
}}); }});
} }
@@ -307,6 +311,7 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
assertEquals(1, dependencies.size()); assertEquals(1, dependencies.size());
assertTrue(dependencies.contains(previousMsgId)); assertTrue(dependencies.contains(previousMsgId));
} }
assertEquals(meta, messageContext.getDictionary());
} }
} }