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 28ecece34d
commit b6b1bdbf82
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,
boolean local, boolean read, boolean sent, boolean seen,
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,
text, available, canBeOpened);
text, available, canBeOpened, autoDeleteTimer);
}
@Override

View File

@@ -12,9 +12,10 @@ public class BlogInvitationResponse extends InvitationResponse {
public BlogInvitationResponse(MessageId id, GroupId groupId, long time,
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,
accept, shareableId);
accept, shareableId, autoDeleteTimer);
}
@Override

View File

@@ -18,5 +18,5 @@ public interface BlogSharingManager extends SharingManager<Blog> {
/**
* 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,
boolean local, boolean read, boolean sent, boolean seen,
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,
text, available, canBeOpened);
text, available, canBeOpened, autoDeleteTimer);
}
@Override

View File

@@ -15,9 +15,10 @@ public class ForumInvitationResponse extends InvitationResponse {
public ForumInvitationResponse(MessageId id, GroupId groupId, long time,
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,
accept, shareableId);
accept, shareableId, autoDeleteTimer);
}
@Override

View File

@@ -18,5 +18,5 @@ public interface ForumSharingManager extends SharingManager<Forum> {
/**
* 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.concurrent.Immutable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
@Immutable
@NotNullByDefault
public class GroupInvitationRequest extends InvitationRequest<PrivateGroup> {
@@ -20,7 +22,7 @@ public class GroupInvitationRequest extends InvitationRequest<PrivateGroup> {
SessionId sessionId, PrivateGroup shareable,
@Nullable String text, boolean available, boolean canBeOpened) {
super(id, groupId, time, local, read, sent, seen, sessionId, shareable,
text, available, canBeOpened);
text, available, canBeOpened, NO_AUTO_DELETE_TIMER);
}
@Override

View File

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

View File

@@ -7,8 +7,6 @@ import org.briarproject.briar.api.conversation.ConversationRequest;
import javax.annotation.Nullable;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
public abstract class InvitationRequest<S extends Shareable> extends
ConversationRequest<S> {
@@ -17,9 +15,9 @@ public abstract class InvitationRequest<S extends Shareable> extends
public InvitationRequest(MessageId messageId, GroupId groupId, long time,
boolean local, boolean read, boolean sent, boolean seen,
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,
object, text, !available, NO_AUTO_DELETE_TIMER);
object, text, !available, autoDeleteTimer);
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.conversation.ConversationResponse;
import static org.briarproject.bramble.api.autodelete.AutoDeleteConstants.NO_AUTO_DELETE_TIMER;
public abstract class InvitationResponse extends ConversationResponse {
private final GroupId shareableId;
public InvitationResponse(MessageId id, GroupId groupId, long time,
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,
NO_AUTO_DELETE_TIMER);
autoDeleteTimer);
this.shareableId = shareableId;
}

View File

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

View File

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

View File

@@ -9,12 +9,13 @@ import javax.annotation.concurrent.Immutable;
@Immutable
@NotNullByDefault
class DeclineMessage extends SharingMessage {
class DeclineMessage extends DeletableSharingMessage {
DeclineMessage(MessageId id, GroupId contactGroupId,
GroupId shareableId, long timestamp,
@Nullable MessageId previousMessageId) {
super(id, contactGroupId, shareableId, timestamp, previousMessageId);
@Nullable MessageId previousMessageId, long autoDeleteTimer) {
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
public ForumInvitationRequest createInvitationRequest(boolean local,
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());
return new ForumInvitationRequest(m.getId(), m.getContactGroupId(),
m.getTimestamp(), local, read, sent, seen, sessionId,
m.getShareable(), m.getText(), available, canBeOpened);
m.getShareable(), m.getText(), available, canBeOpened,
autoDeleteTimer);
}
@Override
public ForumInvitationResponse createInvitationResponse(MessageId id,
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());
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.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.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.ForumInvitationResponse;
import org.briarproject.briar.api.forum.ForumManager;
import org.briarproject.briar.api.forum.ForumSharingManager;
import org.briarproject.briar.api.forum.event.ForumInvitationRequestReceivedEvent;
import org.briarproject.briar.api.forum.event.ForumInvitationResponseReceivedEvent;
import javax.annotation.concurrent.Immutable;
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
@NotNullByDefault
class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
private final ForumManager forumManager;
private final InvitationFactory<Forum, ForumInvitationResponse> invitationFactory;
private final InvitationFactory<Forum, ForumInvitationResponse>
invitationFactory;
@Inject
ForumProtocolEngineImpl(DatabaseComponent db,
@@ -42,8 +40,10 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumManager forumManager,
InvitationFactory<Forum, ForumInvitationResponse> invitationFactory) {
super(db, clientHelper, clientVersioningManager, messageEncoder,
messageParser, messageTracker, clock, CLIENT_ID,
MAJOR_VERSION);
messageParser, messageTracker, clock,
ForumSharingManager.CLIENT_ID,
ForumSharingManager.MAJOR_VERSION,
ForumManager.CLIENT_ID, ForumManager.MAJOR_VERSION);
this.forumManager = forumManager;
this.invitationFactory = invitationFactory;
}
@@ -53,7 +53,8 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ContactId contactId, boolean available, boolean canBeOpened) {
ConversationRequest<Forum> request = invitationFactory
.createInvitationRequest(false, false, true, false, m,
contactId, available, canBeOpened);
contactId, available, canBeOpened,
m.getAutoDeleteTimer());
return new ForumInvitationRequestReceivedEvent(request, contactId);
}
@@ -63,7 +64,7 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, true, false,
true, m.getShareableId());
true, m.getShareableId(), m.getAutoDeleteTimer());
return new ForumInvitationResponseReceivedEvent(response, contactId);
}
@@ -73,15 +74,10 @@ class ForumProtocolEngineImpl extends ProtocolEngineImpl<Forum> {
ForumInvitationResponse response = invitationFactory
.createInvitationResponse(m.getId(), m.getContactGroupId(),
m.getTimestamp(), false, false, true, false,
false, m.getShareableId());
false, m.getShareableId(), m.getAutoDeleteTimer());
return new ForumInvitationResponseReceivedEvent(response, contactId);
}
@Override
protected ClientId getShareableClientId() {
return CLIENT_ID;
}
@Override
protected void addShareable(Transaction txn, MessageId inviteId)
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,
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,
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
@NotNullByDefault
class InviteMessage<S extends Shareable> extends SharingMessage {
class InviteMessage<S extends Shareable> extends DeletableSharingMessage {
private final S shareable;
@Nullable
@@ -18,9 +18,9 @@ class InviteMessage<S extends Shareable> extends SharingMessage {
InviteMessage(MessageId id, @Nullable MessageId previousMessageId,
GroupId contactGroupId, S shareable, @Nullable String text,
long timestamp) {
long timestamp, long autoDeleteTimer) {
super(id, contactGroupId, shareable.getId(), timestamp,
previousMessageId);
previousMessageId, autoDeleteTimer);
if (text != null && text.isEmpty())
throw new IllegalArgumentException();
this.shareable = shareable;

View File

@@ -14,7 +14,7 @@ interface MessageEncoder {
BdfDictionary encodeMetadata(MessageType type, GroupId shareableId,
long timestamp, boolean local, boolean read, boolean visible,
boolean available, boolean accepted);
boolean available, boolean accepted, long autoDeleteTimer);
void setVisibleInUi(BdfDictionary meta, boolean visible);
@@ -22,16 +22,49 @@ interface MessageEncoder {
void setInvitationAccepted(BdfDictionary meta, boolean accepted);
/**
* Encodes an invite message without an auto-delete timer.
*/
Message encodeInviteMessage(GroupId contactGroupId, long timestamp,
@Nullable MessageId previousMessageId, BdfList descriptor,
@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,
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,
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,
long timestamp, @Nullable MessageId previousMessageId);

View File

@@ -14,11 +14,13 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
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.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.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_INVITATION_ACCEPTED;
import static org.briarproject.briar.sharing.SharingConstants.MSG_KEY_LOCAL;
@@ -45,7 +47,8 @@ class MessageEncoderImpl implements MessageEncoder {
@Override
public BdfDictionary encodeMetadata(MessageType type,
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();
meta.put(MSG_KEY_MESSAGE_TYPE, type.getValue());
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_AVAILABLE_TO_ANSWER, available);
meta.put(MSG_KEY_INVITATION_ACCEPTED, accepted);
if (autoDeleteTimer != NO_AUTO_DELETE_TIMER) {
meta.put(MSG_KEY_AUTO_DELETE_TIMER, autoDeleteTimer);
}
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
public Message encodeAcceptMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp,
@@ -101,6 +128,14 @@ class MessageEncoderImpl implements MessageEncoder {
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
public Message encodeDeclineMessage(GroupId contactGroupId,
GroupId shareableId, long timestamp,
@@ -109,6 +144,14 @@ class MessageEncoderImpl implements MessageEncoder {
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
public Message encodeLeaveMessage(GroupId contactGroupId,
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 GroupId shareableId;
private final long timestamp;
private final long timestamp, autoDeleteTimer;
private final boolean local, read, visible, available, accepted;
MessageMetadata(MessageType type, GroupId shareableId, long timestamp,
boolean local, boolean read, boolean visible, boolean available,
boolean accepted) {
boolean accepted, long autoDeleteTimer) {
this.shareableId = shareableId;
this.type = type;
this.timestamp = timestamp;
@@ -25,6 +25,7 @@ class MessageMetadata {
this.visible = visible;
this.available = available;
this.accepted = accepted;
this.autoDeleteTimer = autoDeleteTimer;
}
MessageType getMessageType() {
@@ -64,4 +65,7 @@ class MessageMetadata {
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 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.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_INVITATION_ACCEPTED;
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 available = meta.getBoolean(MSG_KEY_AVAILABLE_TO_ANSWER, 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,
visible, available, accepted);
visible, available, accepted, timer);
}
@Override
@@ -90,8 +94,10 @@ abstract class MessageParserImpl<S extends Shareable>
BdfList descriptor = body.getList(2);
S shareable = createShareable(descriptor);
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,
m.getGroupId(), shareable, text, m.getTimestamp());
m.getGroupId(), shareable, text, m.getTimestamp(), timer);
}
@Override
@@ -100,8 +106,10 @@ abstract class MessageParserImpl<S extends Shareable>
GroupId shareableId = new GroupId(body.getRaw(1));
byte[] b = body.getOptionalRaw(2);
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(),
shareableId, m.getTimestamp());
shareableId, m.getTimestamp(), timer);
}
@Override
@@ -110,8 +118,10 @@ abstract class MessageParserImpl<S extends Shareable>
GroupId shareableId = new GroupId(body.getRaw(1));
byte[] b = body.getOptionalRaw(2);
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,
m.getTimestamp(), previousMessageId);
m.getTimestamp(), previousMessageId, timer);
}
@Override

