Update blog and forum sharing clients to include self-destruct timers.

This commit is contained in:
akwizgran
2020-11-20 17:08:55 +00:00
parent b266b78a49
commit aee663fcc0
30 changed files with 562 additions and 142 deletions

View File

@@ -15,9 +15,9 @@ public class BlogInvitationRequest extends InvitationRequest<Blog> {
public BlogInvitationRequest(MessageId id, GroupId groupId, long time, public BlogInvitationRequest(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, Blog blog, @Nullable String text, SessionId sessionId, Blog blog, @Nullable String text,
boolean available, boolean canBeOpened) { boolean available, boolean canBeOpened, long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, blog, super(id, groupId, time, local, read, sent, seen, sessionId, blog,
text, available, canBeOpened); text, available, canBeOpened, autoDeleteTimer);
} }
@Override @Override

View File

@@ -12,9 +12,10 @@ public class BlogInvitationResponse extends InvitationResponse {
public BlogInvitationResponse(MessageId id, GroupId groupId, long time, public BlogInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId) { SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId); accept, shareableId, autoDeleteTimer);
} }
@Override @Override

View File

@@ -18,5 +18,5 @@ public interface BlogSharingManager extends SharingManager<Blog> {
/** /**
* The current minor version of the blog sharing client. * The current minor version of the blog sharing client.
*/ */
int MINOR_VERSION = 0; int MINOR_VERSION = 1;
} }

View File

@@ -17,9 +17,9 @@ public class ForumInvitationRequest extends InvitationRequest<Forum> {
public ForumInvitationRequest(MessageId id, GroupId groupId, long time, public ForumInvitationRequest(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, Forum forum, @Nullable String text, SessionId sessionId, Forum forum, @Nullable String text,
boolean available, boolean canBeOpened) { boolean available, boolean canBeOpened, long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, forum, super(id, groupId, time, local, read, sent, seen, sessionId, forum,
text, available, canBeOpened); text, available, canBeOpened, autoDeleteTimer);
} }
@Override @Override

View File

@@ -15,9 +15,10 @@ public class ForumInvitationResponse extends InvitationResponse {
public ForumInvitationResponse(MessageId id, GroupId groupId, long time, public ForumInvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId) { SessionId sessionId, boolean accept, GroupId shareableId,
long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId); accept, shareableId, autoDeleteTimer);
} }
@Override @Override

View File

@@ -18,5 +18,5 @@ public interface ForumSharingManager extends SharingManager<Forum> {
/** /**
* The current minor version of the forum sharing client. * The current minor version of the forum sharing client.
*/ */
int MINOR_VERSION = 0; int MINOR_VERSION = 1;
} }

View File

