Use client versioning for private groups.

This commit is contained in:
akwizgran
2018-04-16 14:55:02 +01:00
parent be309057cd
commit f4c5855dd8
20 changed files with 251 additions and 44 deletions

View File

@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Group.Visibility;
import org.briarproject.bramble.api.sync.GroupId;
@@ -28,6 +29,8 @@ import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_VERSION;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
@@ -45,6 +48,7 @@ abstract class AbstractProtocolEngine<S extends Session>
protected final PrivateGroupFactory privateGroupFactory;
protected final MessageTracker messageTracker;
private final ClientVersioningManager clientVersioningManager;
private final GroupMessageFactory groupMessageFactory;
private final IdentityManager identityManager;
private final MessageParser messageParser;
@@ -52,6 +56,7 @@ abstract class AbstractProtocolEngine<S extends Session>
private final Clock clock;
AbstractProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
PrivateGroupManager privateGroupManager,
PrivateGroupFactory privateGroupFactory,
GroupMessageFactory groupMessageFactory,
@@ -60,6 +65,7 @@ abstract class AbstractProtocolEngine<S extends Session>
Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
this.clientVersioningManager = clientVersioningManager;
this.privateGroupManager = privateGroupManager;
this.privateGroupFactory = privateGroupFactory;
this.groupMessageFactory = groupMessageFactory;
@@ -90,10 +96,14 @@ abstract class AbstractProtocolEngine<S extends Session>
return expected != null && dependency.equals(expected);
}
void setPrivateGroupVisibility(Transaction txn, S session, Visibility v)
throws DbException, FormatException {
void setPrivateGroupVisibility(Transaction txn, S session,
Visibility preferred) throws DbException, FormatException {
// Apply min of preferred visibility and client's visibility
ContactId contactId = getContactId(txn, session.getContactGroupId());
db.setGroupVisibility(txn, contactId, session.getPrivateGroupId(), v);
Visibility client = clientVersioningManager.getClientVisibility(txn,
contactId, CLIENT_ID, CLIENT_VERSION);
Visibility min = Visibility.min(preferred, client);
db.setGroupVisibility(txn, contactId, session.getPrivateGroupId(), min);
}
Message sendInviteMessage(Transaction txn, S session,

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.client.MessageTracker;
@@ -36,15 +37,16 @@ import static org.briarproject.briar.privategroup.invitation.CreatorState.START;
class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
CreatorProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
PrivateGroupManager privateGroupManager,
PrivateGroupFactory privateGroupFactory,
GroupMessageFactory groupMessageFactory,
IdentityManager identityManager, MessageParser messageParser,
MessageEncoder messageEncoder, MessageTracker messageTracker,
Clock clock) {
super(db, clientHelper, privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, clock);
super(db, clientHelper, clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
}
@Override

View File

@@ -2,19 +2,30 @@ package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group.Visibility;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
@Immutable
@NotNullByDefault
enum CreatorState implements State {
START(0), INVITED(1), JOINED(2), LEFT(3), DISSOLVED(4), ERROR(5);
START(0, INVISIBLE),
INVITED(1, INVISIBLE),
JOINED(2, SHARED),
LEFT(3, INVISIBLE),
DISSOLVED(4, INVISIBLE),
ERROR(5, INVISIBLE);
private final int value;
private final Visibility visibility;
CreatorState(int value) {
CreatorState(int value, Visibility visibility) {
this.value = value;
this.visibility = visibility;
}
@Override
@@ -22,6 +33,11 @@ enum CreatorState implements State {
return value;
}
@Override
public Visibility getVisibility() {
return visibility;
}
static CreatorState fromValue(int value) throws FormatException {
for (CreatorState s : values()) if (s.value == value) return s;
throw new FormatException();

View File

@@ -15,6 +15,7 @@ interface GroupInvitationConstants {
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
// Session keys
String SESSION_KEY_IS_SESSION = "isSession";
String SESSION_KEY_SESSION_ID = "sessionId";
String SESSION_KEY_PRIVATE_GROUP_ID = "privateGroupId";
String SESSION_KEY_LAST_LOCAL_MESSAGE_ID = "lastLocalMessageId";

View File

@@ -16,7 +16,10 @@ import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Client;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.ClientVersioningManager.ClientVersioningHook;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Group.Visibility;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
@@ -36,15 +39,17 @@ import org.briarproject.briar.client.ConversationClientImpl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static java.util.logging.Level.INFO;
import static org.briarproject.briar.privategroup.invitation.CreatorState.START;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
@@ -59,8 +64,12 @@ import static org.briarproject.briar.privategroup.invitation.Role.PEER;
@NotNullByDefault
class GroupInvitationManagerImpl extends ConversationClientImpl
implements GroupInvitationManager, Client, ContactHook,
PrivateGroupHook {
PrivateGroupHook, ClientVersioningHook {
private static final Logger LOG =
Logger.getLogger(GroupInvitationManagerImpl.class.getName());
private final ClientVersioningManager clientVersioningManager;
private final ContactGroupFactory contactGroupFactory;
private final PrivateGroupFactory privateGroupFactory;
private final PrivateGroupManager privateGroupManager;
@@ -73,8 +82,9 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Inject
GroupInvitationManagerImpl(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser,
MessageTracker messageTracker,
ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MessageTracker messageTracker,
ContactGroupFactory contactGroupFactory,
PrivateGroupFactory privateGroupFactory,
PrivateGroupManager privateGroupManager,
@@ -82,6 +92,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
SessionEncoder sessionEncoder,
ProtocolEngineFactory engineFactory) {
super(db, clientHelper, metadataParser, messageTracker);
this.clientVersioningManager = clientVersioningManager;
this.contactGroupFactory = contactGroupFactory;
this.privateGroupFactory = privateGroupFactory;
this.privateGroupManager = privateGroupManager;
@@ -110,7 +121,11 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
Group g = getContactGroup(c);
// Store the group and share it with the contact
db.addGroup(txn, g);
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
Visibility client = clientVersioningManager.getClientVisibility(txn,
c.getId(), CLIENT_ID, CLIENT_VERSION);
if (LOG.isLoggable(INFO))
LOG.info("Applying visibility " + client + " to new contact group");
db.setGroupVisibility(txn, c.getId(), g.getId(), client);
// Attach the contact ID to the group
BdfDictionary meta = new BdfDictionary();
meta.put(GROUP_KEY_CONTACT_ID, c.getId().getInt());
@@ -565,6 +580,72 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
}
}
@Override
public void onClientVisibilityChanging(Transaction txn, Contact c,
Visibility v) throws DbException {
// Apply the client's visibility to the contact group
if (LOG.isLoggable(INFO))
LOG.info("Applying visibility " + v + " to contact group");
Group g = getContactGroup(c);
db.setGroupVisibility(txn, c.getId(), g.getId(), v);
}
ClientVersioningHook getPrivateGroupClientVersioningHook() {
return this::onPrivateGroupClientVisibilityChanging;
}
private void onPrivateGroupClientVisibilityChanging(Transaction txn,
Contact c, Visibility client) throws DbException {
try {
Collection<Group> shareables =
db.getGroups(txn, PrivateGroupManager.CLIENT_ID,
PrivateGroupManager.CLIENT_VERSION);
Map<GroupId, Visibility> m = getPreferredVisibilities(txn, c);
for (Group g : shareables) {
Visibility preferred = m.get(g.getId());
if (preferred == null) continue; // No session for this group
// Apply min of preferred visibility and client's visibility
Visibility min = Visibility.min(preferred, client);
if (LOG.isLoggable(INFO)) {
LOG.info("Applying visibility " + min
+ " to private group, preferred " + preferred
+ ", client " + client);
}
db.setGroupVisibility(txn, c.getId(), g.getId(), min);
}
} catch (FormatException e) {
throw new DbException(e);
}
}
private Map<GroupId, Visibility> getPreferredVisibilities(Transaction txn,
Contact c) throws DbException, FormatException {
GroupId contactGroupId = getContactGroup(c).getId();
BdfDictionary query = sessionParser.getAllSessionsQuery();
Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, contactGroupId, query);
Map<GroupId, Visibility> m = new HashMap<>();
for (BdfDictionary d : results.values()) {
Role role = sessionParser.getRole(d);
if (role == CREATOR) {
CreatorSession s =
sessionParser.parseCreatorSession(contactGroupId, d);
m.put(s.getPrivateGroupId(), s.getState().getVisibility());
} else if (role == INVITEE) {
InviteeSession s =
sessionParser.parseInviteeSession(contactGroupId, d);
m.put(s.getPrivateGroupId(), s.getState().getVisibility());
} else if (role == PEER) {
PeerSession s =
sessionParser.parsePeerSession(contactGroupId, d);
m.put(s.getPrivateGroupId(), s.getState().getVisibility());
} else {
throw new AssertionError();
}
}
return m;
}
private static class StoredSession {
private final MessageId storageId;

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.data.MetadataEncoder;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.ValidationManager;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.messaging.ConversationManager;
@@ -38,13 +39,25 @@ public class GroupInvitationModule {
LifecycleManager lifecycleManager,
ValidationManager validationManager, ContactManager contactManager,
PrivateGroupManager privateGroupManager,
ConversationManager conversationManager) {
ConversationManager conversationManager,
ClientVersioningManager clientVersioningManager) {
lifecycleManager.registerClient(groupInvitationManager);
validationManager.registerIncomingMessageHook(CLIENT_ID, CLIENT_VERSION,
groupInvitationManager);
contactManager.registerContactHook(groupInvitationManager);
privateGroupManager.registerPrivateGroupHook(groupInvitationManager);
conversationManager.registerConversationClient(groupInvitationManager);
clientVersioningManager.registerClient(CLIENT_ID, CLIENT_VERSION);
clientVersioningManager.registerClientVersioningHook(CLIENT_ID,
CLIENT_VERSION, groupInvitationManager);
// The group invitation manager handles client visibility changes for
// the private group manager
clientVersioningManager.registerClient(PrivateGroupManager.CLIENT_ID,
PrivateGroupManager.CLIENT_VERSION);
clientVersioningManager.registerClientVersioningHook(
PrivateGroupManager.CLIENT_ID,
PrivateGroupManager.CLIENT_VERSION,
groupInvitationManager.getPrivateGroupClientVersioningHook());
return groupInvitationManager;
}

View File

@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.api.system.Clock;
@@ -41,15 +42,16 @@ import static org.briarproject.briar.privategroup.invitation.InviteeState.START;
class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
InviteeProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
PrivateGroupManager privateGroupManager,
PrivateGroupFactory privateGroupFactory,
GroupMessageFactory groupMessageFactory,
IdentityManager identityManager, MessageParser messageParser,
MessageEncoder messageEncoder, MessageTracker messageTracker,
Clock clock) {
super(db, clientHelper, privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, clock);
super(db, clientHelper, clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
}
@Override
@@ -212,6 +214,12 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
throws DbException {
// Send a LEAVE message
Message sent = sendLeaveMessage(txn, s, false);
try {
// Make the private group invisible to the contact
setPrivateGroupVisibility(txn, s, INVISIBLE);
} catch (FormatException e) {
throw new DbException(e); // Invalid group metadata
}
// Move to the LEFT state
return new InviteeSession(s.getContactGroupId(), s.getPrivateGroupId(),
sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),

View File

@@ -2,20 +2,32 @@ package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group.Visibility;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@Immutable
@NotNullByDefault
enum InviteeState implements State {
START(0), INVITED(1), ACCEPTED(2), JOINED(3), LEFT(4), DISSOLVED(5),
ERROR(6);
START(0, INVISIBLE),
INVITED(1, INVISIBLE),
ACCEPTED(2, VISIBLE),
JOINED(3, SHARED),
LEFT(4, INVISIBLE),
DISSOLVED(5, INVISIBLE),
ERROR(6, INVISIBLE);
private final int value;
private final Visibility visibility;
InviteeState(int value) {
InviteeState(int value, Visibility visibility) {
this.value = value;
this.visibility = visibility;
}
@Override
@@ -23,6 +35,11 @@ enum InviteeState implements State {
return value;
}
@Override
public Visibility getVisibility() {
return visibility;
}
static InviteeState fromValue(int value) throws FormatException {
for (InviteeState s : values()) if (s.value == value) return s;
throw new FormatException();

View File

@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.client.MessageTracker;
@@ -36,15 +37,16 @@ import static org.briarproject.briar.privategroup.invitation.PeerState.START;
class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
PeerProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
PrivateGroupManager privateGroupManager,
PrivateGroupFactory privateGroupFactory,
GroupMessageFactory groupMessageFactory,
IdentityManager identityManager, MessageParser messageParser,
MessageEncoder messageEncoder, MessageTracker messageTracker,
Clock clock) {
super(db, clientHelper, privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, clock);
super(db, clientHelper, clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
}
@Override

View File

@@ -2,20 +2,32 @@ package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group.Visibility;
import javax.annotation.concurrent.Immutable;
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
@Immutable
@NotNullByDefault
enum PeerState implements State {
START(0), AWAIT_MEMBER(1), NEITHER_JOINED(2), LOCAL_JOINED(3),
BOTH_JOINED(4), LOCAL_LEFT(5), ERROR(6);
START(0, INVISIBLE),
AWAIT_MEMBER(1, INVISIBLE),
NEITHER_JOINED(2, INVISIBLE),
LOCAL_JOINED(3, VISIBLE),
BOTH_JOINED(4, SHARED),
LOCAL_LEFT(5, INVISIBLE),
ERROR(6, INVISIBLE);
private final int value;
private final Visibility visibility;
PeerState(int value) {
PeerState(int value, Visibility visibility) {
this.value = value;
this.visibility = visibility;
}
@Override
@@ -23,6 +35,11 @@ enum PeerState implements State {
return value;
}
@Override
public Visibility getVisibility() {
return visibility;
}
static PeerState fromValue(int value) throws FormatException {
for (PeerState s : values()) if (s.value == value) return s;
throw new FormatException();

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.api.client.MessageTracker;
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
@@ -19,6 +20,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
private final DatabaseComponent db;
private final ClientHelper clientHelper;
private final ClientVersioningManager clientVersioningManager;
private final PrivateGroupManager privateGroupManager;
private final PrivateGroupFactory privateGroupFactory;
private final GroupMessageFactory groupMessageFactory;
@@ -30,6 +32,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
@Inject
ProtocolEngineFactoryImpl(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager,
PrivateGroupManager privateGroupManager,
PrivateGroupFactory privateGroupFactory,
GroupMessageFactory groupMessageFactory,
@@ -38,6 +41,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
Clock clock) {
this.db = db;
this.clientHelper = clientHelper;
this.clientVersioningManager = clientVersioningManager;
this.privateGroupManager = privateGroupManager;
this.privateGroupFactory = privateGroupFactory;
this.groupMessageFactory = groupMessageFactory;
@@ -50,21 +54,24 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
@Override
public ProtocolEngine<CreatorSession> createCreatorEngine() {
return new CreatorProtocolEngine(db, clientHelper, privateGroupManager,
return new CreatorProtocolEngine(db, clientHelper,
clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
}
@Override
public ProtocolEngine<InviteeSession> createInviteeEngine() {
return new InviteeProtocolEngine(db, clientHelper, privateGroupManager,
return new InviteeProtocolEngine(db, clientHelper,
clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
}
@Override
public ProtocolEngine<PeerSession> createPeerEngine() {
return new PeerProtocolEngine(db, clientHelper, privateGroupManager,
return new PeerProtocolEngine(db, clientHelper,
clientVersioningManager, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
}

View File

@@ -9,6 +9,7 @@ import javax.inject.Inject;
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_INVITE_TIMESTAMP;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_IS_SESSION;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LAST_LOCAL_MESSAGE_ID;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LAST_REMOTE_MESSAGE_ID;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LOCAL_TIMESTAMP;
@@ -28,6 +29,7 @@ class SessionEncoderImpl implements SessionEncoder {
@Override
public BdfDictionary encodeSession(Session s) {
BdfDictionary d = new BdfDictionary();
d.put(SESSION_KEY_IS_SESSION, true);
d.put(SESSION_KEY_SESSION_ID, s.getPrivateGroupId());
d.put(SESSION_KEY_PRIVATE_GROUP_ID, s.getPrivateGroupId());
MessageId lastLocalMessageId = s.getLastLocalMessageId();

View File

@@ -11,6 +11,8 @@ interface SessionParser {
BdfDictionary getSessionQuery(SessionId s);
BdfDictionary getAllSessionsQuery();
Role getRole(BdfDictionary d) throws FormatException;
CreatorSession parseCreatorSession(GroupId contactGroupId, BdfDictionary d)

View File

@@ -13,6 +13,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_INVITE_TIMESTAMP;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_IS_SESSION;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LAST_LOCAL_MESSAGE_ID;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LAST_REMOTE_MESSAGE_ID;
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LOCAL_TIMESTAMP;
@@ -37,6 +38,11 @@ class SessionParserImpl implements SessionParser {
return BdfDictionary.of(new BdfEntry(SESSION_KEY_SESSION_ID, s));
}
@Override
public BdfDictionary getAllSessionsQuery() {
return BdfDictionary.of(new BdfEntry(SESSION_KEY_IS_SESSION, true));
}
@Override
public Role getRole(BdfDictionary d) throws FormatException {
return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue());

View File

@@ -1,6 +1,10 @@
package org.briarproject.briar.privategroup.invitation;
import org.briarproject.bramble.api.sync.Group.Visibility;
interface State {
int getValue();
Visibility getVisibility();
}

View File

@@ -10,7 +10,9 @@ import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Group.Visibility;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId;
@@ -24,6 +26,7 @@ import org.briarproject.briar.api.privategroup.PrivateGroupManager;
import org.jmock.Expectations;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getGroup;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
@@ -47,6 +50,8 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
context.mock(DatabaseComponent.class);
protected final ClientHelper clientHelper =
context.mock(ClientHelper.class);
protected final ClientVersioningManager clientVersioningManager =
context.mock(ClientVersioningManager.class);
protected final PrivateGroupFactory privateGroupFactory =
context.mock(PrivateGroupFactory.class);
protected final PrivateGroupManager privateGroupManager =
@@ -181,10 +186,13 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
}});
}
protected void expectSetPrivateGroupVisibility(Group.Visibility v)
protected void expectSetPrivateGroupVisibility(Visibility v)
throws Exception {
expectGetContactId();
context.checking(new Expectations() {{
oneOf(clientVersioningManager).getClientVisibility(txn, contactId,
CLIENT_ID, CLIENT_VERSION);
will(returnValue(SHARED));
oneOf(db).setGroupVisibility(txn, contactId, privateGroupId, v);
}});
}

View File

@@ -19,9 +19,10 @@ import static org.junit.Assert.assertEquals;
public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
private final CreatorProtocolEngine engine =
new CreatorProtocolEngine(db, clientHelper, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
new CreatorProtocolEngine(db, clientHelper, clientVersioningManager,
privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, clock);
private CreatorSession getDefaultSession(CreatorState state) {
return new CreatorSession(contactGroupId, privateGroupId,

View File

@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.sync.ClientVersioningManager;
import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message;
@@ -69,6 +70,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final ClientVersioningManager clientVersioningManager =
context.mock(ClientVersioningManager.class);
private final ContactGroupFactory contactGroupFactory =
context.mock(ContactGroupFactory.class);
private final PrivateGroupFactory privateGroupFactory =
@@ -140,11 +143,11 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
}});
MetadataParser metadataParser = context.mock(MetadataParser.class);
MessageTracker messageTracker = context.mock(MessageTracker.class);
groupInvitationManager =
new GroupInvitationManagerImpl(db, clientHelper, metadataParser,
messageTracker, contactGroupFactory,
privateGroupFactory, privateGroupManager, messageParser,
sessionParser, sessionEncoder, engineFactory);
groupInvitationManager = new GroupInvitationManagerImpl(db,
clientHelper, clientVersioningManager, metadataParser,
messageTracker, contactGroupFactory, privateGroupFactory,
privateGroupManager, messageParser, sessionParser,
sessionEncoder, engineFactory);
}
@Test
@@ -184,6 +187,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
CLIENT_VERSION, c);
will(returnValue(contactGroup));
oneOf(db).addGroup(txn, contactGroup);
oneOf(clientVersioningManager).getClientVisibility(txn, contactId,
CLIENT_ID, CLIENT_VERSION);
will(returnValue(SHARED));
oneOf(db).setGroupVisibility(txn, c.getId(), contactGroup.getId(),
SHARED);
oneOf(clientHelper)

View File

@@ -38,9 +38,10 @@ import static org.junit.Assert.assertTrue;
public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
private final InviteeProtocolEngine engine =
new InviteeProtocolEngine(db, clientHelper, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
new InviteeProtocolEngine(db, clientHelper, clientVersioningManager,
privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, clock);
private final LocalAuthor localAuthor = getLocalAuthor();
private InviteeSession getDefaultSession(InviteeState state) {
@@ -238,6 +239,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
@Test
public void testOnLeaveActionFromAccepted() throws Exception {
expectSendLeaveMessage(false);
expectSetPrivateGroupVisibility(INVISIBLE);
InviteeSession session = getDefaultSession(ACCEPTED);
InviteeSession newSession = engine.onLeaveAction(txn, session);
@@ -249,6 +251,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
@Test
public void testOnLeaveActionFromJoined() throws Exception {
expectSendLeaveMessage(false);
expectSetPrivateGroupVisibility(INVISIBLE);
InviteeSession session = getDefaultSession(JOINED);
InviteeSession newSession = engine.onLeaveAction(txn, session);

View File

@@ -24,9 +24,10 @@ import static org.junit.Assert.assertTrue;
public class PeerProtocolEngineTest extends AbstractProtocolEngineTest {
private final PeerProtocolEngine engine =
new PeerProtocolEngine(db, clientHelper, privateGroupManager,
privateGroupFactory, groupMessageFactory, identityManager,
messageParser, messageEncoder, messageTracker, clock);
new PeerProtocolEngine(db, clientHelper, clientVersioningManager,
privateGroupManager, privateGroupFactory,
groupMessageFactory, identityManager, messageParser,
messageEncoder, messageTracker, clock);
private PeerSession getDefaultSession(PeerState state) {
return new PeerSession(contactGroupId, privateGroupId,