mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Use client versioning for private groups.
This commit is contained in:
@@ -10,6 +10,7 @@ import org.briarproject.bramble.api.db.Transaction;
|
|||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -28,6 +29,8 @@ 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.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.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
|
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 PrivateGroupFactory privateGroupFactory;
|
||||||
protected final MessageTracker messageTracker;
|
protected final MessageTracker messageTracker;
|
||||||
|
|
||||||
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
private final GroupMessageFactory groupMessageFactory;
|
private final GroupMessageFactory groupMessageFactory;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
private final MessageParser messageParser;
|
private final MessageParser messageParser;
|
||||||
@@ -52,6 +56,7 @@ abstract class AbstractProtocolEngine<S extends Session>
|
|||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
AbstractProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
AbstractProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
|
ClientVersioningManager clientVersioningManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
PrivateGroupFactory privateGroupFactory,
|
PrivateGroupFactory privateGroupFactory,
|
||||||
GroupMessageFactory groupMessageFactory,
|
GroupMessageFactory groupMessageFactory,
|
||||||
@@ -60,6 +65,7 @@ abstract class AbstractProtocolEngine<S extends Session>
|
|||||||
Clock clock) {
|
Clock clock) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
|
this.clientVersioningManager = clientVersioningManager;
|
||||||
this.privateGroupManager = privateGroupManager;
|
this.privateGroupManager = privateGroupManager;
|
||||||
this.privateGroupFactory = privateGroupFactory;
|
this.privateGroupFactory = privateGroupFactory;
|
||||||
this.groupMessageFactory = groupMessageFactory;
|
this.groupMessageFactory = groupMessageFactory;
|
||||||
@@ -90,10 +96,14 @@ abstract class AbstractProtocolEngine<S extends Session>
|
|||||||
return expected != null && dependency.equals(expected);
|
return expected != null && dependency.equals(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPrivateGroupVisibility(Transaction txn, S session, Visibility v)
|
void setPrivateGroupVisibility(Transaction txn, S session,
|
||||||
throws DbException, FormatException {
|
Visibility preferred) throws DbException, FormatException {
|
||||||
|
// Apply min of preferred visibility and client's visibility
|
||||||
ContactId contactId = getContactId(txn, session.getContactGroupId());
|
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,
|
Message sendInviteMessage(Transaction txn, S session,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ 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.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.Message;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.briar.api.client.MessageTracker;
|
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> {
|
class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||||
|
|
||||||
CreatorProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
CreatorProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
|
ClientVersioningManager clientVersioningManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
PrivateGroupFactory privateGroupFactory,
|
PrivateGroupFactory privateGroupFactory,
|
||||||
GroupMessageFactory groupMessageFactory,
|
GroupMessageFactory groupMessageFactory,
|
||||||
IdentityManager identityManager, MessageParser messageParser,
|
IdentityManager identityManager, MessageParser messageParser,
|
||||||
MessageEncoder messageEncoder, MessageTracker messageTracker,
|
MessageEncoder messageEncoder, MessageTracker messageTracker,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
super(db, clientHelper, privateGroupManager, privateGroupFactory,
|
super(db, clientHelper, clientVersioningManager, privateGroupManager,
|
||||||
groupMessageFactory, identityManager, messageParser,
|
privateGroupFactory, groupMessageFactory, identityManager,
|
||||||
messageEncoder, messageTracker, clock);
|
messageParser, messageEncoder, messageTracker, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,19 +2,30 @@ package org.briarproject.briar.privategroup.invitation;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
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
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
enum CreatorState implements State {
|
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 int value;
|
||||||
|
private final Visibility visibility;
|
||||||
|
|
||||||
CreatorState(int value) {
|
CreatorState(int value, Visibility visibility) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.visibility = visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -22,6 +33,11 @@ enum CreatorState implements State {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Visibility getVisibility() {
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
|
||||||
static CreatorState fromValue(int value) throws FormatException {
|
static CreatorState fromValue(int value) throws FormatException {
|
||||||
for (CreatorState s : values()) if (s.value == value) return s;
|
for (CreatorState s : values()) if (s.value == value) return s;
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ interface GroupInvitationConstants {
|
|||||||
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
|
String MSG_KEY_INVITATION_ACCEPTED = "invitationAccepted";
|
||||||
|
|
||||||
// Session keys
|
// Session keys
|
||||||
|
String SESSION_KEY_IS_SESSION = "isSession";
|
||||||
String SESSION_KEY_SESSION_ID = "sessionId";
|
String SESSION_KEY_SESSION_ID = "sessionId";
|
||||||
String SESSION_KEY_PRIVATE_GROUP_ID = "privateGroupId";
|
String SESSION_KEY_PRIVATE_GROUP_ID = "privateGroupId";
|
||||||
String SESSION_KEY_LAST_LOCAL_MESSAGE_ID = "lastLocalMessageId";
|
String SESSION_KEY_LAST_LOCAL_MESSAGE_ID = "lastLocalMessageId";
|
||||||
|
|||||||
@@ -16,7 +16,10 @@ import org.briarproject.bramble.api.db.Transaction;
|
|||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
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;
|
||||||
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
@@ -36,15 +39,17 @@ import org.briarproject.briar.client.ConversationClientImpl;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
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.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.CreatorState.START;
|
||||||
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
|
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.ABORT;
|
||||||
@@ -59,8 +64,12 @@ import static org.briarproject.briar.privategroup.invitation.Role.PEER;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class GroupInvitationManagerImpl extends ConversationClientImpl
|
class GroupInvitationManagerImpl extends ConversationClientImpl
|
||||||
implements GroupInvitationManager, Client, ContactHook,
|
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 ContactGroupFactory contactGroupFactory;
|
||||||
private final PrivateGroupFactory privateGroupFactory;
|
private final PrivateGroupFactory privateGroupFactory;
|
||||||
private final PrivateGroupManager privateGroupManager;
|
private final PrivateGroupManager privateGroupManager;
|
||||||
@@ -73,8 +82,9 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupInvitationManagerImpl(DatabaseComponent db,
|
GroupInvitationManagerImpl(DatabaseComponent db,
|
||||||
ClientHelper clientHelper, MetadataParser metadataParser,
|
ClientHelper clientHelper,
|
||||||
MessageTracker messageTracker,
|
ClientVersioningManager clientVersioningManager,
|
||||||
|
MetadataParser metadataParser, MessageTracker messageTracker,
|
||||||
ContactGroupFactory contactGroupFactory,
|
ContactGroupFactory contactGroupFactory,
|
||||||
PrivateGroupFactory privateGroupFactory,
|
PrivateGroupFactory privateGroupFactory,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
@@ -82,6 +92,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
SessionEncoder sessionEncoder,
|
SessionEncoder sessionEncoder,
|
||||||
ProtocolEngineFactory engineFactory) {
|
ProtocolEngineFactory engineFactory) {
|
||||||
super(db, clientHelper, metadataParser, messageTracker);
|
super(db, clientHelper, metadataParser, messageTracker);
|
||||||
|
this.clientVersioningManager = clientVersioningManager;
|
||||||
this.contactGroupFactory = contactGroupFactory;
|
this.contactGroupFactory = contactGroupFactory;
|
||||||
this.privateGroupFactory = privateGroupFactory;
|
this.privateGroupFactory = privateGroupFactory;
|
||||||
this.privateGroupManager = privateGroupManager;
|
this.privateGroupManager = privateGroupManager;
|
||||||
@@ -110,7 +121,11 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
Group g = getContactGroup(c);
|
Group g = getContactGroup(c);
|
||||||
// Store the group and share it with the contact
|
// Store the group and share it with the contact
|
||||||
db.addGroup(txn, g);
|
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
|
// Attach the contact ID to the group
|
||||||
BdfDictionary meta = new BdfDictionary();
|
BdfDictionary meta = new BdfDictionary();
|
||||||
meta.put(GROUP_KEY_CONTACT_ID, c.getId().getInt());
|
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 static class StoredSession {
|
||||||
|
|
||||||
private final MessageId storageId;
|
private final MessageId storageId;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
|||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
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.sync.ValidationManager;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.briar.api.messaging.ConversationManager;
|
import org.briarproject.briar.api.messaging.ConversationManager;
|
||||||
@@ -38,13 +39,25 @@ public class GroupInvitationModule {
|
|||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager,
|
||||||
ValidationManager validationManager, ContactManager contactManager,
|
ValidationManager validationManager, ContactManager contactManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
ConversationManager conversationManager) {
|
ConversationManager conversationManager,
|
||||||
|
ClientVersioningManager clientVersioningManager) {
|
||||||
lifecycleManager.registerClient(groupInvitationManager);
|
lifecycleManager.registerClient(groupInvitationManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, CLIENT_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, CLIENT_VERSION,
|
||||||
groupInvitationManager);
|
groupInvitationManager);
|
||||||
contactManager.registerContactHook(groupInvitationManager);
|
contactManager.registerContactHook(groupInvitationManager);
|
||||||
privateGroupManager.registerPrivateGroupHook(groupInvitationManager);
|
privateGroupManager.registerPrivateGroupHook(groupInvitationManager);
|
||||||
conversationManager.registerConversationClient(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;
|
return groupInvitationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.db.Transaction;
|
|||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.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;
|
||||||
@@ -41,15 +42,16 @@ import static org.briarproject.briar.privategroup.invitation.InviteeState.START;
|
|||||||
class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||||
|
|
||||||
InviteeProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
InviteeProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
|
ClientVersioningManager clientVersioningManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
PrivateGroupFactory privateGroupFactory,
|
PrivateGroupFactory privateGroupFactory,
|
||||||
GroupMessageFactory groupMessageFactory,
|
GroupMessageFactory groupMessageFactory,
|
||||||
IdentityManager identityManager, MessageParser messageParser,
|
IdentityManager identityManager, MessageParser messageParser,
|
||||||
MessageEncoder messageEncoder, MessageTracker messageTracker,
|
MessageEncoder messageEncoder, MessageTracker messageTracker,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
super(db, clientHelper, privateGroupManager, privateGroupFactory,
|
super(db, clientHelper, clientVersioningManager, privateGroupManager,
|
||||||
groupMessageFactory, identityManager, messageParser,
|
privateGroupFactory, groupMessageFactory, identityManager,
|
||||||
messageEncoder, messageTracker, clock);
|
messageParser, messageEncoder, messageTracker, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -212,6 +214,12 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
|||||||
throws DbException {
|
throws DbException {
|
||||||
// Send a LEAVE message
|
// Send a LEAVE message
|
||||||
Message sent = sendLeaveMessage(txn, s, false);
|
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
|
// Move to the LEFT state
|
||||||
return new InviteeSession(s.getContactGroupId(), s.getPrivateGroupId(),
|
return new InviteeSession(s.getContactGroupId(), s.getPrivateGroupId(),
|
||||||
sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),
|
sent.getId(), s.getLastRemoteMessageId(), sent.getTimestamp(),
|
||||||
|
|||||||
@@ -2,20 +2,32 @@ package org.briarproject.briar.privategroup.invitation;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
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
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
enum InviteeState implements State {
|
enum InviteeState implements State {
|
||||||
|
|
||||||
START(0), INVITED(1), ACCEPTED(2), JOINED(3), LEFT(4), DISSOLVED(5),
|
START(0, INVISIBLE),
|
||||||
ERROR(6);
|
INVITED(1, INVISIBLE),
|
||||||
|
ACCEPTED(2, VISIBLE),
|
||||||
|
JOINED(3, SHARED),
|
||||||
|
LEFT(4, INVISIBLE),
|
||||||
|
DISSOLVED(5, INVISIBLE),
|
||||||
|
ERROR(6, INVISIBLE);
|
||||||
|
|
||||||
private final int value;
|
private final int value;
|
||||||
|
private final Visibility visibility;
|
||||||
|
|
||||||
InviteeState(int value) {
|
InviteeState(int value, Visibility visibility) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.visibility = visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -23,6 +35,11 @@ enum InviteeState implements State {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Visibility getVisibility() {
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
|
||||||
static InviteeState fromValue(int value) throws FormatException {
|
static InviteeState fromValue(int value) throws FormatException {
|
||||||
for (InviteeState s : values()) if (s.value == value) return s;
|
for (InviteeState s : values()) if (s.value == value) return s;
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ 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.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
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.Message;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.briar.api.client.MessageTracker;
|
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> {
|
class PeerProtocolEngine extends AbstractProtocolEngine<PeerSession> {
|
||||||
|
|
||||||
PeerProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
PeerProtocolEngine(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
|
ClientVersioningManager clientVersioningManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
PrivateGroupFactory privateGroupFactory,
|
PrivateGroupFactory privateGroupFactory,
|
||||||
GroupMessageFactory groupMessageFactory,
|
GroupMessageFactory groupMessageFactory,
|
||||||
IdentityManager identityManager, MessageParser messageParser,
|
IdentityManager identityManager, MessageParser messageParser,
|
||||||
MessageEncoder messageEncoder, MessageTracker messageTracker,
|
MessageEncoder messageEncoder, MessageTracker messageTracker,
|
||||||
Clock clock) {
|
Clock clock) {
|
||||||
super(db, clientHelper, privateGroupManager, privateGroupFactory,
|
super(db, clientHelper, clientVersioningManager, privateGroupManager,
|
||||||
groupMessageFactory, identityManager, messageParser,
|
privateGroupFactory, groupMessageFactory, identityManager,
|
||||||
messageEncoder, messageTracker, clock);
|
messageParser, messageEncoder, messageTracker, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,20 +2,32 @@ package org.briarproject.briar.privategroup.invitation;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
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
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
enum PeerState implements State {
|
enum PeerState implements State {
|
||||||
|
|
||||||
START(0), AWAIT_MEMBER(1), NEITHER_JOINED(2), LOCAL_JOINED(3),
|
START(0, INVISIBLE),
|
||||||
BOTH_JOINED(4), LOCAL_LEFT(5), ERROR(6);
|
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 int value;
|
||||||
|
private final Visibility visibility;
|
||||||
|
|
||||||
PeerState(int value) {
|
PeerState(int value, Visibility visibility) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.visibility = visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -23,6 +35,11 @@ enum PeerState implements State {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Visibility getVisibility() {
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
|
||||||
static PeerState fromValue(int value) throws FormatException {
|
static PeerState fromValue(int value) throws FormatException {
|
||||||
for (PeerState s : values()) if (s.value == value) return s;
|
for (PeerState s : values()) if (s.value == value) return s;
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.ClientVersioningManager;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.briar.api.client.MessageTracker;
|
import org.briarproject.briar.api.client.MessageTracker;
|
||||||
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
|
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
|
||||||
@@ -19,6 +20,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
|
|||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
private final PrivateGroupManager privateGroupManager;
|
private final PrivateGroupManager privateGroupManager;
|
||||||
private final PrivateGroupFactory privateGroupFactory;
|
private final PrivateGroupFactory privateGroupFactory;
|
||||||
private final GroupMessageFactory groupMessageFactory;
|
private final GroupMessageFactory groupMessageFactory;
|
||||||
@@ -30,6 +32,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ProtocolEngineFactoryImpl(DatabaseComponent db, ClientHelper clientHelper,
|
ProtocolEngineFactoryImpl(DatabaseComponent db, ClientHelper clientHelper,
|
||||||
|
ClientVersioningManager clientVersioningManager,
|
||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
PrivateGroupFactory privateGroupFactory,
|
PrivateGroupFactory privateGroupFactory,
|
||||||
GroupMessageFactory groupMessageFactory,
|
GroupMessageFactory groupMessageFactory,
|
||||||
@@ -38,6 +41,7 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
|
|||||||
Clock clock) {
|
Clock clock) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
|
this.clientVersioningManager = clientVersioningManager;
|
||||||
this.privateGroupManager = privateGroupManager;
|
this.privateGroupManager = privateGroupManager;
|
||||||
this.privateGroupFactory = privateGroupFactory;
|
this.privateGroupFactory = privateGroupFactory;
|
||||||
this.groupMessageFactory = groupMessageFactory;
|
this.groupMessageFactory = groupMessageFactory;
|
||||||
@@ -50,21 +54,24 @@ class ProtocolEngineFactoryImpl implements ProtocolEngineFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProtocolEngine<CreatorSession> createCreatorEngine() {
|
public ProtocolEngine<CreatorSession> createCreatorEngine() {
|
||||||
return new CreatorProtocolEngine(db, clientHelper, privateGroupManager,
|
return new CreatorProtocolEngine(db, clientHelper,
|
||||||
|
clientVersioningManager, privateGroupManager,
|
||||||
privateGroupFactory, groupMessageFactory, identityManager,
|
privateGroupFactory, groupMessageFactory, identityManager,
|
||||||
messageParser, messageEncoder, messageTracker, clock);
|
messageParser, messageEncoder, messageTracker, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProtocolEngine<InviteeSession> createInviteeEngine() {
|
public ProtocolEngine<InviteeSession> createInviteeEngine() {
|
||||||
return new InviteeProtocolEngine(db, clientHelper, privateGroupManager,
|
return new InviteeProtocolEngine(db, clientHelper,
|
||||||
|
clientVersioningManager, privateGroupManager,
|
||||||
privateGroupFactory, groupMessageFactory, identityManager,
|
privateGroupFactory, groupMessageFactory, identityManager,
|
||||||
messageParser, messageEncoder, messageTracker, clock);
|
messageParser, messageEncoder, messageTracker, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProtocolEngine<PeerSession> createPeerEngine() {
|
public ProtocolEngine<PeerSession> createPeerEngine() {
|
||||||
return new PeerProtocolEngine(db, clientHelper, privateGroupManager,
|
return new PeerProtocolEngine(db, clientHelper,
|
||||||
|
clientVersioningManager, privateGroupManager,
|
||||||
privateGroupFactory, groupMessageFactory, identityManager,
|
privateGroupFactory, groupMessageFactory, identityManager,
|
||||||
messageParser, messageEncoder, messageTracker, clock);
|
messageParser, messageEncoder, messageTracker, clock);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
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_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_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_LAST_REMOTE_MESSAGE_ID;
|
||||||
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LOCAL_TIMESTAMP;
|
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LOCAL_TIMESTAMP;
|
||||||
@@ -28,6 +29,7 @@ class SessionEncoderImpl implements SessionEncoder {
|
|||||||
@Override
|
@Override
|
||||||
public BdfDictionary encodeSession(Session s) {
|
public BdfDictionary encodeSession(Session s) {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
|
d.put(SESSION_KEY_IS_SESSION, true);
|
||||||
d.put(SESSION_KEY_SESSION_ID, s.getPrivateGroupId());
|
d.put(SESSION_KEY_SESSION_ID, s.getPrivateGroupId());
|
||||||
d.put(SESSION_KEY_PRIVATE_GROUP_ID, s.getPrivateGroupId());
|
d.put(SESSION_KEY_PRIVATE_GROUP_ID, s.getPrivateGroupId());
|
||||||
MessageId lastLocalMessageId = s.getLastLocalMessageId();
|
MessageId lastLocalMessageId = s.getLastLocalMessageId();
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ interface SessionParser {
|
|||||||
|
|
||||||
BdfDictionary getSessionQuery(SessionId s);
|
BdfDictionary getSessionQuery(SessionId s);
|
||||||
|
|
||||||
|
BdfDictionary getAllSessionsQuery();
|
||||||
|
|
||||||
Role getRole(BdfDictionary d) throws FormatException;
|
Role getRole(BdfDictionary d) throws FormatException;
|
||||||
|
|
||||||
CreatorSession parseCreatorSession(GroupId contactGroupId, BdfDictionary d)
|
CreatorSession parseCreatorSession(GroupId contactGroupId, BdfDictionary d)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
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_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_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_LAST_REMOTE_MESSAGE_ID;
|
||||||
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.SESSION_KEY_LOCAL_TIMESTAMP;
|
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));
|
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
|
@Override
|
||||||
public Role getRole(BdfDictionary d) throws FormatException {
|
public Role getRole(BdfDictionary d) throws FormatException {
|
||||||
return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue());
|
return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue());
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package org.briarproject.briar.privategroup.invitation;
|
package org.briarproject.briar.privategroup.invitation;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
|
||||||
int getValue();
|
int getValue();
|
||||||
|
|
||||||
|
Visibility getVisibility();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ import org.briarproject.bramble.api.db.Transaction;
|
|||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
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;
|
||||||
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
@@ -24,6 +26,7 @@ import org.briarproject.briar.api.privategroup.PrivateGroupManager;
|
|||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
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.getAuthor;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
@@ -47,6 +50,8 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
|
|||||||
context.mock(DatabaseComponent.class);
|
context.mock(DatabaseComponent.class);
|
||||||
protected final ClientHelper clientHelper =
|
protected final ClientHelper clientHelper =
|
||||||
context.mock(ClientHelper.class);
|
context.mock(ClientHelper.class);
|
||||||
|
protected final ClientVersioningManager clientVersioningManager =
|
||||||
|
context.mock(ClientVersioningManager.class);
|
||||||
protected final PrivateGroupFactory privateGroupFactory =
|
protected final PrivateGroupFactory privateGroupFactory =
|
||||||
context.mock(PrivateGroupFactory.class);
|
context.mock(PrivateGroupFactory.class);
|
||||||
protected final PrivateGroupManager privateGroupManager =
|
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 {
|
throws Exception {
|
||||||
expectGetContactId();
|
expectGetContactId();
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(clientVersioningManager).getClientVisibility(txn, contactId,
|
||||||
|
CLIENT_ID, CLIENT_VERSION);
|
||||||
|
will(returnValue(SHARED));
|
||||||
oneOf(db).setGroupVisibility(txn, contactId, privateGroupId, v);
|
oneOf(db).setGroupVisibility(txn, contactId, privateGroupId, v);
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ import static org.junit.Assert.assertEquals;
|
|||||||
public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
|
public class CreatorProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||||
|
|
||||||
private final CreatorProtocolEngine engine =
|
private final CreatorProtocolEngine engine =
|
||||||
new CreatorProtocolEngine(db, clientHelper, privateGroupManager,
|
new CreatorProtocolEngine(db, clientHelper, clientVersioningManager,
|
||||||
privateGroupFactory, groupMessageFactory, identityManager,
|
privateGroupManager, privateGroupFactory,
|
||||||
messageParser, messageEncoder, messageTracker, clock);
|
groupMessageFactory, identityManager, messageParser,
|
||||||
|
messageEncoder, messageTracker, clock);
|
||||||
|
|
||||||
private CreatorSession getDefaultSession(CreatorState state) {
|
private CreatorSession getDefaultSession(CreatorState state) {
|
||||||
return new CreatorSession(contactGroupId, privateGroupId,
|
return new CreatorSession(contactGroupId, privateGroupId,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.db.Metadata;
|
|||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
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.Group;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
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 DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||||
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||||
|
private final ClientVersioningManager clientVersioningManager =
|
||||||
|
context.mock(ClientVersioningManager.class);
|
||||||
private final ContactGroupFactory contactGroupFactory =
|
private final ContactGroupFactory contactGroupFactory =
|
||||||
context.mock(ContactGroupFactory.class);
|
context.mock(ContactGroupFactory.class);
|
||||||
private final PrivateGroupFactory privateGroupFactory =
|
private final PrivateGroupFactory privateGroupFactory =
|
||||||
@@ -140,11 +143,11 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
MetadataParser metadataParser = context.mock(MetadataParser.class);
|
MetadataParser metadataParser = context.mock(MetadataParser.class);
|
||||||
MessageTracker messageTracker = context.mock(MessageTracker.class);
|
MessageTracker messageTracker = context.mock(MessageTracker.class);
|
||||||
groupInvitationManager =
|
groupInvitationManager = new GroupInvitationManagerImpl(db,
|
||||||
new GroupInvitationManagerImpl(db, clientHelper, metadataParser,
|
clientHelper, clientVersioningManager, metadataParser,
|
||||||
messageTracker, contactGroupFactory,
|
messageTracker, contactGroupFactory, privateGroupFactory,
|
||||||
privateGroupFactory, privateGroupManager, messageParser,
|
privateGroupManager, messageParser, sessionParser,
|
||||||
sessionParser, sessionEncoder, engineFactory);
|
sessionEncoder, engineFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -184,6 +187,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
CLIENT_VERSION, c);
|
CLIENT_VERSION, c);
|
||||||
will(returnValue(contactGroup));
|
will(returnValue(contactGroup));
|
||||||
oneOf(db).addGroup(txn, 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(),
|
oneOf(db).setGroupVisibility(txn, c.getId(), contactGroup.getId(),
|
||||||
SHARED);
|
SHARED);
|
||||||
oneOf(clientHelper)
|
oneOf(clientHelper)
|
||||||
|
|||||||
@@ -38,9 +38,10 @@ import static org.junit.Assert.assertTrue;
|
|||||||
public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||||
|
|
||||||
private final InviteeProtocolEngine engine =
|
private final InviteeProtocolEngine engine =
|
||||||
new InviteeProtocolEngine(db, clientHelper, privateGroupManager,
|
new InviteeProtocolEngine(db, clientHelper, clientVersioningManager,
|
||||||
privateGroupFactory, groupMessageFactory, identityManager,
|
privateGroupManager, privateGroupFactory,
|
||||||
messageParser, messageEncoder, messageTracker, clock);
|
groupMessageFactory, identityManager, messageParser,
|
||||||
|
messageEncoder, messageTracker, clock);
|
||||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
private final LocalAuthor localAuthor = getLocalAuthor();
|
||||||
|
|
||||||
private InviteeSession getDefaultSession(InviteeState state) {
|
private InviteeSession getDefaultSession(InviteeState state) {
|
||||||
@@ -238,6 +239,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testOnLeaveActionFromAccepted() throws Exception {
|
public void testOnLeaveActionFromAccepted() throws Exception {
|
||||||
expectSendLeaveMessage(false);
|
expectSendLeaveMessage(false);
|
||||||
|
expectSetPrivateGroupVisibility(INVISIBLE);
|
||||||
InviteeSession session = getDefaultSession(ACCEPTED);
|
InviteeSession session = getDefaultSession(ACCEPTED);
|
||||||
InviteeSession newSession = engine.onLeaveAction(txn, session);
|
InviteeSession newSession = engine.onLeaveAction(txn, session);
|
||||||
|
|
||||||
@@ -249,6 +251,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testOnLeaveActionFromJoined() throws Exception {
|
public void testOnLeaveActionFromJoined() throws Exception {
|
||||||
expectSendLeaveMessage(false);
|
expectSendLeaveMessage(false);
|
||||||
|
expectSetPrivateGroupVisibility(INVISIBLE);
|
||||||
InviteeSession session = getDefaultSession(JOINED);
|
InviteeSession session = getDefaultSession(JOINED);
|
||||||
InviteeSession newSession = engine.onLeaveAction(txn, session);
|
InviteeSession newSession = engine.onLeaveAction(txn, session);
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,10 @@ import static org.junit.Assert.assertTrue;
|
|||||||
public class PeerProtocolEngineTest extends AbstractProtocolEngineTest {
|
public class PeerProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||||
|
|
||||||
private final PeerProtocolEngine engine =
|
private final PeerProtocolEngine engine =
|
||||||
new PeerProtocolEngine(db, clientHelper, privateGroupManager,
|
new PeerProtocolEngine(db, clientHelper, clientVersioningManager,
|
||||||
privateGroupFactory, groupMessageFactory, identityManager,
|
privateGroupManager, privateGroupFactory,
|
||||||
messageParser, messageEncoder, messageTracker, clock);
|
groupMessageFactory, identityManager, messageParser,
|
||||||
|
messageEncoder, messageTracker, clock);
|
||||||
|
|
||||||
private PeerSession getDefaultSession(PeerState state) {
|
private PeerSession getDefaultSession(PeerState state) {
|
||||||
return new PeerSession(contactGroupId, privateGroupId,
|
return new PeerSession(contactGroupId, privateGroupId,
|
||||||
|
|||||||
Reference in New Issue
Block a user