Refactor SharingManager so its events provide message header

This commit is contained in:
Torsten Grote
2016-10-05 09:20:02 -03:00
parent 064b920626
commit 1731369d7a
28 changed files with 253 additions and 102 deletions

View File

@@ -13,6 +13,7 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY;
import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE; import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG; import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG;
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID; import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
import static org.briarproject.api.sharing.SharingConstants.TIME;
public interface BlogSharingMessage { public interface BlogSharingMessage {
@@ -25,9 +26,9 @@ public interface BlogSharingMessage {
public BlogInvitation(GroupId groupId, SessionId sessionId, public BlogInvitation(GroupId groupId, SessionId sessionId,
String blogTitle, String blogDesc, String blogAuthorName, String blogTitle, String blogDesc, String blogAuthorName,
byte[] blogPublicKey, String message) { byte[] blogPublicKey, long time, String message) {
super(groupId, sessionId, message); super(groupId, sessionId, time, message);
this.blogTitle = blogTitle; this.blogTitle = blogTitle;
this.blogDesc = blogDesc; this.blogDesc = blogDesc;
@@ -65,9 +66,10 @@ public interface BlogSharingMessage {
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME); String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY); byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
String message = d.getOptionalString(INVITATION_MSG); String message = d.getOptionalString(INVITATION_MSG);
long time = d.getLong(TIME);
return new BlogInvitation(groupId, sessionId, blogTitle, return new BlogInvitation(groupId, sessionId, blogTitle,
blogDesc, blogAuthorName, blogPublicKey, message); blogDesc, blogAuthorName, blogPublicKey, time, message);
} }
public String getBlogTitle() { public String getBlogTitle() {

View File

@@ -2,13 +2,15 @@ package org.briarproject.api.event;
import org.briarproject.api.blogs.Blog; import org.briarproject.api.blogs.Blog;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sharing.InvitationRequest;
public class BlogInvitationReceivedEvent extends InvitationReceivedEvent { public class BlogInvitationReceivedEvent extends InvitationReceivedEvent {
private final Blog blog; private final Blog blog;
public BlogInvitationReceivedEvent(Blog blog, ContactId contactId) { public BlogInvitationReceivedEvent(Blog blog, ContactId contactId,
super(contactId); InvitationRequest request) {
super(contactId, request);
this.blog = blog; this.blog = blog;
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.api.event; package org.briarproject.api.event;
import org.briarproject.api.blogs.BlogInvitationResponse;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
public class BlogInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent { public class BlogInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent {
@@ -7,8 +8,8 @@ public class BlogInvitationResponseReceivedEvent extends InvitationResponseRecei
private final String blogTitle; private final String blogTitle;
public BlogInvitationResponseReceivedEvent(String blogTitle, public BlogInvitationResponseReceivedEvent(String blogTitle,
ContactId contactId) { ContactId contactId, BlogInvitationResponse response) {
super(contactId); super(contactId, response);
this.blogTitle = blogTitle; this.blogTitle = blogTitle;
} }

View File

@@ -2,17 +2,20 @@ package org.briarproject.api.event;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumInvitationRequest;
public class ForumInvitationReceivedEvent extends InvitationReceivedEvent { public class ForumInvitationReceivedEvent extends InvitationReceivedEvent {
private final Forum forum; private final Forum forum;
public ForumInvitationReceivedEvent(Forum forum, ContactId contactId) { public ForumInvitationReceivedEvent(Forum forum, ContactId contactId,
super(contactId); ForumInvitationRequest request) {
super(contactId, request);
this.forum = forum; this.forum = forum;
} }
public Forum getForum() { public Forum getForum() {
return forum; return forum;
} }
} }

View File

@@ -1,14 +1,15 @@
package org.briarproject.api.event; package org.briarproject.api.event;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.forum.ForumInvitationResponse;
public class ForumInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent { public class ForumInvitationResponseReceivedEvent extends InvitationResponseReceivedEvent {
private final String forumName; private final String forumName;
public ForumInvitationResponseReceivedEvent(String forumName, public ForumInvitationResponseReceivedEvent(String forumName,
ContactId contactId) { ContactId contactId, ForumInvitationResponse response) {
super(contactId); super(contactId, response);
this.forumName = forumName; this.forumName = forumName;
} }

View File

@@ -1,16 +1,23 @@
package org.briarproject.api.event; package org.briarproject.api.event;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sharing.InvitationRequest;
public abstract class InvitationReceivedEvent extends Event { public abstract class InvitationReceivedEvent extends Event {
private final ContactId contactId; private final ContactId contactId;
private final InvitationRequest request;
InvitationReceivedEvent(ContactId contactId) { InvitationReceivedEvent(ContactId contactId, InvitationRequest request) {
this.contactId = contactId; this.contactId = contactId;
this.request = request;
} }
public ContactId getContactId() { public ContactId getContactId() {
return contactId; return contactId;
} }
public InvitationRequest getRequest() {
return request;
}
} }

View File

@@ -1,16 +1,24 @@
package org.briarproject.api.event; package org.briarproject.api.event;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sharing.InvitationResponse;
public abstract class InvitationResponseReceivedEvent extends Event { public abstract class InvitationResponseReceivedEvent extends Event {
private final ContactId contactId; private final ContactId contactId;
private final InvitationResponse response;
public InvitationResponseReceivedEvent(ContactId contactId) { public InvitationResponseReceivedEvent(ContactId contactId,
InvitationResponse response) {
this.contactId = contactId; this.contactId = contactId;
this.response = response;
} }
public ContactId getContactId() { public ContactId getContactId() {
return contactId; return contactId;
} }
public InvitationResponse getResponse() {
return response;
}
} }

View File

@@ -4,12 +4,13 @@ import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sharing.InvitationRequest;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
public class ForumInvitationRequest extends InvitationRequest { public class ForumInvitationRequest extends InvitationRequest {
private final String forumName; private final String forumName;
public ForumInvitationRequest(MessageId id, SessionId sessionId, public ForumInvitationRequest(@Nullable MessageId id, SessionId sessionId,
ContactId contactId, String forumName, String message, ContactId contactId, String forumName, String message,
boolean available, long time, boolean local, boolean sent, boolean available, long time, boolean local, boolean sent,
boolean seen, boolean read) { boolean seen, boolean read) {

View File

@@ -4,10 +4,11 @@ import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sharing.InvitationResponse; import org.briarproject.api.sharing.InvitationResponse;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
public class ForumInvitationResponse extends InvitationResponse { public class ForumInvitationResponse extends InvitationResponse {
public ForumInvitationResponse(MessageId id, SessionId sessionId, public ForumInvitationResponse(@Nullable MessageId id, SessionId sessionId,
ContactId contactId, boolean accept, long time, boolean local, ContactId contactId, boolean accept, long time, boolean local,
boolean sent, boolean seen, boolean read) { boolean sent, boolean seen, boolean read) {

View File

@@ -11,6 +11,7 @@ import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG; import static org.briarproject.api.sharing.SharingConstants.INVITATION_MSG;
import static org.briarproject.api.sharing.SharingConstants.SESSION_ID; import static org.briarproject.api.sharing.SharingConstants.SESSION_ID;
import static org.briarproject.api.sharing.SharingConstants.TIME;
public interface ForumSharingMessage { public interface ForumSharingMessage {
@@ -20,9 +21,9 @@ public interface ForumSharingMessage {
private final byte[] forumSalt; private final byte[] forumSalt;
public ForumInvitation(GroupId groupId, SessionId sessionId, public ForumInvitation(GroupId groupId, SessionId sessionId,
String forumName, byte[] forumSalt, String message) { String forumName, byte[] forumSalt, long time, String message) {
super(groupId, sessionId, message); super(groupId, sessionId, time, message);
this.forumName = forumName; this.forumName = forumName;
this.forumSalt = forumSalt; this.forumSalt = forumSalt;
@@ -53,9 +54,10 @@ public interface ForumSharingMessage {
String forumName = d.getString(FORUM_NAME); String forumName = d.getString(FORUM_NAME);
byte[] forumSalt = d.getRaw(FORUM_SALT); byte[] forumSalt = d.getRaw(FORUM_SALT);
String message = d.getOptionalString(INVITATION_MSG); String message = d.getOptionalString(INVITATION_MSG);
long time = d.getLong(TIME);
return new ForumInvitation(groupId, sessionId, forumName, forumSalt, return new ForumInvitation(groupId, sessionId, forumName, forumSalt,
message); time, message);
} }
public String getForumName() { public String getForumName() {

View File

@@ -3,6 +3,7 @@ package org.briarproject.api.sharing;
import org.briarproject.api.clients.SessionId; import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
public abstract class InvitationRequest extends InvitationMessage { public abstract class InvitationRequest extends InvitationMessage {
@@ -19,6 +20,7 @@ public abstract class InvitationRequest extends InvitationMessage {
this.available = available; this.available = available;
} }
@Nullable
public String getMessage() { public String getMessage() {
return message; return message;
} }

View File

@@ -19,6 +19,8 @@ public interface SharingConstants {
String IS_SHARER = "isSharer"; String IS_SHARER = "isSharer";
String SHAREABLE_ID = "shareableId"; String SHAREABLE_ID = "shareableId";
String INVITATION_MSG = "invitationMsg"; String INVITATION_MSG = "invitationMsg";
String INVITATION_ID = "invitationId";
String RESPONSE_ID = "responseId";
int SHARE_MSG_TYPE_INVITATION = 1; int SHARE_MSG_TYPE_INVITATION = 1;
int SHARE_MSG_TYPE_ACCEPT = 2; int SHARE_MSG_TYPE_ACCEPT = 2;
int SHARE_MSG_TYPE_DECLINE = 3; int SHARE_MSG_TYPE_DECLINE = 3;

View File

@@ -14,6 +14,7 @@ import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEP
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
import static org.briarproject.api.sharing.SharingConstants.TIME;
import static org.briarproject.api.sharing.SharingConstants.TYPE; import static org.briarproject.api.sharing.SharingConstants.TYPE;
public interface SharingMessage { public interface SharingMessage {
@@ -21,10 +22,12 @@ public interface SharingMessage {
abstract class BaseMessage { abstract class BaseMessage {
private final GroupId groupId; private final GroupId groupId;
private final SessionId sessionId; private final SessionId sessionId;
private final long time;
BaseMessage(GroupId groupId, SessionId sessionId) { BaseMessage(GroupId groupId, SessionId sessionId, long time) {
this.groupId = groupId; this.groupId = groupId;
this.sessionId = sessionId; this.sessionId = sessionId;
this.time = time;
} }
public BdfList toBdfList() { public BdfList toBdfList() {
@@ -62,16 +65,20 @@ public interface SharingMessage {
public SessionId getSessionId() { public SessionId getSessionId() {
return sessionId; return sessionId;
} }
public long getTime() {
return time;
}
} }
abstract class Invitation extends BaseMessage { abstract class Invitation extends BaseMessage {
protected final String message; protected final String message;
public Invitation(GroupId groupId, SessionId sessionId, public Invitation(GroupId groupId, SessionId sessionId, long time,
String message) { String message) {
super(groupId, sessionId); super(groupId, sessionId, time);
this.message = message; this.message = message;
} }
@@ -90,8 +97,9 @@ public interface SharingMessage {
private final long type; private final long type;
public SimpleMessage(long type, GroupId groupId, SessionId sessionId) { public SimpleMessage(long type, GroupId groupId, SessionId sessionId,
super(groupId, sessionId); long time) {
super(groupId, sessionId, time);
this.type = type; this.type = type;
} }
@@ -114,7 +122,8 @@ public interface SharingMessage {
type != SHARE_MSG_TYPE_ABORT) throw new FormatException(); type != SHARE_MSG_TYPE_ABORT) throw new FormatException();
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID)); SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
return new SimpleMessage(type, groupId, sessionId); long time = d.getLong(TIME);
return new SimpleMessage(type, groupId, sessionId, time);
} }
} }

View File

@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME; import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC; import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
@@ -21,8 +22,9 @@ public class BlogInviteeSessionState extends InviteeSessionState {
public BlogInviteeSessionState(SessionId sessionId, MessageId storageId, public BlogInviteeSessionState(SessionId sessionId, MessageId storageId,
GroupId groupId, State state, ContactId contactId, GroupId blogId, GroupId groupId, State state, ContactId contactId, GroupId blogId,
String blogTitle, String blogDesc, String blogAuthorName, String blogTitle, String blogDesc, String blogAuthorName,
byte[] blogPublicKey) { byte[] blogPublicKey, @Nullable MessageId invitationId) {
super(sessionId, storageId, groupId, state, contactId, blogId); super(sessionId, storageId, groupId, state, contactId, blogId,
invitationId);
this.blogTitle = blogTitle; this.blogTitle = blogTitle;
this.blogDesc = blogDesc; this.blogDesc = blogDesc;

View File

@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME; import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC; import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
@@ -21,8 +22,9 @@ public class BlogSharerSessionState extends SharerSessionState {
public BlogSharerSessionState(SessionId sessionId, MessageId storageId, public BlogSharerSessionState(SessionId sessionId, MessageId storageId,
GroupId groupId, State state, ContactId contactId, GroupId blogId, GroupId groupId, State state, ContactId contactId, GroupId blogId,
String blogTitle, String blogDesc, String blogAuthorName, String blogTitle, String blogDesc, String blogAuthorName,
byte[] blogPublicKey) { byte[] blogPublicKey, @Nullable MessageId responseId) {
super(sessionId, storageId, groupId, state, contactId, blogId); super(sessionId, storageId, groupId, state, contactId, blogId,
responseId);
this.blogTitle = blogTitle; this.blogTitle = blogTitle;
this.blogDesc = blogDesc; this.blogDesc = blogDesc;

View File

@@ -10,8 +10,8 @@ import org.briarproject.api.blogs.BlogManager.RemoveBlogHook;
import org.briarproject.api.blogs.BlogSharingManager; import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation; import org.briarproject.api.blogs.BlogSharingMessage.BlogInvitation;
import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.ContactGroupFactory; import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.SessionId; import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
@@ -43,6 +43,7 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_AUTHOR_NAME;
import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC; import static org.briarproject.api.blogs.BlogConstants.BLOG_DESC;
import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY; import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY;
import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE; import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
class BlogSharingManagerImpl extends class BlogSharingManagerImpl extends
SharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent> SharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent>
@@ -163,7 +164,7 @@ class BlogSharingManagerImpl extends
private final BlogFactory blogFactory; private final BlogFactory blogFactory;
private final BlogManager blogManager; private final BlogManager blogManager;
SFactory(AuthorFactory authorFactory, BlogFactory BlogFactory, private SFactory(AuthorFactory authorFactory, BlogFactory BlogFactory,
BlogManager BlogManager) { BlogManager BlogManager) {
this.authorFactory = authorFactory; this.authorFactory = authorFactory;
this.blogFactory = BlogFactory; this.blogFactory = BlogFactory;
@@ -230,11 +231,13 @@ class BlogSharingManagerImpl extends
} }
@Override @Override
public BlogInvitation build(BlogSharerSessionState localState) { public BlogInvitation build(BlogSharerSessionState localState,
long time) {
return new BlogInvitation(localState.getGroupId(), return new BlogInvitation(localState.getGroupId(),
localState.getSessionId(), localState.getBlogTitle(), localState.getSessionId(), localState.getBlogTitle(),
localState.getBlogDesc(), localState.getBlogAuthorName(), localState.getBlogDesc(), localState.getBlogAuthorName(),
localState.getBlogPublicKey(), localState.getMessage()); localState.getBlogPublicKey(), time,
localState.getMessage());
} }
} }
@@ -249,20 +252,24 @@ class BlogSharingManagerImpl extends
String blogDesc = d.getString(BLOG_DESC); String blogDesc = d.getString(BLOG_DESC);
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME); String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY); byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
MessageId invitationId = null;
byte[] invitationIdBytes = d.getOptionalRaw(INVITATION_ID);
if (invitationIdBytes != null)
invitationId = new MessageId(invitationIdBytes);
return new BlogInviteeSessionState(sessionId, storageId, return new BlogInviteeSessionState(sessionId, storageId,
groupId, state, contactId, blogId, blogTitle, blogDesc, groupId, state, contactId, blogId, blogTitle, blogDesc,
blogAuthorName, blogPublicKey); blogAuthorName, blogPublicKey, invitationId);
} }
@Override @Override
public BlogInviteeSessionState build(SessionId sessionId, public BlogInviteeSessionState build(SessionId sessionId,
MessageId storageId, GroupId groupId, MessageId storageId, GroupId groupId,
InviteeSessionState.State state, ContactId contactId, InviteeSessionState.State state, ContactId contactId,
Blog blog) { Blog blog, MessageId invitationId) {
return new BlogInviteeSessionState(sessionId, storageId, return new BlogInviteeSessionState(sessionId, storageId,
groupId, state, contactId, blog.getId(), blog.getName(), groupId, state, contactId, blog.getId(), blog.getName(),
blog.getDescription(), blog.getAuthor().getName(), blog.getDescription(), blog.getAuthor().getName(),
blog.getAuthor().getPublicKey()); blog.getAuthor().getPublicKey(), invitationId);
} }
} }
@@ -277,9 +284,13 @@ class BlogSharingManagerImpl extends
String blogDesc = d.getString(BLOG_DESC); String blogDesc = d.getString(BLOG_DESC);
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME); String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY); byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
MessageId responseId = null;
byte[] responseIdBytes = d.getOptionalRaw(INVITATION_ID);
if (responseIdBytes != null)
responseId = new MessageId(responseIdBytes);
return new BlogSharerSessionState(sessionId, storageId, return new BlogSharerSessionState(sessionId, storageId,
groupId, state, contactId, blogId, blogTitle, blogDesc, groupId, state, contactId, blogId, blogTitle, blogDesc,
blogAuthorName, blogPublicKey); blogAuthorName, blogPublicKey, responseId);
} }
@Override @Override
@@ -290,7 +301,7 @@ class BlogSharingManagerImpl extends
return new BlogSharerSessionState(sessionId, storageId, return new BlogSharerSessionState(sessionId, storageId,
groupId, state, contactId, blog.getId(), blog.getName(), groupId, state, contactId, blog.getId(), blog.getName(),
blog.getDescription(), blog.getAuthor().getName(), blog.getDescription(), blog.getAuthor().getName(),
blog.getAuthor().getPublicKey()); blog.getAuthor().getPublicKey(), null);
} }
} }
@@ -299,16 +310,21 @@ class BlogSharingManagerImpl extends
private final SFactory sFactory; private final SFactory sFactory;
IRFactory(SFactory sFactory) { private IRFactory(SFactory sFactory) {
this.sFactory = sFactory; this.sFactory = sFactory;
} }
@Override @Override
public BlogInvitationReceivedEvent build( public BlogInvitationReceivedEvent build(
BlogInviteeSessionState localState) { BlogInviteeSessionState localState, long time, String msg) {
Blog blog = sFactory.parse(localState); Blog blog = sFactory.parse(localState);
ContactId contactId = localState.getContactId(); ContactId contactId = localState.getContactId();
return new BlogInvitationReceivedEvent(blog, contactId); BlogInvitationRequest request =
new BlogInvitationRequest(localState.getInvitationId(),
localState.getSessionId(), contactId,
blog.getAuthor().getName(), msg, true, time, false,
false, false, false);
return new BlogInvitationReceivedEvent(blog, contactId, request);
} }
} }
@@ -316,10 +332,15 @@ class BlogSharingManagerImpl extends
InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> { InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> {
@Override @Override
public BlogInvitationResponseReceivedEvent build( public BlogInvitationResponseReceivedEvent build(
BlogSharerSessionState localState) { BlogSharerSessionState localState, boolean accept, long time) {
String title = localState.getBlogTitle(); String title = localState.getBlogTitle();
ContactId c = localState.getContactId(); ContactId c = localState.getContactId();
return new BlogInvitationResponseReceivedEvent(title, c); BlogInvitationResponse response =
new BlogInvitationResponse(localState.getResponseId(),
localState.getSessionId(),
localState.getContactId(), accept, time, false,
false, false, false);
return new BlogInvitationResponseReceivedEvent(title, c, response);
} }
} }
} }

View File

@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
@@ -16,8 +17,10 @@ public class ForumInviteeSessionState extends InviteeSessionState {
public ForumInviteeSessionState(SessionId sessionId, MessageId storageId, public ForumInviteeSessionState(SessionId sessionId, MessageId storageId,
GroupId groupId, State state, ContactId contactId, GroupId forumId, GroupId groupId, State state, ContactId contactId, GroupId forumId,
String forumName, byte[] forumSalt) { String forumName, byte[] forumSalt,
super(sessionId, storageId, groupId, state, contactId, forumId); @Nullable MessageId invitationId) {
super(sessionId, storageId, groupId, state, contactId, forumId,
invitationId);
this.forumName = forumName; this.forumName = forumName;
this.forumSalt = forumSalt; this.forumSalt = forumSalt;

View File

@@ -5,6 +5,7 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
@@ -16,8 +17,10 @@ class ForumSharerSessionState extends SharerSessionState {
ForumSharerSessionState(SessionId sessionId, MessageId storageId, ForumSharerSessionState(SessionId sessionId, MessageId storageId,
GroupId groupId, State state, ContactId contactId, GroupId forumId, GroupId groupId, State state, ContactId contactId, GroupId forumId,
String forumName, byte[] forumSalt) { String forumName, byte[] forumSalt,
super(sessionId, storageId, groupId, state, contactId, forumId); @Nullable MessageId responseId) {
super(sessionId, storageId, groupId, state, contactId, forumId,
responseId);
this.forumName = forumName; this.forumName = forumName;
this.forumSalt = forumSalt; this.forumSalt = forumSalt;

View File

@@ -2,8 +2,8 @@ package org.briarproject.sharing;
import org.briarproject.api.FormatException; import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ClientHelper; import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.ContactGroupFactory; import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.SessionId; import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
@@ -35,6 +35,7 @@ import javax.inject.Inject;
import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
class ForumSharingManagerImpl extends class ForumSharingManagerImpl extends
SharingManagerImpl<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent> SharingManagerImpl<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent>
@@ -136,7 +137,7 @@ class ForumSharingManagerImpl extends
private final ForumFactory forumFactory; private final ForumFactory forumFactory;
private final ForumManager forumManager; private final ForumManager forumManager;
SFactory(ForumFactory forumFactory, ForumManager forumManager) { private SFactory(ForumFactory forumFactory, ForumManager forumManager) {
this.forumFactory = forumFactory; this.forumFactory = forumFactory;
this.forumManager = forumManager; this.forumManager = forumManager;
} }
@@ -185,10 +186,11 @@ class ForumSharingManagerImpl extends
} }
@Override @Override
public ForumInvitation build(ForumSharerSessionState localState) { public ForumInvitation build(ForumSharerSessionState localState,
long time) {
return new ForumInvitation(localState.getGroupId(), return new ForumInvitation(localState.getGroupId(),
localState.getSessionId(), localState.getForumName(), localState.getSessionId(), localState.getForumName(),
localState.getForumSalt(), localState.getMessage()); localState.getForumSalt(), time, localState.getMessage());
} }
} }
@@ -201,18 +203,23 @@ class ForumSharingManagerImpl extends
GroupId forumId, BdfDictionary d) throws FormatException { GroupId forumId, BdfDictionary d) throws FormatException {
String forumName = d.getString(FORUM_NAME); String forumName = d.getString(FORUM_NAME);
byte[] forumSalt = d.getRaw(FORUM_SALT); byte[] forumSalt = d.getRaw(FORUM_SALT);
MessageId invitationId = null;
byte[] invitationIdBytes = d.getOptionalRaw(INVITATION_ID);
if (invitationIdBytes != null)
invitationId = new MessageId(invitationIdBytes);
return new ForumInviteeSessionState(sessionId, storageId, return new ForumInviteeSessionState(sessionId, storageId,
groupId, state, contactId, forumId, forumName, forumSalt); groupId, state, contactId, forumId, forumName, forumSalt,
invitationId);
} }
@Override @Override
public ForumInviteeSessionState build(SessionId sessionId, public ForumInviteeSessionState build(SessionId sessionId,
MessageId storageId, GroupId groupId, MessageId storageId, GroupId groupId,
InviteeSessionState.State state, ContactId contactId, InviteeSessionState.State state, ContactId contactId,
Forum forum) { Forum forum, MessageId invitationId) {
return new ForumInviteeSessionState(sessionId, storageId, return new ForumInviteeSessionState(sessionId, storageId,
groupId, state, contactId, forum.getId(), forum.getName(), groupId, state, contactId, forum.getId(), forum.getName(),
forum.getSalt()); forum.getSalt(), invitationId);
} }
} }
@@ -225,8 +232,13 @@ class ForumSharingManagerImpl extends
GroupId forumId, BdfDictionary d) throws FormatException { GroupId forumId, BdfDictionary d) throws FormatException {
String forumName = d.getString(FORUM_NAME); String forumName = d.getString(FORUM_NAME);
byte[] forumSalt = d.getRaw(FORUM_SALT); byte[] forumSalt = d.getRaw(FORUM_SALT);
MessageId responseId = null;
byte[] responseIdBytes = d.getOptionalRaw(INVITATION_ID);
if (responseIdBytes != null)
responseId = new MessageId(responseIdBytes);
return new ForumSharerSessionState(sessionId, storageId, return new ForumSharerSessionState(sessionId, storageId,
groupId, state, contactId, forumId, forumName, forumSalt); groupId, state, contactId, forumId, forumName, forumSalt,
responseId);
} }
@Override @Override
@@ -236,7 +248,7 @@ class ForumSharingManagerImpl extends
Forum forum) { Forum forum) {
return new ForumSharerSessionState(sessionId, storageId, return new ForumSharerSessionState(sessionId, storageId,
groupId, state, contactId, forum.getId(), forum.getName(), groupId, state, contactId, forum.getId(), forum.getName(),
forum.getSalt()); forum.getSalt(), null);
} }
} }
@@ -245,16 +257,20 @@ class ForumSharingManagerImpl extends
private final SFactory sFactory; private final SFactory sFactory;
IRFactory(SFactory sFactory) { private IRFactory(SFactory sFactory) {
this.sFactory = sFactory; this.sFactory = sFactory;
} }
@Override @Override
public ForumInvitationReceivedEvent build( public ForumInvitationReceivedEvent build(
ForumInviteeSessionState localState) { ForumInviteeSessionState localState, long time, String msg) {
Forum forum = sFactory.parse(localState); Forum forum = sFactory.parse(localState);
ContactId contactId = localState.getContactId(); ContactId contactId = localState.getContactId();
return new ForumInvitationReceivedEvent(forum, contactId); ForumInvitationRequest request = new ForumInvitationRequest(
localState.getInvitationId(), localState.getSessionId(),
contactId, forum.getName(), msg, true, time, false, false,
false, false);
return new ForumInvitationReceivedEvent(forum, contactId, request);
} }
} }
@@ -262,10 +278,14 @@ class ForumSharingManagerImpl extends
InvitationResponseReceivedEventFactory<ForumSharerSessionState, ForumInvitationResponseReceivedEvent> { InvitationResponseReceivedEventFactory<ForumSharerSessionState, ForumInvitationResponseReceivedEvent> {
@Override @Override
public ForumInvitationResponseReceivedEvent build( public ForumInvitationResponseReceivedEvent build(
ForumSharerSessionState localState) { ForumSharerSessionState localState, boolean accept, long time) {
String name = localState.getForumName(); String name = localState.getForumName();
ContactId c = localState.getContactId(); ContactId c = localState.getContactId();
return new ForumInvitationResponseReceivedEvent(name, c); ForumInvitationResponse response = new ForumInvitationResponse(
localState.getResponseId(),
localState.getSessionId(), localState.getContactId(),
accept, time, false, false, false, false);
return new ForumInvitationResponseReceivedEvent(name, c, response);
} }
} }
} }

View File

@@ -5,5 +5,5 @@ import org.briarproject.api.sharing.SharingMessage;
public interface InvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState> extends public interface InvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState> extends
org.briarproject.api.sharing.InvitationFactory<I> { org.briarproject.api.sharing.InvitationFactory<I> {
I build(SS localState); I build(SS localState, long time);
} }

View File

@@ -4,5 +4,5 @@ import org.briarproject.api.event.InvitationReceivedEvent;
public interface InvitationReceivedEventFactory<IS extends InviteeSessionState, IR extends InvitationReceivedEvent> { public interface InvitationReceivedEventFactory<IS extends InviteeSessionState, IR extends InvitationReceivedEvent> {
IR build(IS localState); IR build(IS localState, long time, String msg);
} }

View File

@@ -4,5 +4,5 @@ import org.briarproject.api.event.InvitationResponseReceivedEvent;
public interface InvitationResponseReceivedEventFactory<SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> { public interface InvitationResponseReceivedEventFactory<SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> {
IRR build(SS localState); IRR build(SS localState, boolean accept, long time);
} }

View File

@@ -4,6 +4,8 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ProtocolEngine; import org.briarproject.api.clients.ProtocolEngine;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
import org.briarproject.api.event.InvitationReceivedEvent; import org.briarproject.api.event.InvitationReceivedEvent;
import org.briarproject.api.sharing.SharingMessage.Invitation;
import org.briarproject.api.system.Clock;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -30,9 +32,13 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
Logger.getLogger(InviteeEngine.class.getName()); Logger.getLogger(InviteeEngine.class.getName());
private final InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory; private final InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory;
private final Clock clock;
InviteeEngine(InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory) { InviteeEngine(
InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory,
Clock clock) {
this.invitationReceivedEventFactory = invitationReceivedEventFactory; this.invitationReceivedEventFactory = invitationReceivedEventFactory;
this.clock = clock;
} }
@Override @Override
@@ -63,19 +69,22 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
if (action == InviteeSessionState.Action.LOCAL_ACCEPT) { if (action == InviteeSessionState.Action.LOCAL_ACCEPT) {
localState.setTask(TASK_ADD_SHARED_SHAREABLE); localState.setTask(TASK_ADD_SHARED_SHAREABLE);
msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT, msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT,
localState.getGroupId(), localState.getSessionId()); localState.getGroupId(), localState.getSessionId(),
clock.currentTimeMillis());
} else { } else {
localState.setTask( localState.setTask(
TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US); TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US);
msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE, msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE,
localState.getGroupId(), localState.getSessionId()); localState.getGroupId(), localState.getSessionId(),
clock.currentTimeMillis());
} }
messages = Collections.singletonList(msg); messages = Collections.singletonList(msg);
logLocalAction(currentState, localState, msg); logLocalAction(currentState, localState, msg);
} }
else if (action == InviteeSessionState.Action.LOCAL_LEAVE) { else if (action == InviteeSessionState.Action.LOCAL_LEAVE) {
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE, BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
localState.getGroupId(), localState.getSessionId()); localState.getGroupId(), localState.getSessionId(),
clock.currentTimeMillis());
messages = Collections.singletonList(msg); messages = Collections.singletonList(msg);
logLocalAction(currentState, localState, msg); logLocalAction(currentState, localState, msg);
} }
@@ -133,7 +142,9 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
// we have just received our invitation // we have just received our invitation
else if (action == InviteeSessionState.Action.REMOTE_INVITATION) { else if (action == InviteeSessionState.Action.REMOTE_INVITATION) {
localState.setTask(TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US); localState.setTask(TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US);
Event event = invitationReceivedEventFactory.build(localState); Invitation invitation = (Invitation) msg;
Event event = invitationReceivedEventFactory.build(localState,
msg.getTime(), invitation.getMessage());
events = Collections.singletonList(event); events = Collections.singletonList(event);
} }
else { else {
@@ -203,7 +214,7 @@ class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationReceive
localState.setState(InviteeSessionState.State.ERROR); localState.setState(InviteeSessionState.State.ERROR);
BaseMessage msg = BaseMessage msg =
new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getGroupId(), new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getGroupId(),
localState.getSessionId()); localState.getSessionId(), clock.currentTimeMillis());
List<BaseMessage> messages = Collections.singletonList(msg); List<BaseMessage> messages = Collections.singletonList(msg);
List<Event> events = Collections.emptyList(); List<Event> events = Collections.emptyList();