@@ -11,6 +11,8 @@ import org.briarproject.briar.api.sharing.InvitationRequest;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class GroupInvitationRequest extends InvitationRequest<PrivateGroup> { public class GroupInvitationRequest extends InvitationRequest<PrivateGroup> {
@@ -20,7 +22,7 @@ public class GroupInvitationRequest extends InvitationRequest<PrivateGroup> {
SessionId sessionId, PrivateGroup shareable, SessionId sessionId, PrivateGroup shareable,
@Nullable String text, boolean available, boolean canBeOpened) { @Nullable String text, boolean available, boolean canBeOpened) {
super(id, groupId, time, local, read, sent, seen, sessionId, shareable, super(id, groupId, time, local, read, sent, seen, sessionId, shareable,
text, available, canBeOpened); text, available, canBeOpened, NO_AUTO_DELETE_TIMER);
} }
@Override @Override

View File

@@ -9,6 +9,8 @@ import org.briarproject.briar.api.sharing.InvitationResponse;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
public class GroupInvitationResponse extends InvitationResponse { public class GroupInvitationResponse extends InvitationResponse {
@@ -17,7 +19,7 @@ public class GroupInvitationResponse extends InvitationResponse {
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accept, GroupId shareableId) { SessionId sessionId, boolean accept, GroupId shareableId) {
super(id, groupId, time, local, read, sent, seen, sessionId, super(id, groupId, time, local, read, sent, seen, sessionId,
accept, shareableId); accept, shareableId, NO_AUTO_DELETE_TIMER);
} }
@Override @Override

View File

@@ -7,8 +7,6 @@ import org.briarproject.briar.api.conversation.ConversationRequest;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
public abstract class InvitationRequest<S extends Shareable> extends public abstract class InvitationRequest<S extends Shareable> extends
ConversationRequest<S> { ConversationRequest<S> {
@@ -17,9 +15,9 @@ public abstract class InvitationRequest<S extends Shareable> extends
public InvitationRequest(MessageId messageId, GroupId groupId, long time, public InvitationRequest(MessageId messageId, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, S object, @Nullable String text, SessionId sessionId, S object, @Nullable String text,
boolean available, boolean canBeOpened) { boolean available, boolean canBeOpened, long autoDeleteTimer) {
super(messageId, groupId, time, local, read, sent, seen, sessionId, super(messageId, groupId, time, local, read, sent, seen, sessionId,
object, text, !available, NO_AUTO_DELETE_TIMER); object, text, !available, autoDeleteTimer);
this.canBeOpened = canBeOpened; this.canBeOpened = canBeOpened;
} }

View File

@@ -5,17 +5,16 @@ import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.conversation.ConversationResponse; import org.briarproject.briar.api.conversation.ConversationResponse;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
public abstract class InvitationResponse extends ConversationResponse { public abstract class InvitationResponse extends ConversationResponse {
private final GroupId shareableId; private final GroupId shareableId;
public InvitationResponse(MessageId id, GroupId groupId, long time, public InvitationResponse(MessageId id, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen, boolean local, boolean read, boolean sent, boolean seen,
SessionId sessionId, boolean accepted, GroupId shareableId) { SessionId sessionId, boolean accepted, GroupId shareableId,
long autoDeleteTimer) {
super(id, groupId, time, local, read, sent, seen, sessionId, accepted, super(id, groupId, time, local, read, sent, seen, sessionId, accepted,
NO_AUTO_DELETE_TIMER); autoDeleteTimer);
this.shareableId = shareableId; this.shareableId = shareableId;
} }

View File

@@ -9,11 +9,13 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class AcceptMessage extends SharingMessage { class AcceptMessage extends DeletableSharingMessage {
AcceptMessage(MessageId id, @Nullable MessageId previousMessageId, AcceptMessage(MessageId id, @Nullable MessageId previousMessageId,
GroupId contactGroupId, GroupId shareableId, long timestamp) { GroupId contactGroupId, GroupId shareableId, long timestamp,
super(id, contactGroupId, shareableId, timestamp, previousMessageId); long autoDeleteTimer) {
super(id, contactGroupId, shareableId, timestamp, previousMessageId,
autoDeleteTimer);
} }
} }

View File

@@ -20,20 +20,24 @@ public class BlogInvitationFactoryImpl
@Override @Override
public BlogInvitationRequest createInvitationRequest(boolean local, public BlogInvitationRequest createInvitationRequest(boolean local,
boolean sent, boolean seen, boolean read, InviteMessage<Blog> m, boolean sent, boolean seen, boolean read, InviteMessage<Blog> m,
ContactId c, boolean available, boolean canBeOpened) { ContactId c, boolean available, boolean canBeOpened,
long autoDeleteTimer) {
SessionId sessionId = new SessionId(m.getShareableId().getBytes()); SessionId sessionId = new SessionId(m.getShareableId().getBytes());
return new BlogInvitationRequest(m.getId(), m.getContactGroupId(), return new BlogInvitationRequest(m.getId(), m.getContactGroupId(),
m.getTimestamp(), local, read, sent, seen, sessionId, m.getTimestamp(), local, read, sent, seen, sessionId,
m.getShareable(), m.getText(), available, canBeOpened); m.getShareable(), m.getText(), available, canBeOpened,
autoDeleteTimer);
} }
@Override @Override
public BlogInvitationResponse createInvitationResponse(MessageId id, public BlogInvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent, GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, boolean accept, GroupId shareableId) { boolean seen, boolean read, boolean accept, GroupId shareableId,
long autoDeleteTimer) {
SessionId sessionId = new SessionId(shareableId.getBytes()); SessionId sessionId = new SessionId(shareableId.getBytes());
return new BlogInvitationResponse(id, contactGroupId, time, local, read, return new BlogInvitationResponse(id, contactGroupId, time, local, read,
sent, seen, sessionId, accept, shareableId); sent, seen, sessionId, accept, shareableId,
autoDeleteTimer);
} }
} }

View File

@@ -8,13 +8,13 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager;
import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogInvitationResponse; import org.briarproject.briar.api.blog.BlogInvitationResponse;
import org.briarproject.briar.api.blog.BlogManager; 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.BlogInvitationRequestReceivedEvent;
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent; import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.MessageTracker;
@@ -23,9 +23,6 @@ import org.briarproject.briar.api.conversation.ConversationRequest;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
import static org.briarproject.briar.api.blog.BlogManager.MAJOR_VERSION;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> { class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
@@ -41,8 +38,9 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
MessageTracker messageTracker, Clock clock, BlogManager blogManager, MessageTracker messageTracker, Clock clock, BlogManager blogManager,
InvitationFactory<Blog, BlogInvitationResponse> invitationFactory) { InvitationFactory<Blog, BlogInvitationResponse> invitationFactory) {
super(db, clientHelper, clientVersioningManager, messageEncoder, super(db, clientHelper, clientVersioningManager, messageEncoder,
messageParser, messageTracker, clock, CLIENT_ID, messageParser, messageTracker, clock,
MAJOR_VERSION); BlogSharingManager.CLIENT_ID, BlogSharingManager.MAJOR_VERSION,
BlogManager.CLIENT_ID, BlogManager.MAJOR_VERSION);
this.blogManager = blogManager; this.blogManager = blogManager;
this.invitationFactory = invitationFactory; this.invitationFactory = invitationFactory;
} }
@@ -52,7 +50,8 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
ContactId contactId, boolean available, boolean canBeOpened) { ContactId contactId, boolean available, boolean canBeOpened) {
ConversationRequest<Blog> request = invitationFactory ConversationRequest<Blog> request = invitationFactory
.createInvitationRequest(false, false, true, false, m, .createInvitationRequest(false, false, true, false, m,
contactId, available, canBeOpened); contactId, available, canBeOpened,
m.getAutoDeleteTimer());
return new BlogInvitationRequestReceivedEvent(request, contactId); return new BlogInvitationRequestReceivedEvent(request, contactId);
} }
@@ -62,7 +61,7 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
BlogInvitationResponse response = invitationFactory BlogInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, false, false, m.getTimestamp(), false, false, false, false,
true, m.getShareableId()); true, m.getShareableId(), m.getAutoDeleteTimer());
return new BlogInvitationResponseReceivedEvent(response, contactId); return new BlogInvitationResponseReceivedEvent(response, contactId);
} }
@@ -72,15 +71,10 @@ class BlogProtocolEngineImpl extends ProtocolEngineImpl<Blog> {
BlogInvitationResponse response = invitationFactory BlogInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, false, false, m.getTimestamp(), false, false, false, false,
false, m.getShareableId()); false, m.getShareableId(), m.getAutoDeleteTimer());
return new BlogInvitationResponseReceivedEvent(response, contactId); return new BlogInvitationResponseReceivedEvent(response, contactId);
} }
@Override
protected ClientId getShareableClientId() {
return CLIENT_ID;
}
@Override @Override
protected void addShareable(Transaction txn, MessageId inviteId) protected void addShareable(Transaction txn, MessageId inviteId)
throws DbException, FormatException { throws DbException, FormatException {

View File

@@ -9,12 +9,13 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class DeclineMessage extends SharingMessage { class DeclineMessage extends DeletableSharingMessage {
DeclineMessage(MessageId id, GroupId contactGroupId, DeclineMessage(MessageId id, GroupId contactGroupId,
GroupId shareableId, long timestamp, GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) { @Nullable MessageId previousMessageId, long autoDeleteTimer) {
super(id, contactGroupId, shareableId, timestamp, previousMessageId); super(id, contactGroupId, shareableId, timestamp, previousMessageId,
autoDeleteTimer);
} }
} }

View File

@@ -0,0 +1,22 @@
package org.briarproject.briar.sharing;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import javax.annotation.Nullable;
abstract class DeletableSharingMessage extends SharingMessage {
private final long autoDeleteTimer;
DeletableSharingMessage(MessageId id, GroupId contactGroupId,
GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId, long autoDeleteTimer) {
super(id, contactGroupId, shareableId, timestamp, previousMessageId);
this.autoDeleteTimer = autoDeleteTimer;
}
public long getAutoDeleteTimer() {
return autoDeleteTimer;
}
}

View File

@@ -20,20 +20,24 @@ public class ForumInvitationFactoryImpl
@Override @Override
public ForumInvitationRequest createInvitationRequest(boolean local, public ForumInvitationRequest createInvitationRequest(boolean local,
boolean sent, boolean seen, boolean read, InviteMessage<Forum> m, boolean sent, boolean seen, boolean read, InviteMessage<Forum> m,
ContactId c, boolean available, boolean canBeOpened) { ContactId c, boolean available, boolean canBeOpened,
long autoDeleteTimer) {
SessionId sessionId = new SessionId(m.getShareableId().getBytes()); SessionId sessionId = new SessionId(m.getShareableId().getBytes());
return new ForumInvitationRequest(m.getId(), m.getContactGroupId(), return new ForumInvitationRequest(m.getId(), m.getContactGroupId(),
m.getTimestamp(), local, read, sent, seen, sessionId, m.getTimestamp(), local, read, sent, seen, sessionId,
m.getShareable(), m.getText(), available, canBeOpened); m.getShareable(), m.getText(), available, canBeOpened,
autoDeleteTimer);
} }
@Override @Override
public ForumInvitationResponse createInvitationResponse(MessageId id, public ForumInvitationResponse createInvitationResponse(MessageId id,
GroupId contactGroupId, long time, boolean local, boolean sent, GroupId contactGroupId, long time, boolean local, boolean sent,
boolean seen, boolean read, boolean accept, GroupId shareableId) { boolean seen, boolean read, boolean accept, GroupId shareableId,
long autoDeleteTimer) {
SessionId sessionId = new SessionId(shareableId.getBytes()); SessionId sessionId = new SessionId(shareableId.getBytes());
return new ForumInvitationResponse(id, contactGroupId, time, local, return new ForumInvitationResponse(id, contactGroupId, time, local,
read, sent, seen, sessionId, accept, shareableId); read, sent, seen, sessionId, accept, shareableId,
autoDeleteTimer);
} }
} }

View File

