diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationFactory.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationFactory.java index eab12f741..5b4e275a3 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationFactory.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/InvitationFactory.java @@ -4,6 +4,7 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.sync.GroupId; +@Deprecated public interface InvitationFactory { I build(GroupId groupId, BdfDictionary d) throws FormatException; diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingConstants.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingConstants.java index 53f4557e4..6b8fcc4a0 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingConstants.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingConstants.java @@ -15,34 +15,63 @@ public interface SharingConstants { */ int MAX_INVITATION_MESSAGE_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024; + @Deprecated String CONTACT_ID = "contactId"; + @Deprecated String GROUP_ID = "groupId"; + @Deprecated String TO_BE_SHARED_BY_US = "toBeSharedByUs"; + @Deprecated String SHARED_BY_US = "sharedByUs"; + @Deprecated String SHARED_WITH_US = "sharedWithUs"; + @Deprecated String TYPE = "type"; + @Deprecated String SESSION_ID = "sessionId"; + @Deprecated String STORAGE_ID = "storageId"; + @Deprecated String STATE = "state"; + @Deprecated String LOCAL = "local"; + @Deprecated String TIME = "time"; + @Deprecated String IS_SHARER = "isSharer"; + @Deprecated String SHAREABLE_ID = "shareableId"; + @Deprecated String INVITATION_MSG = "invitationMsg"; + @Deprecated String INVITATION_ID = "invitationId"; + @Deprecated String RESPONSE_ID = "responseId"; + @Deprecated int SHARE_MSG_TYPE_INVITATION = 1; + @Deprecated int SHARE_MSG_TYPE_ACCEPT = 2; + @Deprecated int SHARE_MSG_TYPE_DECLINE = 3; + @Deprecated int SHARE_MSG_TYPE_LEAVE = 4; + @Deprecated int SHARE_MSG_TYPE_ABORT = 5; + @Deprecated int TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US = 0; + @Deprecated int TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US = 1; + @Deprecated int TASK_ADD_SHARED_SHAREABLE = 2; + @Deprecated 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; + @Deprecated int TASK_SHARE_SHAREABLE = 5; + @Deprecated int TASK_UNSHARE_SHAREABLE_SHARED_BY_US = 6; + @Deprecated int TASK_UNSHARE_SHAREABLE_SHARED_WITH_US = 7; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingMessage.java b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingMessage.java index 23340ac1c..dd4b987aa 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingMessage.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/sharing/SharingMessage.java @@ -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.TYPE; +@Deprecated @NotNullByDefault public interface SharingMessage { diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngine.java index 36c00ffb1..30c140119 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngine.java @@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.contact.ContactId; 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.DbException; import org.briarproject.bramble.api.db.Transaction; @@ -177,7 +176,7 @@ abstract class AbstractProtocolEngine void subscribeToPrivateGroup(Transaction txn, MessageId inviteId) throws DbException, FormatException { - InviteMessage invite = getInviteMessage(txn, inviteId); + InviteMessage invite = messageParser.getInviteMessage(txn, inviteId); PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup( invite.getGroupName(), invite.getCreator(), invite.getSalt()); long timestamp = @@ -197,14 +196,6 @@ abstract class AbstractProtocolEngine 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, GroupId privateGroupId, boolean visibleInConversation) throws DbException { diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java index 9e19966d8..1fac77c63 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java @@ -401,7 +401,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl throws DbException, FormatException { SessionId sessionId = getSessionId(meta.getPrivateGroupId()); // 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 .createPrivateGroup(invite.getGroupName(), invite.getCreator(), invite.getSalt()); @@ -412,14 +412,6 @@ class GroupInvitationManagerImpl extends ConversationClientImpl 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, GroupId contactGroupId, MessageId m, MessageMetadata meta, MessageStatus status, boolean accept) @@ -479,7 +471,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl private GroupInvitationItem parseGroupInvitationItem(Transaction txn, Contact c, MessageId m) throws DbException, FormatException { - InviteMessage invite = getInviteMessage(txn, m); + InviteMessage invite = messageParser.getInviteMessage(txn, m); PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup( invite.getGroupName(), invite.getCreator(), invite.getSalt()); return new GroupInvitationItem(privateGroup, c); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParser.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParser.java index 9e6a7ad9d..8300b305c 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParser.java @@ -3,9 +3,12 @@ package org.briarproject.briar.privategroup.invitation; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.data.BdfDictionary; 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.sync.GroupId; import org.briarproject.bramble.api.sync.Message; +import org.briarproject.bramble.api.sync.MessageId; @NotNullByDefault interface MessageParser { @@ -18,6 +21,9 @@ interface MessageParser { MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; + InviteMessage getInviteMessage(Transaction txn, MessageId m) + throws DbException, FormatException; + InviteMessage parseInviteMessage(Message m, BdfList body) throws FormatException; diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java index b31ff7d31..1cf35ee9c 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/MessageParserImpl.java @@ -1,9 +1,12 @@ package org.briarproject.briar.privategroup.invitation; 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.BdfEntry; 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.AuthorFactory; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @@ -31,12 +34,14 @@ class MessageParserImpl implements MessageParser { private final AuthorFactory authorFactory; private final PrivateGroupFactory privateGroupFactory; + private final ClientHelper clientHelper; @Inject MessageParserImpl(AuthorFactory authorFactory, - PrivateGroupFactory privateGroupFactory) { + PrivateGroupFactory privateGroupFactory, ClientHelper clientHelper) { this.authorFactory = authorFactory; this.privateGroupFactory = privateGroupFactory; + this.clientHelper = clientHelper; } @Override @@ -78,6 +83,15 @@ class MessageParserImpl implements MessageParser { 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 public InviteMessage parseInviteMessage(Message m, BdfList body) throws FormatException { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/AbortMessage.java b/briar-core/src/main/java/org/briarproject/briar/sharing/AbortMessage.java index 872ab42d1..188c0b501 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/AbortMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/AbortMessage.java @@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class AbortMessage extends SharingMessage { +class AbortMessage extends SharingMessage { AbortMessage(MessageId id, GroupId contactGroupId, GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId) { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/AcceptMessage.java b/briar-core/src/main/java/org/briarproject/briar/sharing/AcceptMessage.java index 81d7df815..0a440a5cd 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/AcceptMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/AcceptMessage.java @@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class AcceptMessage extends SharingMessage { +class AcceptMessage extends SharingMessage { AcceptMessage(MessageId id, @Nullable MessageId previousMessageId, GroupId contactGroupId, GroupId shareableId, long timestamp) { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java index c0bd11ca9..a436dd9a3 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/BlogSharingManagerImpl.java @@ -159,7 +159,7 @@ class BlogSharingManagerImpl extends } @Override - protected InvitationFactory getIFactory() { + protected OldInvitationFactory getIFactory() { return iFactory; } @@ -251,7 +251,7 @@ class BlogSharingManagerImpl extends } private static class IFactory implements - InvitationFactory { + OldInvitationFactory { @Override public BlogInvitation build(GroupId groupId, BdfDictionary d) throws FormatException { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/DeclineMessage.java b/briar-core/src/main/java/org/briarproject/briar/sharing/DeclineMessage.java index 9ae35ece6..65f9a9fe1 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/DeclineMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/DeclineMessage.java @@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class DeclineMessage extends SharingMessage { +class DeclineMessage extends SharingMessage { DeclineMessage(MessageId id, GroupId contactGroupId, GroupId shareableId, long timestamp, diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java new file mode 100644 index 000000000..591f25bc9 --- /dev/null +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumInvitationFactoryImpl.java @@ -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 { + + @Inject + ForumInvitationFactoryImpl() { + } + + @Override + public ForumInvitationRequest createInvitationRequest(boolean local, + boolean sent, boolean seen, boolean read, InviteMessage 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); + } + +} diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java index 1e542b760..ed1ca425c 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumMessageParserImpl.java @@ -1,6 +1,7 @@ package org.briarproject.briar.sharing; 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.nullsafety.NotNullByDefault; import org.briarproject.briar.api.forum.Forum; @@ -16,8 +17,9 @@ class ForumMessageParserImpl extends MessageParserImpl { private final ForumFactory forumFactory; @Inject - ForumMessageParserImpl(ForumFactory forumFactory) { - super(); + ForumMessageParserImpl(ClientHelper clientHelper, + ForumFactory forumFactory) { + super(clientHelper); this.forumFactory = forumFactory; } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java index 3e89fab90..0dd97300b 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumProtocolEngineImpl.java @@ -3,22 +3,20 @@ package org.briarproject.briar.sharing; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; 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.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.GroupId; -import org.briarproject.bramble.api.sync.Message; +import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.system.Clock; 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.ForumInvitationRequest; import org.briarproject.briar.api.forum.ForumInvitationResponse; 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.ForumInvitationResponseReceivedEvent; @@ -30,23 +28,27 @@ import javax.inject.Inject; class ForumProtocolEngineImpl extends ProtocolEngineImpl { private final ForumManager forumManager; + private final InvitationFactory invitationFactory; @Inject ForumProtocolEngineImpl(DatabaseComponent db, ClientHelper clientHelper, MessageEncoder messageEncoder, MessageParser messageParser, MessageTracker messageTracker, - Clock clock, ForumManager forumManager) { + Clock clock, ForumManager forumManager, + InvitationFactory invitationFactory) { super(db, clientHelper, messageEncoder, messageParser, messageTracker, clock); this.forumManager = forumManager; + this.invitationFactory = invitationFactory; } @Override Event getInvitationRequestReceivedEvent(InviteMessage m, ContactId contactId, boolean available, boolean canBeOpened) { ForumInvitationRequest request = - createInvitationRequest(false, false, true, false, m, contactId, - available, canBeOpened); + (ForumInvitationRequest) invitationFactory + .createInvitationRequest(false, false, true, false, m, + contactId, available, canBeOpened); return new ForumInvitationRequestReceivedEvent(m.getShareable(), contactId, request); } @@ -55,9 +57,11 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { Event getInvitationResponseReceivedEvent(AcceptMessage m, ContactId contactId) { ForumInvitationResponse response = - createInvitationResponse(m.getId(), m.getContactGroupId(), - m.getTimestamp(), false, false, true, false, - m.getShareableId(), contactId, true); + (ForumInvitationResponse) invitationFactory + .createInvitationResponse(m.getId(), + m.getContactGroupId(), m.getTimestamp(), false, + false, true, false, m.getShareableId(), + contactId, true); return new ForumInvitationResponseReceivedEvent(contactId, response); } @@ -65,45 +69,25 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl { Event getInvitationResponseReceivedEvent(DeclineMessage m, ContactId contactId) { ForumInvitationResponse response = - createInvitationResponse(m.getId(), m.getContactGroupId(), - m.getTimestamp(), false, false, true, false, - m.getShareableId(), contactId, true); + (ForumInvitationResponse) invitationFactory + .createInvitationResponse(m.getId(), + m.getContactGroupId(), m.getTimestamp(), false, + false, true, false, m.getShareableId(), + contactId, true); return new ForumInvitationResponseReceivedEvent(contactId, response); } + @Override + protected ClientId getClientId() { + return ForumSharingManager.CLIENT_ID; + } + @Override protected void addShareable(Transaction txn, MessageId inviteId) throws DbException, FormatException { - InviteMessage invite = getInviteMessage(txn, inviteId); + InviteMessage invite = + messageParser.getInviteMessage(txn, inviteId); forumManager.addForum(txn, invite.getShareable()); } - 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); - } - - @Override - public ForumInvitationRequest createInvitationRequest(boolean local, - boolean sent, boolean seen, boolean read, InviteMessage 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); - } - } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumSharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumSharingManagerImpl.java index 24a04a752..a2e8d18d9 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ForumSharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ForumSharingManagerImpl.java @@ -25,9 +25,11 @@ class ForumSharingManagerImpl extends SharingManagerImpl SessionEncoder sessionEncoder, SessionParser sessionParser, MessageTracker messageTracker, ContactGroupFactory contactGroupFactory, - ProtocolEngine engine) { + ProtocolEngine engine, + InvitationFactory invitationFactory) { super(db, clientHelper, metadataParser, messageParser, sessionEncoder, - sessionParser, messageTracker, contactGroupFactory, engine); + sessionParser, messageTracker, contactGroupFactory, engine, + invitationFactory); } @Override diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java b/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java index cc704e6fa..ab9fa0e23 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/InvitationFactory.java @@ -1,12 +1,21 @@ package org.briarproject.briar.sharing; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.briar.api.sharing.SharingMessage; +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.sharing.InvitationRequest; +import org.briarproject.briar.api.sharing.InvitationResponse; +import org.briarproject.briar.api.sharing.Shareable; -@Deprecated -@NotNullByDefault -interface InvitationFactory - extends org.briarproject.briar.api.sharing.InvitationFactory { +public interface InvitationFactory { + + InvitationRequest createInvitationRequest(boolean local, boolean sent, + boolean seen, boolean read, InviteMessage 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); } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/InviteMessage.java b/briar-core/src/main/java/org/briarproject/briar/sharing/InviteMessage.java index 31b53efe9..f6343cd8d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/InviteMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/InviteMessage.java @@ -10,7 +10,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class InviteMessage extends SharingMessage { +class InviteMessage extends SharingMessage { private final S shareable; @Nullable diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/LeaveMessage.java b/briar-core/src/main/java/org/briarproject/briar/sharing/LeaveMessage.java index 33953bc31..f51857055 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/LeaveMessage.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/LeaveMessage.java @@ -9,7 +9,7 @@ import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class LeaveMessage extends SharingMessage { +class LeaveMessage extends SharingMessage { LeaveMessage(MessageId id, GroupId contactGroupId, GroupId shareableId, long timestamp, diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoder.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoder.java index d19d55bdf..33ce9b3fc 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoder.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoder.java @@ -12,7 +12,7 @@ import javax.annotation.Nullable; @NotNullByDefault interface MessageEncoder { - BdfDictionary encodeMetadata(MessageType type, GroupId groupId, + BdfDictionary encodeMetadata(MessageType type, GroupId shareableId, long timestamp, boolean local, boolean read, boolean visible, boolean available); @@ -24,16 +24,16 @@ interface MessageEncoder { @Nullable MessageId previousMessageId, BdfList descriptor, @Nullable String message); - Message encodeAcceptMessage(GroupId contactGroupId, GroupId groupId, + Message encodeAcceptMessage(GroupId contactGroupId, GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId); - Message encodeDeclineMessage(GroupId contactGroupId, GroupId groupId, + Message encodeDeclineMessage(GroupId contactGroupId, GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId); - Message encodeLeaveMessage(GroupId contactGroupId, GroupId groupId, + Message encodeLeaveMessage(GroupId contactGroupId, GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId); - Message encodeAbortMessage(GroupId contactGroupId, GroupId groupId, + Message encodeAbortMessage(GroupId contactGroupId, GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId); } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoderImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoderImpl.java index 187cafe56..1047df487 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoderImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageEncoderImpl.java @@ -43,11 +43,11 @@ class MessageEncoderImpl implements MessageEncoder { @Override 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) { BdfDictionary meta = new BdfDictionary(); 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_LOCAL, local); meta.put(MSG_KEY_READ, read); @@ -88,42 +88,42 @@ class MessageEncoderImpl implements MessageEncoder { @Override public Message encodeAcceptMessage(GroupId contactGroupId, - GroupId privateGroupId, long timestamp, + GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId) { - return encodeMessage(ACCEPT, contactGroupId, privateGroupId, timestamp, + return encodeMessage(ACCEPT, contactGroupId, shareableId, timestamp, previousMessageId); } @Override public Message encodeDeclineMessage(GroupId contactGroupId, - GroupId privateGroupId, long timestamp, + GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId) { - return encodeMessage(DECLINE, contactGroupId, privateGroupId, timestamp, + return encodeMessage(DECLINE, contactGroupId, shareableId, timestamp, previousMessageId); } @Override public Message encodeLeaveMessage(GroupId contactGroupId, - GroupId privateGroupId, long timestamp, + GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId) { - return encodeMessage(LEAVE, contactGroupId, privateGroupId, timestamp, + return encodeMessage(LEAVE, contactGroupId, shareableId, timestamp, previousMessageId); } @Override public Message encodeAbortMessage(GroupId contactGroupId, - GroupId privateGroupId, long timestamp, + GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId) { - return encodeMessage(ABORT, contactGroupId, privateGroupId, timestamp, + return encodeMessage(ABORT, contactGroupId, shareableId, timestamp, previousMessageId); } private Message encodeMessage(MessageType type, GroupId contactGroupId, - GroupId groupId, long timestamp, + GroupId shareableId, long timestamp, @Nullable MessageId previousMessageId) { BdfList body = BdfList.of( type.getValue(), - groupId, + shareableId, previousMessageId ); try { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java index 17d9f73b1..869d017ad 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParser.java @@ -3,9 +3,12 @@ package org.briarproject.briar.sharing; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.data.BdfDictionary; 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.sync.GroupId; import org.briarproject.bramble.api.sync.Message; +import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.briar.api.sharing.Shareable; @NotNullByDefault @@ -15,10 +18,13 @@ interface MessageParser { BdfDictionary getInvitesAvailableToAnswerQuery(); - BdfDictionary getInvitesAvailableToAnswerQuery(GroupId privateGroupId); + BdfDictionary getInvitesAvailableToAnswerQuery(GroupId shareableId); MessageMetadata parseMetadata(BdfDictionary meta) throws FormatException; + InviteMessage getInviteMessage(Transaction txn, MessageId m) + throws DbException, FormatException; + InviteMessage parseInviteMessage(Message m, BdfList body) throws FormatException; diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java index 74be4c5ca..438494117 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/MessageParserImpl.java @@ -1,9 +1,12 @@ package org.briarproject.briar.sharing; 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.BdfEntry; 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.sync.GroupId; 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 implements MessageParser { - MessageParserImpl() { + private final ClientHelper clientHelper; + + MessageParserImpl(ClientHelper clientHelper) { + this.clientHelper = clientHelper; } @Override @@ -66,6 +72,15 @@ abstract class MessageParserImpl 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 public InviteMessage parseInviteMessage(Message m, BdfList body) throws FormatException { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/OldInvitationFactory.java b/briar-core/src/main/java/org/briarproject/briar/sharing/OldInvitationFactory.java new file mode 100644 index 000000000..7f127a1c8 --- /dev/null +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/OldInvitationFactory.java @@ -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 + extends org.briarproject.briar.api.sharing.InvitationFactory { + + I build(SS localState, long time); +} diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/OldSharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/OldSharingManagerImpl.java index 0284e980d..613ee0bed 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/OldSharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/OldSharingManagerImpl.java @@ -137,7 +137,7 @@ abstract class OldSharingManagerImpl getSFactory(); - protected abstract InvitationFactory getIFactory(); + protected abstract OldInvitationFactory getIFactory(); protected abstract InviteeSessionStateFactory getISFactory(); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java index 57945d4ef..4277303c6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngine.java @@ -1,14 +1,9 @@ package org.briarproject.briar.sharing; 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.Transaction; 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 javax.annotation.Nullable; @@ -41,13 +36,4 @@ interface ProtocolEngine { Session onAbortMessage(Transaction txn, Session session, AbortMessage m) throws DbException, FormatException; - InvitationRequest createInvitationRequest(boolean local, boolean sent, - boolean seen, boolean read, InviteMessage 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); - } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java index 3c54a62f7..dd8132d90 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/ProtocolEngineImpl.java @@ -10,6 +10,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.Event; 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.Visibility; 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.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.ACCEPT; import static org.briarproject.briar.sharing.MessageType.DECLINE; @@ -91,11 +93,16 @@ abstract class ProtocolEngineImpl Message sent = sendInviteMessage(txn, s, message, timestamp); // Track the message 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 - long localTimestamp = Math.max(timestamp, getLocalTimestamp(s)); return new Session(REMOTE_INVITED, s.getContactGroupId(), s.getShareableId(), sent.getId(), s.getLastRemoteMessageId(), - localTimestamp, s.getInviteTimestamp()); + sent.getTimestamp(), s.getInviteTimestamp()); } private Message sendInviteMessage(Transaction txn, Session s, @@ -107,8 +114,9 @@ abstract class ProtocolEngineImpl } catch (FormatException e) { throw new DbException(e); // Invalid group descriptor } + long localTimestamp = Math.max(timestamp, getLocalTimestamp(s)); Message m = messageEncoder - .encodeInviteMessage(s.getContactGroupId(), timestamp, + .encodeInviteMessage(s.getContactGroupId(), localTimestamp, s.getLastLocalMessageId(), descriptor, message); sendMessage(txn, m, INVITE, s.getShareableId(), true); return m; @@ -140,14 +148,14 @@ abstract class ProtocolEngineImpl if (inviteId == null) throw new IllegalStateException(); markMessageAvailableToAnswer(txn, inviteId, false); // Send a ACCEPT message - Message sent = sendAcceptMessage(txn, s, true); + Message sent = sendAcceptMessage(txn, s); // Track the message messageTracker.trackOutgoingMessage(txn, sent); try { // Add and subscribe to the shareable addShareable(txn, inviteId); // Share the shareable with the contact - setPrivateGroupVisibility(txn, s, SHARED); + setShareableVisibility(txn, s, SHARED); } catch (FormatException e) { throw new DbException(e); // Invalid group metadata } @@ -160,12 +168,12 @@ abstract class ProtocolEngineImpl protected abstract void addShareable(Transaction txn, MessageId inviteId) throws DbException, FormatException; - private Message sendAcceptMessage(Transaction txn, Session session, - boolean visibleInUi) throws DbException { + private Message sendAcceptMessage(Transaction txn, Session session) + throws DbException { Message m = messageEncoder.encodeAcceptMessage( session.getContactGroupId(), session.getShareableId(), getLocalTimestamp(session), session.getLastLocalMessageId()); - sendMessage(txn, m, ACCEPT, session.getShareableId(), visibleInUi); + sendMessage(txn, m, ACCEPT, session.getShareableId(), true); return m; } @@ -195,7 +203,7 @@ abstract class ProtocolEngineImpl if (inviteId == null) throw new IllegalStateException(); markMessageAvailableToAnswer(txn, inviteId, false); // Send a DECLINE message - Message sent = sendDeclineMessage(txn, s, true); + Message sent = sendDeclineMessage(txn, s); // Track the message messageTracker.trackOutgoingMessage(txn, sent); // Move to the START state @@ -204,12 +212,12 @@ abstract class ProtocolEngineImpl s.getInviteTimestamp()); } - private Message sendDeclineMessage(Transaction txn, Session session, - boolean visibleInUi) throws DbException { + private Message sendDeclineMessage(Transaction txn, Session session) + throws DbException { Message m = messageEncoder.encodeDeclineMessage( session.getContactGroupId(), session.getShareableId(), getLocalTimestamp(session), session.getLastLocalMessageId()); - sendMessage(txn, m, DECLINE, session.getShareableId(), visibleInUi); + sendMessage(txn, m, DECLINE, session.getShareableId(), true); return m; } @@ -228,7 +236,7 @@ abstract class ProtocolEngineImpl case LOCAL_LEFT: case REMOTE_HANGING: case ERROR: - throw new ProtocolStateException(); // Invalid in these states + return s; // Ignored in this state default: throw new AssertionError(); } @@ -237,25 +245,25 @@ abstract class ProtocolEngineImpl private Session onLocalLeave(Transaction txn, Session s, State nextState) throws DbException { try { - // Stop sharing the shareable with the contact - setPrivateGroupVisibility(txn, s, INVISIBLE); + // Stop sharing the shareable (not actually needed in REMOTE_LEFT) + setShareableVisibility(txn, s, INVISIBLE); } catch (FormatException e) { throw new DbException(e); // Invalid group metadata } // Send a LEAVE message - Message sent = sendLeaveMessage(txn, s, false); + Message sent = sendLeaveMessage(txn, s); // Move to the next state return new Session(nextState, s.getContactGroupId(), s.getShareableId(), sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(), s.getInviteTimestamp()); } - private Message sendLeaveMessage(Transaction txn, Session session, - boolean visibleInUi) throws DbException { + private Message sendLeaveMessage(Transaction txn, Session session) + throws DbException { Message m = messageEncoder.encodeLeaveMessage( session.getContactGroupId(), session.getShareableId(), getLocalTimestamp(session), session.getLastLocalMessageId()); - sendMessage(txn, m, LEAVE, session.getShareableId(), visibleInUi); + sendMessage(txn, m, LEAVE, session.getShareableId(), false); return m; } @@ -286,7 +294,10 @@ abstract class ProtocolEngineImpl throws DbException, FormatException { // The timestamp must be higher than the last invite message, if any 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); markMessageAvailableToAnswer(txn, m.getId(), available); // Track the message @@ -309,14 +320,14 @@ abstract class ProtocolEngineImpl // 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 available to answer + // Mark the invite message visible in the UI and unavailable to answer markMessageVisibleInUi(txn, m.getId(), true); markMessageAvailableToAnswer(txn, m.getId(), false); // Track the message messageTracker.trackMessage(txn, m.getContactGroupId(), m.getTimestamp(), false); // Share the shareable with the contact - setPrivateGroupVisibility(txn, s, SHARED); + setShareableVisibility(txn, s, SHARED); // Broadcast an event ContactId contactId = getContactId(txn, s.getContactGroupId()); txn.attach( @@ -335,9 +346,9 @@ abstract class ProtocolEngineImpl AcceptMessage m) throws DbException, FormatException { switch (s.getState()) { case REMOTE_INVITED: - return onRemoteAccept(txn, s, m); + return onRemoteAcceptWhenInvited(txn, s, m); case REMOTE_HANGING: - return onRemoteAcceptWhenHanging(txn, s, m, LOCAL_LEFT); + return onRemoteAccept(txn, s, m, LOCAL_LEFT); case START: case LOCAL_INVITED: case SHARING: @@ -351,9 +362,8 @@ abstract class ProtocolEngineImpl } } - private Session onRemoteAcceptWhenHanging(Transaction txn, Session s, - AcceptMessage m, State nextState) - throws DbException, FormatException { + private Session onRemoteAccept(Transaction txn, Session s, AcceptMessage m, + State nextState) throws DbException, FormatException { // The timestamp must be higher than the last invite message if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s); // The dependency, if any, must be the last remote message @@ -373,13 +383,13 @@ abstract class ProtocolEngineImpl s.getInviteTimestamp()); } - private Session onRemoteAccept(Transaction txn, Session s, AcceptMessage m) - throws DbException, FormatException { + private Session onRemoteAcceptWhenInvited(Transaction txn, Session s, + AcceptMessage m) throws DbException, FormatException { // 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 if (session.getState() != ERROR) - setPrivateGroupVisibility(txn, s, SHARED); + setShareableVisibility(txn, s, SHARED); return session; } @@ -392,7 +402,7 @@ abstract class ProtocolEngineImpl switch (s.getState()) { case REMOTE_INVITED: case REMOTE_HANGING: - return onRemoteDecline(txn, s, m, START); + return onRemoteDecline(txn, s, m); case START: case LOCAL_INVITED: case SHARING: @@ -407,8 +417,7 @@ abstract class ProtocolEngineImpl } private Session onRemoteDecline(Transaction txn, Session s, - DeclineMessage m, State nextState) - throws DbException, FormatException { + DeclineMessage m) throws DbException, FormatException { // The timestamp must be higher than the last invite message if (m.getTimestamp() <= s.getInviteTimestamp()) return abort(txn, s); // The dependency, if any, must be the last remote message @@ -419,11 +428,17 @@ abstract class ProtocolEngineImpl // Track the message messageTracker.trackMessage(txn, m.getContactGroupId(), 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 ContactId contactId = getContactId(txn, m.getContactGroupId()); txn.attach(getInvitationResponseReceivedEvent(m, contactId)); // 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.getInviteTimestamp()); } @@ -440,7 +455,7 @@ abstract class ProtocolEngineImpl case LOCAL_LEFT: return onRemoteLeave(txn, s, m, START); case SHARING: - return onRemoteLeaveWhenSharing(txn, s, m, REMOTE_LEFT); + return onRemoteLeaveWhenSharing(txn, s, m); case START: case REMOTE_INVITED: case REMOTE_LEFT: @@ -478,13 +493,12 @@ abstract class ProtocolEngineImpl } private Session onRemoteLeaveWhenSharing(Transaction txn, Session s, - LeaveMessage m, State nextState) - throws DbException, FormatException { + LeaveMessage m) throws DbException, FormatException { // 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 if (session.getState() != ERROR) - setPrivateGroupVisibility(txn, s, INVISIBLE); + setShareableVisibility(txn, s, INVISIBLE); // Move to the next state return session; } @@ -503,7 +517,7 @@ abstract class ProtocolEngineImpl markInvitesUnavailableToAnswer(txn, s); // If we subscribe, make the shareable invisible to the contact if (isSubscribed(txn, s.getShareableId())) - setPrivateGroupVisibility(txn, s, INVISIBLE); + setShareableVisibility(txn, s, INVISIBLE); // Send an ABORT message Message sent = sendAbortMessage(txn, s); // Move to the ERROR state @@ -526,9 +540,13 @@ abstract class ProtocolEngineImpl private boolean isSubscribed(Transaction txn, GroupId g) 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) throws DbException { Message m = messageEncoder.encodeAbortMessage( @@ -572,7 +590,7 @@ abstract class ProtocolEngineImpl } } - private void setPrivateGroupVisibility(Transaction txn, Session session, + private void setShareableVisibility(Transaction txn, Session session, Visibility v) throws DbException, FormatException { ContactId contactId = getContactId(txn, session.getContactGroupId()); db.setGroupVisibility(txn, contactId, session.getShareableId(), v); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/Session.java b/briar-core/src/main/java/org/briarproject/briar/sharing/Session.java index b1f826462..6e0a55201 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/Session.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/Session.java @@ -32,8 +32,8 @@ class Session { this.inviteTimestamp = inviteTimestamp; } - Session(GroupId contactGroupId, GroupId privateGroupId) { - this(START, contactGroupId, privateGroupId, null, null, 0, 0); + Session(GroupId contactGroupId, GroupId shareableId) { + this(START, contactGroupId, shareableId, null, null, 0, 0); } public State getState() { diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharerEngine.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharerEngine.java index 5d959f40f..eb05d87cd 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharerEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharerEngine.java @@ -38,12 +38,12 @@ class SharerEngine invitationFactory; + private final OldInvitationFactory invitationFactory; private final InvitationResponseReceivedEventFactory invitationResponseReceivedEventFactory; private final Clock clock; - SharerEngine(InvitationFactory invitationFactory, + SharerEngine(OldInvitationFactory invitationFactory, InvitationResponseReceivedEventFactory invitationResponseReceivedEventFactory, Clock clock) { this.invitationFactory = invitationFactory; diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java index 32789212d..e0c640e1e 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java @@ -35,11 +35,9 @@ import org.briarproject.briar.client.ConversationClientImpl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import javax.annotation.Nullable; @@ -62,18 +60,21 @@ abstract class SharingManagerImpl private final SessionParser sessionParser; private final ContactGroupFactory contactGroupFactory; private final ProtocolEngine engine; + private final InvitationFactory invitationFactory; SharingManagerImpl(DatabaseComponent db, ClientHelper clientHelper, MetadataParser metadataParser, MessageParser messageParser, SessionEncoder sessionEncoder, SessionParser sessionParser, MessageTracker messageTracker, - ContactGroupFactory contactGroupFactory, ProtocolEngine engine) { + ContactGroupFactory contactGroupFactory, ProtocolEngine engine, + InvitationFactory invitationFactory) { super(db, clientHelper, metadataParser, messageTracker); this.messageParser = messageParser; this.sessionEncoder = sessionEncoder; this.sessionParser = sessionParser; this.contactGroupFactory = contactGroupFactory; this.engine = engine; + this.invitationFactory = invitationFactory; } protected abstract ClientId getClientId(); @@ -137,8 +138,8 @@ abstract class SharingManagerImpl return false; } - private SessionId getSessionId(GroupId privateGroupId) { - return new SessionId(privateGroupId.getBytes()); + private SessionId getSessionId(GroupId shareableId) { + return new SessionId(shareableId.getBytes()); } @Nullable @@ -222,7 +223,7 @@ abstract class SharingManagerImpl session = new Session(contactGroupId, shareableId); storageId = createStorageId(txn, contactGroupId); } else { - // An earlier invite was declined, so we already have a session + // We already have a session session = sessionParser .parseSession(contactGroupId, ss.bdfSession); storageId = ss.storageId; @@ -315,26 +316,19 @@ abstract class SharingManagerImpl ContactId c, MessageId m, MessageMetadata meta, MessageStatus status) throws DbException, FormatException { // Look up the invite message to get the details of the private group - InviteMessage invite = getInviteMessage(txn, m); + InviteMessage invite = messageParser.getInviteMessage(txn, m); boolean canBeOpened = db.containsGroup(txn, invite.getShareableId()); - return engine.createInvitationRequest(meta.isLocal(), status.isSent(), - status.isSeen(), meta.isRead(), invite, c, - 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); + return invitationFactory + .createInvitationRequest(meta.isLocal(), status.isSent(), + status.isSeen(), meta.isRead(), invite, c, + meta.isAvailableToAnswer(), canBeOpened); } private InvitationResponse parseInvitationResponse(ContactId c, GroupId contactGroupId, MessageId m, MessageMetadata meta, MessageStatus status, boolean accept) throws DbException, FormatException { - return engine.createInvitationResponse(m, contactGroupId, + return invitationFactory.createInvitationResponse(m, contactGroupId, meta.getTimestamp(), meta.isLocal(), status.isSent(), status.isSeen(), meta.isRead(), meta.getShareableId(), c, accept); @@ -346,9 +340,8 @@ abstract class SharingManagerImpl List items = new ArrayList(); BdfDictionary query = messageParser.getInvitesAvailableToAnswerQuery(); - Set shareables = new HashSet(); - Map> sharers = - new HashMap>(); + Map> sharers = + new HashMap>(); Transaction txn = db.startTransaction(true); try { // get invitations from each contact @@ -358,21 +351,22 @@ abstract class SharingManagerImpl clientHelper.getMessageMetadataAsDictionary(txn, contactGroupId, query); for (MessageId m : results.keySet()) { - InviteMessage invite = getInviteMessage(txn, m); + InviteMessage invite = + messageParser.getInviteMessage(txn, m); S s = invite.getShareable(); - shareables.add(s); - if (sharers.containsKey(s.getId())) { - sharers.get(s.getId()).add(c); + if (sharers.containsKey(s)) { + sharers.get(s).add(c); } else { Collection contacts = new ArrayList(); contacts.add(c); - sharers.put(s.getId(), contacts); + sharers.put(s, contacts); } } } // construct the invitation items - for (S s : shareables) { - Collection contacts = sharers.get(s.getId()); + for (Entry> e : sharers.entrySet()) { + S s = e.getKey(); + Collection contacts = e.getValue(); boolean subscribed = db.containsGroup(txn, s.getId()); SharingInvitationItem invitation = new SharingInvitationItem(s, subscribed, contacts); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java index 9eda631b6..e4a24c1b7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java @@ -129,4 +129,10 @@ public class SharingModule { return forumProtocolEngine; } + @Provides + InvitationFactory provideForumInvitationFactory( + ForumInvitationFactoryImpl forumInvitationFactory) { + return forumInvitationFactory; + } + } diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java index 631a6b30c..e8f9287f8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingValidator.java @@ -59,13 +59,13 @@ abstract class SharingValidator extends BdfMessageValidator { byte[] previousMessageId = body.getOptionalRaw(1); checkLength(previousMessageId, UniqueId.LENGTH); BdfList descriptor = body.getList(2); - GroupId groupId = validateDescriptor(descriptor); + GroupId shareableId = validateDescriptor(descriptor); String msg = body.getOptionalString(3); checkLength(msg, 1, MAX_INVITATION_MESSAGE_LENGTH); BdfDictionary meta = messageEncoder - .encodeMetadata(INVITE, groupId, m.getTimestamp(), false, false, - false, false); + .encodeMetadata(INVITE, shareableId, m.getTimestamp(), false, + false, false, false); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { @@ -81,14 +81,14 @@ abstract class SharingValidator extends BdfMessageValidator { private BdfMessageContext validateNonInviteMessage(MessageType type, Message m, BdfList body) throws FormatException { checkSize(body, 3); - byte[] groupId = body.getRaw(1); - checkLength(groupId, UniqueId.LENGTH); + byte[] shareableId = body.getRaw(1); + checkLength(shareableId, UniqueId.LENGTH); byte[] previousMessageId = body.getOptionalRaw(2); checkLength(previousMessageId, UniqueId.LENGTH); BdfDictionary meta = messageEncoder - .encodeMetadata(type, new GroupId(groupId), m.getTimestamp(), - false, false, false, false); + .encodeMetadata(type, new GroupId(shareableId), + m.getTimestamp(), false, false, false, false); if (previousMessageId == null) { return new BdfMessageContext(meta); } else { diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java index 774057c50..37c7b76e3 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java @@ -666,11 +666,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { oneOf(messageParser).parseMetadata(meta); will(returnValue(messageMetadata1)); oneOf(db).getMessageStatus(txn, contactId, message.getId()); - oneOf(clientHelper).getMessage(txn, message.getId()); - will(returnValue(message)); - oneOf(clientHelper).toList(message); - will(returnValue(body)); - oneOf(messageParser).parseInviteMessage(message, body); + oneOf(messageParser).getInviteMessage(txn, message.getId()); will(returnValue(invite)); oneOf(privateGroupFactory).createPrivateGroup(invite.getGroupName(), invite.getCreator(), invite.getSalt()); @@ -743,21 +739,13 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { contactGroup.getId(), query); will(returnValue(results)); // message 1 - oneOf(clientHelper).getMessage(txn, message.getId()); - will(returnValue(message)); - oneOf(clientHelper).toList(message); - will(returnValue(body)); - oneOf(messageParser).parseInviteMessage(message, body); + oneOf(messageParser).getInviteMessage(txn, message.getId()); will(returnValue(inviteMessage1)); oneOf(privateGroupFactory).createPrivateGroup(groupName, author, salt); will(returnValue(pg)); // message 2 - oneOf(clientHelper).getMessage(txn, messageId2); - will(returnValue(message2)); - oneOf(clientHelper).toList(message2); - will(returnValue(body2)); - oneOf(messageParser).parseInviteMessage(message2, body2); + oneOf(messageParser).getInviteMessage(txn, messageId2); will(returnValue(inviteMessage2)); oneOf(privateGroupFactory).createPrivateGroup(groupName, author, salt); diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java index 2e4c64ddb..6e4272770 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java @@ -144,11 +144,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest { expectSendJoinMessage(properJoinMessage, true); context.checking(new Expectations() {{ oneOf(messageTracker).trackOutgoingMessage(txn, message); - oneOf(clientHelper).getMessage(txn, lastRemoteMessageId); - will(returnValue(inviteMsg)); - oneOf(clientHelper).toList(inviteMsg); - will(returnValue(inviteList)); - oneOf(messageParser).parseInviteMessage(inviteMsg, inviteList); + oneOf(messageParser).getInviteMessage(txn, lastRemoteMessageId); will(returnValue(inviteMessage)); oneOf(privateGroupFactory) .createPrivateGroup(inviteMessage.getGroupName(), diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java index 943baa034..3452025b9 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingIntegrationTest.java @@ -33,8 +33,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import javax.inject.Inject; - import static junit.framework.Assert.assertNotNull; import static org.briarproject.bramble.test.TestUtils.getRandomString; import static org.junit.Assert.assertEquals; @@ -49,9 +47,6 @@ public class ForumSharingIntegrationTest private InviteeListener listener1; private Forum forum0; - @Inject - MessageEncoder messageEncoder; - // objects accessed from background threads need to be volatile private volatile ForumSharingManager forumSharingManager0; private volatile ForumSharingManager forumSharingManager1; diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java index 3772e87fc..c7d2d98f2 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/ForumSharingValidatorTest.java @@ -3,6 +3,8 @@ package org.briarproject.briar.sharing; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.UniqueId; 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.sync.MessageId; 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.MAX_FORUM_NAME_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.ACCEPT; 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 String content = TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH); + private final BdfDictionary meta = + BdfDictionary.of(new BdfEntry("meta", "data")); @Test public void testAcceptsInvitationWithContent() throws Exception { @@ -121,21 +124,20 @@ public class ForumSharingValidatorTest extends ValidatorTestCase { @Test(expected = FormatException.class) public void testRejectsInvalidMessageType() throws Exception { - int invalidMessageType = SHARE_MSG_TYPE_ABORT + 1; + int invalidMessageType = ABORT.getValue() + 1; v.validateMessage(message, group, BdfList.of(invalidMessageType, groupId, previousMsgId)); } @Test(expected = FormatException.class) - public void testRejectsNullGroupId() throws Exception { + public void testRejectsNullSessionId() throws Exception { v.validateMessage(message, group, BdfList.of(ABORT.getValue(), null, previousMsgId)); } @Test(expected = FormatException.class) public void testRejectsNonRawSessionId() throws Exception { - v.validateMessage(message, group, - BdfList.of(SHARE_MSG_TYPE_ABORT, 123)); + v.validateMessage(message, group, BdfList.of(ABORT.getValue(), 123)); } @Test(expected = FormatException.class) @@ -161,13 +163,13 @@ public class ForumSharingValidatorTest extends ValidatorTestCase { @Test(expected = FormatException.class) public void testRejectsTooLongBodyForAbort() throws Exception { v.validateMessage(message, group, - BdfList.of(SHARE_MSG_TYPE_ABORT, groupId, previousMsgId, 123)); + BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123)); } @Test(expected = FormatException.class) public void testRejectsTooShortBodyForInvitation() throws Exception { v.validateMessage(message, group, - BdfList.of(INVITE.getValue(), groupId, forumName)); + BdfList.of(INVITE.getValue(), previousMsgId, descriptor)); } @Test(expected = FormatException.class) @@ -207,9 +209,10 @@ public class ForumSharingValidatorTest extends ValidatorTestCase { BdfList validDescriptor = BdfList.of(shortForumName, salt); expectCreateForum(shortForumName); expectEncodeMetadata(INVITE); - v.validateMessage(message, group, + BdfMessageContext messageContext = v.validateMessage(message, group, BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor, null)); + assertExpectedContext(messageContext, previousMsgId); } @Test(expected = FormatException.class) @@ -295,6 +298,7 @@ public class ForumSharingValidatorTest extends ValidatorTestCase { oneOf(messageEncoder) .encodeMetadata(type, groupId, timestamp, false, false, false, false); + will(returnValue(meta)); }}); } @@ -307,6 +311,7 @@ public class ForumSharingValidatorTest extends ValidatorTestCase { assertEquals(1, dependencies.size()); assertTrue(dependencies.contains(previousMsgId)); } + assertEquals(meta, messageContext.getDictionary()); } }