View File

@@ -5,7 +5,9 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.api.sharing.SharingConstants.INVITATION_ID;
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER; import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
@@ -21,19 +23,22 @@ import static org.briarproject.sharing.InviteeSessionState.Action.REMOTE_LEAVE;
public abstract class InviteeSessionState extends SharingSessionState { public abstract class InviteeSessionState extends SharingSessionState {
private State state; private State state;
private final MessageId invitationId;
public InviteeSessionState(SessionId sessionId, MessageId storageId, public InviteeSessionState(SessionId sessionId, MessageId storageId,
GroupId groupId, State state, ContactId contactId, GroupId groupId, State state, ContactId contactId,
GroupId shareableId) { GroupId shareableId, MessageId invitationId) {
super(sessionId, storageId, groupId, contactId, shareableId); super(sessionId, storageId, groupId, contactId, shareableId);
this.state = state; this.state = state;
this.invitationId = invitationId;
} }
public BdfDictionary toBdfDictionary() { public BdfDictionary toBdfDictionary() {
BdfDictionary d = super.toBdfDictionary(); BdfDictionary d = super.toBdfDictionary();
d.put(STATE, getState().getValue()); d.put(STATE, getState().getValue());
d.put(IS_SHARER, false); d.put(IS_SHARER, false);
if (invitationId != null) d.put(INVITATION_ID, invitationId);
return d; return d;
} }
@@ -45,6 +50,11 @@ public abstract class InviteeSessionState extends SharingSessionState {
return state; return state;
} }
@Nullable
public MessageId getInvitationId() {
return invitationId;
}
public enum State { public enum State {
ERROR(0), ERROR(0),
AWAIT_INVITATION(1) { AWAIT_INVITATION(1) {

View File

@@ -15,5 +15,6 @@ public interface InviteeSessionStateFactory<S extends Shareable, IS extends Invi
GroupId shareableId, BdfDictionary d) throws FormatException; GroupId shareableId, BdfDictionary d) throws FormatException;
IS build(SessionId sessionId, MessageId storageId, GroupId groupId, IS build(SessionId sessionId, MessageId storageId, GroupId groupId,
InviteeSessionState.State state, ContactId contactId, S shareable); InviteeSessionState.State state, ContactId contactId, S shareable,
MessageId invitationId);
} }

View File

@@ -4,6 +4,7 @@ import org.briarproject.api.FormatException;
import org.briarproject.api.clients.ProtocolEngine; import org.briarproject.api.clients.ProtocolEngine;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
import org.briarproject.api.event.InvitationResponseReceivedEvent; import org.briarproject.api.event.InvitationResponseReceivedEvent;
import org.briarproject.api.system.Clock;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@@ -22,6 +23,8 @@ import static org.briarproject.api.sharing.SharingConstants.TASK_UNSHARE_SHAREAB
import static org.briarproject.api.sharing.SharingMessage.BaseMessage; import static org.briarproject.api.sharing.SharingMessage.BaseMessage;
import static org.briarproject.api.sharing.SharingMessage.Invitation; import static org.briarproject.api.sharing.SharingMessage.Invitation;
import static org.briarproject.api.sharing.SharingMessage.SimpleMessage; import static org.briarproject.api.sharing.SharingMessage.SimpleMessage;
import static org.briarproject.sharing.SharerSessionState.Action.REMOTE_ACCEPT;
import static org.briarproject.sharing.SharerSessionState.Action.REMOTE_DECLINE;
class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent>
implements ProtocolEngine<SharerSessionState.Action, SS, BaseMessage> { implements ProtocolEngine<SharerSessionState.Action, SS, BaseMessage> {
@@ -32,12 +35,15 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
private final InvitationFactory<I, SS> invitationFactory; private final InvitationFactory<I, SS> invitationFactory;
private final InvitationResponseReceivedEventFactory<SS, IRR> private final InvitationResponseReceivedEventFactory<SS, IRR>
invitationResponseReceivedEventFactory; invitationResponseReceivedEventFactory;
private final Clock clock;
SharerEngine(InvitationFactory<I, SS> invitationFactory, SharerEngine(InvitationFactory<I, SS> invitationFactory,
InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory) { InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory,
Clock clock) {
this.invitationFactory = invitationFactory; this.invitationFactory = invitationFactory;
this.invitationResponseReceivedEventFactory = this.invitationResponseReceivedEventFactory =
invitationResponseReceivedEventFactory; invitationResponseReceivedEventFactory;
this.clock = clock;
} }
@Override @Override
@@ -65,7 +71,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
List<Event> events = Collections.emptyList(); List<Event> events = Collections.emptyList();
if (action == SharerSessionState.Action.LOCAL_INVITATION) { if (action == SharerSessionState.Action.LOCAL_INVITATION) {
BaseMessage msg = invitationFactory.build(localState); BaseMessage msg = invitationFactory.build(localState,
clock.currentTimeMillis());
messages = Collections.singletonList(msg); messages = Collections.singletonList(msg);
logLocalAction(currentState, nextState, msg); logLocalAction(currentState, nextState, msg);
@@ -74,7 +81,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
.setTask(TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US); .setTask(TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US);
} else if (action == SharerSessionState.Action.LOCAL_LEAVE) { } else if (action == SharerSessionState.Action.LOCAL_LEAVE) {
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE, BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
localState.getGroupId(), localState.getSessionId()); localState.getGroupId(), localState.getSessionId(),
clock.currentTimeMillis());
messages = Collections.singletonList(msg); messages = Collections.singletonList(msg);
logLocalAction(currentState, nextState, msg); logLocalAction(currentState, nextState, msg);
} else { } else {
@@ -122,9 +130,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
deleteMsg = true; deleteMsg = true;
} }
// we have sent our invitation and just got a response // we have sent our invitation and just got a response
else if (action == SharerSessionState.Action.REMOTE_ACCEPT || else if (action == REMOTE_ACCEPT || action == REMOTE_DECLINE) {
action == SharerSessionState.Action.REMOTE_DECLINE) { if (action == REMOTE_ACCEPT) {
if (action == SharerSessionState.Action.REMOTE_ACCEPT) {
localState.setTask(TASK_SHARE_SHAREABLE); localState.setTask(TASK_SHARE_SHAREABLE);
} else { } else {
// this ensures that the forum can be shared again // this ensures that the forum can be shared again
@@ -132,7 +139,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US); TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US);
} }
Event event = invitationResponseReceivedEventFactory Event event = invitationResponseReceivedEventFactory
.build(localState); .build(localState, action == REMOTE_ACCEPT,
msg.getTime());
events = Collections.singletonList(event); events = Collections.singletonList(event);
} else { } else {
throw new IllegalArgumentException("Bad state"); throw new IllegalArgumentException("Bad state");
@@ -204,7 +212,8 @@ class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR exte
localState.setState(SharerSessionState.State.ERROR); localState.setState(SharerSessionState.State.ERROR);
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT, BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT,
localState.getGroupId(), localState.getSessionId()); localState.getGroupId(), localState.getSessionId(),
clock.currentTimeMillis());
List<BaseMessage> messages = Collections.singletonList(msg); List<BaseMessage> messages = Collections.singletonList(msg);
List<Event> events = Collections.emptyList(); List<Event> events = Collections.emptyList();