@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager;
@@ -17,21 +16,20 @@ import org.briarproject.briar.api.conversation.ConversationRequest;
import org.briarproject.briar.api.forum.Forum; import org.briarproject.briar.api.forum.Forum;
import org.briarproject.briar.api.forum.ForumInvitationResponse; import org.briarproject.briar.api.forum.ForumInvitationResponse;
import org.briarproject.briar.api.forum.ForumManager; import org.briarproject.briar.api.forum.ForumManager;
import org.briarproject.briar.api.forum.ForumSharingManager;
import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent; import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent;
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent; import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.briar.api.forum.ForumManager.CLIENT_ID;
import static org.briarproject.briar.api.forum.ForumManager.MAJOR_VERSION;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> { class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
private final ForumManager forumManager; private final ForumManager forumManager;
private final InvitationFactory<Forum, ForumInvitationResponse> invitationFactory; private final InvitationFactory<Forum, ForumInvitationResponse>
invitationFactory;
@Inject @Inject
ForumProtocolEngineImpl(DatabaseComponent db, ForumProtocolEngineImpl(DatabaseComponent db,
@@ -42,8 +40,10 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumManager forumManager, ForumManager forumManager,
InvitationFactory<Forum, ForumInvitationResponse> invitationFactory) { InvitationFactory<Forum, ForumInvitationResponse> invitationFactory) {
super(db, clientHelper, clientVersioningManager, messageEncoder, super(db, clientHelper, clientVersioningManager, messageEncoder,
messageParser, messageTracker, clock, CLIENT_ID, messageParser, messageTracker, clock,
MAJOR_VERSION); ForumSharingManager.CLIENT_ID,
ForumSharingManager.MAJOR_VERSION,
ForumManager.CLIENT_ID, ForumManager.MAJOR_VERSION);
this.forumManager = forumManager; this.forumManager = forumManager;
this.invitationFactory = invitationFactory; this.invitationFactory = invitationFactory;
} }
@@ -53,7 +53,8 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ContactId contactId, boolean available, boolean canBeOpened) { ContactId contactId, boolean available, boolean canBeOpened) {
ConversationRequest<Forum> request = invitationFactory ConversationRequest<Forum> request = invitationFactory
.createInvitationRequest(false, false, true, false, m, .createInvitationRequest(false, false, true, false, m,
contactId, available, canBeOpened); contactId, available, canBeOpened,
m.getAutoDeleteTimer());
return new ForumInvitationRequestReceivedEvent(request, contactId); return new ForumInvitationRequestReceivedEvent(request, contactId);
} }
@@ -63,7 +64,7 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumInvitationResponse response = invitationFactory ForumInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, true, false, m.getTimestamp(), false, false, true, false,
true, m.getShareableId()); true, m.getShareableId(), m.getAutoDeleteTimer());
return new ForumInvitationResponseReceivedEvent(response, contactId); return new ForumInvitationResponseReceivedEvent(response, contactId);
} }
@@ -73,15 +74,10 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumInvitationResponse response = invitationFactory ForumInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(), .createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, true, false, m.getTimestamp(), false, false, true, false,
false, m.getShareableId()); false, m.getShareableId(), m.getAutoDeleteTimer());
return new ForumInvitationResponseReceivedEvent(response, contactId); return new ForumInvitationResponseReceivedEvent(response, contactId);
} }
@Override
protected ClientId getShareableClientId() {
return CLIENT_ID;
}
@Override @Override
protected void addShareable(Transaction txn, MessageId inviteId) protected void addShareable(Transaction txn, MessageId inviteId)
throws DbException, FormatException { throws DbException, FormatException {

View File

@@ -11,10 +11,10 @@ public interface InvitationFactory<S extends Shareable, R extends InvitationResp
ConversationRequest<S> createInvitationRequest(boolean local, boolean sent, ConversationRequest<S> createInvitationRequest(boolean local, boolean sent,
boolean seen, boolean read, InviteMessage<S> m, ContactId c, boolean seen, boolean read, InviteMessage<S> m, ContactId c,
boolean available, boolean canBeOpened); boolean available, boolean canBeOpened, long autoDeleteTimer);
R createInvitationResponse(MessageId id, GroupId contactGroupId, long time, R createInvitationResponse(MessageId id, GroupId contactGroupId, long time,
boolean local, boolean sent, boolean seen, boolean read, boolean local, boolean sent, boolean seen, boolean read,
boolean accept, GroupId shareableId); boolean accept, GroupId shareableId, long autoDeleteTimer);
} }

View File