View File

@@ -28,6 +28,7 @@ import java.util.Map;
import javax.annotation.Nullable;
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.SHARED;
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 MessageTracker messageTracker;
private final Clock clock;
private final ClientId shareableClientId;
private final int shareableClientVersion;
private final ClientId sharingClientId, shareableClientId;
private final int sharingClientMajorVersion, shareableClientMajorVersion;
ProtocolEngineImpl(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
MessageEncoder messageEncoder, MessageParser<S> messageParser,
MessageTracker messageTracker, Clock clock,
ClientId shareableClientId, int shareableClientVersion) {
ClientId sharingClientId, int sharingClientMajorVersion,
ClientId shareableClientId, int shareableClientMajorVersion) {
this.db = db;
this.clientHelper = clientHelper;
this.clientVersioningManager = clientVersioningManager;
@@ -72,8 +74,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
this.messageParser = messageParser;
this.messageTracker = messageTracker;
this.clock = clock;
this.sharingClientId = sharingClientId;
this.sharingClientMajorVersion = sharingClientMajorVersion;
this.shareableClientId = shareableClientId;
this.shareableClientVersion = shareableClientVersion;
this.shareableClientMajorVersion = shareableClientMajorVersion;
}
@Override
@@ -121,9 +125,21 @@ abstract class ProtocolEngineImpl<S extends Shareable>
throw new DbException(e); // Invalid group descriptor
}
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
Message m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
localTimestamp, s.getLastLocalMessageId(), descriptor, text);
sendMessage(txn, m, INVITE, s.getShareableId(), true);
Message m;
if (contactSupportsAutoDeletion(txn, s.getContactGroupId())) {
// 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;
}
@@ -173,12 +189,23 @@ abstract class ProtocolEngineImpl<S extends Shareable>
protected abstract void addShareable(Transaction txn, MessageId inviteId)
throws DbException, FormatException;
private Message sendAcceptMessage(Transaction txn, Session session)
private Message sendAcceptMessage(Transaction txn, Session s)
throws DbException {
Message m = messageEncoder.encodeAcceptMessage(
session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, ACCEPT, session.getShareableId(), true);
Message m;
if (contactSupportsAutoDeletion(txn, s.getContactGroupId())) {
// TODO: Look up the current auto-delete timer
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;
}
@@ -215,12 +242,23 @@ abstract class ProtocolEngineImpl<S extends Shareable>
s.getInviteTimestamp());
}
private Message sendDeclineMessage(Transaction txn, Session session)
private Message sendDeclineMessage(Transaction txn, Session s)
throws DbException {
Message m = messageEncoder.encodeDeclineMessage(
session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, DECLINE, session.getShareableId(), true);
Message m;
if (contactSupportsAutoDeletion(txn, s.getContactGroupId())) {
// TODO: Look up the current auto-delete timer
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;
}
@@ -263,7 +301,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
Message m = messageEncoder.encodeLeaveMessage(
session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, LEAVE, session.getShareableId(), false);
sendMessage(txn, m, LEAVE, session.getShareableId(), false,
NO_AUTO_DELETE_TIMER);
return m;
}
@@ -547,26 +586,25 @@ abstract class ProtocolEngineImpl<S extends Shareable>
throws DbException {
if (!db.containsGroup(txn, g)) return false;
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)
throws DbException {
Message m = messageEncoder.encodeAbortMessage(
session.getContactGroupId(), session.getShareableId(),
getLocalTimestamp(session), session.getLastLocalMessageId());
sendMessage(txn, m, ABORT, session.getShareableId(), false);
sendMessage(txn, m, ABORT, session.getShareableId(), false,
NO_AUTO_DELETE_TIMER);
return m;
}
private void sendMessage(Transaction txn, Message m, MessageType type,
GroupId shareableId, boolean visibleInConversation)
throws DbException {
BdfDictionary meta = messageEncoder
.encodeMetadata(type, shareableId, m.getTimestamp(), true, true,
visibleInConversation, false, false);
GroupId shareableId, boolean visibleInConversation,
long autoDeleteTimer) throws DbException {
BdfDictionary meta = messageEncoder.encodeMetadata(type, shareableId,
m.getTimestamp(), true, true, visibleInConversation, false,
false, autoDeleteTimer);
try {
clientHelper.addLocalMessage(txn, m, meta, true, false);
} catch (FormatException e) {
@@ -612,7 +650,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
// Apply min of preferred visibility and client's visibility
ContactId contactId = getContactId(txn, session.getContactGroupId());
Visibility client = clientVersioningManager.getClientVisibility(txn,
contactId, shareableClientId, shareableClientVersion);
contactId, shareableClientId, shareableClientMajorVersion);
Visibility min = Visibility.min(preferred, client);
db.setGroupVisibility(txn, contactId, session.getShareableId(), min);
}
@@ -637,4 +675,20 @@ abstract class ProtocolEngineImpl<S extends Shareable>
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_AVAILABLE_TO_ANSWER = "availableToAnswer";
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
String MSG_KEY_AUTO_DELETE_TIMER = "autoDeleteTimer";
// Session keys
String SESSION_KEY_IS_SESSION = "isSession";