View File

@@ -5,8 +5,10 @@ import org.briarproject.api.contact.ContactId;
import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId; import org.briarproject.api.sync.MessageId;
import org.jetbrains.annotations.Nullable;
import static org.briarproject.api.sharing.SharingConstants.IS_SHARER; import static org.briarproject.api.sharing.SharingConstants.IS_SHARER;
import static org.briarproject.api.sharing.SharingConstants.RESPONSE_ID;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
@@ -22,20 +24,25 @@ import static org.briarproject.sharing.SharerSessionState.Action.REMOTE_LEAVE;
public abstract class SharerSessionState extends SharingSessionState { public abstract class SharerSessionState extends SharingSessionState {
private State state; private State state;
@Nullable
private String msg = null; private String msg = null;
@Nullable
private MessageId responseId;
public SharerSessionState(SessionId sessionId, MessageId storageId, public SharerSessionState(SessionId sessionId, MessageId storageId,
GroupId groupId, State state, ContactId contactId, GroupId groupId, State state, ContactId contactId,
GroupId shareableId) { GroupId shareableId, @Nullable MessageId responseId) {
super(sessionId, storageId, groupId, contactId, shareableId); super(sessionId, storageId, groupId, contactId, shareableId);
this.state = state; this.state = state;
this.responseId = responseId;
} }
public BdfDictionary toBdfDictionary() { public BdfDictionary toBdfDictionary() {
BdfDictionary d = super.toBdfDictionary(); BdfDictionary d = super.toBdfDictionary();
d.put(STATE, getState().getValue()); d.put(STATE, getState().getValue());
d.put(IS_SHARER, true); d.put(IS_SHARER, true);
if (responseId != null) d.put(RESPONSE_ID, responseId);
return d; return d;
} }
@@ -55,6 +62,15 @@ public abstract class SharerSessionState extends SharingSessionState {
return this.msg; return this.msg;
} }
public void setResponseId(@Nullable MessageId responseId) {
this.responseId = responseId;
}
@Nullable
public MessageId getResponseId() {
return responseId;
}
public enum State { public enum State {
ERROR(0), ERROR(0),
PREPARE_INVITATION(1) { PREPARE_INVITATION(1) {

View File

@@ -211,6 +211,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
if (stateExists) throw new FormatException(); if (stateExists) throw new FormatException();
// check if shareable can be shared // check if shareable can be shared
@SuppressWarnings("unchecked")
I invitation = (I) msg; I invitation = (I) msg;
S f = getSFactory().parse(invitation); S f = getSFactory().parse(invitation);
ContactId contactId = getContactId(txn, m.getGroupId()); ContactId contactId = getContactId(txn, m.getGroupId());
@@ -219,9 +220,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
checkForRaceCondition(txn, f, contact); checkForRaceCondition(txn, f, contact);
// initialize state and process invitation // initialize state and process invitation
IS state = initializeInviteeState(txn, contactId, invitation); IS state = initializeInviteeState(txn, contactId, invitation,
m.getId());
InviteeEngine<IS, IR> engine = InviteeEngine<IS, IR> engine =
new InviteeEngine<IS, IR>(getIRFactory()); new InviteeEngine<IS, IR>(getIRFactory(), clock);
processInviteeStateUpdate(txn, m.getId(), processInviteeStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg)); engine.onMessageReceived(state, msg));
trackIncomingMessage(txn, m); trackIncomingMessage(txn, m);
@@ -233,9 +235,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
msg.getType() == SHARE_MSG_TYPE_DECLINE) { msg.getType() == SHARE_MSG_TYPE_DECLINE) {
// we are a sharer who just received a response // we are a sharer who just received a response
SS state = getSessionStateForSharer(txn, sessionId); SS state = getSessionStateForSharer(txn, sessionId);
state.setResponseId(m.getId());
SharerEngine<I, SS, IRR> engine = SharerEngine<I, SS, IRR> engine =
new SharerEngine<I, SS, IRR>(getIFactory(), new SharerEngine<I, SS, IRR>(getIFactory(),
getIRRFactory()); getIRRFactory(), clock);
processSharerStateUpdate(txn, m.getId(), processSharerStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg)); engine.onMessageReceived(state, msg));
trackIncomingMessage(txn, m); trackIncomingMessage(txn, m);
@@ -245,17 +248,19 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
SharingSessionState s = getSessionState(txn, sessionId, true); SharingSessionState s = getSessionState(txn, sessionId, true);
if (s instanceof SharerSessionState) { if (s instanceof SharerSessionState) {
// we are a sharer and the invitee wants to leave or abort // we are a sharer and the invitee wants to leave or abort
@SuppressWarnings("unchecked")
SS state = (SS) s; SS state = (SS) s;
SharerEngine<I, SS, IRR> engine = SharerEngine<I, SS, IRR> engine =
new SharerEngine<I, SS, IRR>(getIFactory(), new SharerEngine<I, SS, IRR>(getIFactory(),
getIRRFactory()); getIRRFactory(), clock);
processSharerStateUpdate(txn, m.getId(), processSharerStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg)); engine.onMessageReceived(state, msg));
} else { } else {
// we are an invitee and the sharer wants to leave or abort // we are an invitee and the sharer wants to leave or abort
@SuppressWarnings("unchecked")
IS state = (IS) s; IS state = (IS) s;
InviteeEngine<IS, IR> engine = InviteeEngine<IS, IR> engine =
new InviteeEngine<IS, IR>(getIRFactory()); new InviteeEngine<IS, IR>(getIRFactory(), clock);
processInviteeStateUpdate(txn, m.getId(), processInviteeStateUpdate(txn, m.getId(),
engine.onMessageReceived(state, msg)); engine.onMessageReceived(state, msg));
} }
@@ -285,13 +290,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
// start engine and process its state update // start engine and process its state update
SharerEngine<I, SS, IRR> engine = SharerEngine<I, SS, IRR> engine =
new SharerEngine<I, SS, IRR>(getIFactory(), new SharerEngine<I, SS, IRR>(getIFactory(),
getIRRFactory()); getIRRFactory(), clock);
processSharerStateUpdate(txn, null, StateUpdate<SS, BaseMessage> update =
engine.onLocalAction(localState, engine.onLocalAction(localState,
SharerSessionState.Action.LOCAL_INVITATION)); SharerSessionState.Action.LOCAL_INVITATION);
processSharerStateUpdate(txn, null, update);
// track message // track message
long time = clock.currentTimeMillis(); long time = update.toSend.get(0).getTime();
trackMessage(txn, localState.getGroupId(), time, true); trackMessage(txn, localState.getGroupId(), time, true);
txn.setComplete(); txn.setComplete();
@@ -321,12 +327,13 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
// start engine and process its state update // start engine and process its state update
InviteeEngine<IS, IR> engine = InviteeEngine<IS, IR> engine =
new InviteeEngine<IS, IR>(getIRFactory()); new InviteeEngine<IS, IR>(getIRFactory(), clock);
processInviteeStateUpdate(txn, null, StateUpdate<IS, BaseMessage> update =
engine.onLocalAction(localState, localAction)); engine.onLocalAction(localState, localAction);
processInviteeStateUpdate(txn, null, update);
// track message // track message
long time = clock.currentTimeMillis(); long time = update.toSend.get(0).getTime();
trackMessage(txn, localState.getGroupId(), time, true); trackMessage(txn, localState.getGroupId(), time, true);
txn.setComplete(); txn.setComplete();
@@ -466,6 +473,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
BdfDictionary d = m.getValue(); BdfDictionary d = m.getValue();
try { try {
I msg = getIFactory().build(group.getId(), d); I msg = getIFactory().build(group.getId(), d);
@SuppressWarnings("unchecked")
IS iss = (IS) getSessionState(txn, msg.getSessionId(), true); IS iss = (IS) getSessionState(txn, msg.getSessionId(), true);
// get and add the shareable if the invitation is unanswered // get and add the shareable if the invitation is unanswered
if (iss.getState().equals(AWAIT_LOCAL_RESPONSE)) { if (iss.getState().equals(AWAIT_LOCAL_RESPONSE)) {
@@ -642,7 +650,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
} }
private IS initializeInviteeState(Transaction txn, private IS initializeInviteeState(Transaction txn,
ContactId contactId, I msg) ContactId contactId, I msg, MessageId id)
throws FormatException, DbException { throws FormatException, DbException {
Contact c = db.getContact(txn, contactId); Contact c = db.getContact(txn, contactId);
@@ -656,9 +664,10 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
Message m = clientHelper.createMessage(localGroup.getId(), now, Message m = clientHelper.createMessage(localGroup.getId(), now,
BdfList.of(mSalt)); BdfList.of(mSalt));
IS s = getISFactory().build(msg.getSessionId(), IS s = getISFactory()
m.getId(), group.getId(), .build(msg.getSessionId(), m.getId(), group.getId(),
InviteeSessionState.State.AWAIT_INVITATION, contactId, f); InviteeSessionState.State.AWAIT_INVITATION, contactId,
f, id);
// save local state to database // save local state to database
BdfDictionary d = s.toBdfDictionary(); BdfDictionary d = s.toBdfDictionary();
@@ -712,6 +721,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
if (!d.getBoolean(IS_SHARER)) throw new FormatException(); if (!d.getBoolean(IS_SHARER)) throw new FormatException();
//noinspection unchecked
return (SS) SharingSessionState return (SS) SharingSessionState
.fromBdfDictionary(getISFactory(), getSSFactory(), d); .fromBdfDictionary(getISFactory(), getSSFactory(), d);
} }
@@ -746,6 +756,7 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
} }
throw new DbException(); throw new DbException();
} }
//noinspection unchecked
return (IS) SharingSessionState return (IS) SharingSessionState
.fromBdfDictionary(getISFactory(), getSSFactory(), .fromBdfDictionary(getISFactory(), getSSFactory(),
map.values().iterator().next()); map.values().iterator().next());
@@ -898,16 +909,15 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
byte[] body = clientHelper.toByteArray(m.toBdfList()); byte[] body = clientHelper.toByteArray(m.toBdfList());
Group group = db.getGroup(txn, m.getGroupId()); Group group = db.getGroup(txn, m.getGroupId());
long timestamp = clock.currentTimeMillis();
// add message itself as metadata // add message itself as metadata
BdfDictionary d = m.toBdfDictionary(); BdfDictionary d = m.toBdfDictionary();
d.put(LOCAL, true); d.put(LOCAL, true);
d.put(TIME, timestamp); d.put(TIME, m.getTime());
Metadata meta = metadataEncoder.encode(d); Metadata meta = metadataEncoder.encode(d);
messageQueueManager messageQueueManager
.sendMessage(txn, group, timestamp, body, meta); .sendMessage(txn, group, m.getTime(), body, meta);
} }
private Group getContactGroup(Contact c) { private Group getContactGroup(Contact c) {
@@ -930,14 +940,16 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IS
SharerSessionState.Action.LOCAL_LEAVE; SharerSessionState.Action.LOCAL_LEAVE;
SharerEngine<I, SS, IRR> engine = SharerEngine<I, SS, IRR> engine =
new SharerEngine<I, SS, IRR>(getIFactory(), new SharerEngine<I, SS, IRR>(getIFactory(),
getIRRFactory()); getIRRFactory(), clock);
//noinspection unchecked
processSharerStateUpdate(txn, null, processSharerStateUpdate(txn, null,
engine.onLocalAction((SS) state, action)); engine.onLocalAction((SS) state, action));
} else { } else {
InviteeSessionState.Action action = InviteeSessionState.Action action =
InviteeSessionState.Action.LOCAL_LEAVE; InviteeSessionState.Action.LOCAL_LEAVE;
InviteeEngine<IS, IR> engine = InviteeEngine<IS, IR> engine =
new InviteeEngine<IS, IR>(getIRFactory()); new InviteeEngine<IS, IR>(getIRFactory(), clock);
//noinspection unchecked
processInviteeStateUpdate(txn, null, processInviteeStateUpdate(txn, null,
engine.onLocalAction((IS) state, action)); engine.onLocalAction((IS) state, action));
} }