@@ -10,7 +10,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable @Immutable
@NotNullByDefault @NotNullByDefault
class InviteMessage<S extends Shareable> extends SharingMessage { class InviteMessage<S extends Shareable> extends DeletableSharingMessage {
private final S shareable; private final S shareable;
@Nullable @Nullable
@@ -18,9 +18,9 @@ class InviteMessage<S extends Shareable> extends SharingMessage {
InviteMessage(MessageId id, @Nullable MessageId previousMessageId, InviteMessage(MessageId id, @Nullable MessageId previousMessageId,
GroupId contactGroupId, S shareable, @Nullable String text, GroupId contactGroupId, S shareable, @Nullable String text,
long timestamp) { long timestamp, long autoDeleteTimer) {
super(id, contactGroupId, shareable.getId(), timestamp, super(id, contactGroupId, shareable.getId(), timestamp,
previousMessageId); previousMessageId, autoDeleteTimer);
if (text != null && text.isEmpty()) if (text != null && text.isEmpty())
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.shareable = shareable; this.shareable = shareable;

View File

@@ -14,7 +14,7 @@ interface MessageEncoder {
BdfDictionary encodeMetadata(MessageType type, GroupId shareableId, BdfDictionary encodeMetadata(MessageType type, GroupId shareableId,
long timestamp, boolean local, boolean read, boolean visible, long timestamp, boolean local, boolean read, boolean visible,
boolean available, boolean accepted); boolean available, boolean accepted, long autoDeleteTimer);
void setVisibleInUi(BdfDictionary meta, boolean visible); void setVisibleInUi(BdfDictionary meta, boolean visible);
@@ -22,16 +22,49 @@ interface MessageEncoder {
void setInvitationAccepted(BdfDictionary meta, boolean accepted); void setInvitationAccepted(BdfDictionary meta, boolean accepted);
/**
* Encodes an invite message without an auto-delete timer.
*/
Message encodeInviteMessage(GroupId contactGroupId, long timestamp, Message encodeInviteMessage(GroupId contactGroupId, long timestamp,
@Nullable MessageId previousMessageId, BdfList descriptor, @Nullable MessageId previousMessageId, BdfList descriptor,
@Nullable String text); @Nullable String text);
/**
* Encodes an invite message with an optional auto-delete timer. This
* requires the contact to support client version 0.1 or higher.
*/
Message encodeInviteMessage(GroupId contactGroupId, long timestamp,
@Nullable MessageId previousMessageId, BdfList descriptor,
@Nullable String text, long autoDeleteTimer);
/**
* Encodes an accept message without an auto-delete timer.
*/
Message encodeAcceptMessage(GroupId contactGroupId, GroupId shareableId, Message encodeAcceptMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);
/**
* Encodes an accept message with an optional auto-delete timer. This
* requires the contact to support client version 0.1 or higher.
*/
Message encodeAcceptMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId,
long autoDeleteTimer);
/**
* Encodes a decline message without an auto-delete timer.
*/
Message encodeDeclineMessage(GroupId contactGroupId, GroupId shareableId, Message encodeDeclineMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);
/**
* Encodes a decline message with an optional auto-delete timer. This
* requires the contact to support client version 0.1 or higher.
*/
Message encodeDeclineMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId,
long autoDeleteTimer);
Message encodeLeaveMessage(GroupId contactGroupId, GroupId shareableId, Message encodeLeaveMessage(GroupId contactGroupId, GroupId shareableId,
long timestamp, @Nullable MessageId previousMessageId); long timestamp, @Nullable MessageId previousMessageId);

View File

@@ -14,11 +14,13 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.sharing.MessageType.ABORT; import static org.briarproject.briar.sharing.MessageType.ABORT;
import static org.briarproject.briar.sharing.MessageType.ACCEPT; import static org.briarproject.briar.sharing.MessageType.ACCEPT;
import static org.briarproject.briar.sharing.MessageType.DECLINE; import static org.briarproject.briar.sharing.MessageType.DECLINE;
import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.briarproject.briar.sharing.MessageType.LEAVE; import static org.briarproject.briar.sharing.MessageType.LEAVE;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AUTO_DELETE_TIMER;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL;
@@ -45,7 +47,8 @@ class MessageEncoderImpl implements MessageEncoder {
@Override @Override
public BdfDictionary encodeMetadata(MessageType type, public BdfDictionary encodeMetadata(MessageType type,
GroupId shareableId, long timestamp, boolean local, boolean read, GroupId shareableId, long timestamp, boolean local, boolean read,
boolean visible, boolean available, boolean accepted) { boolean visible, boolean available, boolean accepted,
long autoDeleteTimer) {
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue()); meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue());
meta.put(MSG_KEY_SHAREABLE_ID, shareableId); meta.put(MSG_KEY_SHAREABLE_ID, shareableId);
@@ -55,6 +58,9 @@ class MessageEncoderImpl implements MessageEncoder {
meta.put(MSG_KEY_VISIBLE_IN_UI, visible); meta.put(MSG_KEY_VISIBLE_IN_UI, visible);
meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, available); meta.put(MSG_KEY_AVAILABLE_TO_ANSWER, available);
meta.put(MSG_KEY_INVITATION_ACCEPTED, accepted); meta.put(MSG_KEY_INVITATION_ACCEPTED, accepted);
if (autoDeleteTimer != NO_AUTO_DELETE_TIMER) {
meta.put(MSG_KEY_AUTO_DELETE_TIMER, autoDeleteTimer);
}
return meta; return meta;
} }
@@ -93,6 +99,27 @@ class MessageEncoderImpl implements MessageEncoder {
} }
} }
@Override
public Message encodeInviteMessage(GroupId contactGroupId, long timestamp,
@Nullable MessageId previousMessageId, BdfList descriptor,
@Nullable String text, long autoDeleteTimer) {
if (text != null && text.isEmpty())
throw new IllegalArgumentException();
BdfList body = BdfList.of(
INVITE.getValue(),
previousMessageId,
descriptor,
text,
encodeTimer(autoDeleteTimer)
);
try {
return messageFactory.createMessage(contactGroupId, timestamp,
clientHelper.toByteArray(body));
} catch (FormatException e) {
throw new AssertionError(e);
}
}
@Override @Override
public Message encodeAcceptMessage(GroupId contactGroupId, public Message encodeAcceptMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp, GroupId shareableId, long timestamp,
@@ -101,6 +128,14 @@ class MessageEncoderImpl implements MessageEncoder {
previousMessageId); previousMessageId);
} }
@Override
public Message encodeAcceptMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId, long autoDeleteTimer) {
return encodeMessage(ACCEPT, contactGroupId, shareableId, timestamp,
previousMessageId, autoDeleteTimer);
}
@Override @Override
public Message encodeDeclineMessage(GroupId contactGroupId, public Message encodeDeclineMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp, GroupId shareableId, long timestamp,
@@ -109,6 +144,14 @@ class MessageEncoderImpl implements MessageEncoder {
previousMessageId); previousMessageId);
} }
@Override
public Message encodeDeclineMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId, long autoDeleteTimer) {
return encodeMessage(DECLINE, contactGroupId, shareableId, timestamp,
previousMessageId, autoDeleteTimer);
}
@Override @Override
public Message encodeLeaveMessage(GroupId contactGroupId, public Message encodeLeaveMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp, GroupId shareableId, long timestamp,
@@ -141,4 +184,25 @@ class MessageEncoderImpl implements MessageEncoder {
} }
} }
private Message encodeMessage(MessageType type, GroupId contactGroupId,
GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId, long autoDeleteTimer) {
BdfList body = BdfList.of(
type.getValue(),
shareableId,
previousMessageId,
encodeTimer(autoDeleteTimer)
);
try {
return messageFactory.createMessage(contactGroupId, timestamp,
clientHelper.toByteArray(body));
} catch (FormatException e) {
throw new AssertionError(e);
}
}
@Nullable
private Long encodeTimer(long autoDeleteTimer) {
return autoDeleteTimer == NO_AUTO_DELETE_TIMER ? null : autoDeleteTimer;
}
} }

View File

@@ -11,12 +11,12 @@ class MessageMetadata {
private final MessageType type; private final MessageType type;
private final GroupId shareableId; private final GroupId shareableId;
private final long timestamp; private final long timestamp, autoDeleteTimer;
private final boolean local, read, visible, available, accepted; private final boolean local, read, visible, available, accepted;
MessageMetadata(MessageType type, GroupId shareableId, long timestamp, MessageMetadata(MessageType type, GroupId shareableId, long timestamp,
boolean local, boolean read, boolean visible, boolean available, boolean local, boolean read, boolean visible, boolean available,
boolean accepted) { boolean accepted, long autoDeleteTimer) {
this.shareableId = shareableId; this.shareableId = shareableId;
this.type = type; this.type = type;
this.timestamp = timestamp; this.timestamp = timestamp;
@@ -25,6 +25,7 @@ class MessageMetadata {
this.visible = visible; this.visible = visible;
this.available = available; this.available = available;
this.accepted = accepted; this.accepted = accepted;
this.autoDeleteTimer = autoDeleteTimer;
} }
MessageType getMessageType() { MessageType getMessageType() {
@@ -64,4 +65,7 @@ class MessageMetadata {
return accepted; return accepted;
} }
public long getAutoDeleteTimer() {
return autoDeleteTimer;
}
} }

View File

@@ -15,7 +15,9 @@ import org.briarproject.briar.api.sharing.Shareable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AUTO_DELETE_TIMER;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_INVITATION_ACCEPTED;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL; import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL;
@@ -70,8 +72,10 @@ abstract class MessageParserImpl<S extends Shareable>
boolean visible = meta.getBoolean(MSG_KEY_VISIBLE_IN_UI, false); boolean visible = meta.getBoolean(MSG_KEY_VISIBLE_IN_UI, false);
boolean available = meta.getBoolean(MSG_KEY_AVAILABLE_TO_ANSWER, false); boolean available = meta.getBoolean(MSG_KEY_AVAILABLE_TO_ANSWER, false);
boolean accepted = meta.getBoolean(MSG_KEY_INVITATION_ACCEPTED, false); boolean accepted = meta.getBoolean(MSG_KEY_INVITATION_ACCEPTED, false);
long timer = meta.getLong(MSG_KEY_AUTO_DELETE_TIMER,
NO_AUTO_DELETE_TIMER);
return new MessageMetadata(type, shareableId, timestamp, local, read, return new MessageMetadata(type, shareableId, timestamp, local, read,
visible, available, accepted); visible, available, accepted, timer);
} }
@Override @Override
@@ -90,8 +94,10 @@ abstract class MessageParserImpl<S extends Shareable>
BdfList descriptor = body.getList(2); BdfList descriptor = body.getList(2);
S shareable = createShareable(descriptor); S shareable = createShareable(descriptor);
String text = body.getOptionalString(3); String text = body.getOptionalString(3);
long timer = NO_AUTO_DELETE_TIMER;
if (body.size() == 5) timer = body.getLong(4, NO_AUTO_DELETE_TIMER);
return new InviteMessage<>(m.getId(), previousMessageId, return new InviteMessage<>(m.getId(), previousMessageId,
m.getGroupId(), shareable, text, m.getTimestamp()); m.getGroupId(), shareable, text, m.getTimestamp(), timer);
} }
@Override @Override
@@ -100,8 +106,10 @@ abstract class MessageParserImpl<S extends Shareable>
GroupId shareableId = new GroupId(body.getRaw(1)); GroupId shareableId = new GroupId(body.getRaw(1));
byte[] b = body.getOptionalRaw(2); byte[] b = body.getOptionalRaw(2);
MessageId previousMessageId = (b == null ? null : new MessageId(b)); MessageId previousMessageId = (b == null ? null : new MessageId(b));
long timer = NO_AUTO_DELETE_TIMER;
if (body.size() == 4) timer = body.getLong(3, NO_AUTO_DELETE_TIMER);
return new AcceptMessage(m.getId(), previousMessageId, m.getGroupId(), return new AcceptMessage(m.getId(), previousMessageId, m.getGroupId(),
shareableId, m.getTimestamp()); shareableId, m.getTimestamp(), timer);
} }
@Override @Override
@@ -110,8 +118,10 @@ abstract class MessageParserImpl<S extends Shareable>
GroupId shareableId = new GroupId(body.getRaw(1)); GroupId shareableId = new GroupId(body.getRaw(1));
byte[] b = body.getOptionalRaw(2); byte[] b = body.getOptionalRaw(2);
MessageId previousMessageId = (b == null ? null : new MessageId(b)); MessageId previousMessageId = (b == null ? null : new MessageId(b));
long timer = NO_AUTO_DELETE_TIMER;
if (body.size() == 4) timer = body.getLong(3, NO_AUTO_DELETE_TIMER);
return new DeclineMessage(m.getId(), m.getGroupId(), shareableId, return new DeclineMessage(m.getId(), m.getGroupId(), shareableId,
m.getTimestamp(), previousMessageId); m.getTimestamp(), previousMessageId, timer);
} }
@Override @Override