View File

@@ -368,7 +368,8 @@ abstract class SharingManagerImpl<S extends Shareable>
return invitationFactory
.createInvitationRequest(meta.isLocal(), status.isSent(),
status.isSeen(), meta.isRead(), invite, c,
meta.isAvailableToAnswer(), canBeOpened);
meta.isAvailableToAnswer(), canBeOpened,
meta.getAutoDeleteTimer());
}
private InvitationResponse parseInvitationResponse(GroupId contactGroupId,
@@ -376,7 +377,8 @@ abstract class SharingManagerImpl<S extends Shareable>
boolean accept) {
return invitationFactory.createInvitationResponse(m, contactGroupId,
meta.getTimestamp(), meta.isLocal(), status.isSent(),
status.isSeen(), meta.isRead(), accept, meta.getShareableId());
status.isSeen(), meta.isRead(), accept, meta.getShareableId(),
meta.getAutoDeleteTimer());
}
@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.system.Clock;
import java.util.Collections;
import javax.annotation.Nullable;
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.checkRange;
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.sharing.MessageType.INVITE;
@@ -45,9 +49,10 @@ abstract class SharingValidator extends BdfMessageValidator {
return validateInviteMessage(m, body);
case ACCEPT:
case DECLINE:
return validateNonInviteMessageWithOptionalTimer(type, m, body);
case LEAVE:
case ABORT:
return validateNonInviteMessage(type, m, body);
return validateNonInviteMessageWithoutTimer(type, m, body);
default:
throw new FormatException();
}
@@ -55,47 +60,80 @@ abstract class SharingValidator extends BdfMessageValidator {
private BdfMessageContext validateInviteMessage(Message m, BdfList body)
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);
checkLength(previousMessageId, UniqueId.LENGTH);
BdfList descriptor = body.getList(2);
GroupId shareableId = validateDescriptor(descriptor);
String text = body.getOptionalString(3);
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
.encodeMetadata(INVITE, shareableId, m.getTimestamp(), false,
false, false, false, false);
BdfDictionary meta = messageEncoder.encodeMetadata(INVITE, 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,
Collections.singletonList(dependency));
return new BdfMessageContext(meta, singletonList(dependency));
}
}
protected abstract GroupId validateDescriptor(BdfList descriptor)
throws FormatException;
private BdfMessageContext validateNonInviteMessage(MessageType type,
Message m, BdfList body) throws FormatException {
private BdfMessageContext validateNonInviteMessageWithoutTimer(
MessageType type, Message m, BdfList body) throws FormatException {
checkSize(body, 3);
byte[] shareableId = body.getRaw(1);
checkLength(shareableId, UniqueId.LENGTH);
byte[] previousMessageId = body.getOptionalRaw(2);
checkLength(previousMessageId, UniqueId.LENGTH);
BdfDictionary meta = messageEncoder
.encodeMetadata(type, new GroupId(shareableId),
m.getTimestamp(), false, false, false, false, false);
BdfDictionary meta = messageEncoder.encodeMetadata(type,
new GroupId(shareableId), m.getTimestamp(), false, false,
false, false, false, NO_AUTO_DELETE_TIMER);
if (previousMessageId == null) {
return new BdfMessageContext(meta);
} else {
MessageId dependency = new MessageId(previousMessageId);
return new BdfMessageContext(meta,
Collections.singletonList(dependency));
return new BdfMessageContext(meta, 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.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.util.StringUtils.getRandomString;
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_TEXT_LENGTH;
import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.junit.Assert.fail;
public class BlogSharingValidatorTest extends SharingValidatorTest {
@@ -31,7 +37,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsInvitationWithText() throws Exception {
expectCreateBlog();
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text));
assertExpectedContext(context, previousMsgId);
@@ -40,7 +46,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsInvitationWithNullText() throws Exception {
expectCreateBlog();
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
assertExpectedContext(context, previousMsgId);
@@ -49,16 +55,64 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
expectCreateBlog();
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, text));
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
public void testAcceptsInvitationForRssBlog() throws Exception {
expectCreateRssBlog();
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfList rssDescriptor = BdfList.of(authorList, true);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, rssDescriptor,
@@ -93,7 +147,7 @@ public class BlogSharingValidatorTest extends SharingValidatorTest {
public void testAcceptsMinLengthText() throws Exception {
String shortText = getRandomString(1);
expectCreateBlog();
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
shortText));

View File

@@ -7,12 +7,18 @@ import org.briarproject.briar.api.forum.Forum;
import org.jmock.Expectations;
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.util.StringUtils.getRandomString;
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_TEXT_LENGTH;
import static org.briarproject.briar.sharing.MessageType.INVITE;
import static org.junit.Assert.fail;
public class ForumSharingValidatorTest extends SharingValidatorTest {
@@ -31,7 +37,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsInvitationWithText() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, text));
assertExpectedContext(context, previousMsgId);
@@ -40,7 +46,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsInvitationWithNullText() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
assertExpectedContext(context, previousMsgId);
@@ -49,12 +55,60 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), null, descriptor, 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)
public void testRejectsNullForumName() throws Exception {
BdfList invalidDescriptor = BdfList.of(null, salt);
@@ -84,7 +138,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
String shortForumName = getRandomString(1);
BdfList validDescriptor = BdfList.of(shortForumName, salt);
expectCreateForum(shortForumName);
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
null));
@@ -144,7 +198,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
@Test
public void testAcceptsMinLengthText() throws Exception {
expectCreateForum(forumName);
expectEncodeMetadata(INVITE);
expectEncodeMetadata(INVITE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
assertExpectedContext(context, previousMsgId);

View File

@@ -16,6 +16,11 @@ import java.util.Collection;
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.getRandomId;
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.LEAVE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public abstract class SharingValidatorTest extends ValidatorTestCase {
@@ -54,23 +59,84 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Test
public void testAcceptsAccept() throws Exception {
expectEncodeMetadata(ACCEPT);
expectEncodeMetadata(ACCEPT, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(ACCEPT.getValue(), groupId, 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
public void testAcceptsDecline() throws Exception {
expectEncodeMetadata(DECLINE);
expectEncodeMetadata(DECLINE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(DECLINE.getValue(), groupId, 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
public void testAcceptsLeave() throws Exception {
expectEncodeMetadata(LEAVE);
expectEncodeMetadata(LEAVE, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(LEAVE.getValue(), groupId, previousMsgId));
assertExpectedContext(context, previousMsgId);
@@ -78,7 +144,7 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Test
public void testAcceptsAbort() throws Exception {
expectEncodeMetadata(ABORT);
expectEncodeMetadata(ABORT, NO_AUTO_DELETE_TIMER);
BdfMessageContext context = validator.validateMessage(message, group,
BdfList.of(ABORT.getValue(), groupId, previousMsgId));
assertExpectedContext(context, previousMsgId);
@@ -141,10 +207,10 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
}
void expectEncodeMetadata(MessageType type) {
void expectEncodeMetadata(MessageType type, long autoDeleteTimer) {
context.checking(new Expectations() {{
oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp,
false, false, false, false, false);
false, false, false, false, false, autoDeleteTimer);
will(returnValue(meta));
}});
}
@@ -153,12 +219,26 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
@Nullable MessageId previousMsgId) {
Collection<MessageId> dependencies = messageContext.getDependencies();
if (previousMsgId == null) {
assertTrue(dependencies.isEmpty());
assertEquals(emptyList(), dependencies);
} else {
assertEquals(1, dependencies.size());
assertTrue(dependencies.contains(previousMsgId));
assertEquals(singletonList(previousMsgId), dependencies);
}
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();
}
}