mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Migrate blog sharing to new sharing client infrastructure
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.briarproject.briar.api.blog;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||
|
||||
public interface BlogConstants {
|
||||
@@ -7,12 +8,7 @@ public interface BlogConstants {
|
||||
/**
|
||||
* The maximum length of a blogs's name in UTF-8 bytes.
|
||||
*/
|
||||
int MAX_BLOG_TITLE_LENGTH = 100;
|
||||
|
||||
/**
|
||||
* The length of a blogs's description in UTF-8 bytes.
|
||||
*/
|
||||
int MAX_BLOG_DESC_LENGTH = 240;
|
||||
int MAX_BLOG_NAME_LENGTH = MAX_AUTHOR_NAME_LENGTH;
|
||||
|
||||
/**
|
||||
* The maximum length of a blog post's body in bytes.
|
||||
@@ -24,13 +20,8 @@ public interface BlogConstants {
|
||||
*/
|
||||
int MAX_BLOG_COMMENT_LENGTH = MAX_BLOG_POST_BODY_LENGTH;
|
||||
|
||||
/* Blog Sharing Constants */
|
||||
String BLOG_AUTHOR_NAME = "blogAuthorName";
|
||||
String BLOG_PUBLIC_KEY = "blogPublicKey";
|
||||
|
||||
// Metadata keys
|
||||
String KEY_TYPE = "type";
|
||||
String KEY_DESCRIPTION = "description";
|
||||
String KEY_TIMESTAMP = "timestamp";
|
||||
String KEY_TIME_RECEIVED = "timeReceived";
|
||||
String KEY_AUTHOR_ID = "id";
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package org.briarproject.briar.api.blog;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
@@ -15,24 +12,16 @@ import javax.annotation.Nullable;
|
||||
@NotNullByDefault
|
||||
public class BlogInvitationRequest extends InvitationRequest<Blog> {
|
||||
|
||||
private final String blogAuthorName;
|
||||
|
||||
public BlogInvitationRequest(MessageId id, SessionId sessionId,
|
||||
GroupId groupId, ContactId contactId, String blogAuthorName,
|
||||
@Nullable String message, GroupId blogId,
|
||||
boolean available, boolean canBeOpened, long time,
|
||||
boolean local, boolean sent, boolean seen, boolean read) {
|
||||
// TODO pass a proper blog here when redoing the BlogSharingManager
|
||||
super(id, groupId, time, local, sent, seen, read, sessionId,
|
||||
new Blog(new Group(blogId, BlogManager.CLIENT_ID, new byte[0]),
|
||||
new Author(new AuthorId(new byte[AuthorId.LENGTH]),
|
||||
blogAuthorName, new byte[0])), contactId,
|
||||
message, available, canBeOpened);
|
||||
this.blogAuthorName = blogAuthorName;
|
||||
public BlogInvitationRequest(MessageId id, GroupId groupId, long time,
|
||||
boolean local, boolean sent, boolean seen, boolean read,
|
||||
SessionId sessionId, Blog blog, ContactId contactId,
|
||||
@Nullable String message, boolean available, boolean canBeOpened) {
|
||||
super(id, groupId, time, local, sent, seen, read, sessionId, blog,
|
||||
contactId, message, available, canBeOpened);
|
||||
}
|
||||
|
||||
public String getBlogAuthorName() {
|
||||
return blogAuthorName;
|
||||
return getShareable().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ import org.briarproject.briar.api.sharing.InvitationResponse;
|
||||
@NotNullByDefault
|
||||
public class BlogInvitationResponse extends InvitationResponse {
|
||||
|
||||
public BlogInvitationResponse(MessageId id, SessionId sessionId,
|
||||
GroupId groupId, ContactId contactId, GroupId blogId,
|
||||
boolean accept, long time, boolean local, boolean sent,
|
||||
boolean seen, boolean read) {
|
||||
public BlogInvitationResponse(MessageId id, GroupId groupId, long time,
|
||||
boolean local, boolean sent, boolean seen, boolean read,
|
||||
SessionId sessionId, GroupId blogId, ContactId contactId,
|
||||
boolean accept) {
|
||||
super(id, groupId, time, local, sent, seen, read, sessionId, blogId,
|
||||
contactId, accept);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,16 @@ public interface BlogManager {
|
||||
*/
|
||||
ClientId CLIENT_ID = new ClientId("org.briarproject.briar.blog");
|
||||
|
||||
/**
|
||||
* Adds a blog from the given author.
|
||||
*/
|
||||
Blog addBlog(Author author) throws DbException;
|
||||
|
||||
/**
|
||||
* Adds the given {@link Blog} within the given {@link Transaction}.
|
||||
*/
|
||||
void addBlog(Transaction txn, Blog b) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true if a blog can be removed.
|
||||
*/
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package org.briarproject.briar.api.blog;
|
||||
|
||||
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.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.sharing.SharingMessage.Invitation;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.INVITATION_MSG;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SESSION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TIME;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface BlogSharingMessage {
|
||||
|
||||
class BlogInvitation extends Invitation {
|
||||
|
||||
private final String blogAuthorName;
|
||||
private final byte[] blogPublicKey;
|
||||
|
||||
public BlogInvitation(GroupId groupId, SessionId sessionId,
|
||||
String blogAuthorName, byte[] blogPublicKey, long time,
|
||||
@Nullable String message) {
|
||||
super(groupId, sessionId, time, message);
|
||||
|
||||
this.blogAuthorName = blogAuthorName;
|
||||
this.blogPublicKey = blogPublicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfList toBdfList() {
|
||||
BdfList list = super.toBdfList();
|
||||
list.add(BdfList.of(blogAuthorName, blogPublicKey));
|
||||
if (message != null) list.add(message);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = toBdfDictionaryHelper();
|
||||
d.put(BLOG_AUTHOR_NAME, blogAuthorName);
|
||||
d.put(BLOG_PUBLIC_KEY, blogPublicKey);
|
||||
if (message != null) d.put(INVITATION_MSG, message);
|
||||
return d;
|
||||
}
|
||||
|
||||
public static BlogInvitation from(GroupId groupId, BdfDictionary d)
|
||||
throws FormatException {
|
||||
|
||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
||||
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
||||
String message = d.getOptionalString(INVITATION_MSG);
|
||||
long time = d.getLong(TIME);
|
||||
|
||||
return new BlogInvitation(groupId, sessionId, blogAuthorName,
|
||||
blogPublicKey, time, message);
|
||||
}
|
||||
|
||||
public String getBlogAuthorName() {
|
||||
return blogAuthorName;
|
||||
}
|
||||
|
||||
public byte[] getBlogPublicKey() {
|
||||
return blogPublicKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
package org.briarproject.briar.api.forum;
|
||||
|
||||
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.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.sharing.SharingMessage.Invitation;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_NAME;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.INVITATION_MSG;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SESSION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TIME;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface ForumSharingMessage {
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class ForumInvitation extends Invitation {
|
||||
|
||||
private final String forumName;
|
||||
private final byte[] forumSalt;
|
||||
|
||||
public ForumInvitation(GroupId groupId, SessionId sessionId,
|
||||
String forumName, byte[] forumSalt, long time,
|
||||
@Nullable String message) {
|
||||
|
||||
super(groupId, sessionId, time, message);
|
||||
|
||||
this.forumName = forumName;
|
||||
this.forumSalt = forumSalt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfList toBdfList() {
|
||||
BdfList list = super.toBdfList();
|
||||
list.add(forumName);
|
||||
list.add(forumSalt);
|
||||
if (message != null) list.add(message);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = toBdfDictionaryHelper();
|
||||
d.put(FORUM_NAME, forumName);
|
||||
d.put(FORUM_SALT, forumSalt);
|
||||
if (message != null) d.put(INVITATION_MSG, message);
|
||||
return d;
|
||||
}
|
||||
|
||||
public static ForumInvitation from(GroupId groupId, BdfDictionary d)
|
||||
throws FormatException {
|
||||
|
||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||
String forumName = d.getString(FORUM_NAME);
|
||||
byte[] forumSalt = d.getRaw(FORUM_SALT);
|
||||
String message = d.getOptionalString(INVITATION_MSG);
|
||||
long time = d.getLong(TIME);
|
||||
|
||||
return new ForumInvitation(groupId, sessionId, forumName, forumSalt,
|
||||
time, message);
|
||||
}
|
||||
|
||||
public String getForumName() {
|
||||
return forumName;
|
||||
}
|
||||
|
||||
public byte[] getForumSalt() {
|
||||
return forumSalt;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.briarproject.briar.api.sharing;
|
||||
|
||||
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 extends SharingMessage.Invitation> {
|
||||
|
||||
I build(GroupId groupId, BdfDictionary d) throws FormatException;
|
||||
}
|
||||
@@ -4,74 +4,10 @@ import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_L
|
||||
|
||||
public interface SharingConstants {
|
||||
|
||||
/**
|
||||
* The length of a sharing session's random salt in bytes.
|
||||
*/
|
||||
int SHARING_SALT_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* The maximum length of the optional message from the inviter to the
|
||||
* invitee in UTF-8 bytes.
|
||||
*/
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
package org.briarproject.briar.api.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.GROUP_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SESSION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TIME;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TYPE;
|
||||
|
||||
@Deprecated
|
||||
@NotNullByDefault
|
||||
public interface SharingMessage {
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
abstract class BaseMessage {
|
||||
|
||||
private final GroupId groupId;
|
||||
private final SessionId sessionId;
|
||||
private final long time;
|
||||
|
||||
BaseMessage(GroupId groupId, SessionId sessionId, long time) {
|
||||
this.groupId = groupId;
|
||||
this.sessionId = sessionId;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public BdfList toBdfList() {
|
||||
return BdfList.of(getType(), getSessionId());
|
||||
}
|
||||
|
||||
public abstract BdfDictionary toBdfDictionary();
|
||||
|
||||
protected BdfDictionary toBdfDictionaryHelper() {
|
||||
return BdfDictionary.of(
|
||||
new BdfEntry(TYPE, getType()),
|
||||
new BdfEntry(GROUP_ID, groupId),
|
||||
new BdfEntry(SESSION_ID, sessionId)
|
||||
);
|
||||
}
|
||||
|
||||
public static BaseMessage from(InvitationFactory invitationFactory,
|
||||
GroupId groupId, BdfDictionary d)
|
||||
throws FormatException {
|
||||
|
||||
long type = d.getLong(TYPE);
|
||||
|
||||
if (type == SHARE_MSG_TYPE_INVITATION)
|
||||
return invitationFactory.build(groupId, d);
|
||||
else
|
||||
return SimpleMessage.from(type, groupId, d);
|
||||
}
|
||||
|
||||
public abstract long getType();
|
||||
|
||||
public GroupId getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public SessionId getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
abstract class Invitation extends BaseMessage {
|
||||
|
||||
@Nullable
|
||||
protected final String message;
|
||||
|
||||
public Invitation(GroupId groupId, SessionId sessionId, long time,
|
||||
@Nullable String message) {
|
||||
|
||||
super(groupId, sessionId, time);
|
||||
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getType() {
|
||||
return SHARE_MSG_TYPE_INVITATION;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class SimpleMessage extends BaseMessage {
|
||||
|
||||
private final long type;
|
||||
|
||||
public SimpleMessage(long type, GroupId groupId, SessionId sessionId,
|
||||
long time) {
|
||||
super(groupId, sessionId, time);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
return toBdfDictionaryHelper();
|
||||
}
|
||||
|
||||
public static SimpleMessage from(long type, GroupId groupId,
|
||||
BdfDictionary d) throws FormatException {
|
||||
|
||||
if (type != SHARE_MSG_TYPE_ACCEPT &&
|
||||
type != SHARE_MSG_TYPE_DECLINE &&
|
||||
type != SHARE_MSG_TYPE_LEAVE &&
|
||||
type != SHARE_MSG_TYPE_ABORT) throw new FormatException();
|
||||
|
||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||
long time = d.getLong(TIME);
|
||||
return new SimpleMessage(type, groupId, sessionId, time);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
public void addingContact(Transaction txn, Contact c) throws DbException {
|
||||
// Add the personal blog of the contact and share it with the contact
|
||||
Blog b = blogFactory.createBlog(c.getAuthor());
|
||||
db.addGroup(txn, b.getGroup());
|
||||
addBlog(txn, b);
|
||||
db.setGroupVisibility(txn, c.getId(), b.getId(), SHARED);
|
||||
// Share our personal blog with the contact
|
||||
LocalAuthor a = identityManager.getLocalAuthor(txn);
|
||||
@@ -170,6 +170,25 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog addBlog(Author author) throws DbException {
|
||||
Blog b = blogFactory.createBlog(author);
|
||||
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
db.addGroup(txn, b.getGroup());
|
||||
db.commitTransaction(txn);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBlog(Transaction txn, Blog b) throws DbException {
|
||||
db.addGroup(txn, b.getGroup());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeRemoved(GroupId g) throws DbException {
|
||||
Transaction txn = db.startTransaction(true);
|
||||
|
||||
@@ -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.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
||||
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class BlogInvitationFactoryImpl implements InvitationFactory<Blog> {
|
||||
|
||||
@Inject
|
||||
BlogInvitationFactoryImpl() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogInvitationRequest createInvitationRequest(boolean local,
|
||||
boolean sent, boolean seen, boolean read, InviteMessage<Blog> m,
|
||||
ContactId c, boolean available, boolean canBeOpened) {
|
||||
SessionId sessionId = new SessionId(m.getShareableId().getBytes());
|
||||
return new BlogInvitationRequest(m.getId(), m.getContactGroupId(),
|
||||
m.getTimestamp(), local, sent, seen, read, sessionId,
|
||||
m.getShareable(), c, m.getMessage(), available, canBeOpened);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogInvitationResponse 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 BlogInvitationResponse(id, contactGroupId, time, local,
|
||||
sent, seen, read, sessionId, shareableId, contactId, accept);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.client.SessionId;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_PUBLIC_KEY;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class BlogInviteeSessionState extends InviteeSessionState {
|
||||
|
||||
private final String blogAuthorName;
|
||||
private final byte[] blogPublicKey;
|
||||
|
||||
BlogInviteeSessionState(SessionId sessionId, MessageId storageId,
|
||||
GroupId groupId, State state, ContactId contactId, GroupId blogId,
|
||||
String blogAuthorName, byte[] blogPublicKey,
|
||||
MessageId invitationId) {
|
||||
super(sessionId, storageId, groupId, state, contactId, blogId,
|
||||
invitationId);
|
||||
this.blogAuthorName = blogAuthorName;
|
||||
this.blogPublicKey = blogPublicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = super.toBdfDictionary();
|
||||
d.put(BLOG_AUTHOR_NAME, getBlogAuthorName());
|
||||
d.put(BLOG_PUBLIC_KEY, getBlogPublicKey());
|
||||
return d;
|
||||
}
|
||||
|
||||
String getBlogAuthorName() {
|
||||
return blogAuthorName;
|
||||
}
|
||||
|
||||
byte[] getBlogPublicKey() {
|
||||
return blogPublicKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
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.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class BlogMessageParserImpl extends MessageParserImpl<Blog> {
|
||||
|
||||
private final BlogFactory blogFactory;
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
@Inject
|
||||
BlogMessageParserImpl(ClientHelper clientHelper, BlogFactory blogFactory,
|
||||
AuthorFactory authorFactory) {
|
||||
super(clientHelper);
|
||||
this.blogFactory = blogFactory;
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blog createShareable(BdfList descriptor)
|
||||
throws FormatException {
|
||||
String name = descriptor.getString(0);
|
||||
byte[] publicKey = descriptor.getRaw(1);
|
||||
Author author = authorFactory.createAuthor(name, publicKey);
|
||||
return blogFactory.createBlog(author);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
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.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.ClientId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
||||
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||
import org.briarproject.briar.api.blog.BlogManager;
|
||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
|
||||
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
|
||||
|
||||
private final BlogManager blogManager;
|
||||
private final InvitationFactory<Blog> invitationFactory;
|
||||
|
||||
@Inject
|
||||
BlogProtocolEngineImpl(DatabaseComponent db,
|
||||
ClientHelper clientHelper, MessageEncoder messageEncoder,
|
||||
MessageParser<Blog> messageParser, MessageTracker messageTracker,
|
||||
Clock clock, BlogManager blogManager,
|
||||
InvitationFactory<Blog> invitationFactory) {
|
||||
super(db, clientHelper, messageEncoder, messageParser, messageTracker,
|
||||
clock);
|
||||
this.blogManager = blogManager;
|
||||
this.invitationFactory = invitationFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
Event getInvitationRequestReceivedEvent(InviteMessage<Blog> m,
|
||||
ContactId contactId, boolean available, boolean canBeOpened) {
|
||||
BlogInvitationRequest request =
|
||||
(BlogInvitationRequest) invitationFactory
|
||||
.createInvitationRequest(false, false, true, false, m,
|
||||
contactId, available, canBeOpened);
|
||||
return new BlogInvitationRequestReceivedEvent(m.getShareable(),
|
||||
contactId, request);
|
||||
}
|
||||
|
||||
@Override
|
||||
Event getInvitationResponseReceivedEvent(AcceptMessage m,
|
||||
ContactId contactId) {
|
||||
BlogInvitationResponse response =
|
||||
(BlogInvitationResponse) invitationFactory
|
||||
.createInvitationResponse(m.getId(),
|
||||
m.getContactGroupId(), m.getTimestamp(), false,
|
||||
false, true, false, m.getShareableId(),
|
||||
contactId, true);
|
||||
return new BlogInvitationResponseReceivedEvent(contactId, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
Event getInvitationResponseReceivedEvent(DeclineMessage m,
|
||||
ContactId contactId) {
|
||||
BlogInvitationResponse response =
|
||||
(BlogInvitationResponse) invitationFactory
|
||||
.createInvitationResponse(m.getId(),
|
||||
m.getContactGroupId(), m.getTimestamp(), false,
|
||||
false, true, false, m.getShareableId(),
|
||||
contactId, true);
|
||||
return new BlogInvitationResponseReceivedEvent(contactId, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClientId getClientId() {
|
||||
return BlogSharingManager.CLIENT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addShareable(Transaction txn, MessageId inviteId)
|
||||
throws DbException, FormatException {
|
||||
InviteMessage<Blog> invite =
|
||||
messageParser.getInviteMessage(txn, inviteId);
|
||||
blogManager.addBlog(txn, invite.getShareable());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.client.SessionId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_PUBLIC_KEY;
|
||||
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
class BlogSharerSessionState extends SharerSessionState {
|
||||
|
||||
private final String blogAuthorName;
|
||||
private final byte[] blogPublicKey;
|
||||
|
||||
BlogSharerSessionState(SessionId sessionId, MessageId storageId,
|
||||
GroupId groupId, State state, ContactId contactId, GroupId blogId,
|
||||
String blogAuthorName, byte[] blogPublicKey,
|
||||
@Nullable MessageId responseId) {
|
||||
super(sessionId, storageId, groupId, state, contactId, blogId,
|
||||
responseId);
|
||||
|
||||
this.blogAuthorName = blogAuthorName;
|
||||
this.blogPublicKey = blogPublicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = super.toBdfDictionary();
|
||||
d.put(BLOG_AUTHOR_NAME, getBlogAuthorName());
|
||||
d.put(BLOG_PUBLIC_KEY, getBlogPublicKey());
|
||||
return d;
|
||||
}
|
||||
|
||||
String getBlogAuthorName() {
|
||||
return blogAuthorName;
|
||||
}
|
||||
|
||||
byte[] getBlogPublicKey() {
|
||||
return blogPublicKey;
|
||||
}
|
||||
}
|
||||
@@ -1,93 +1,48 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.data.MetadataParser;
|
||||
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.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
||||
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||
import org.briarproject.briar.api.blog.BlogManager;
|
||||
import org.briarproject.briar.api.blog.BlogManager.RemoveBlogHook;
|
||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||
import org.briarproject.briar.api.blog.BlogSharingMessage.BlogInvitation;
|
||||
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
|
||||
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
||||
import org.briarproject.briar.api.client.MessageQueueManager;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.INVITATION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.RESPONSE_ID;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class BlogSharingManagerImpl extends
|
||||
OldSharingManagerImpl<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationRequestReceivedEvent, BlogInvitationResponseReceivedEvent>
|
||||
class BlogSharingManagerImpl extends SharingManagerImpl<Blog>
|
||||
implements BlogSharingManager, RemoveBlogHook {
|
||||
|
||||
private final ContactManager contactManager;
|
||||
private final IdentityManager identityManager;
|
||||
private final BlogManager blogManager;
|
||||
|
||||
private final SFactory sFactory;
|
||||
private final IFactory iFactory;
|
||||
private final ISFactory isFactory;
|
||||
private final SSFactory ssFactory;
|
||||
private final IRFactory irFactory;
|
||||
private final IRRFactory irrFactory;
|
||||
|
||||
@Inject
|
||||
BlogSharingManagerImpl(AuthorFactory authorFactory, BlogFactory blogFactory,
|
||||
BlogManager blogManager, ClientHelper clientHelper, Clock clock,
|
||||
DatabaseComponent db, MessageQueueManager messageQueueManager,
|
||||
MetadataEncoder metadataEncoder, MetadataParser metadataParser,
|
||||
ContactGroupFactory contactGroupFactory, SecureRandom random,
|
||||
ContactManager contactManager, IdentityManager identityManager,
|
||||
MessageTracker messageTracker) {
|
||||
|
||||
super(db, messageQueueManager, clientHelper, metadataParser,
|
||||
metadataEncoder, random, contactGroupFactory, messageTracker,
|
||||
clock);
|
||||
|
||||
this.blogManager = blogManager;
|
||||
this.contactManager = contactManager;
|
||||
BlogSharingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
|
||||
MetadataParser metadataParser, MessageParser<Blog> messageParser,
|
||||
SessionEncoder sessionEncoder, SessionParser sessionParser,
|
||||
MessageTracker messageTracker,
|
||||
ContactGroupFactory contactGroupFactory,
|
||||
ProtocolEngine<Blog> engine,
|
||||
InvitationFactory<Blog> invitationFactory,
|
||||
IdentityManager identityManager, BlogManager blogManager) {
|
||||
super(db, clientHelper, metadataParser, messageParser, sessionEncoder,
|
||||
sessionParser, messageTracker, contactGroupFactory, engine,
|
||||
invitationFactory);
|
||||
this.identityManager = identityManager;
|
||||
sFactory = new SFactory(authorFactory, blogFactory, blogManager);
|
||||
iFactory = new IFactory();
|
||||
isFactory = new ISFactory();
|
||||
ssFactory = new SSFactory();
|
||||
irFactory = new IRFactory(sFactory);
|
||||
irrFactory = new IRRFactory();
|
||||
this.blogManager = blogManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,91 +51,18 @@ class BlogSharingManagerImpl extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBeShared(Transaction txn, GroupId g, Contact c)
|
||||
throws DbException {
|
||||
|
||||
// check if g is our personal blog
|
||||
protected boolean canBeShared(Transaction txn, GroupId shareableId,
|
||||
Contact c) throws DbException {
|
||||
// check if shareableId belongs to our personal blog
|
||||
LocalAuthor author = identityManager.getLocalAuthor(txn);
|
||||
Blog b = blogManager.getPersonalBlog(author);
|
||||
if (b.getId().equals(g)) return false;
|
||||
if (b.getId().equals(shareableId)) return false;
|
||||
|
||||
// check if g is c's personal blog
|
||||
// check if shareableId belongs to c's personal blog
|
||||
b = blogManager.getPersonalBlog(c.getAuthor());
|
||||
if (b.getId().equals(g)) return false;
|
||||
if (b.getId().equals(shareableId)) return false;
|
||||
|
||||
return super.canBeShared(txn, g, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Contact> getSharedWith(GroupId g) throws DbException {
|
||||
Blog blog = blogManager.getBlog(g);
|
||||
LocalAuthor author = identityManager.getLocalAuthor();
|
||||
if (blog.getAuthor().equals(author)) {
|
||||
// This is our personal blog. It is shared with all our contacts
|
||||
return contactManager.getActiveContacts();
|
||||
} else {
|
||||
// This is someone else's blog. Look up who it is shared with
|
||||
Collection<Contact> shared = super.getSharedWith(g);
|
||||
// If the blog author is our contact, also add her to the list
|
||||
boolean isContact = contactManager
|
||||
.contactExists(blog.getAuthor().getId(), author.getId());
|
||||
if (isContact) {
|
||||
shared.add(contactManager
|
||||
.getContact(blog.getAuthor().getId(), author.getId()));
|
||||
}
|
||||
return shared;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvitationMessage createInvitationRequest(MessageId id,
|
||||
BlogInvitation msg, ContactId contactId, GroupId blogId,
|
||||
boolean available, boolean canBeOpened, long time, boolean local,
|
||||
boolean sent, boolean seen, boolean read) {
|
||||
|
||||
return new BlogInvitationRequest(id, msg.getSessionId(),
|
||||
msg.getGroupId(), contactId, msg.getBlogAuthorName(),
|
||||
msg.getMessage(), blogId, available, canBeOpened, time, local,
|
||||
sent, seen, read);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvitationMessage createInvitationResponse(MessageId id,
|
||||
SessionId sessionId, GroupId groupId, ContactId contactId,
|
||||
GroupId blogId, boolean accept, long time, boolean local,
|
||||
boolean sent, boolean seen, boolean read) {
|
||||
return new BlogInvitationResponse(id, sessionId, groupId, contactId,
|
||||
blogId, accept, time, local, sent, seen, read);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ShareableFactory<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState> getSFactory() {
|
||||
return sFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OldInvitationFactory<BlogInvitation, BlogSharerSessionState> getIFactory() {
|
||||
return iFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InviteeSessionStateFactory<Blog, BlogInviteeSessionState> getISFactory() {
|
||||
return isFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SharerSessionStateFactory<Blog, BlogSharerSessionState> getSSFactory() {
|
||||
return ssFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvitationReceivedEventFactory<BlogInviteeSessionState, BlogInvitationRequestReceivedEvent> getIRFactory() {
|
||||
return irFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> getIRRFactory() {
|
||||
return irrFactory;
|
||||
return super.canBeShared(txn, shareableId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,187 +70,4 @@ class BlogSharingManagerImpl extends
|
||||
removingShareable(txn, b);
|
||||
}
|
||||
|
||||
private static class SFactory implements
|
||||
ShareableFactory<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState> {
|
||||
|
||||
private final AuthorFactory authorFactory;
|
||||
private final BlogFactory blogFactory;
|
||||
private final BlogManager blogManager;
|
||||
|
||||
private SFactory(AuthorFactory authorFactory, BlogFactory BlogFactory,
|
||||
BlogManager BlogManager) {
|
||||
this.authorFactory = authorFactory;
|
||||
this.blogFactory = BlogFactory;
|
||||
this.blogManager = BlogManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfList encode(Blog f) {
|
||||
return BdfList.of(
|
||||
BdfList.of(
|
||||
f.getAuthor().getName(),
|
||||
f.getAuthor().getPublicKey()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog get(Transaction txn, GroupId groupId)
|
||||
throws DbException {
|
||||
return blogManager.getBlog(txn, groupId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog parse(BdfList shareable) throws FormatException {
|
||||
Author author = authorFactory
|
||||
.createAuthor(shareable.getList(0).getString(0),
|
||||
shareable.getList(0).getRaw(1));
|
||||
return blogFactory.createBlog(author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog parse(BlogInvitation msg) {
|
||||
Author author = authorFactory.createAuthor(msg.getBlogAuthorName(),
|
||||
msg.getBlogPublicKey());
|
||||
return blogFactory.createBlog(author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog parse(BlogInviteeSessionState state) {
|
||||
Author author = authorFactory
|
||||
.createAuthor(state.getBlogAuthorName(),
|
||||
state.getBlogPublicKey());
|
||||
return blogFactory.createBlog(author);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog parse(BlogSharerSessionState state) {
|
||||
Author author = authorFactory
|
||||
.createAuthor(state.getBlogAuthorName(),
|
||||
state.getBlogPublicKey());
|
||||
return blogFactory.createBlog(author);
|
||||
}
|
||||
}
|
||||
|
||||
private static class IFactory implements
|
||||
OldInvitationFactory<BlogInvitation, BlogSharerSessionState> {
|
||||
@Override
|
||||
public BlogInvitation build(GroupId groupId, BdfDictionary d)
|
||||
throws FormatException {
|
||||
return BlogInvitation.from(groupId, d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogInvitation build(BlogSharerSessionState localState,
|
||||
long time) {
|
||||
return new BlogInvitation(localState.getContactGroupId(),
|
||||
localState.getSessionId(), localState.getBlogAuthorName(),
|
||||
localState.getBlogPublicKey(), time,
|
||||
localState.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ISFactory implements
|
||||
InviteeSessionStateFactory<Blog, BlogInviteeSessionState> {
|
||||
@Override
|
||||
public BlogInviteeSessionState build(SessionId sessionId,
|
||||
MessageId storageId, GroupId groupId,
|
||||
InviteeSessionState.State state, ContactId contactId,
|
||||
GroupId blogId, BdfDictionary d) throws FormatException {
|
||||
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
||||
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
||||
MessageId invitationId = new MessageId(d.getRaw(INVITATION_ID));
|
||||
return new BlogInviteeSessionState(sessionId, storageId,
|
||||
groupId, state, contactId, blogId, blogAuthorName,
|
||||
blogPublicKey, invitationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogInviteeSessionState build(SessionId sessionId,
|
||||
MessageId storageId, GroupId groupId,
|
||||
InviteeSessionState.State state, ContactId contactId,
|
||||
Blog blog, MessageId invitationId) {
|
||||
return new BlogInviteeSessionState(sessionId, storageId,
|
||||
groupId, state, contactId, blog.getId(),
|
||||
blog.getAuthor().getName(), blog.getAuthor().getPublicKey(),
|
||||
invitationId);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SSFactory implements
|
||||
SharerSessionStateFactory<Blog, BlogSharerSessionState> {
|
||||
@Override
|
||||
public BlogSharerSessionState build(SessionId sessionId,
|
||||
MessageId storageId, GroupId groupId,
|
||||
SharerSessionState.State state, ContactId contactId,
|
||||
GroupId blogId, BdfDictionary d) throws FormatException {
|
||||
String blogAuthorName = d.getString(BLOG_AUTHOR_NAME);
|
||||
byte[] blogPublicKey = d.getRaw(BLOG_PUBLIC_KEY);
|
||||
MessageId responseId = null;
|
||||
byte[] responseIdBytes = d.getOptionalRaw(RESPONSE_ID);
|
||||
if (responseIdBytes != null)
|
||||
responseId = new MessageId(responseIdBytes);
|
||||
return new BlogSharerSessionState(sessionId, storageId,
|
||||
groupId, state, contactId, blogId, blogAuthorName,
|
||||
blogPublicKey, responseId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogSharerSessionState build(SessionId sessionId,
|
||||
MessageId storageId, GroupId groupId,
|
||||
SharerSessionState.State state, ContactId contactId,
|
||||
Blog blog) {
|
||||
return new BlogSharerSessionState(sessionId, storageId,
|
||||
groupId, state, contactId, blog.getId(),
|
||||
blog.getAuthor().getName(), blog.getAuthor().getPublicKey(),
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
private static class IRFactory implements
|
||||
InvitationReceivedEventFactory<BlogInviteeSessionState, BlogInvitationRequestReceivedEvent> {
|
||||
|
||||
private final SFactory sFactory;
|
||||
|
||||
private IRFactory(SFactory sFactory) {
|
||||
this.sFactory = sFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogInvitationRequestReceivedEvent build(
|
||||
BlogInviteeSessionState localState, long time,
|
||||
@Nullable String msg) {
|
||||
Blog blog = sFactory.parse(localState);
|
||||
ContactId contactId = localState.getContactId();
|
||||
BlogInvitationRequest request =
|
||||
new BlogInvitationRequest(localState.getInvitationId(),
|
||||
localState.getSessionId(),
|
||||
localState.getContactGroupId(), contactId,
|
||||
blog.getAuthor().getName(), msg,
|
||||
localState.getShareableId(), true, false, time,
|
||||
false, false, false, false);
|
||||
return new BlogInvitationRequestReceivedEvent(blog, contactId,
|
||||
request);
|
||||
}
|
||||
}
|
||||
|
||||
private static class IRRFactory implements
|
||||
InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> {
|
||||
@Override
|
||||
public BlogInvitationResponseReceivedEvent build(
|
||||
BlogSharerSessionState localState, boolean accept, long time) {
|
||||
ContactId c = localState.getContactId();
|
||||
MessageId responseId = localState.getResponseId();
|
||||
if (responseId == null)
|
||||
throw new IllegalStateException("No responseId");
|
||||
BlogInvitationResponse response =
|
||||
new BlogInvitationResponse(responseId,
|
||||
localState.getSessionId(),
|
||||
localState.getContactGroupId(),
|
||||
localState.getContactId(),
|
||||
localState.getShareableId(), accept, time, false,
|
||||
false, false, false);
|
||||
return new BlogInvitationResponseReceivedEvent(c, response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.client.BdfQueueMessageValidator;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
@@ -20,73 +19,35 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_N
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.BLOG_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.INVITATION_MSG;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.LOCAL;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SESSION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TIME;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TYPE;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class BlogSharingValidator extends BdfQueueMessageValidator {
|
||||
class BlogSharingValidator extends SharingValidator {
|
||||
|
||||
private final BlogFactory blogFactory;
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
@Inject
|
||||
BlogSharingValidator(ClientHelper clientHelper,
|
||||
MetadataEncoder metadataEncoder, Clock clock) {
|
||||
super(clientHelper, metadataEncoder, clock);
|
||||
BlogSharingValidator(MessageEncoder messageEncoder,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, BlogFactory blogFactory, AuthorFactory authorFactory) {
|
||||
super(messageEncoder, clientHelper, metadataEncoder, clock);
|
||||
this.blogFactory = blogFactory;
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BdfMessageContext validateMessage(Message m, Group g,
|
||||
BdfList body) throws FormatException {
|
||||
protected GroupId validateDescriptor(BdfList descriptor)
|
||||
throws FormatException {
|
||||
checkSize(descriptor, 2);
|
||||
String name = descriptor.getString(0);
|
||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = descriptor.getRaw(1);
|
||||
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
long type = body.getLong(0);
|
||||
byte[] id = body.getRaw(1);
|
||||
checkLength(id, SessionId.LENGTH);
|
||||
|
||||
if (type == SHARE_MSG_TYPE_INVITATION) {
|
||||
checkSize(body, 3, 4);
|
||||
|
||||
BdfList author = body.getList(2);
|
||||
checkSize(author, 2);
|
||||
|
||||
String authorName = author.getString(0);
|
||||
checkLength(authorName, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
|
||||
byte[] publicKey = author.getRaw(1);
|
||||
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
|
||||
d.put(BLOG_AUTHOR_NAME, authorName);
|
||||
d.put(BLOG_PUBLIC_KEY, publicKey);
|
||||
|
||||
if (body.size() > 3) {
|
||||
String msg = body.getString(3);
|
||||
checkLength(msg, 0, MAX_INVITATION_MESSAGE_LENGTH);
|
||||
d.put(INVITATION_MSG, msg);
|
||||
}
|
||||
} else {
|
||||
checkSize(body, 2);
|
||||
if (type != SHARE_MSG_TYPE_ACCEPT &&
|
||||
type != SHARE_MSG_TYPE_DECLINE &&
|
||||
type != SHARE_MSG_TYPE_LEAVE &&
|
||||
type != SHARE_MSG_TYPE_ABORT) {
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
// Return the metadata
|
||||
d.put(TYPE, type);
|
||||
d.put(SESSION_ID, id);
|
||||
d.put(LOCAL, false);
|
||||
d.put(TIME, m.getTimestamp());
|
||||
return new BdfMessageContext(d);
|
||||
Author author = authorFactory.createAuthor(name, publicKey);
|
||||
Blog blog = blogFactory.createBlog(author);
|
||||
return blog.getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Deprecated
|
||||
@NotNullByDefault
|
||||
interface InvitationReceivedEventFactory<IS extends InviteeSessionState, IR extends InvitationRequestReceivedEvent> {
|
||||
|
||||
IR build(IS localState, long time, @Nullable String msg);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
|
||||
|
||||
@Deprecated
|
||||
@NotNullByDefault
|
||||
interface InvitationResponseReceivedEventFactory<SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> {
|
||||
|
||||
IRR build(SS localState, boolean accept, long time);
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.client.ProtocolEngine;
|
||||
import org.briarproject.briar.api.sharing.SharingMessage.Invitation;
|
||||
import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_ADD_SHARED_SHAREABLE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_UNSHARE_SHAREABLE_SHARED_WITH_US;
|
||||
import static org.briarproject.briar.api.sharing.SharingMessage.BaseMessage;
|
||||
import static org.briarproject.briar.api.sharing.SharingMessage.SimpleMessage;
|
||||
|
||||
@Deprecated
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class InviteeEngine<IS extends InviteeSessionState, IR extends InvitationRequestReceivedEvent>
|
||||
implements ProtocolEngine<InviteeSessionState.Action, IS, BaseMessage> {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(InviteeEngine.class.getName());
|
||||
|
||||
private final InvitationReceivedEventFactory<IS, IR>
|
||||
invitationReceivedEventFactory;
|
||||
private final Clock clock;
|
||||
|
||||
InviteeEngine(
|
||||
InvitationReceivedEventFactory<IS, IR> invitationReceivedEventFactory,
|
||||
Clock clock) {
|
||||
this.invitationReceivedEventFactory = invitationReceivedEventFactory;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateUpdate<IS, BaseMessage> onLocalAction(
|
||||
IS localState, InviteeSessionState.Action action) {
|
||||
|
||||
try {
|
||||
InviteeSessionState.State currentState = localState.getState();
|
||||
InviteeSessionState.State nextState = currentState.next(action);
|
||||
localState.setState(nextState);
|
||||
|
||||
if (action == InviteeSessionState.Action.LOCAL_ABORT &&
|
||||
currentState != InviteeSessionState.State.ERROR) {
|
||||
return abortSession(currentState, localState);
|
||||
}
|
||||
|
||||
if (nextState == InviteeSessionState.State.ERROR) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Error: Invalid action in state " +
|
||||
currentState.name());
|
||||
}
|
||||
return noUpdate(localState, true);
|
||||
}
|
||||
List<BaseMessage> messages;
|
||||
List<Event> events = Collections.emptyList();
|
||||
|
||||
if (action == InviteeSessionState.Action.LOCAL_ACCEPT ||
|
||||
action == InviteeSessionState.Action.LOCAL_DECLINE) {
|
||||
BaseMessage msg;
|
||||
if (action == InviteeSessionState.Action.LOCAL_ACCEPT) {
|
||||
localState.setTask(TASK_ADD_SHARED_SHAREABLE);
|
||||
msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT,
|
||||
localState.getContactGroupId(), localState.getSessionId(),
|
||||
clock.currentTimeMillis());
|
||||
} else {
|
||||
localState.setTask(
|
||||
TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US);
|
||||
msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE,
|
||||
localState.getContactGroupId(), localState.getSessionId(),
|
||||
clock.currentTimeMillis());
|
||||
}
|
||||
messages = Collections.singletonList(msg);
|
||||
logLocalAction(currentState, localState, msg);
|
||||
} else if (action == InviteeSessionState.Action.LOCAL_LEAVE) {
|
||||
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
|
||||
localState.getContactGroupId(), localState.getSessionId(),
|
||||
clock.currentTimeMillis());
|
||||
messages = Collections.singletonList(msg);
|
||||
logLocalAction(currentState, localState, msg);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Local Action");
|
||||
}
|
||||
return new StateUpdate<IS, BaseMessage>(false,
|
||||
false, localState, messages, events);
|
||||
} catch (FormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateUpdate<IS, BaseMessage> onMessageReceived(
|
||||
IS localState, BaseMessage msg) {
|
||||
|
||||
try {
|
||||
InviteeSessionState.State currentState = localState.getState();
|
||||
InviteeSessionState.Action action =
|
||||
InviteeSessionState.Action.getRemote(msg.getType());
|
||||
InviteeSessionState.State nextState = currentState.next(action);
|
||||
localState.setState(nextState);
|
||||
|
||||
logMessageReceived(currentState, nextState, msg.getType(), msg);
|
||||
|
||||
if (nextState == InviteeSessionState.State.ERROR) {
|
||||
if (currentState != InviteeSessionState.State.ERROR) {
|
||||
return abortSession(currentState, localState);
|
||||
} else {
|
||||
return noUpdate(localState, true);
|
||||
}
|
||||
}
|
||||
|
||||
List<BaseMessage> messages = Collections.emptyList();
|
||||
List<Event> events = Collections.emptyList();
|
||||
boolean deleteMsg = false;
|
||||
|
||||
if (currentState == InviteeSessionState.State.LEFT) {
|
||||
// ignore and delete messages coming in while in that state
|
||||
deleteMsg = true;
|
||||
}
|
||||
// the sharer left the forum she had shared with us
|
||||
else if (action == InviteeSessionState.Action.REMOTE_LEAVE &&
|
||||
currentState == InviteeSessionState.State.FINISHED) {
|
||||
localState.setTask(TASK_UNSHARE_SHAREABLE_SHARED_WITH_US);
|
||||
} else if (currentState == InviteeSessionState.State.FINISHED) {
|
||||
// ignore and delete messages coming in while in that state
|
||||
// note that LEAVE is possible, but was handled above
|
||||
deleteMsg = true;
|
||||
}
|
||||
// the sharer left the forum before we couldn't even respond
|
||||
else if (action == InviteeSessionState.Action.REMOTE_LEAVE) {
|
||||
localState.setTask(
|
||||
TASK_REMOVE_SHAREABLE_FROM_LIST_SHARED_WITH_US);
|
||||
}
|
||||
// we have just received our invitation
|
||||
else if (action == InviteeSessionState.Action.REMOTE_INVITATION) {
|
||||
localState.setTask(TASK_ADD_SHAREABLE_TO_LIST_SHARED_WITH_US);
|
||||
Invitation invitation = (Invitation) msg;
|
||||
Event event = invitationReceivedEventFactory.build(localState,
|
||||
msg.getTime(), invitation.getMessage());
|
||||
events = Collections.singletonList(event);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad state");
|
||||
}
|
||||
return new StateUpdate<IS, BaseMessage>(deleteMsg,
|
||||
false, localState, messages, events);
|
||||
} catch (FormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void logLocalAction(InviteeSessionState.State state,
|
||||
InviteeSessionState localState, BaseMessage msg) {
|
||||
|
||||
if (!LOG.isLoggable(INFO)) return;
|
||||
|
||||
String a = "response";
|
||||
if (msg.getType() == SHARE_MSG_TYPE_LEAVE) a = "leave";
|
||||
|
||||
LOG.info("Sending " + a + " in state " + state.name() +
|
||||
" with session ID " +
|
||||
msg.getSessionId().hashCode() + " in group " +
|
||||
msg.getGroupId().hashCode() + ". " +
|
||||
"Moving on to state " + localState.getState().name()
|
||||
);
|
||||
}
|
||||
|
||||
private void logMessageReceived(InviteeSessionState.State currentState,
|
||||
InviteeSessionState.State nextState,
|
||||
long type, BaseMessage msg) {
|
||||
|
||||
if (!LOG.isLoggable(INFO)) return;
|
||||
|
||||
String t = "unknown";
|
||||
if (type == SHARE_MSG_TYPE_INVITATION) t = "INVITE";
|
||||
else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE";
|
||||
else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT";
|
||||
|
||||
LOG.info("Received " + t + " in state " + currentState.name() +
|
||||
" with session ID " +
|
||||
msg.getSessionId().hashCode() + " in group " +
|
||||
msg.getGroupId().hashCode() + ". " +
|
||||
"Moving on to state " + nextState.name()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateUpdate<IS, BaseMessage> onMessageDelivered(
|
||||
IS localState, BaseMessage delivered) {
|
||||
try {
|
||||
return noUpdate(localState, false);
|
||||
} catch (FormatException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private StateUpdate<IS, BaseMessage> abortSession(
|
||||
InviteeSessionState.State currentState, IS localState)
|
||||
throws FormatException {
|
||||
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Aborting protocol session " +
|
||||
localState.getSessionId().hashCode() +
|
||||
" in state " + currentState.name());
|
||||
}
|
||||
localState.setState(InviteeSessionState.State.ERROR);
|
||||
BaseMessage msg =
|
||||
new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getContactGroupId(),
|
||||
localState.getSessionId(), clock.currentTimeMillis());
|
||||
List<BaseMessage> messages = Collections.singletonList(msg);
|
||||
|
||||
List<Event> events = Collections.emptyList();
|
||||
|
||||
return new StateUpdate<IS, BaseMessage>(false, false,
|
||||
localState, messages, events);
|
||||
}
|
||||
|
||||
private StateUpdate<IS, BaseMessage> noUpdate(
|
||||
IS localState, boolean delete) throws FormatException {
|
||||
|
||||
return new StateUpdate<IS, BaseMessage>(delete, false,
|
||||
localState, Collections.<BaseMessage>emptyList(),
|
||||
Collections.<Event>emptyList());
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.client.SessionId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.INVITATION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.IS_SHARER;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.STATE;
|
||||
import static org.briarproject.briar.sharing.InviteeSessionState.Action.LOCAL_ACCEPT;
|
||||
import static org.briarproject.briar.sharing.InviteeSessionState.Action.LOCAL_DECLINE;
|
||||
import static org.briarproject.briar.sharing.InviteeSessionState.Action.LOCAL_LEAVE;
|
||||
import static org.briarproject.briar.sharing.InviteeSessionState.Action.REMOTE_INVITATION;
|
||||
import static org.briarproject.briar.sharing.InviteeSessionState.Action.REMOTE_LEAVE;
|
||||
|
||||
@Deprecated
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
public abstract class InviteeSessionState extends SharingSessionState {
|
||||
|
||||
private State state;
|
||||
private final MessageId invitationId;
|
||||
|
||||
public InviteeSessionState(SessionId sessionId, MessageId storageId,
|
||||
GroupId groupId, State state, ContactId contactId,
|
||||
GroupId shareableId, MessageId invitationId) {
|
||||
|
||||
super(sessionId, storageId, groupId, contactId, shareableId);
|
||||
this.state = state;
|
||||
this.invitationId = invitationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = super.toBdfDictionary();
|
||||
d.put(STATE, getState().getValue());
|
||||
d.put(IS_SHARER, false);
|
||||
d.put(INVITATION_ID, invitationId);
|
||||
return d;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public MessageId getInvitationId() {
|
||||
return invitationId;
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public enum State {
|
||||
|
||||
ERROR(0),
|
||||
AWAIT_INVITATION(1) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == REMOTE_INVITATION) return AWAIT_LOCAL_RESPONSE;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_LOCAL_RESPONSE(2) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == LOCAL_ACCEPT || a == LOCAL_DECLINE) return FINISHED;
|
||||
if (a == REMOTE_LEAVE) return LEFT;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
FINISHED(3) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == LOCAL_LEAVE || a == REMOTE_LEAVE) return LEFT;
|
||||
return FINISHED;
|
||||
}
|
||||
},
|
||||
LEFT(4) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == LOCAL_LEAVE) return ERROR;
|
||||
return LEFT;
|
||||
}
|
||||
};
|
||||
|
||||
private final int value;
|
||||
|
||||
State(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static State fromValue(int value) {
|
||||
for (State s : values()) {
|
||||
if (s.value == value) return s;
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public State next(Action a) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNullByDefault
|
||||
public enum Action {
|
||||
|
||||
LOCAL_ACCEPT,
|
||||
LOCAL_DECLINE,
|
||||
LOCAL_LEAVE,
|
||||
LOCAL_ABORT,
|
||||
REMOTE_INVITATION,
|
||||
REMOTE_LEAVE,
|
||||
REMOTE_ABORT;
|
||||
|
||||
@Nullable
|
||||
public static Action getRemote(long type) {
|
||||
if (type == SHARE_MSG_TYPE_INVITATION) return REMOTE_INVITATION;
|
||||
if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE;
|
||||
if (type == SHARE_MSG_TYPE_ABORT) return REMOTE_ABORT;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.sharing.Shareable;
|
||||
|
||||
@Deprecated
|
||||
interface InviteeSessionStateFactory<S extends Shareable, IS extends InviteeSessionState> {
|
||||
|
||||
IS build(SessionId sessionId, MessageId storageId, GroupId groupId,
|
||||
InviteeSessionState.State state, ContactId contactId,
|
||||
GroupId shareableId, BdfDictionary d) throws FormatException;
|
||||
|
||||
IS build(SessionId sessionId, MessageId storageId, GroupId groupId,
|
||||
InviteeSessionState.State state, ContactId contactId, S shareable,
|
||||
MessageId invitationId);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.api.sharing.SharingMessage;
|
||||
|
||||
@Deprecated
|
||||
@NotNullByDefault
|
||||
interface OldInvitationFactory<I extends SharingMessage.Invitation, SS extends SharerSessionState>
|
||||
extends org.briarproject.briar.api.sharing.InvitationFactory<I> {
|
||||
|
||||
I build(SS localState, long time);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,7 @@ import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
import org.briarproject.briar.api.client.ProtocolStateException;
|
||||
import org.briarproject.briar.api.sharing.Shareable;
|
||||
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -486,6 +487,14 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
// The dependency, if any, must be the last remote message
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abort(txn, s);
|
||||
if (s.getState() == SHARING) {
|
||||
// Broadcast event informing that contact left
|
||||
ContactId contactId = getContactId(txn, s.getContactGroupId());
|
||||
ContactLeftShareableEvent e =
|
||||
new ContactLeftShareableEvent(s.getShareableId(),
|
||||
contactId);
|
||||
txn.attach(e);
|
||||
}
|
||||
// Move to the next state
|
||||
return new Session(nextState, s.getContactGroupId(), s.getShareableId(),
|
||||
s.getLastLocalMessageId(), m.getId(), s.getLocalTimestamp(),
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.briar.api.sharing.Shareable;
|
||||
import org.briarproject.briar.api.sharing.SharingMessage;
|
||||
|
||||
@Deprecated
|
||||
@NotNullByDefault
|
||||
interface ShareableFactory<S extends Shareable, I extends SharingMessage.Invitation, IS extends InviteeSessionState, SS extends SharerSessionState> {
|
||||
|
||||
BdfList encode(S sh);
|
||||
|
||||
S get(Transaction txn, GroupId groupId) throws DbException;
|
||||
|
||||
S parse(BdfList shareable) throws FormatException;
|
||||
|
||||
S parse(I msg);
|
||||
|
||||
S parse(IS state);
|
||||
|
||||
S parse(SS state);
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.client.ProtocolEngine;
|
||||
import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_SHARE_SHAREABLE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.TASK_UNSHARE_SHAREABLE_SHARED_BY_US;
|
||||
import static org.briarproject.briar.api.sharing.SharingMessage.BaseMessage;
|
||||
import static org.briarproject.briar.api.sharing.SharingMessage.Invitation;
|
||||
import static org.briarproject.briar.api.sharing.SharingMessage.SimpleMessage;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.REMOTE_ACCEPT;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.REMOTE_DECLINE;
|
||||
|
||||
@Deprecated
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent>
|
||||
implements ProtocolEngine<SharerSessionState.Action, SS, BaseMessage> {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SharerEngine.class.getName());
|
||||
|
||||
private final OldInvitationFactory<I, SS> invitationFactory;
|
||||
private final InvitationResponseReceivedEventFactory<SS, IRR>
|
||||
invitationResponseReceivedEventFactory;
|
||||
private final Clock clock;
|
||||
|
||||
SharerEngine(OldInvitationFactory<I, SS> invitationFactory,
|
||||
InvitationResponseReceivedEventFactory<SS, IRR> invitationResponseReceivedEventFactory,
|
||||
Clock clock) {
|
||||
this.invitationFactory = invitationFactory;
|
||||
this.invitationResponseReceivedEventFactory =
|
||||
invitationResponseReceivedEventFactory;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateUpdate<SS, BaseMessage> onLocalAction(
|
||||
SS localState, SharerSessionState.Action action) {
|
||||
|
||||
try {
|
||||
SharerSessionState.State currentState = localState.getState();
|
||||
SharerSessionState.State nextState = currentState.next(action);
|
||||
localState.setState(nextState);
|
||||
|
||||
if (action == SharerSessionState.Action.LOCAL_ABORT &&
|
||||
currentState != SharerSessionState.State.ERROR) {
|
||||
return abortSession(currentState, localState);
|
||||
}
|
||||
|
||||
if (nextState == SharerSessionState.State.ERROR) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Error: Invalid action in state " +
|
||||
currentState.name());
|
||||
}
|
||||
return noUpdate(localState, true);
|
||||
}
|
||||
List<BaseMessage> messages;
|
||||
List<Event> events = Collections.emptyList();
|
||||
|
||||
if (action == SharerSessionState.Action.LOCAL_INVITATION) {
|
||||
BaseMessage msg = invitationFactory.build(localState,
|
||||
clock.currentTimeMillis());
|
||||
messages = Collections.singletonList(msg);
|
||||
logLocalAction(currentState, nextState, msg);
|
||||
|
||||
// remember that we offered to share this forum
|
||||
localState
|
||||
.setTask(TASK_ADD_SHAREABLE_TO_LIST_TO_BE_SHARED_BY_US);
|
||||
} else if (action == SharerSessionState.Action.LOCAL_LEAVE) {
|
||||
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE,
|
||||
localState.getContactGroupId(), localState.getSessionId(),
|
||||
clock.currentTimeMillis());
|
||||
messages = Collections.singletonList(msg);
|
||||
logLocalAction(currentState, nextState, msg);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown Local Action");
|
||||
}
|
||||
return new StateUpdate<SS, BaseMessage>(false,
|
||||
false, localState, messages, events);
|
||||
} catch (FormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateUpdate<SS, BaseMessage> onMessageReceived(
|
||||
SS localState, BaseMessage msg) {
|
||||
|
||||
try {
|
||||
SharerSessionState.State currentState = localState.getState();
|
||||
SharerSessionState.Action action =
|
||||
SharerSessionState.Action.getRemote(msg.getType());
|
||||
SharerSessionState.State nextState = currentState.next(action);
|
||||
localState.setState(nextState);
|
||||
|
||||
logMessageReceived(currentState, nextState, msg.getType(), msg);
|
||||
|
||||
if (nextState == SharerSessionState.State.ERROR) {
|
||||
if (currentState != SharerSessionState.State.ERROR) {
|
||||
return abortSession(currentState, localState);
|
||||
} else {
|
||||
return noUpdate(localState, true);
|
||||
}
|
||||
}
|
||||
List<BaseMessage> messages = Collections.emptyList();
|
||||
List<Event> events = Collections.emptyList();
|
||||
boolean deleteMsg = false;
|
||||
|
||||
if (currentState == SharerSessionState.State.LEFT) {
|
||||
// ignore and delete messages coming in while in that state
|
||||
deleteMsg = true;
|
||||
} else if (action == SharerSessionState.Action.REMOTE_LEAVE) {
|
||||
localState.setTask(TASK_UNSHARE_SHAREABLE_SHARED_BY_US);
|
||||
} else if (currentState == SharerSessionState.State.FINISHED) {
|
||||
// ignore and delete messages coming in while in that state
|
||||
// note that LEAVE is possible, but was handled above
|
||||
deleteMsg = true;
|
||||
}
|
||||
// we have sent our invitation and just got a response
|
||||
else if (action == REMOTE_ACCEPT || action == REMOTE_DECLINE) {
|
||||
if (action == REMOTE_ACCEPT) {
|
||||
localState.setTask(TASK_SHARE_SHAREABLE);
|
||||
} else {
|
||||
// this ensures that the forum can be shared again
|
||||
localState.setTask(
|
||||
TASK_REMOVE_SHAREABLE_FROM_LIST_TO_BE_SHARED_BY_US);
|
||||
}
|
||||
Event event = invitationResponseReceivedEventFactory
|
||||
.build(localState, action == REMOTE_ACCEPT,
|
||||
msg.getTime());
|
||||
events = Collections.singletonList(event);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad state");
|
||||
}
|
||||
return new StateUpdate<SS, BaseMessage>(deleteMsg,
|
||||
false, localState, messages, events);
|
||||
} catch (FormatException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void logLocalAction(SharerSessionState.State currentState,
|
||||
SharerSessionState.State nextState,
|
||||
BaseMessage msg) {
|
||||
|
||||
if (!LOG.isLoggable(INFO)) return;
|
||||
|
||||
String a = "invitation";
|
||||
if (msg.getType() == SHARE_MSG_TYPE_LEAVE) a = "leave";
|
||||
|
||||
LOG.info("Sending " + a + " in state " + currentState.name() +
|
||||
" with session ID " +
|
||||
msg.getSessionId().hashCode() + " in group " +
|
||||
msg.getGroupId().hashCode() + ". " +
|
||||
"Moving on to state " + nextState.name()
|
||||
);
|
||||
}
|
||||
|
||||
private void logMessageReceived(SharerSessionState.State currentState,
|
||||
SharerSessionState.State nextState,
|
||||
long type, BaseMessage msg) {
|
||||
|
||||
if (!LOG.isLoggable(INFO)) return;
|
||||
|
||||
String t = "unknown";
|
||||
if (type == SHARE_MSG_TYPE_ACCEPT) t = "ACCEPT";
|
||||
else if (type == SHARE_MSG_TYPE_DECLINE) t = "DECLINE";
|
||||
else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE";
|
||||
else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT";
|
||||
|
||||
LOG.info("Received " + t + " in state " + currentState.name() +
|
||||
" with session ID " +
|
||||
msg.getSessionId().hashCode() + " in group " +
|
||||
msg.getGroupId().hashCode() + ". " +
|
||||
"Moving on to state " + nextState.name()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateUpdate<SS, BaseMessage> onMessageDelivered(
|
||||
SS localState, BaseMessage delivered) {
|
||||
try {
|
||||
return noUpdate(localState, false);
|
||||
} catch (FormatException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private StateUpdate<SS, BaseMessage> abortSession(
|
||||
SharerSessionState.State currentState, SS localState)
|
||||
throws FormatException {
|
||||
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Aborting protocol session " +
|
||||
localState.getSessionId().hashCode() +
|
||||
" in state " + currentState.name());
|
||||
}
|
||||
|
||||
localState.setState(SharerSessionState.State.ERROR);
|
||||
BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT,
|
||||
localState.getContactGroupId(), localState.getSessionId(),
|
||||
clock.currentTimeMillis());
|
||||
List<BaseMessage> messages = Collections.singletonList(msg);
|
||||
|
||||
List<Event> events = Collections.emptyList();
|
||||
|
||||
return new StateUpdate<SS, BaseMessage>(false, false,
|
||||
localState, messages, events);
|
||||
}
|
||||
|
||||
private StateUpdate<SS, BaseMessage> noUpdate(
|
||||
SS localState, boolean delete)
|
||||
throws FormatException {
|
||||
|
||||
return new StateUpdate<SS, BaseMessage>(delete, false,
|
||||
localState, Collections.<BaseMessage>emptyList(),
|
||||
Collections.<Event>emptyList());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.client.SessionId;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.IS_SHARER;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.RESPONSE_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ABORT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_ACCEPT;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_DECLINE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHARE_MSG_TYPE_LEAVE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.STATE;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.LOCAL_INVITATION;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.LOCAL_LEAVE;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.REMOTE_ACCEPT;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.REMOTE_DECLINE;
|
||||
import static org.briarproject.briar.sharing.SharerSessionState.Action.REMOTE_LEAVE;
|
||||
|
||||
@Deprecated
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
public abstract class SharerSessionState extends SharingSessionState {
|
||||
|
||||
private State state;
|
||||
@Nullable
|
||||
private String msg = null;
|
||||
@Nullable
|
||||
private MessageId responseId;
|
||||
|
||||
public SharerSessionState(SessionId sessionId, MessageId storageId,
|
||||
GroupId groupId, State state, ContactId contactId,
|
||||
GroupId shareableId, @Nullable MessageId responseId) {
|
||||
|
||||
super(sessionId, storageId, groupId, contactId, shareableId);
|
||||
this.state = state;
|
||||
this.responseId = responseId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = super.toBdfDictionary();
|
||||
d.put(STATE, getState().getValue());
|
||||
d.put(IS_SHARER, true);
|
||||
if (responseId != null) d.put(RESPONSE_ID, responseId);
|
||||
return d;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setMessage(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMessage() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setResponseId(@Nullable MessageId responseId) {
|
||||
this.responseId = responseId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MessageId getResponseId() {
|
||||
return responseId;
|
||||
}
|
||||
|
||||
public enum State {
|
||||
ERROR(0),
|
||||
PREPARE_INVITATION(1) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == LOCAL_INVITATION) return AWAIT_RESPONSE;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
AWAIT_RESPONSE(2) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == REMOTE_ACCEPT || a == REMOTE_DECLINE) return FINISHED;
|
||||
if (a == LOCAL_LEAVE) return LEFT;
|
||||
return ERROR;
|
||||
}
|
||||
},
|
||||
FINISHED(3) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == LOCAL_LEAVE || a == REMOTE_LEAVE) return LEFT;
|
||||
return FINISHED;
|
||||
}
|
||||
},
|
||||
LEFT(4) {
|
||||
@Override
|
||||
public State next(Action a) {
|
||||
if (a == LOCAL_LEAVE) return ERROR;
|
||||
return LEFT;
|
||||
}
|
||||
};
|
||||
|
||||
private final int value;
|
||||
|
||||
State(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static State fromValue(int value) {
|
||||
for (State s : values()) {
|
||||
if (s.value == value) return s;
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public State next(Action a) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
LOCAL_INVITATION,
|
||||
LOCAL_LEAVE,
|
||||
LOCAL_ABORT,
|
||||
REMOTE_ACCEPT,
|
||||
REMOTE_DECLINE,
|
||||
REMOTE_LEAVE,
|
||||
REMOTE_ABORT;
|
||||
|
||||
public static Action getRemote(long type) {
|
||||
if (type == SHARE_MSG_TYPE_ACCEPT) return REMOTE_ACCEPT;
|
||||
if (type == SHARE_MSG_TYPE_DECLINE) return REMOTE_DECLINE;
|
||||
if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE;
|
||||
if (type == SHARE_MSG_TYPE_ABORT) return REMOTE_ABORT;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.client.SessionId;
|
||||
import org.briarproject.briar.api.sharing.Shareable;
|
||||
|
||||
@Deprecated
|
||||
@NotNullByDefault
|
||||
interface SharerSessionStateFactory<S extends Shareable, SS extends SharerSessionState> {
|
||||
|
||||
SS build(SessionId sessionId, MessageId storageId, GroupId groupId,
|
||||
SharerSessionState.State state, ContactId contactId,
|
||||
GroupId shareableId, BdfDictionary d) throws FormatException;
|
||||
|
||||
SS build(SessionId sessionId, MessageId storageId, GroupId groupId,
|
||||
SharerSessionState.State state, ContactId contactId, S shareable);
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
import org.briarproject.briar.api.client.ProtocolStateException;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
||||
import org.briarproject.briar.api.sharing.InvitationRequest;
|
||||
@@ -211,8 +212,10 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
SessionId sessionId = getSessionId(shareableId);
|
||||
Transaction txn = db.startTransaction(false);
|
||||
try {
|
||||
// Look up the session, if there is one
|
||||
Contact contact = db.getContact(txn, contactId);
|
||||
if (!canBeShared(txn, shareableId, contact))
|
||||
throw new ProtocolStateException();
|
||||
// Look up the session, if there is one
|
||||
GroupId contactGroupId = getContactGroup(contact).getId();
|
||||
StoredSession ss = getSession(txn, contactGroupId, sessionId);
|
||||
// Create or parse the session
|
||||
@@ -400,12 +403,22 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
|
||||
@Override
|
||||
public boolean canBeShared(GroupId g, Contact c) throws DbException {
|
||||
GroupId contactGroupId = getContactGroup(c).getId();
|
||||
SessionId sessionId = getSessionId(g);
|
||||
Transaction txn = db.startTransaction(true);
|
||||
try {
|
||||
StoredSession ss = getSession(txn, contactGroupId, sessionId);
|
||||
boolean canBeShared = canBeShared(txn, g, c);
|
||||
db.commitTransaction(txn);
|
||||
return canBeShared;
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canBeShared(Transaction txn, GroupId g, Contact c)
|
||||
throws DbException {
|
||||
GroupId contactGroupId = getContactGroup(c).getId();
|
||||
SessionId sessionId = getSessionId(g);
|
||||
try {
|
||||
StoredSession ss = getSession(txn, contactGroupId, sessionId);
|
||||
// If there's no session, we can share the group with the contact
|
||||
if (ss == null) return true;
|
||||
// If the session's in the right state, the contact can be invited
|
||||
@@ -414,8 +427,6 @@ abstract class SharingManagerImpl<S extends Shareable>
|
||||
return session.getState().canInvite();
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
} finally {
|
||||
db.endTransaction(txn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ package org.briarproject.briar.sharing;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import org.briarproject.briar.api.blog.BlogManager;
|
||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||
import org.briarproject.briar.api.client.MessageQueueManager;
|
||||
import org.briarproject.briar.api.forum.Forum;
|
||||
import org.briarproject.briar.api.forum.ForumFactory;
|
||||
import org.briarproject.briar.api.forum.ForumManager;
|
||||
@@ -35,17 +37,32 @@ public class SharingModule {
|
||||
BlogSharingManager blogSharingManager;
|
||||
}
|
||||
|
||||
@Provides
|
||||
MessageEncoder provideMessageEncoder(MessageEncoderImpl messageEncoder) {
|
||||
return messageEncoder;
|
||||
}
|
||||
|
||||
@Provides
|
||||
SessionEncoder provideSessionEncoder(SessionEncoderImpl sessionEncoder) {
|
||||
return sessionEncoder;
|
||||
}
|
||||
|
||||
@Provides
|
||||
SessionParser provideSessionParser(SessionParserImpl sessionParser) {
|
||||
return sessionParser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
BlogSharingValidator provideBlogSharingValidator(
|
||||
MessageQueueManager messageQueueManager, ClientHelper clientHelper,
|
||||
MetadataEncoder metadataEncoder, Clock clock) {
|
||||
|
||||
ValidationManager validationManager, MessageEncoder messageEncoder,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, BlogFactory blogFactory, AuthorFactory authorFactory) {
|
||||
BlogSharingValidator validator =
|
||||
new BlogSharingValidator(clientHelper, metadataEncoder, clock);
|
||||
messageQueueManager.registerMessageValidator(
|
||||
BlogSharingManager.CLIENT_ID, validator);
|
||||
|
||||
new BlogSharingValidator(messageEncoder, clientHelper,
|
||||
metadataEncoder, clock, blogFactory, authorFactory);
|
||||
validationManager.registerMessageValidator(BlogSharingManager.CLIENT_ID,
|
||||
validator);
|
||||
return validator;
|
||||
}
|
||||
|
||||
@@ -53,14 +70,13 @@ public class SharingModule {
|
||||
@Singleton
|
||||
BlogSharingManager provideBlogSharingManager(
|
||||
LifecycleManager lifecycleManager, ContactManager contactManager,
|
||||
MessageQueueManager messageQueueManager,
|
||||
ValidationManager validationManager,
|
||||
ConversationManager conversationManager, BlogManager blogManager,
|
||||
BlogSharingManagerImpl blogSharingManager) {
|
||||
|
||||
lifecycleManager.registerClient(blogSharingManager);
|
||||
contactManager.registerAddContactHook(blogSharingManager);
|
||||
contactManager.registerRemoveContactHook(blogSharingManager);
|
||||
messageQueueManager.registerIncomingMessageHook(
|
||||
validationManager.registerIncomingMessageHook(
|
||||
BlogSharingManager.CLIENT_ID, blogSharingManager);
|
||||
conversationManager.registerConversationClient(blogSharingManager);
|
||||
blogManager.registerRemoveBlogHook(blogSharingManager);
|
||||
@@ -68,6 +84,24 @@ public class SharingModule {
|
||||
return blogSharingManager;
|
||||
}
|
||||
|
||||
@Provides
|
||||
MessageParser<Blog> provideBlogMessageParser(
|
||||
BlogMessageParserImpl blogMessageParser) {
|
||||
return blogMessageParser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ProtocolEngine<Blog> provideBlogProtocolEngine(
|
||||
BlogProtocolEngineImpl blogProtocolEngine) {
|
||||
return blogProtocolEngine;
|
||||
}
|
||||
|
||||
@Provides
|
||||
InvitationFactory<Blog> provideBlogInvitationFactory(
|
||||
BlogInvitationFactoryImpl blogInvitationFactory) {
|
||||
return blogInvitationFactory;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ForumSharingValidator provideForumSharingValidator(
|
||||
@@ -102,27 +136,12 @@ public class SharingModule {
|
||||
return forumSharingManager;
|
||||
}
|
||||
|
||||
@Provides
|
||||
MessageEncoder provideMessageEncoder(MessageEncoderImpl messageEncoder) {
|
||||
return messageEncoder;
|
||||
}
|
||||
|
||||
@Provides
|
||||
MessageParser<Forum> provideForumMessageParser(
|
||||
ForumMessageParserImpl forumMessageParser) {
|
||||
return forumMessageParser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
SessionEncoder provideSessionEncoder(SessionEncoderImpl sessionEncoder) {
|
||||
return sessionEncoder;
|
||||
}
|
||||
|
||||
@Provides
|
||||
SessionParser provideSessionParser(SessionParserImpl sessionParser) {
|
||||
return sessionParser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ProtocolEngine<Forum> provideForumProtocolEngine(
|
||||
ForumProtocolEngineImpl forumProtocolEngine) {
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
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.client.SessionId;
|
||||
|
||||
import javax.annotation.concurrent.NotThreadSafe;
|
||||
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.CONTACT_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.GROUP_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.IS_SHARER;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SESSION_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.SHAREABLE_ID;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.STATE;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.STORAGE_ID;
|
||||
|
||||
@Deprecated
|
||||
@NotThreadSafe
|
||||
@NotNullByDefault
|
||||
abstract class SharingSessionState {
|
||||
|
||||
private final SessionId sessionId;
|
||||
private final MessageId storageId;
|
||||
private final GroupId groupId;
|
||||
private final ContactId contactId;
|
||||
private final GroupId shareableId;
|
||||
private int task = -1; // TODO get rid of task, see #376
|
||||
|
||||
SharingSessionState(SessionId sessionId, MessageId storageId,
|
||||
GroupId groupId, ContactId contactId, GroupId shareableId) {
|
||||
|
||||
this.sessionId = sessionId;
|
||||
this.storageId = storageId;
|
||||
this.groupId = groupId;
|
||||
this.contactId = contactId;
|
||||
this.shareableId = shareableId;
|
||||
}
|
||||
|
||||
static SharingSessionState fromBdfDictionary(
|
||||
InviteeSessionStateFactory isFactory,
|
||||
SharerSessionStateFactory ssFactory, BdfDictionary d)
|
||||
throws FormatException {
|
||||
|
||||
SessionId sessionId = new SessionId(d.getRaw(SESSION_ID));
|
||||
MessageId messageId = new MessageId(d.getRaw(STORAGE_ID));
|
||||
GroupId groupId = new GroupId(d.getRaw(GROUP_ID));
|
||||
ContactId contactId = new ContactId(d.getLong(CONTACT_ID).intValue());
|
||||
GroupId forumId = new GroupId(d.getRaw(SHAREABLE_ID));
|
||||
|
||||
int intState = d.getLong(STATE).intValue();
|
||||
if (d.getBoolean(IS_SHARER)) {
|
||||
SharerSessionState.State state =
|
||||
SharerSessionState.State.fromValue(intState);
|
||||
return ssFactory.build(sessionId, messageId, groupId, state,
|
||||
contactId, forumId, d);
|
||||
} else {
|
||||
InviteeSessionState.State state =
|
||||
InviteeSessionState.State.fromValue(intState);
|
||||
return isFactory.build(sessionId, messageId, groupId, state,
|
||||
contactId, forumId, d);
|
||||
}
|
||||
}
|
||||
|
||||
public BdfDictionary toBdfDictionary() {
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
d.put(SESSION_ID, getSessionId());
|
||||
d.put(STORAGE_ID, getStorageId());
|
||||
d.put(GROUP_ID, getContactGroupId());
|
||||
d.put(CONTACT_ID, getContactId().getInt());
|
||||
d.put(SHAREABLE_ID, getShareableId());
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
public SessionId getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public MessageId getStorageId() {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
public GroupId getContactGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public ContactId getContactId() {
|
||||
return contactId;
|
||||
}
|
||||
|
||||
public GroupId getShareableId() {
|
||||
return shareableId;
|
||||
}
|
||||
|
||||
public void setTask(int task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public int getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import net.jodah.concurrentunit.Waiter;
|
||||
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@@ -17,6 +16,7 @@ import org.briarproject.briar.api.blog.BlogManager;
|
||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||
import org.briarproject.briar.api.blog.event.BlogInvitationRequestReceivedEvent;
|
||||
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
||||
import org.briarproject.briar.api.client.ProtocolStateException;
|
||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
||||
import org.briarproject.briar.test.BriarIntegrationTest;
|
||||
import org.briarproject.briar.test.BriarIntegrationTestComponent;
|
||||
@@ -35,7 +35,6 @@ import static org.briarproject.briar.test.BriarTestUtils.assertGroupCount;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class BlogSharingIntegrationTest
|
||||
extends BriarIntegrationTest<BriarIntegrationTestComponent> {
|
||||
@@ -92,7 +91,7 @@ public class BlogSharingIntegrationTest
|
||||
injectEagerSingletons(c2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = ProtocolStateException.class)
|
||||
public void testPersonalBlogCannotBeSharedWithOwner() throws Exception {
|
||||
listenToEvents(true);
|
||||
|
||||
@@ -109,11 +108,6 @@ public class BlogSharingIntegrationTest
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog1.getId(), contactId1From0, "Hi!",
|
||||
clock.currentTimeMillis());
|
||||
|
||||
// sync invitation
|
||||
sync0To1(1, false);
|
||||
// make sure the invitee ignored the request for their own blog
|
||||
assertFalse(listener1.requestReceived);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -293,17 +287,11 @@ public class BlogSharingIntegrationTest
|
||||
assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
|
||||
.contains(contact1From0));
|
||||
// invitee no longer has blog shared by sharer
|
||||
try {
|
||||
blogSharingManager1.getSharedWith(blog2.getId());
|
||||
fail();
|
||||
} catch (NoSuchGroupException e) {
|
||||
// expected
|
||||
}
|
||||
// blog can be shared again
|
||||
assertEquals(0,
|
||||
blogSharingManager1.getSharedWith(blog2.getId()).size());
|
||||
// blog can be shared again by sharer
|
||||
assertTrue(
|
||||
blogSharingManager0.canBeShared(blog2.getId(), contact1From0));
|
||||
assertTrue(
|
||||
blogSharingManager1.canBeShared(blog2.getId(), contact0From1));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package org.briarproject.briar.sharing;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_NAME_LENGTH;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
|
||||
import static org.briarproject.briar.sharing.MessageType.INVITE;
|
||||
|
||||
public class BlogSharingValidatorTest extends SharingValidatorTest {
|
||||
|
||||
private final AuthorId authorId = new AuthorId(getRandomId());
|
||||
private final String authorName = TestUtils.getRandomString(42);
|
||||
private final byte[] publicKey =
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final Author author = new Author(authorId, authorName, publicKey);
|
||||
private final Blog blog = new Blog(group, author);
|
||||
private final BdfList descriptor = BdfList.of(authorName, publicKey);
|
||||
private final String content =
|
||||
TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
|
||||
|
||||
@Override
|
||||
SharingValidator getValidator() {
|
||||
return new BlogSharingValidator(messageEncoder, clientHelper,
|
||||
metadataEncoder, clock, blogFactory, authorFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
content));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithNullContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), null, descriptor, null));
|
||||
assertExpectedContext(messageContext, null);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullBlogName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(null, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringBlogName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(123, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBlogName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of("", publicKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthBlogName() throws Exception {
|
||||
String shortBlogName = TestUtils.getRandomString(1);
|
||||
BdfList validDescriptor = BdfList.of(shortBlogName, publicKey);
|
||||
expectCreateBlog(shortBlogName, publicKey);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
|
||||
null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBlogName() throws Exception {
|
||||
String invalidBlogName =
|
||||
TestUtils.getRandomString(MAX_BLOG_NAME_LENGTH + 1);
|
||||
BdfList invalidDescriptor = BdfList.of(invalidBlogName, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullPublicKey() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(authorName, null);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawPublicKey() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(authorName, 123);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongPublicKey() throws Exception {
|
||||
byte[] invalidKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1);
|
||||
BdfList invalidDescriptor = BdfList.of(authorName, invalidKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthPublicKey() throws Exception {
|
||||
byte[] key = TestUtils.getRandomBytes(1);
|
||||
BdfList validDescriptor = BdfList.of(authorName, key);
|
||||
|
||||
expectCreateBlog(authorName, key);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
|
||||
null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongContent() throws Exception {
|
||||
String invalidContent =
|
||||
TestUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
invalidContent));
|
||||
}
|
||||
|
||||
private void expectCreateBlog(final String name, final byte[] key) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(name, key);
|
||||
will(returnValue(author));
|
||||
oneOf(blogFactory).createBlog(author);
|
||||
will(returnValue(blog));
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +1,20 @@
|
||||
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;
|
||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||
import org.briarproject.briar.api.forum.Forum;
|
||||
import org.briarproject.briar.api.forum.ForumFactory;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
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.sharing.MessageType.ABORT;
|
||||
import static org.briarproject.briar.sharing.MessageType.ACCEPT;
|
||||
import static org.briarproject.briar.sharing.MessageType.DECLINE;
|
||||
import static org.briarproject.briar.sharing.MessageType.INVITE;
|
||||
import static org.briarproject.briar.sharing.MessageType.LEAVE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ForumSharingValidatorTest extends ValidatorTestCase {
|
||||
public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
|
||||
private final MessageEncoder messageEncoder =
|
||||
context.mock(MessageEncoder.class);
|
||||
private final ForumFactory forumFactory = context.mock(ForumFactory.class);
|
||||
private final ForumSharingValidator v =
|
||||
new ForumSharingValidator(messageEncoder, clientHelper,
|
||||
metadataEncoder, clock, forumFactory);
|
||||
|
||||
private final MessageId previousMsgId = new MessageId(getRandomId());
|
||||
private final String forumName =
|
||||
TestUtils.getRandomString(MAX_FORUM_NAME_LENGTH);
|
||||
private final byte[] salt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH);
|
||||
@@ -47,8 +22,12 @@ 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"));
|
||||
|
||||
@Override
|
||||
SharingValidator getValidator() {
|
||||
return new ForumSharingValidator(messageEncoder, clientHelper,
|
||||
metadataEncoder, clock, forumFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithContent() throws Exception {
|
||||
@@ -78,107 +57,6 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
|
||||
assertExpectedContext(messageContext, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsAccept() throws Exception {
|
||||
expectEncodeMetadata(ACCEPT);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(ACCEPT.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsDecline() throws Exception {
|
||||
expectEncodeMetadata(DECLINE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(DECLINE.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsLeave() throws Exception {
|
||||
expectEncodeMetadata(LEAVE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(LEAVE.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsAbort() throws Exception {
|
||||
expectEncodeMetadata(ABORT);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullMessageType() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(null, groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonLongMessageType() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of("", groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidMessageType() throws Exception {
|
||||
int invalidMessageType = ABORT.getValue() + 1;
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(invalidMessageType, groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
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(ABORT.getValue(), 123));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortSessionId() throws Exception {
|
||||
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH - 1);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongSessionId() throws Exception {
|
||||
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH + 1);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForAbort() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForAbort() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForInvitation() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForInvitation() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null,
|
||||
123));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullForumName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(null, salt);
|
||||
@@ -293,25 +171,4 @@ public class ForumSharingValidatorTest extends ValidatorTestCase {
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectEncodeMetadata(final MessageType type) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder)
|
||||
.encodeMetadata(type, groupId, timestamp, false, false,
|
||||
false, false);
|
||||
will(returnValue(meta));
|
||||
}});
|
||||
}
|
||||
|
||||
private void assertExpectedContext(BdfMessageContext messageContext,
|
||||
@Nullable MessageId previousMsgId) throws FormatException {
|
||||
Collection<MessageId> dependencies = messageContext.getDependencies();
|
||||
if (previousMsgId == null) {
|
||||
assertTrue(dependencies.isEmpty());
|
||||
} else {
|
||||
assertEquals(1, dependencies.size());
|
||||
assertTrue(dependencies.contains(previousMsgId));
|
||||
}
|
||||
assertEquals(meta, messageContext.getDictionary());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
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;
|
||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import org.briarproject.briar.api.forum.ForumFactory;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.sharing.MessageType.ABORT;
|
||||
import static org.briarproject.briar.sharing.MessageType.ACCEPT;
|
||||
import static org.briarproject.briar.sharing.MessageType.DECLINE;
|
||||
import static org.briarproject.briar.sharing.MessageType.INVITE;
|
||||
import static org.briarproject.briar.sharing.MessageType.LEAVE;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public abstract class SharingValidatorTest extends ValidatorTestCase {
|
||||
|
||||
protected final MessageEncoder messageEncoder =
|
||||
context.mock(MessageEncoder.class);
|
||||
protected final ForumFactory forumFactory =
|
||||
context.mock(ForumFactory.class);
|
||||
protected final BlogFactory blogFactory = context.mock(BlogFactory.class);
|
||||
protected final SharingValidator v = getValidator();
|
||||
|
||||
protected final MessageId previousMsgId = new MessageId(getRandomId());
|
||||
private final BdfDictionary meta =
|
||||
BdfDictionary.of(new BdfEntry("meta", "data"));
|
||||
|
||||
abstract SharingValidator getValidator();
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForInvitation() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForInvitation() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null,
|
||||
123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsAccept() throws Exception {
|
||||
expectEncodeMetadata(ACCEPT);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(ACCEPT.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsDecline() throws Exception {
|
||||
expectEncodeMetadata(DECLINE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(DECLINE.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsLeave() throws Exception {
|
||||
expectEncodeMetadata(LEAVE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(LEAVE.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsAbort() throws Exception {
|
||||
expectEncodeMetadata(ABORT);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullMessageType() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(null, groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonLongMessageType() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of("", groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidMessageType() throws Exception {
|
||||
int invalidMessageType = ABORT.getValue() + 1;
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(invalidMessageType, groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
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(ABORT.getValue(), 123));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortSessionId() throws Exception {
|
||||
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH - 1);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongSessionId() throws Exception {
|
||||
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH + 1);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForAbort() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForAbort() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
|
||||
}
|
||||
|
||||
protected void expectEncodeMetadata(final MessageType type) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder)
|
||||
.encodeMetadata(type, groupId, timestamp, false, false,
|
||||
false, false);
|
||||
will(returnValue(meta));
|
||||
}});
|
||||
}
|
||||
|
||||
protected void assertExpectedContext(BdfMessageContext messageContext,
|
||||
@Nullable MessageId previousMsgId) throws FormatException {
|
||||
Collection<MessageId> dependencies = messageContext.getDependencies();
|
||||
if (previousMsgId == null) {
|
||||
assertTrue(dependencies.isEmpty());
|
||||
} else {
|
||||
assertEquals(1, dependencies.size());
|
||||
assertTrue(dependencies.contains(previousMsgId));
|
||||
}
|
||||
assertEquals(meta, messageContext.getDictionary());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user