View File

@@ -28,6 +28,7 @@ import java.util.Map;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@@ -57,14 +58,15 @@ abstract class ProtocolEngineImpl<S extends Shareable>
private final MessageEncoder messageEncoder; private final MessageEncoder messageEncoder;
private final MessageTracker messageTracker; private final MessageTracker messageTracker;
private final Clock clock; private final Clock clock;
private final ClientId shareableClientId; private final ClientId sharingClientId, shareableClientId;
private final int shareableClientVersion; private final int sharingClientMajorVersion, shareableClientMajorVersion;
ProtocolEngineImpl(DatabaseComponent db, ClientHelper clientHelper, ProtocolEngineImpl(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MessageEncoder messageEncoder, MessageParser<S> messageParser, MessageEncoder messageEncoder, MessageParser<S> messageParser,
MessageTracker messageTracker, Clock clock, MessageTracker messageTracker, Clock clock,
ClientId shareableClientId, int shareableClientVersion) { ClientId sharingClientId, int sharingClientMajorVersion,
ClientId shareableClientId, int shareableClientMajorVersion) {
this.db = db; this.db = db;
this.clientHelper = clientHelper; this.clientHelper = clientHelper;
this.clientVersioningManager = clientVersioningManager; this.clientVersioningManager = clientVersioningManager;
@@ -72,8 +74,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
this.messageParser = messageParser; this.messageParser = messageParser;
this.messageTracker = messageTracker; this.messageTracker = messageTracker;
this.clock = clock; this.clock = clock;
this.sharingClientId = sharingClientId;
this.sharingClientMajorVersion = sharingClientMajorVersion;
this.shareableClientId = shareableClientId; this.shareableClientId = shareableClientId;
this.shareableClientVersion = shareableClientVersion; this.shareableClientMajorVersion = shareableClientMajorVersion;
} }
@Override @Override
@@ -121,9 +125,21 @@ abstract class ProtocolEngineImpl<S extends Shareable>
throw new DbException(e); // Invalid group descriptor throw new DbException(e); // Invalid group descriptor
} }
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s)); long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
Message m = messageEncoder.encodeInviteMessage(s.getContactGroupId(), Message m;
localTimestamp, s.getLastLocalMessageId(), descriptor, text); if (contactSupportsAutoDeletion(txn, s.getContactGroupId())) {
sendMessage(txn, m, INVITE, s.getShareableId(), true); // TODO: Look up the current auto-delete timer
long timer = NO_AUTO_DELETE_TIMER;
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
localTimestamp, s.getLastLocalMessageId(), descriptor,
text, timer);
sendMessage(txn, m, INVITE, s.getShareableId(), true, timer);
} else {
m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
localTimestamp, s.getLastLocalMessageId(), descriptor,
text);
sendMessage(txn, m, INVITE, s.getShareableId(), true,
NO_AUTO_DELETE_TIMER);
}
return m; return m;
} }
@@ -173,12 +189,23 @@ abstract class ProtocolEngineImpl<S extends Shareable>
protected abstract void addShareable(Transaction txn, MessageId inviteId) protected abstract void addShareable(Transaction txn, MessageId inviteId)
throws DbException, FormatException; throws DbException, FormatException;
private Message sendAcceptMessage(Transaction txn, Session session) private Message sendAcceptMessage(Transaction txn, Session s)
throws DbException { throws DbException {
Message m = messageEncoder.encodeAcceptMessage( Message m;
session.getContactGroupId(), session.getShareableId(), if (contactSupportsAutoDeletion(txn, s.getContactGroupId())) {
getLocalTimestamp(session), session.getLastLocalMessageId()); // TODO: Look up the current auto-delete timer
sendMessage(txn, m, ACCEPT, session.getShareableId(), true); long timer = NO_AUTO_DELETE_TIMER;
m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, ACCEPT, s.getShareableId(), true, timer);
} else {
m = messageEncoder.encodeAcceptMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getLastLocalMessageId());
sendMessage(txn, m, ACCEPT, s.getShareableId(), true,
NO_AUTO_DELETE_TIMER);
}
return m; return m;
} }
@@ -215,12 +242,23 @@ abstract class ProtocolEngineImpl<S extends Shareable>
s.getInviteTimestamp()); s.getInviteTimestamp());
} }
private Message sendDeclineMessage(Transaction txn, Session session) private Message sendDeclineMessage(Transaction txn, Session s)
throws DbException { throws DbException {
Message m = messageEncoder.encodeDeclineMessage( Message m;
session.getContactGroupId(), session.getShareableId(), if (contactSupportsAutoDeletion(txn, s.getContactGroupId())) {
getLocalTimestamp(session), session.getLastLocalMessageId()); // TODO: Look up the current auto-delete timer
sendMessage(txn, m, DECLINE, session.getShareableId(), true); long timer = NO_AUTO_DELETE_TIMER;
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getLastLocalMessageId(), timer);
sendMessage(txn, m, DECLINE, s.getShareableId(), true, timer);
} else {
m = messageEncoder.encodeDeclineMessage(s.getContactGroupId(),
s.getShareableId(), getLocalTimestamp(s),
s.getLastLocalMessageId());
sendMessage(txn, m, DECLINE, s.getShareableId(), true,
NO_AUTO_DELETE_TIMER);
}
return m; return m;
} }
@@ -263,7 +301,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
Message m = messageEncoder.encodeLeaveMessage( Message m = messageEncoder.encodeLeaveMessage(
session.getContactGroupId(), session.getShareableId(), session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId()); getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, LEAVE, session.getShareableId(), false); sendMessage(txn, m, LEAVE, session.getShareableId(), false,
NO_AUTO_DELETE_TIMER);
return m; return m;
} }
@@ -547,26 +586,25 @@ abstract class ProtocolEngineImpl<S extends Shareable>
throws DbException { throws DbException {
if (!db.containsGroup(txn, g)) return false; if (!db.containsGroup(txn, g)) return false;
Group group = db.getGroup(txn, g); Group group = db.getGroup(txn, g);
return group.getClientId().equals(getShareableClientId()); return group.getClientId().equals(shareableClientId);
} }
protected abstract ClientId getShareableClientId();
private Message sendAbortMessage(Transaction txn, Session session) private Message sendAbortMessage(Transaction txn, Session session)
throws DbException { throws DbException {
Message m = messageEncoder.encodeAbortMessage( Message m = messageEncoder.encodeAbortMessage(
session.getContactGroupId(), session.getShareableId(), session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId()); getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, ABORT, session.getShareableId(), false); sendMessage(txn, m, ABORT, session.getShareableId(), false,
NO_AUTO_DELETE_TIMER);
return m; return m;
} }
private void sendMessage(Transaction txn, Message m, MessageType type, private void sendMessage(Transaction txn, Message m, MessageType type,
GroupId shareableId, boolean visibleInConversation) GroupId shareableId, boolean visibleInConversation,
throws DbException { long autoDeleteTimer) throws DbException {
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(type, shareableId,
.encodeMetadata(type, shareableId, m.getTimestamp(), true, true, m.getTimestamp(), true, true, visibleInConversation, false,
visibleInConversation, false, false); false, autoDeleteTimer);
try { try {
clientHelper.addLocalMessage(txn, m, meta, true, false); clientHelper.addLocalMessage(txn, m, meta, true, false);
} catch (FormatException e) { } catch (FormatException e) {
@@ -612,7 +650,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
// Apply min of preferred visibility and client's visibility // Apply min of preferred visibility and client's visibility
ContactId contactId = getContactId(txn, session.getContactGroupId()); ContactId contactId = getContactId(txn, session.getContactGroupId());
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
contactId, shareableClientId, shareableClientVersion); contactId, shareableClientId, shareableClientMajorVersion);
Visibility min = Visibility.min(preferred, client); Visibility min = Visibility.min(preferred, client);
db.setGroupVisibility(txn, contactId, session.getShareableId(), min); db.setGroupVisibility(txn, contactId, session.getShareableId(), min);
} }
@@ -637,4 +675,20 @@ abstract class ProtocolEngineImpl<S extends Shareable>
session.getInviteTimestamp()) + 1); session.getInviteTimestamp()) + 1);
} }
boolean contactSupportsAutoDeletion(Transaction txn, GroupId contactGroupId)
throws DbException {
try {
BdfDictionary meta = clientHelper
.getGroupMetadataAsDictionary(txn, contactGroupId);
int contactId = meta.getLong(GROUP_KEY_CONTACT_ID).intValue();
ContactId c = new ContactId(contactId);
int minorVersion = clientVersioningManager
.getClientMinorVersion(txn, c, sharingClientId,
sharingClientMajorVersion);
// Auto-delete was added in client version 0.1
return minorVersion >= 1;
} catch (FormatException e) {
throw new DbException(e);
}
}
} }

View File

@@ -16,6 +16,7 @@ interface SharingConstants {
String MSG_KEY_VISIBLE_IN_UI = "visibleInUi"; String MSG_KEY_VISIBLE_IN_UI = "visibleInUi";
String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer"; String MSG_KEY_AVAILABLE_TO_ANSWER = "availableToAnswer";
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted"; String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer";
// Session keys // Session keys
String SESSION_KEY_IS_SESSION = "isSession"; String SESSION_KEY_IS_SESSION = "isSession";

View File

@@ -368,7 +368,8 @@ abstract class SharingManagerImpl<S extends Shareable>
return invitationFactory return invitationFactory
.createInvitationRequest(meta.isLocal(), status.isSent(), .createInvitationRequest(meta.isLocal(), status.isSent(),
status.isSeen(), meta.isRead(), invite, c, status.isSeen(), meta.isRead(), invite, c,
meta.isAvailableToAnswer(), canBeOpened); meta.isAvailableToAnswer(), canBeOpened,
meta.getAutoDeleteTimer());
} }
private InvitationResponse parseInvitationResponse(GroupId contactGroupId, private InvitationResponse parseInvitationResponse(GroupId contactGroupId,
@@ -376,7 +377,8 @@ abstract class SharingManagerImpl<S extends Shareable>
boolean accept) { boolean accept) {
return invitationFactory.createInvitationResponse(m, contactGroupId, return invitationFactory.createInvitationResponse(m, contactGroupId,
meta.getTimestamp(), meta.isLocal(), status.isSent(), meta.getTimestamp(), meta.isLocal(), status.isSent(),
status.isSeen(), meta.isRead(), accept, meta.getShareableId()); status.isSeen(), meta.isRead(), accept, meta.getShareableId(),
meta.getAutoDeleteTimer());
} }
@Override @Override

View File

@@ -15,11 +15,15 @@ import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import java.util.Collections; import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.Immutable;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.bramble.util.ValidationUtils.checkLength; import static org.briarproject.bramble.util.ValidationUtils.checkLength;
import static org.briarproject.bramble.util.ValidationUtils.checkRange;
import static org.briarproject.bramble.util.ValidationUtils.checkSize; import static org.briarproject.bramble.util.ValidationUtils.checkSize;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH; import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH;
import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.INVITE;
@@ -45,9 +49,10 @@ abstract class SharingValidator extends BdfMessageValidator {
return validateInviteMessage(m, body); return validateInviteMessage(m, body);
case ACCEPT: case ACCEPT:
case DECLINE: case DECLINE:
return validateNonInviteMessageWithOptionalTimer(type, m, body);
case LEAVE: case LEAVE:
case ABORT: case ABORT:
return validateNonInviteMessage(type, m, body); return validateNonInviteMessageWithoutTimer(type, m, body);
default: default:
throw new FormatException(); throw new FormatException();
} }
@@ -55,47 +60,80 @@ abstract class SharingValidator extends BdfMessageValidator {
private BdfMessageContext validateInviteMessage(Message m, BdfList body) private BdfMessageContext validateInviteMessage(Message m, BdfList body)
throws FormatException { throws FormatException {
checkSize(body, 4); // Client version 0.0: Message type, optional previous message ID,
// descriptor, optional text.
// Client version 0.1: Message type, optional previous message ID,
// descriptor, optional text, optional auto-delete timer.
checkSize(body, 4, 5);
byte[] previousMessageId = body.getOptionalRaw(1); byte[] previousMessageId = body.getOptionalRaw(1);
checkLength(previousMessageId, UniqueId.LENGTH); checkLength(previousMessageId, UniqueId.LENGTH);
BdfList descriptor = body.getList(2); BdfList descriptor = body.getList(2);
GroupId shareableId = validateDescriptor(descriptor); GroupId shareableId = validateDescriptor(descriptor);
String text = body.getOptionalString(3); String text = body.getOptionalString(3);
checkLength(text, 1, MAX_INVITATION_TEXT_LENGTH); checkLength(text, 1, MAX_INVITATION_TEXT_LENGTH);
long timer = NO_AUTO_DELETE_TIMER;
if (body.size() == 5) timer = validateTimer(body.getOptionalLong(4));
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(INVITE, shareableId,
.encodeMetadata(INVITE, shareableId, m.getTimestamp(), false, m.getTimestamp(), false, false, false, false, false, timer);
false, false, false, false);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
} }
protected abstract GroupId validateDescriptor(BdfList descriptor) protected abstract GroupId validateDescriptor(BdfList descriptor)
throws FormatException; throws FormatException;
private BdfMessageContext validateNonInviteMessage(MessageType type, private BdfMessageContext validateNonInviteMessageWithoutTimer(
Message m, BdfList body) throws FormatException { MessageType type, Message m, BdfList body) throws FormatException {
checkSize(body, 3); checkSize(body, 3);
byte[] shareableId = body.getRaw(1); byte[] shareableId = body.getRaw(1);
checkLength(shareableId, UniqueId.LENGTH); checkLength(shareableId, UniqueId.LENGTH);
byte[] previousMessageId = body.getOptionalRaw(2); byte[] previousMessageId = body.getOptionalRaw(2);
checkLength(previousMessageId, UniqueId.LENGTH); checkLength(previousMessageId, UniqueId.LENGTH);
BdfDictionary meta = messageEncoder BdfDictionary meta = messageEncoder.encodeMetadata(type,
.encodeMetadata(type, new GroupId(shareableId), new GroupId(shareableId), m.getTimestamp(), false, false,
m.getTimestamp(), false, false, false, false, false); false, false, false, NO_AUTO_DELETE_TIMER);
if (previousMessageId == null) { if (previousMessageId == null) {
return new BdfMessageContext(meta); return new BdfMessageContext(meta);
} else { } else {
MessageId dependency = new MessageId(previousMessageId); MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, return new BdfMessageContext(meta, singletonList(dependency));
Collections.singletonList(dependency));
} }
} }
private BdfMessageContext validateNonInviteMessageWithOptionalTimer(
MessageType type, Message m, BdfList body) throws FormatException {
// Client version 0.0: Message type, shareable ID, optional previous
// message ID.
// Client version 0.1: Message type, shareable ID, optional previous
// message ID, optional auto-delete timer.
checkSize(body, 3, 4);
byte[] shareableId = body.getRaw(1);
checkLength(shareableId, UniqueId.LENGTH);
byte[] previousMessageId = body.getOptionalRaw(2);
checkLength(previousMessageId, UniqueId.LENGTH);
long timer = NO_AUTO_DELETE_TIMER;
if (body.size() == 4) timer = validateTimer(body.getOptionalLong(3));
BdfDictionary meta = messageEncoder.encodeMetadata(type,
new GroupId(shareableId), m.getTimestamp(), false, false,
false, false, false, timer);
if (previousMessageId == null) {
return new BdfMessageContext(meta);
} else {
MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta, singletonList(dependency));
}
}
private long validateTimer(@Nullable Long timer) throws FormatException {
if (timer == null) return NO_AUTO_DELETE_TIMER;
checkRange(timer, MIN_AUTO_DELETE_TIMER_MS, MAX_AUTO_DELETE_TIMER_MS);
return timer;
}
} }

View File

@@ -8,10 +8,16 @@ import org.briarproject.briar.api.blog.Blog;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH; import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH;
import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.junit.Assert.fail;
public class BlogSharingValidatorTest extends SharingValidatorTest { public class BlogSharingValidatorTest extends SharingValidatorTest {
@@ -31,7 +37,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsInvitationWithText() throws Exception { public void testAcceptsInvitationWithText() throws Exception {
expectCreateBlog(); expectCreateBlog();
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text)); BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
@@ -40,7 +46,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsInvitationWithNullText() throws Exception { public void testAcceptsInvitationWithNullText() throws Exception {
expectCreateBlog(); expectCreateBlog();
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null)); BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
@@ -49,16 +55,64 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception { public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
expectCreateBlog(); expectCreateBlog();
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, text)); BdfList.of(INVITE.getValue(), null, descriptor, text));
assertExpectedContext(context, null); assertExpectedContext(context, null);
} }
@Test
public void testAcceptsInvitationWithMinAutoDeleteTimer() throws Exception {
testAcceptsInvitationWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsInvitationWithMaxAutoDeleteTimer() throws Exception {
testAcceptsInvitationWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsInvitationWithNullAutoDeleteTimer()
throws Exception {
testAcceptsInvitationWithAutoDeleteTimer(null);
}
private void testAcceptsInvitationWithAutoDeleteTimer(@Nullable Long timer)
throws Exception {
expectCreateBlog();
expectEncodeMetadata(INVITE,
timer == null ? NO_AUTO_DELETE_TIMER : timer);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text,
timer));
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsInvitationWithTooBigAutoDeleteTimer()
throws Exception {
testRejectsInvitationWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS + 1);
}
@Test(expected = FormatException.class)
public void testRejectsInvitationWithTooSmallAutoDeleteTimer()
throws Exception {
testRejectsInvitationWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS - 1);
}
private void testRejectsInvitationWithAutoDeleteTimer(Long timer)
throws Exception {
expectCreateBlog();
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text,
timer));
fail();
}
@Test @Test
public void testAcceptsInvitationForRssBlog() throws Exception { public void testAcceptsInvitationForRssBlog() throws Exception {
expectCreateRssBlog(); expectCreateRssBlog();
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfList rssDescriptor = BdfList.of(authorList, true); BdfList rssDescriptor = BdfList.of(authorList, true);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, rssDescriptor, BdfList.of(INVITE.getValue(), previousMsgId, rssDescriptor,
@@ -93,7 +147,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
public void testAcceptsMinLengthText() throws Exception { public void testAcceptsMinLengthText() throws Exception {
String shortText = getRandomString(1); String shortText = getRandomString(1);
expectCreateBlog(); expectCreateBlog();
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
shortText)); shortText));

View File

@@ -7,12 +7,18 @@ import org.briarproject.briar.api.forum.Forum;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.junit.Test; import org.junit.Test;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH; import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH; import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH; import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH;
import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.junit.Assert.fail;
public class ForumSharingValidatorTest extends SharingValidatorTest { public class ForumSharingValidatorTest extends SharingValidatorTest {
@@ -31,7 +37,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsInvitationWithText() throws Exception { public void testAcceptsInvitationWithText() throws Exception {
expectCreateForum(forumName); expectCreateForum(forumName);
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text)); BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
@@ -40,7 +46,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsInvitationWithNullText() throws Exception { public void testAcceptsInvitationWithNullText() throws Exception {
expectCreateForum(forumName); expectCreateForum(forumName);
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null)); BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
@@ -49,12 +55,60 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception { public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
expectCreateForum(forumName); expectCreateForum(forumName);
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, null)); BdfList.of(INVITE.getValue(), null, descriptor, null));
assertExpectedContext(context, null); assertExpectedContext(context, null);
} }
@Test
public void testAcceptsInvitationWithMinAutoDeleteTimer() throws Exception {
testAcceptsInvitationWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsInvitationWithMaxAutoDeleteTimer() throws Exception {
testAcceptsInvitationWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsInvitationWithNullAutoDeleteTimer()
throws Exception {
testAcceptsInvitationWithAutoDeleteTimer(null);
}
private void testAcceptsInvitationWithAutoDeleteTimer(@Nullable Long timer)
throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE,
timer == null ? NO_AUTO_DELETE_TIMER : timer);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text,
timer));
assertExpectedContext(context, previousMsgId);
}
@Test(expected = FormatException.class)
public void testRejectsInvitationWithTooBigAutoDeleteTimer()
throws Exception {
testRejectsInvitationWithAutoDeleteTimer(MAX_AUTO_DELETE_TIMER_MS + 1);
}
@Test(expected = FormatException.class)
public void testRejectsInvitationWithTooSmallAutoDeleteTimer()
throws Exception {
testRejectsInvitationWithAutoDeleteTimer(MIN_AUTO_DELETE_TIMER_MS - 1);
}
private void testRejectsInvitationWithAutoDeleteTimer(long timer)
throws FormatException {
expectCreateForum(forumName);
validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text,
timer));
fail();
}
@Test(expected = FormatException.class) @Test(expected = FormatException.class)
public void testRejectsNullForumName() throws Exception { public void testRejectsNullForumName() throws Exception {
BdfList invalidDescriptor = BdfList.of(null, salt); BdfList invalidDescriptor = BdfList.of(null, salt);
@@ -84,7 +138,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
String shortForumName = getRandomString(1); String shortForumName = getRandomString(1);
BdfList validDescriptor = BdfList.of(shortForumName, salt); BdfList validDescriptor = BdfList.of(shortForumName, salt);
expectCreateForum(shortForumName); expectCreateForum(shortForumName);
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor, BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
null)); null));
@@ -144,7 +198,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test @Test
public void testAcceptsMinLengthText() throws Exception { public void testAcceptsMinLengthText() throws Exception {
expectCreateForum(forumName); expectCreateForum(forumName);
expectEncodeMetadata(INVITE); expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1")); BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);

View File

@@ -16,6 +16,11 @@ import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MAX_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.MIN_AUTO_DELETE_TIMER_MS;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.briar.sharing.MessageType.ABORT; import static org.briarproject.briar.sharing.MessageType.ABORT;
@@ -24,7 +29,7 @@ import static org.briarproject.briar.sharing.MessageType.DECLINE;
import static org.briarproject.briar.sharing.MessageType.INVITE; import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.briarproject.briar.sharing.MessageType.LEAVE; import static org.briarproject.briar.sharing.MessageType.LEAVE;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail;
public abstract class SharingValidatorTest extends ValidatorTestCase { public abstract class SharingValidatorTest extends ValidatorTestCase {
@@ -54,23 +59,84 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Test @Test
public void testAcceptsAccept() throws Exception { public void testAcceptsAccept() throws Exception {
expectEncodeMetadata(ACCEPT); expectEncodeMetadata(ACCEPT, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(ACCEPT.getValue(), groupId, previousMsgId)); BdfList.of(ACCEPT.getValue(), groupId, previousMsgId));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
} }
@Test
public void testAcceptsAcceptWithMinAutoDeleteTimer() throws Exception {
testAcceptsResponseWithAutoDeleteTimer(ACCEPT,
MIN_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsAcceptWithMaxAutoDeleteTimer() throws Exception {
testAcceptsResponseWithAutoDeleteTimer(ACCEPT,
MAX_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsAcceptWithNullAutoDeleteTimer() throws Exception {
testAcceptsResponseWithAutoDeleteTimer(ACCEPT, null);
}
@Test(expected = FormatException.class)
public void testRejectsAcceptWithTooBigAutoDeleteTimer() throws Exception {
testRejectsResponseWithAutoDeleteTimer(ACCEPT,
MAX_AUTO_DELETE_TIMER_MS + 1);
}
@Test(expected = FormatException.class)
public void testRejectsAcceptWithTooSmallAutoDeleteTimer()
throws Exception {
testRejectsResponseWithAutoDeleteTimer(ACCEPT,
MIN_AUTO_DELETE_TIMER_MS - 1);
}
@Test @Test
public void testAcceptsDecline() throws Exception { public void testAcceptsDecline() throws Exception {
expectEncodeMetadata(DECLINE); expectEncodeMetadata(DECLINE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(DECLINE.getValue(), groupId, previousMsgId)); BdfList.of(DECLINE.getValue(), groupId, previousMsgId));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
} }
@Test
public void testAcceptsDeclineWithMinAutoDeleteTimer() throws Exception {
testAcceptsResponseWithAutoDeleteTimer(DECLINE,
MIN_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsDeclineWithMaxAutoDeleteTimer() throws Exception {
testAcceptsResponseWithAutoDeleteTimer(DECLINE,
MAX_AUTO_DELETE_TIMER_MS);
}
@Test
public void testAcceptsDeclineWithNullAutoDeleteTimer() throws Exception {
testAcceptsResponseWithAutoDeleteTimer(DECLINE, null);
}
@Test(expected = FormatException.class)
public void testRejectsDeclineWithTooBigAutoDeleteTimer()
throws Exception {
testRejectsResponseWithAutoDeleteTimer(DECLINE,
MAX_AUTO_DELETE_TIMER_MS + 1);
}
@Test(expected = FormatException.class)
public void testRejectsDeclineWithTooSmallAutoDeleteTimer()
throws Exception {
testRejectsResponseWithAutoDeleteTimer(DECLINE,
MIN_AUTO_DELETE_TIMER_MS - 1);
}
@Test @Test
public void testAcceptsLeave() throws Exception { public void testAcceptsLeave() throws Exception {
expectEncodeMetadata(LEAVE); expectEncodeMetadata(LEAVE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(LEAVE.getValue(), groupId, previousMsgId)); BdfList.of(LEAVE.getValue(), groupId, previousMsgId));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
@@ -78,7 +144,7 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Test @Test
public void testAcceptsAbort() throws Exception { public void testAcceptsAbort() throws Exception {
expectEncodeMetadata(ABORT); expectEncodeMetadata(ABORT, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group, BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), groupId, previousMsgId)); BdfList.of(ABORT.getValue(), groupId, previousMsgId));
assertExpectedContext(context, previousMsgId); assertExpectedContext(context, previousMsgId);
@@ -141,10 +207,10 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123)); BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
} }
void expectEncodeMetadata(MessageType type) { void expectEncodeMetadata(MessageType type, long autoDeleteTimer) {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp, oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp,
false, false, false, false, false); false, false, false, false, false, autoDeleteTimer);
will(returnValue(meta)); will(returnValue(meta));
}}); }});
} }
@@ -153,12 +219,26 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Nullable MessageId previousMsgId) { @Nullable MessageId previousMsgId) {
Collection<MessageId> dependencies = messageContext.getDependencies(); Collection<MessageId> dependencies = messageContext.getDependencies();
if (previousMsgId == null) { if (previousMsgId == null) {
assertTrue(dependencies.isEmpty()); assertEquals(emptyList(), dependencies);
} else { } else {
assertEquals(1, dependencies.size()); assertEquals(singletonList(previousMsgId), dependencies);
assertTrue(dependencies.contains(previousMsgId));
} }
assertEquals(meta, messageContext.getDictionary()); assertEquals(meta, messageContext.getDictionary());
} }
private void testAcceptsResponseWithAutoDeleteTimer(MessageType type,
@Nullable Long timer) throws Exception {
expectEncodeMetadata(type,
timer == null ? NO_AUTO_DELETE_TIMER : timer);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(type.getValue(), groupId, previousMsgId, timer));
assertExpectedContext(context, previousMsgId);
}
private void testRejectsResponseWithAutoDeleteTimer(MessageType type,
long timer) throws FormatException {
validator.validateMessage(message, group,
BdfList.of(type.getValue(), groupId, previousMsgId, timer));
fail();
}
} }