diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java b/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java index 262d82c9b..940ee2f13 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/client/ClientHelper.java @@ -9,7 +9,7 @@ import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.Author; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.properties.TransportProperties; @@ -21,8 +21,6 @@ import java.security.GeneralSecurityException; import java.util.Collection; import java.util.Map; -import javax.annotation.Nullable; - @NotNullByDefault public interface ClientHelper { @@ -127,16 +125,14 @@ public interface ClientHelper { BdfDictionary properties) throws FormatException; /** - * Parse and validate the property dictionary of a Mailbox property update - * message. + * Parse and validate the elements of a Mailbox update message. * - * @return the properties for using the Mailbox, or null if there is no - * Mailbox available - * @throws FormatException if the properties are not valid + * @return the parsed update message + * @throws FormatException if the message elements are invalid */ - @Nullable - MailboxPropertiesUpdate parseAndValidateMailboxPropertiesUpdate( - BdfDictionary properties) throws FormatException; + MailboxUpdate parseAndValidateMailboxUpdate(BdfList clientSupports, + BdfList serverSupports, BdfDictionary properties) + throws FormatException; /** * Retrieves the contact ID from the group metadata of the given contact diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxSettingsManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxSettingsManager.java index e2a4c7110..3bd50d6c6 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxSettingsManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxSettingsManager.java @@ -7,6 +7,8 @@ import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import java.util.List; + import javax.annotation.Nullable; @NotNullByDefault @@ -49,7 +51,8 @@ public interface MailboxSettingsManager { * @param txn A read-write transaction * @param ownOnion Our new mailbox's onion (56 base32 chars) */ - void mailboxPaired(Transaction txn, String ownOnion) + void mailboxPaired(Transaction txn, String ownOnion, + List serverSupports) throws DbException; /** diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdate.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdate.java new file mode 100644 index 000000000..8ead367d3 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdate.java @@ -0,0 +1,28 @@ +package org.briarproject.bramble.api.mailbox; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.util.List; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@NotNullByDefault +public class MailboxUpdate { + + boolean hasMailbox; + private final List clientSupports; + + public MailboxUpdate(List clientSupports) { + this.hasMailbox = false; + this.clientSupports = clientSupports; + } + + public List getClientSupports() { + return clientSupports; + } + + public boolean hasMailbox() { + return hasMailbox; + } +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPropertyManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdateManager.java similarity index 67% rename from bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPropertyManager.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdateManager.java index b0ecf8fdd..92c0ebc78 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPropertyManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdateManager.java @@ -9,31 +9,31 @@ import org.briarproject.bramble.api.sync.ClientId; import javax.annotation.Nullable; @NotNullByDefault -public interface MailboxPropertyManager { +public interface MailboxUpdateManager { /** - * The unique ID of the mailbox property client. + * The unique ID of the mailbox update (properties) client. */ ClientId CLIENT_ID = new ClientId("org.briarproject.bramble.mailbox.properties"); /** - * The current major version of the mailbox property client. + * The current major version of the mailbox update (properties) client. */ - int MAJOR_VERSION = 0; + int MAJOR_VERSION = 1; /** - * The current minor version of the mailbox property client. + * The current minor version of the mailbox update (properties) client. */ int MINOR_VERSION = 0; /** - * The number of properties required for a (non-empty) update message. + * The number of properties required for an update message with a mailbox. */ int PROP_COUNT = 4; /** - * The required properties of a non-empty update message. + * The required properties of an update message with a mailbox. */ String PROP_KEY_ONION = "onion"; String PROP_KEY_AUTHTOKEN = "authToken"; @@ -57,11 +57,10 @@ public interface MailboxPropertyManager { */ String MSG_KEY_LOCAL = "local"; - @Nullable - MailboxPropertiesUpdate getLocalProperties(Transaction txn, ContactId c) + MailboxUpdate getLocalUpdate(Transaction txn, ContactId c) throws DbException; @Nullable - MailboxPropertiesUpdate getRemoteProperties(Transaction txn, ContactId c) + MailboxUpdate getRemoteUpdate(Transaction txn, ContactId c) throws DbException; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPropertiesUpdate.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdateWithMailbox.java similarity index 61% rename from bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPropertiesUpdate.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdateWithMailbox.java index fb37448dd..e84506dbd 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPropertiesUpdate.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxUpdateWithMailbox.java @@ -2,20 +2,27 @@ package org.briarproject.bramble.api.mailbox; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import java.util.List; + import javax.annotation.concurrent.Immutable; @Immutable @NotNullByDefault -public class MailboxPropertiesUpdate { - +public class MailboxUpdateWithMailbox extends MailboxUpdate { + private final List serverSupports; private final String onion; private final MailboxAuthToken authToken; private final MailboxFolderId inboxId; private final MailboxFolderId outboxId; - public MailboxPropertiesUpdate(String onion, + public MailboxUpdateWithMailbox(List clientSupports, + List serverSupports, String onion, MailboxAuthToken authToken, MailboxFolderId inboxId, - MailboxFolderId outboxId) { + MailboxFolderId outboxId + ) { + super(clientSupports); + this.hasMailbox = true; + this.serverSupports = serverSupports; this.onion = onion; this.authToken = authToken; this.inboxId = inboxId; @@ -38,4 +45,7 @@ public class MailboxPropertiesUpdate { return outboxId; } + public List getServerSupports() { + return serverSupports; + } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/RemoteMailboxPropertiesUpdateEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/RemoteMailboxPropertiesUpdateEvent.java deleted file mode 100644 index 3d63acd37..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/RemoteMailboxPropertiesUpdateEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.briarproject.bramble.api.mailbox; - -import org.briarproject.bramble.api.contact.ContactId; -import org.briarproject.bramble.api.event.Event; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * An event that is broadcast when {@link MailboxPropertiesUpdate} are received - * from a contact. - */ -@Immutable -@NotNullByDefault -public class RemoteMailboxPropertiesUpdateEvent extends Event { - - private final ContactId contactId; - @Nullable - private final MailboxPropertiesUpdate mailboxPropertiesUpdate; - - public RemoteMailboxPropertiesUpdateEvent(ContactId contactId, - @Nullable MailboxPropertiesUpdate mailboxPropertiesUpdate) { - this.contactId = contactId; - this.mailboxPropertiesUpdate = mailboxPropertiesUpdate; - } - - public ContactId getContact() { - return contactId; - } - - @Nullable - public MailboxPropertiesUpdate getMailboxPropertiesUpdate() { - return mailboxPropertiesUpdate; - } -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/RemoteMailboxUpdateEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/RemoteMailboxUpdateEvent.java new file mode 100644 index 000000000..f213eb27b --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/RemoteMailboxUpdateEvent.java @@ -0,0 +1,33 @@ +package org.briarproject.bramble.api.mailbox; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.event.Event; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import javax.annotation.concurrent.Immutable; + +/** + * An event that is broadcast when {@link MailboxUpdate} are received + * from a contact. + */ +@Immutable +@NotNullByDefault +public class RemoteMailboxUpdateEvent extends Event { + + private final ContactId contactId; + private final MailboxUpdate mailboxUpdate; + + public RemoteMailboxUpdateEvent(ContactId contactId, + MailboxUpdate mailboxUpdate) { + this.contactId = contactId; + this.mailboxUpdate = mailboxUpdate; + } + + public ContactId getContact() { + return contactId; + } + + public MailboxUpdate getMailboxUpdate() { + return mailboxUpdate; + } +} diff --git a/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java b/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java index 0f4a4748d..0b9c646a4 100644 --- a/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java +++ b/bramble-api/src/test/java/org/briarproject/bramble/test/TestUtils.java @@ -21,7 +21,8 @@ import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.sync.ClientId; @@ -280,20 +281,27 @@ public class TestUtils { asList(optionalTests.split(",")).contains(testClass.getName()); } - public static boolean mailboxPropertiesUpdateEqual( - @Nullable MailboxPropertiesUpdate a, - @Nullable MailboxPropertiesUpdate b) { + public static boolean mailboxUpdateEqual(@Nullable MailboxUpdate a, + @Nullable MailboxUpdate b) { if (a == null || b == null) { return a == b; } - return a.getOnion().equals(b.getOnion()) && - a.getAuthToken().equals(b.getAuthToken()) && - a.getInboxId().equals(b.getInboxId()) && - a.getOutboxId().equals(b.getOutboxId()); + if (!a.hasMailbox() && !b.hasMailbox()) { + return a.getClientSupports().equals(b.getClientSupports()); + } else if (a.hasMailbox() && b.hasMailbox()) { + MailboxUpdateWithMailbox am = (MailboxUpdateWithMailbox) a; + MailboxUpdateWithMailbox bm = (MailboxUpdateWithMailbox) b; + return am.getClientSupports().equals(bm.getClientSupports()) && + am.getServerSupports().equals(bm.getServerSupports()) && + am.getOnion().equals(bm.getOnion()) && + am.getAuthToken().equals(bm.getAuthToken()) && + am.getInboxId().equals(bm.getInboxId()) && + am.getOutboxId().equals(bm.getOutboxId()); + } + return false; } - public static boolean mailboxPropertiesEqual( - @Nullable MailboxProperties a, + public static boolean mailboxPropertiesEqual(@Nullable MailboxProperties a, @Nullable MailboxProperties b) { if (a == null || b == null) { return a == b; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java index bab9a18e6..7baf56f56 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/client/ClientHelperImpl.java @@ -25,7 +25,9 @@ import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFolderId; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; +import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.properties.TransportProperties; @@ -39,12 +41,13 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; +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 javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import javax.inject.Inject; @@ -52,12 +55,12 @@ import static org.briarproject.bramble.api.client.ContactGroupConstants.GROUP_KE import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_COUNT; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_AUTHTOKEN; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_INBOXID; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_ONION; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_OUTBOXID; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_ONION_LENGTH; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_COUNT; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_AUTHTOKEN; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_INBOXID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_ONION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_OUTBOXID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_ONION_LENGTH; import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT; import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH; import static org.briarproject.bramble.util.ValidationUtils.checkLength; @@ -412,11 +415,28 @@ class ClientHelperImpl implements ClientHelper { } @Override - @Nullable - public MailboxPropertiesUpdate parseAndValidateMailboxPropertiesUpdate( - BdfDictionary properties) throws FormatException { + public MailboxUpdate parseAndValidateMailboxUpdate(BdfList clientSupports, + BdfList serverSupports, BdfDictionary properties) + throws FormatException { + List clientSupportsList = + getMailboxVersionList(clientSupports); + List serverSupportsList = + getMailboxVersionList(serverSupports); + + // We must always learn what Mailbox API version(s) the client supports + if (clientSupports.isEmpty()) { + throw new FormatException(); + } if (properties.isEmpty()) { - return null; + // No mailbox -- cannot claim to support any API versions! + if (!serverSupports.isEmpty()) { + throw new FormatException(); + } + return new MailboxUpdate(clientSupportsList); + } + // Mailbox must be accompanied by the Mailbox API version(s) it supports + if (serverSupports.isEmpty()) { + throw new FormatException(); } // Accepting more props than we need, for forward compatibility if (properties.size() < PROP_COUNT) { @@ -435,9 +455,23 @@ class ClientHelperImpl implements ClientHelper { checkLength(inboxId, UniqueId.LENGTH); byte[] outboxId = properties.getRaw(PROP_KEY_OUTBOXID); checkLength(outboxId, UniqueId.LENGTH); - return new MailboxPropertiesUpdate(onion, - new MailboxAuthToken(authToken), new MailboxFolderId(inboxId), - new MailboxFolderId(outboxId)); + return new MailboxUpdateWithMailbox(clientSupportsList, + serverSupportsList, onion, new MailboxAuthToken(authToken), + new MailboxFolderId(inboxId), new MailboxFolderId(outboxId)); + } + + private List getMailboxVersionList(BdfList bdfList) + throws FormatException { + List list = new ArrayList<>(); + for (int i = 0; i < bdfList.size(); i++) { + BdfList element = bdfList.getList(i); + if (element.size() != 2) { + throw new FormatException(); + } + list.add(new MailboxVersion(element.getLong(0).intValue(), + element.getLong(1).intValue())); + } + return list; } @Override diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java index 9596ce2f3..37b6ca042 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java @@ -7,6 +7,8 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFileId; import org.briarproject.bramble.api.mailbox.MailboxFolderId; import org.briarproject.bramble.api.mailbox.MailboxProperties; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; +import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.io.File; @@ -17,9 +19,18 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; +import static java.util.Collections.singletonList; + @NotNullByDefault interface MailboxApi { + /** + * Mailbox API versions that we support as a client. This is reported to our + * contacts by {@link MailboxUpdateManager}. + */ + List CLIENT_SUPPORTS = singletonList( + new MailboxVersion(1, 0)); + /** * Sets up the mailbox with the setup token. * diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java index a89065011..e1ad79555 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java @@ -5,8 +5,8 @@ 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.mailbox.MailboxManager; -import org.briarproject.bramble.api.mailbox.MailboxPropertyManager; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; import org.briarproject.bramble.api.sync.validation.ValidationManager; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.versioning.ClientVersioningManager; @@ -17,18 +17,18 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.CLIENT_ID; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MAJOR_VERSION; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MINOR_VERSION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MINOR_VERSION; @Module public class MailboxModule { public static class EagerSingletons { @Inject - MailboxPropertyValidator mailboxPropertyValidator; + MailboxUpdateValidator mailboxUpdateValidator; @Inject - MailboxPropertyManager mailboxPropertyManager; + MailboxUpdateManager mailboxUpdateManager; } @Provides @@ -56,10 +56,10 @@ public class MailboxModule { @Provides @Singleton - MailboxPropertyValidator provideMailboxPropertyValidator( + MailboxUpdateValidator provideMailboxUpdateValidator( ValidationManager validationManager, ClientHelper clientHelper, MetadataEncoder metadataEncoder, Clock clock) { - MailboxPropertyValidator validator = new MailboxPropertyValidator( + MailboxUpdateValidator validator = new MailboxUpdateValidator( clientHelper, metadataEncoder, clock); validationManager.registerMessageValidator(CLIENT_ID, MAJOR_VERSION, validator); @@ -68,19 +68,19 @@ public class MailboxModule { @Provides @Singleton - MailboxPropertyManager provideMailboxPropertyManager( + MailboxUpdateManager provideMailboxUpdateManager( LifecycleManager lifecycleManager, ValidationManager validationManager, ContactManager contactManager, ClientVersioningManager clientVersioningManager, MailboxSettingsManager mailboxSettingsManager, - MailboxPropertyManagerImpl mailboxPropertyManager) { - lifecycleManager.registerOpenDatabaseHook(mailboxPropertyManager); + MailboxUpdateManagerImpl mailboxUpdateManager) { + lifecycleManager.registerOpenDatabaseHook(mailboxUpdateManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, - mailboxPropertyManager); - contactManager.registerContactHook(mailboxPropertyManager); + mailboxUpdateManager); + contactManager.registerContactHook(mailboxUpdateManager); clientVersioningManager.registerClient(CLIENT_ID, MAJOR_VERSION, - MINOR_VERSION, mailboxPropertyManager); - mailboxSettingsManager.registerMailboxHook(mailboxPropertyManager); - return mailboxPropertyManager; + MINOR_VERSION, mailboxUpdateManager); + mailboxSettingsManager.registerMailboxHook(mailboxUpdateManager); + return mailboxUpdateManager; } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskFactoryImpl.java index 1bab17766..c688fc511 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskFactoryImpl.java @@ -4,8 +4,8 @@ import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.event.EventExecutor; import org.briarproject.bramble.api.mailbox.MailboxPairingTask; -import org.briarproject.bramble.api.mailbox.MailboxPropertyManager; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.system.Clock; @@ -24,7 +24,7 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory { private final Clock clock; private final MailboxApi api; private final MailboxSettingsManager mailboxSettingsManager; - private final MailboxPropertyManager mailboxPropertyManager; + private final MailboxUpdateManager mailboxUpdateManager; @Inject MailboxPairingTaskFactoryImpl( @@ -34,20 +34,20 @@ class MailboxPairingTaskFactoryImpl implements MailboxPairingTaskFactory { Clock clock, MailboxApi api, MailboxSettingsManager mailboxSettingsManager, - MailboxPropertyManager mailboxPropertyManager) { + MailboxUpdateManager mailboxUpdateManager) { this.eventExecutor = eventExecutor; this.db = db; this.crypto = crypto; this.clock = clock; this.api = api; this.mailboxSettingsManager = mailboxSettingsManager; - this.mailboxPropertyManager = mailboxPropertyManager; + this.mailboxUpdateManager = mailboxUpdateManager; } @Override public MailboxPairingTask createPairingTask(String qrCodePayload) { return new MailboxPairingTaskImpl(qrCodePayload, eventExecutor, db, crypto, clock, api, mailboxSettingsManager, - mailboxPropertyManager); + mailboxUpdateManager); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java index 7dabeaa2c..4d7eea749 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java @@ -11,9 +11,9 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxPairingState; import org.briarproject.bramble.api.mailbox.MailboxPairingTask; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; -import org.briarproject.bramble.api.mailbox.MailboxPropertyManager; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.mailbox.MailboxApi.ApiException; @@ -51,7 +51,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { private final Clock clock; private final MailboxApi api; private final MailboxSettingsManager mailboxSettingsManager; - private final MailboxPropertyManager mailboxPropertyManager; + private final MailboxUpdateManager mailboxUpdateManager; private final Object lock = new Object(); @GuardedBy("lock") @@ -68,7 +68,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { Clock clock, MailboxApi api, MailboxSettingsManager mailboxSettingsManager, - MailboxPropertyManager mailboxPropertyManager) { + MailboxUpdateManager mailboxUpdateManager) { this.payload = payload; this.eventExecutor = eventExecutor; this.db = db; @@ -76,7 +76,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { this.clock = clock; this.api = api; this.mailboxSettingsManager = mailboxSettingsManager; - this.mailboxPropertyManager = mailboxPropertyManager; + this.mailboxUpdateManager = mailboxUpdateManager; state = new MailboxPairingState.QrCodeReceived(); } @@ -125,9 +125,9 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { // timers for contacts who doesn't have their own mailbox. This way, // data stranded on our old mailbox will be re-uploaded to our new. for (Contact c : db.getContacts(txn)) { - MailboxPropertiesUpdate remoteProps = mailboxPropertyManager - .getRemoteProperties(txn, c.getId()); - if (remoteProps == null) { + MailboxUpdate update = mailboxUpdateManager.getRemoteUpdate( + txn, c.getId()); + if (update == null || !update.hasMailbox()) { db.resetUnackedMessagesToSend(txn, c.getId()); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSettingsManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSettingsManagerImpl.java index ae705784e..eee2a49c2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSettingsManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxSettingsManagerImpl.java @@ -91,7 +91,7 @@ class MailboxSettingsManagerImpl implements MailboxSettingsManager { s.putIntArray(SETTINGS_KEY_SERVER_SUPPORTS, ints); settingsManager.mergeSettings(txn, s, SETTINGS_NAMESPACE); for (MailboxHook hook : hooks) { - hook.mailboxPaired(txn, p.getOnion()); + hook.mailboxPaired(txn, p.getOnion(), p.getServerSupports()); } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPropertyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxUpdateManagerImpl.java similarity index 68% rename from bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPropertyManagerImpl.java rename to bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxUpdateManagerImpl.java index c1db5697d..7cbaf2fb9 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPropertyManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxUpdateManagerImpl.java @@ -18,11 +18,13 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFolderId; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; -import org.briarproject.bramble.api.mailbox.MailboxPropertyManager; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager.MailboxHook; -import org.briarproject.bramble.api.mailbox.RemoteMailboxPropertiesUpdateEvent; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; +import org.briarproject.bramble.api.mailbox.MailboxVersion; +import org.briarproject.bramble.api.mailbox.RemoteMailboxUpdateEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; @@ -35,6 +37,7 @@ import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager.ClientVersioningHook; +import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -42,9 +45,10 @@ import javax.annotation.Nullable; import javax.inject.Inject; import static org.briarproject.bramble.api.sync.validation.IncomingMessageHook.DeliveryAction.ACCEPT_DO_NOT_SHARE; +import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; @NotNullByDefault -class MailboxPropertyManagerImpl implements MailboxPropertyManager, +class MailboxUpdateManagerImpl implements MailboxUpdateManager, OpenDatabaseHook, ContactHook, ClientVersioningHook, IncomingMessageHook, MailboxHook { @@ -59,7 +63,7 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager, private final Group localGroup; @Inject - MailboxPropertyManagerImpl(DatabaseComponent db, ClientHelper clientHelper, + MailboxUpdateManagerImpl(DatabaseComponent db, ClientHelper clientHelper, ClientVersioningManager clientVersioningManager, MetadataParser metadataParser, ContactGroupFactory contactGroupFactory, Clock clock, @@ -100,11 +104,15 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager, db.setGroupVisibility(txn, c.getId(), g.getId(), client); // Attach the contact ID to the group clientHelper.setContactId(txn, g.getId(), c.getId()); - // If we are paired, create and send props to the newly added contact MailboxProperties ownProps = mailboxSettingsManager.getOwnMailboxProperties(txn); if (ownProps != null) { - createAndSendProperties(txn, c, ownProps.getOnion()); + // We are paired, create and send props to the newly added contact + createAndSendUpdateWithMailbox(txn, c, ownProps.getServerSupports(), + ownProps.getOnion()); + } else { + // Not paired, but we still want to get our clientSupports sent + sendUpdateNoMailbox(txn, c); } } @@ -114,17 +122,18 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager, } @Override - public void mailboxPaired(Transaction txn, String ownOnion) + public void mailboxPaired(Transaction txn, String ownOnion, + List serverSupports) throws DbException { for (Contact c : db.getContacts(txn)) { - createAndSendProperties(txn, c, ownOnion); + createAndSendUpdateWithMailbox(txn, c, serverSupports, ownOnion); } } @Override public void mailboxUnpaired(Transaction txn) throws DbException { for (Contact c : db.getContacts(txn)) { - sendEmptyProperties(txn, c); + sendUpdateNoMailbox(txn, c); } } @@ -156,8 +165,8 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager, } ContactId c = clientHelper.getContactId(txn, m.getGroupId()); BdfList body = clientHelper.getMessageAsList(txn, m.getId()); - MailboxPropertiesUpdate p = parseProperties(body); - txn.attach(new RemoteMailboxPropertiesUpdateEvent(c, p)); + MailboxUpdate u = parseUpdate(body); + txn.attach(new RemoteMailboxUpdateEvent(c, u)); // Reset message retransmission timers for the contact. Avoiding // messages getting stranded: // - on our mailbox, if they now have a mailbox but didn't before @@ -171,70 +180,79 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager, } @Override - @Nullable - public MailboxPropertiesUpdate getLocalProperties(Transaction txn, - ContactId c) throws DbException { - return getProperties(txn, db.getContact(txn, c), true); + public MailboxUpdate getLocalUpdate(Transaction txn, ContactId c) + throws DbException { + MailboxUpdate local = getUpdate(txn, db.getContact(txn, c), true); + // An update (with or without mailbox) is created when contact is added + if (local == null) { + throw new DbException(); + } + return local; } @Override @Nullable - public MailboxPropertiesUpdate getRemoteProperties(Transaction txn, - ContactId c) throws DbException { - return getProperties(txn, db.getContact(txn, c), false); + public MailboxUpdate getRemoteUpdate(Transaction txn, ContactId c) throws + DbException { + return getUpdate(txn, db.getContact(txn, c), false); } /** * Creates and sends an update message to the given contact. The message - * holds our own mailbox's onion, and generated unique properties. All of - * which the contact needs to communicate with our Mailbox. + * holds our own mailbox's onion, generated unique properties, and lists of + * supported Mailbox API version(s). All of which the contact needs to + * communicate with our Mailbox. */ - private void createAndSendProperties(Transaction txn, - Contact c, String ownOnion) throws DbException { - MailboxPropertiesUpdate p = new MailboxPropertiesUpdate(ownOnion, + private void createAndSendUpdateWithMailbox(Transaction txn, Contact c, + List serverSupports, String ownOnion) + throws DbException { + MailboxUpdate u = new MailboxUpdateWithMailbox( + CLIENT_SUPPORTS, serverSupports, ownOnion, new MailboxAuthToken(crypto.generateUniqueId().getBytes()), new MailboxFolderId(crypto.generateUniqueId().getBytes()), new MailboxFolderId(crypto.generateUniqueId().getBytes())); Group g = getContactGroup(c); - storeMessageReplaceLatest(txn, g.getId(), p); + storeMessageReplaceLatest(txn, g.getId(), u); } /** - * Sends an empty update message to the given contact. The empty update - * indicates for the receiving contact that we no longer have a Mailbox that - * they can use. + * Sends an update message with empty properties to the given contact. The + * empty update indicates for the receiving contact that we don't have any + * Mailbox that they can use. It still includes the list of Mailbox API + * version(s) that we support as a client. */ - private void sendEmptyProperties(Transaction txn, Contact c) + private void sendUpdateNoMailbox(Transaction txn, Contact c) throws DbException { Group g = getContactGroup(c); - storeMessageReplaceLatest(txn, g.getId(), null); + MailboxUpdate u = new MailboxUpdate(CLIENT_SUPPORTS); + storeMessageReplaceLatest(txn, g.getId(), u); } @Nullable - private MailboxPropertiesUpdate getProperties(Transaction txn, - Contact c, boolean local) throws DbException { - MailboxPropertiesUpdate p = null; + private MailboxUpdate getUpdate(Transaction txn, Contact c, boolean local) + throws DbException { + MailboxUpdate u = null; Group g = getContactGroup(c); try { LatestUpdate latest = findLatest(txn, g.getId(), local); if (latest != null) { BdfList body = clientHelper.getMessageAsList(txn, latest.messageId); - p = parseProperties(body); + u = parseUpdate(body); } } catch (FormatException e) { throw new DbException(e); } - return p; + return u; } private void storeMessageReplaceLatest(Transaction txn, GroupId g, - @Nullable MailboxPropertiesUpdate p) throws DbException { + MailboxUpdate u) throws DbException { try { LatestUpdate latest = findLatest(txn, g, true); long version = latest == null ? 1 : latest.version + 1; Message m = clientHelper.createMessage(g, clock.currentTimeMillis(), - encodeProperties(version, p)); + encodeProperties(version, u)); BdfDictionary meta = new BdfDictionary(); meta.put(MSG_KEY_VERSION, version); meta.put(MSG_KEY_LOCAL, true); @@ -266,23 +284,36 @@ class MailboxPropertyManagerImpl implements MailboxPropertyManager, return null; } - private BdfList encodeProperties(long version, - @Nullable MailboxPropertiesUpdate p) { + private BdfList encodeProperties(long version, MailboxUpdate u) { BdfDictionary dict = new BdfDictionary(); - if (p != null) { - dict.put(PROP_KEY_ONION, p.getOnion()); - dict.put(PROP_KEY_AUTHTOKEN, p.getAuthToken().getBytes()); - dict.put(PROP_KEY_INBOXID, p.getInboxId().getBytes()); - dict.put(PROP_KEY_OUTBOXID, p.getOutboxId().getBytes()); + BdfList serverSupports = new BdfList(); + if (u.hasMailbox()) { + MailboxUpdateWithMailbox um = (MailboxUpdateWithMailbox) u; + serverSupports = encodeSupportsList(um.getServerSupports()); + dict.put(PROP_KEY_ONION, um.getOnion()); + dict.put(PROP_KEY_AUTHTOKEN, um.getAuthToken().getBytes()); + dict.put(PROP_KEY_INBOXID, um.getInboxId().getBytes()); + dict.put(PROP_KEY_OUTBOXID, um.getOutboxId().getBytes()); } - return BdfList.of(version, dict); + return BdfList.of(version, encodeSupportsList(u.getClientSupports()), + serverSupports, dict); } - @Nullable - private MailboxPropertiesUpdate parseProperties(BdfList body) + private BdfList encodeSupportsList(List supportsList) { + BdfList supports = new BdfList(); + for (MailboxVersion version : supportsList) { + supports.add(BdfList.of(version.getMajor(), version.getMinor())); + } + return supports; + } + + private MailboxUpdate parseUpdate(BdfList body) throws FormatException { - BdfDictionary dict = body.getDictionary(1); - return clientHelper.parseAndValidateMailboxPropertiesUpdate(dict); + BdfList clientSupports = body.getList(1); + BdfList serverSupports = body.getList(2); + BdfDictionary dict = body.getDictionary(3); + return clientHelper.parseAndValidateMailboxUpdate(clientSupports, + serverSupports, dict); } private Group getContactGroup(Contact c) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPropertyValidator.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxUpdateValidator.java similarity index 68% rename from bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPropertyValidator.java rename to bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxUpdateValidator.java index 32b581fc0..e717f911f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPropertyValidator.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxUpdateValidator.java @@ -15,15 +15,15 @@ import org.briarproject.bramble.api.system.Clock; import javax.annotation.concurrent.Immutable; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MSG_KEY_LOCAL; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MSG_KEY_VERSION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_LOCAL; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_VERSION; import static org.briarproject.bramble.util.ValidationUtils.checkSize; @Immutable @NotNullByDefault -class MailboxPropertyValidator extends BdfMessageValidator { +class MailboxUpdateValidator extends BdfMessageValidator { - MailboxPropertyValidator(ClientHelper clientHelper, + MailboxUpdateValidator(ClientHelper clientHelper, MetadataEncoder metadataEncoder, Clock clock) { super(clientHelper, metadataEncoder, clock); } @@ -31,14 +31,19 @@ class MailboxPropertyValidator extends BdfMessageValidator { @Override protected BdfMessageContext validateMessage(Message m, Group g, BdfList body) throws InvalidMessageException, FormatException { - // Version, properties - checkSize(body, 2); + // Version, Properties, clientSupports, serverSupports + checkSize(body, 4); // Version long version = body.getLong(0); if (version < 0) throw new FormatException(); + // clientSupports + BdfList clientSupports = body.getList(1); + // serverSupports + BdfList serverSupports = body.getList(2); // Properties - BdfDictionary dictionary = body.getDictionary(1); - clientHelper.parseAndValidateMailboxPropertiesUpdate(dictionary); + BdfDictionary dictionary = body.getDictionary(3); + clientHelper.parseAndValidateMailboxUpdate(clientSupports, + serverSupports, dictionary); // Return the metadata BdfDictionary meta = new BdfDictionary(); meta.put(MSG_KEY_VERSION, version); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java index 6214d67c5..9e316b07d 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/client/ClientHelperImplTest.java @@ -23,7 +23,9 @@ import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFolderId; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; +import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.MessageFactory; @@ -41,24 +43,25 @@ import java.util.HashMap; import java.util.Map; import java.util.Random; +import static java.util.Collections.singletonList; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_AUTHTOKEN; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_INBOXID; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_ONION; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_OUTBOXID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_AUTHTOKEN; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_INBOXID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_ONION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_OUTBOXID; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getSignaturePrivateKey; import static org.briarproject.bramble.test.TestUtils.getSignaturePublicKey; -import static org.briarproject.bramble.test.TestUtils.mailboxPropertiesUpdateEqual; +import static org.briarproject.bramble.test.TestUtils.mailboxUpdateEqual; import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -95,24 +98,34 @@ public class ClientHelperImplTest extends BrambleMockTestCase { messageFactory, bdfReaderFactory, bdfWriterFactory, metadataParser, metadataEncoder, cryptoComponent, authorFactory); - private final MailboxPropertiesUpdate validMailboxPropsUpdate; + private final MailboxUpdateWithMailbox validMailboxUpdateWithMailbox; + private final BdfList emptyClientSupports; + private final BdfList someClientSupports; + private final BdfList emptyServerSupports; + private final BdfList someServerSupports; public ClientHelperImplTest() { - validMailboxPropsUpdate = new MailboxPropertiesUpdate( + emptyClientSupports = new BdfList(); + someClientSupports = BdfList.of(BdfList.of(1, 0)); + emptyServerSupports = new BdfList(); + someServerSupports = BdfList.of(BdfList.of(1, 0)); + validMailboxUpdateWithMailbox = new MailboxUpdateWithMailbox( + singletonList(new MailboxVersion(1, 0)), + singletonList(new MailboxVersion(1, 0)), "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd", new MailboxAuthToken(getRandomId()), new MailboxFolderId(getRandomId()), new MailboxFolderId(getRandomId())); } - private BdfDictionary getValidMailboxPropsUpdateDict() { + private BdfDictionary getValidMailboxUpdateWithMailboxDict() { BdfDictionary dict = new BdfDictionary(); - dict.put(PROP_KEY_ONION, validMailboxPropsUpdate.getOnion()); - dict.put(PROP_KEY_AUTHTOKEN, validMailboxPropsUpdate.getAuthToken() + dict.put(PROP_KEY_ONION, validMailboxUpdateWithMailbox.getOnion()); + dict.put(PROP_KEY_AUTHTOKEN, validMailboxUpdateWithMailbox + .getAuthToken().getBytes()); + dict.put(PROP_KEY_INBOXID, validMailboxUpdateWithMailbox.getInboxId() .getBytes()); - dict.put(PROP_KEY_INBOXID, validMailboxPropsUpdate.getInboxId() - .getBytes()); - dict.put(PROP_KEY_OUTBOXID, validMailboxPropsUpdate.getOutboxId() + dict.put(PROP_KEY_OUTBOXID, validMailboxUpdateWithMailbox.getOutboxId() .getBytes()); return dict; } @@ -546,94 +559,151 @@ public class ClientHelperImplTest extends BrambleMockTestCase { }}); } - @Test - public void testParseEmptyMailboxPropsUpdate() throws Exception { + @Test(expected = FormatException.class) + public void testRejectsMailboxUpdateWithEmptyClientSupports() + throws Exception { BdfDictionary emptyPropsDict = new BdfDictionary(); - MailboxPropertiesUpdate parsedProps = clientHelper - .parseAndValidateMailboxPropertiesUpdate(emptyPropsDict); - assertNull(parsedProps); + clientHelper.parseAndValidateMailboxUpdate(emptyClientSupports, + emptyServerSupports, emptyPropsDict + ); } @Test - public void testParseValidMailboxPropsUpdate() throws Exception { - MailboxPropertiesUpdate parsedProps = clientHelper - .parseAndValidateMailboxPropertiesUpdate( - getValidMailboxPropsUpdateDict()); - assertTrue(mailboxPropertiesUpdateEqual(validMailboxPropsUpdate, - parsedProps)); + public void testParseMailboxUpdateNoMailbox() throws Exception { + BdfDictionary emptyPropsDict = new BdfDictionary(); + MailboxUpdate parsedUpdate = clientHelper.parseAndValidateMailboxUpdate( + someClientSupports, emptyServerSupports, emptyPropsDict); + assertFalse(parsedUpdate.hasMailbox()); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateOnionNotDecodable() + public void testRejectsMailboxUpdateNoMailboxWithSomeServerSupports() throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + BdfDictionary emptyPropsDict = new BdfDictionary(); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, emptyPropsDict); + } + + @Test(expected = FormatException.class) + public void testRejectsMailboxUpdateShortSupports() throws Exception { + clientHelper.parseAndValidateMailboxUpdate(BdfList.of(BdfList.of(1)), + emptyServerSupports, new BdfDictionary()); + } + + @Test(expected = FormatException.class) + public void testRejectsMailboxUpdateLongSupports() throws Exception { + clientHelper.parseAndValidateMailboxUpdate( + BdfList.of(BdfList.of(1, 0, 0)), emptyServerSupports, + new BdfDictionary()); + } + + @Test(expected = FormatException.class) + public void testRejectsMailboxUpdateNonIntSupports() throws Exception { + clientHelper.parseAndValidateMailboxUpdate( + BdfList.of(BdfList.of(1, "0")), emptyServerSupports, + new BdfDictionary() + ); + } + + @Test(expected = FormatException.class) + public void testRejectsMailboxUpdateNonListSupports() throws Exception { + clientHelper.parseAndValidateMailboxUpdate( + BdfList.of("non-list"), emptyServerSupports, + new BdfDictionary()); + } + + @Test + public void testParseValidMailboxUpdateWithMailbox() throws Exception { + MailboxUpdate parsedUpdate = clientHelper.parseAndValidateMailboxUpdate( + someClientSupports, someServerSupports, + getValidMailboxUpdateWithMailboxDict()); + assertTrue( + mailboxUpdateEqual(validMailboxUpdateWithMailbox, + parsedUpdate)); + } + + @Test(expected = FormatException.class) + public void rejectsMailboxUpdateWithEmptyServerSupports() throws Exception { + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + emptyServerSupports, getValidMailboxUpdateWithMailboxDict()); + } + + @Test(expected = FormatException.class) + public void testRejectsMailboxUpdateOnionNotDecodable() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); String badOnion = "!" + propsDict.getString(PROP_KEY_ONION) .substring(1); propsDict.put(PROP_KEY_ONION, badOnion); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + emptyServerSupports, propsDict); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateOnionWrongLength() - throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateOnionWrongLength() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); String tooLongOnion = propsDict.getString(PROP_KEY_ONION) + "!"; propsDict.put(PROP_KEY_ONION, tooLongOnion); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + emptyServerSupports, propsDict + ); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateInboxIdWrongLength() - throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateInboxIdWrongLength() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.put(PROP_KEY_INBOXID, getRandomBytes(UniqueId.LENGTH + 1)); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateOutboxIdWrongLength() - throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateOutboxIdWrongLength() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.put(PROP_KEY_OUTBOXID, getRandomBytes(UniqueId.LENGTH + 1)); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateAuthTokenWrongLength() + public void testRejectsMailboxUpdateAuthTokenWrongLength() throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.put(PROP_KEY_AUTHTOKEN, getRandomBytes(UniqueId.LENGTH + 1)); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateMissingOnion() throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateMissingOnion() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.remove(PROP_KEY_ONION); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict + ); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateMissingAuthToken() - throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateMissingAuthToken() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.remove(PROP_KEY_AUTHTOKEN); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateMissingInboxId() throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateMissingInboxId() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.remove(PROP_KEY_INBOXID); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict); } @Test(expected = FormatException.class) - public void testRejectsMailboxPropsUpdateMissingOutboxId() - throws Exception { - BdfDictionary propsDict = getValidMailboxPropsUpdateDict(); + public void testRejectsMailboxUpdateMissingOutboxId() throws Exception { + BdfDictionary propsDict = getValidMailboxUpdateWithMailboxDict(); propsDict.remove(PROP_KEY_OUTBOXID); - clientHelper.parseAndValidateMailboxPropertiesUpdate(propsDict); + clientHelper.parseAndValidateMailboxUpdate(someClientSupports, + someServerSupports, propsDict); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java index 70d6477a7..be7555d90 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java @@ -9,8 +9,9 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxPairingState; import org.briarproject.bramble.api.mailbox.MailboxPairingTask; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.api.mailbox.MailboxPropertyManager; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.test.BrambleMockTestCase; @@ -24,10 +25,11 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.ArrayList; -import java.util.Collections; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; +import static java.util.Collections.singletonList; +import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; @@ -47,11 +49,11 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { private final MailboxApi api = context.mock(MailboxApi.class); private final MailboxSettingsManager mailboxSettingsManager = context.mock(MailboxSettingsManager.class); - private final MailboxPropertyManager mailboxPropertyManager = - context.mock(MailboxPropertyManager.class); + private final MailboxUpdateManager mailboxUpdateManager = + context.mock(MailboxUpdateManager.class); private final MailboxPairingTaskFactory factory = new MailboxPairingTaskFactoryImpl(executor, db, crypto, clock, api, - mailboxSettingsManager, mailboxPropertyManager); + mailboxSettingsManager, mailboxUpdateManager); private final String onion = getRandomString(56); private final byte[] onionBytes = getRandomBytes(32); @@ -105,16 +107,17 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { }}); Contact contact1 = getContact(); Transaction txn = new Transaction(null, false); + MailboxUpdate updateNoMailbox = new MailboxUpdate(CLIENT_SUPPORTS); context.checking(new DbExpectations() {{ oneOf(db).transaction(with(false), withDbRunnable(txn)); oneOf(mailboxSettingsManager).setOwnMailboxProperties( with(txn), with(matches(ownerProperties))); oneOf(mailboxSettingsManager).recordSuccessfulConnection(txn, time); oneOf(db).getContacts(txn); - will(returnValue(Collections.singletonList(contact1))); - oneOf(mailboxPropertyManager).getRemoteProperties(txn, + will(returnValue(singletonList(contact1))); + oneOf(mailboxUpdateManager).getRemoteUpdate(txn, contact1.getId()); - will(returnValue(null)); + will(returnValue(updateNoMailbox)); oneOf(db).resetUnackedMessagesToSend(txn, contact1.getId()); }}); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPropertyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxUpdateManagerImplTest.java similarity index 69% rename from bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPropertyManagerImplTest.java rename to bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxUpdateManagerImplTest.java index fd2c6ab22..0301f4dd0 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPropertyManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxUpdateManagerImplTest.java @@ -14,9 +14,11 @@ import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFolderId; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; import org.briarproject.bramble.api.mailbox.MailboxSettingsManager; -import org.briarproject.bramble.api.mailbox.RemoteMailboxPropertiesUpdateEvent; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; +import org.briarproject.bramble.api.mailbox.MailboxVersion; +import org.briarproject.bramble.api.mailbox.RemoteMailboxUpdateEvent; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.Message; @@ -27,34 +29,34 @@ import org.briarproject.bramble.test.BrambleMockTestCase; import org.jmock.Expectations; import org.junit.Test; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static java.util.Collections.singletonList; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.CLIENT_ID; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MAJOR_VERSION; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MSG_KEY_LOCAL; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.MSG_KEY_VERSION; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_AUTHTOKEN; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_INBOXID; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_ONION; -import static org.briarproject.bramble.api.mailbox.MailboxPropertyManager.PROP_KEY_OUTBOXID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_LOCAL; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MSG_KEY_VERSION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_AUTHTOKEN; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_INBOXID; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_ONION; +import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.PROP_KEY_OUTBOXID; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.validation.IncomingMessageHook.DeliveryAction.ACCEPT_DO_NOT_SHARE; +import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.hasEvent; -import static org.briarproject.bramble.test.TestUtils.mailboxPropertiesUpdateEqual; +import static org.briarproject.bramble.test.TestUtils.mailboxUpdateEqual; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { +public class MailboxUpdateManagerImplTest extends BrambleMockTestCase { private final DatabaseComponent db = context.mock(DatabaseComponent.class); private final ClientHelper clientHelper = context.mock(ClientHelper.class); @@ -72,30 +74,54 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final BdfDictionary propsDict; private final BdfDictionary emptyPropsDict = new BdfDictionary(); - private final MailboxPropertiesUpdate props; + private final BdfList realClientSupports; + private final BdfList someClientSupports; + private final List someClientSupportsList; + private final BdfList emptyServerSupports; + private final BdfList someServerSupports; + private final List someServerSupportsList; + private final MailboxUpdateWithMailbox updateWithMailbox; + private final MailboxUpdate updateNoMailbox; private final MailboxProperties ownProps; - public MailboxPropertyManagerImplTest() { + public MailboxUpdateManagerImplTest() { + someClientSupports = BdfList.of(BdfList.of(1, 0)); + someClientSupportsList = singletonList(new MailboxVersion(1, 0)); + emptyServerSupports = new BdfList(); + someServerSupports = BdfList.of(BdfList.of(1, 0)); + someServerSupportsList = singletonList(new MailboxVersion(1, 0)); + realClientSupports = new BdfList(); + for (MailboxVersion v : CLIENT_SUPPORTS) { + realClientSupports.add(BdfList.of(v.getMajor(), v.getMinor())); + } ownProps = new MailboxProperties("http://bar.onion", - new MailboxAuthToken(getRandomId()), true, new ArrayList<>()); - props = new MailboxPropertiesUpdate(ownProps.getOnion(), + new MailboxAuthToken(getRandomId()), true, + someServerSupportsList); + updateWithMailbox = new MailboxUpdateWithMailbox( + singletonList(new MailboxVersion(1, 0)), + singletonList(new MailboxVersion(1, 0)), + ownProps.getOnion(), new MailboxAuthToken(getRandomId()), new MailboxFolderId(getRandomId()), new MailboxFolderId(getRandomId())); propsDict = new BdfDictionary(); - propsDict.put(PROP_KEY_ONION, props.getOnion()); - propsDict.put(PROP_KEY_AUTHTOKEN, props.getAuthToken().getBytes()); - propsDict.put(PROP_KEY_INBOXID, props.getInboxId().getBytes()); - propsDict.put(PROP_KEY_OUTBOXID, props.getOutboxId().getBytes()); + propsDict.put(PROP_KEY_ONION, updateWithMailbox.getOnion()); + propsDict.put(PROP_KEY_AUTHTOKEN, updateWithMailbox.getAuthToken() + .getBytes()); + propsDict.put(PROP_KEY_INBOXID, updateWithMailbox.getInboxId() + .getBytes()); + propsDict.put(PROP_KEY_OUTBOXID, updateWithMailbox.getOutboxId() + .getBytes()); + updateNoMailbox = new MailboxUpdate(someClientSupportsList); } - private MailboxPropertyManagerImpl createInstance() { + private MailboxUpdateManagerImpl createInstance() { context.checking(new Expectations() {{ oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID, MAJOR_VERSION); will(returnValue(localGroup)); }}); - return new MailboxPropertyManagerImpl(db, clientHelper, + return new MailboxUpdateManagerImpl(db, clientHelper, clientVersioningManager, metadataParser, contactGroupFactory, clock, mailboxSettingsManager, crypto); } @@ -105,6 +131,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { Transaction txn = new Transaction(null, false); Contact contact = getContact(); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); + Map messageMetadata = new LinkedHashMap<>(); context.checking(new Expectations() {{ oneOf(db).containsGroup(txn, localGroup.getId()); @@ -125,9 +152,17 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { contact.getId()); oneOf(mailboxSettingsManager).getOwnMailboxProperties(txn); will(returnValue(null)); + oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, + MAJOR_VERSION, contact); + will(returnValue(contactGroup)); + oneOf(clientHelper).getMessageMetadataAsDictionary(txn, + contactGroup.getId()); + will(returnValue(messageMetadata)); + expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports, + emptyServerSupports, emptyPropsDict, true); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.onDatabaseOpened(txn); } @@ -159,21 +194,22 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(mailboxSettingsManager).getOwnMailboxProperties(txn); will(returnValue(ownProps)); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getAuthToken())); + will(returnValue(updateWithMailbox.getAuthToken())); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getInboxId())); + will(returnValue(updateWithMailbox.getInboxId())); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getOutboxId())); + will(returnValue(updateWithMailbox.getOutboxId())); oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, MAJOR_VERSION, contact); will(returnValue(contactGroup)); oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - expectStoreMessage(txn, contactGroup.getId(), propsDict, 1, true); + expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports, + someServerSupports, propsDict, true); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.onDatabaseOpened(txn); } @@ -187,7 +223,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { will(returnValue(true)); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.onDatabaseOpened(txn); } @@ -197,6 +233,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { Transaction txn = new Transaction(null, false); Contact contact = getContact(); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); + Map messageMetadata = new LinkedHashMap<>(); context.checking(new Expectations() {{ // Create the group and share it with the contact @@ -213,9 +250,17 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { contact.getId()); oneOf(mailboxSettingsManager).getOwnMailboxProperties(txn); will(returnValue(null)); + oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, + MAJOR_VERSION, contact); + will(returnValue(contactGroup)); + oneOf(clientHelper).getMessageMetadataAsDictionary(txn, + contactGroup.getId()); + will(returnValue(messageMetadata)); + expectStoreMessage(txn, contactGroup.getId(), 1, realClientSupports, + emptyServerSupports, emptyPropsDict, true); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.addingContact(txn, contact); } @@ -243,21 +288,22 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(mailboxSettingsManager).getOwnMailboxProperties(txn); will(returnValue(ownProps)); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getAuthToken())); + will(returnValue(updateWithMailbox.getAuthToken())); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getInboxId())); + will(returnValue(updateWithMailbox.getInboxId())); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getOutboxId())); + will(returnValue(updateWithMailbox.getOutboxId())); oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, MAJOR_VERSION, contact); will(returnValue(contactGroup)); oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - expectStoreMessage(txn, contactGroup.getId(), propsDict, 1, true); + expectStoreMessage(txn, contactGroup.getId(), 1, someClientSupports, + someServerSupports, propsDict, true); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.addingContact(txn, contact); } @@ -274,7 +320,7 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(db).removeGroup(txn, contactGroup); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.removingContact(txn, contact); } @@ -285,7 +331,8 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { Contact contact = getContact(); GroupId contactGroupId = new GroupId(getRandomId()); Message message = getMessage(contactGroupId); - BdfList body = BdfList.of(1, propsDict); + BdfList body = BdfList.of(1, someClientSupports, someServerSupports, + propsDict); Metadata meta = new Metadata(); BdfDictionary metaDictionary = BdfDictionary.of( new BdfEntry(MSG_KEY_VERSION, 1), @@ -309,16 +356,16 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { will(returnValue(contact.getId())); oneOf(clientHelper).getMessageAsList(txn, message.getId()); will(returnValue(body)); - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - propsDict); - will(returnValue(props)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, someServerSupports, propsDict); + will(returnValue(updateWithMailbox)); oneOf(db).resetUnackedMessagesToSend(txn, contact.getId()); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); assertEquals(ACCEPT_DO_NOT_SHARE, t.incomingMessage(txn, message, meta)); - assertTrue(hasEvent(txn, RemoteMailboxPropertiesUpdateEvent.class)); + assertTrue(hasEvent(txn, RemoteMailboxUpdateEvent.class)); } @Test @@ -328,7 +375,8 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { Contact contact = getContact(); GroupId contactGroupId = new GroupId(getRandomId()); Message message = getMessage(contactGroupId); - BdfList body = BdfList.of(1, propsDict); + BdfList body = BdfList.of(1, someClientSupports, someServerSupports, + propsDict); Metadata meta = new Metadata(); BdfDictionary metaDictionary = BdfDictionary.of( new BdfEntry(MSG_KEY_VERSION, 2), @@ -360,16 +408,16 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { will(returnValue(contact.getId())); oneOf(clientHelper).getMessageAsList(txn, message.getId()); will(returnValue(body)); - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - propsDict); - will(returnValue(props)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, someServerSupports, propsDict); + will(returnValue(updateWithMailbox)); oneOf(db).resetUnackedMessagesToSend(txn, contact.getId()); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); assertEquals(ACCEPT_DO_NOT_SHARE, t.incomingMessage(txn, message, meta)); - assertTrue(hasEvent(txn, RemoteMailboxPropertiesUpdateEvent.class)); + assertTrue(hasEvent(txn, RemoteMailboxUpdateEvent.class)); } @Test @@ -400,14 +448,14 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(db).deleteMessageMetadata(txn, message.getId()); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); assertEquals(ACCEPT_DO_NOT_SHARE, t.incomingMessage(txn, message, meta)); - assertFalse(hasEvent(txn, RemoteMailboxPropertiesUpdateEvent.class)); + assertFalse(hasEvent(txn, RemoteMailboxUpdateEvent.class)); } @Test - public void testCreatesAndStoresLocalPropertiesWithNewVersionOnPairing() + public void testCreatesAndStoresLocalUpdateWithNewVersionOnPairing() throws Exception { Contact contact = getContact(); List contacts = singletonList(contact); @@ -430,27 +478,28 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(db).getContacts(txn); will(returnValue(contacts)); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getAuthToken())); + will(returnValue(updateWithMailbox.getAuthToken())); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getInboxId())); + will(returnValue(updateWithMailbox.getInboxId())); oneOf(crypto).generateUniqueId(); - will(returnValue(props.getOutboxId())); + will(returnValue(updateWithMailbox.getOutboxId())); oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, MAJOR_VERSION, contact); will(returnValue(contactGroup)); oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - expectStoreMessage(txn, contactGroup.getId(), propsDict, 2, true); + expectStoreMessage(txn, contactGroup.getId(), 2, someClientSupports, + someServerSupports, propsDict, true); oneOf(db).removeMessage(txn, latestId); }}); - MailboxPropertyManagerImpl t = createInstance(); - t.mailboxPaired(txn, ownProps.getOnion()); + MailboxUpdateManagerImpl t = createInstance(); + t.mailboxPaired(txn, ownProps.getOnion(), someServerSupportsList); } @Test - public void testStoresEmptyLocalPropertiesWithNewVersionOnUnpairing() + public void testStoresLocalUpdateNoMailboxWithNewVersionOnUnpairing() throws Exception { Contact contact = getContact(); List contacts = singletonList(contact); @@ -478,18 +527,17 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - expectStoreMessage(txn, contactGroup.getId(), emptyPropsDict, - 2, true); + expectStoreMessage(txn, contactGroup.getId(), 2, someClientSupports, + emptyServerSupports, emptyPropsDict, true); oneOf(db).removeMessage(txn, latestId); }}); - MailboxPropertyManagerImpl t = createInstance(); + MailboxUpdateManagerImpl t = createInstance(); t.mailboxUnpaired(txn); } @Test - public void testGetRemoteProperties() - throws Exception { + public void testGetRemoteUpdate() throws Exception { Transaction txn = new Transaction(null, false); Contact contact = getContact(); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); @@ -498,34 +546,34 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { new BdfEntry(MSG_KEY_LOCAL, false) ); Map messageMetadata = new LinkedHashMap<>(); - MessageId fooUpdateId = new MessageId(getRandomId()); - messageMetadata.put(fooUpdateId, metaDictionary); - BdfList fooUpdate = BdfList.of(1, propsDict); + MessageId messageId = new MessageId(getRandomId()); + messageMetadata.put(messageId, metaDictionary); + BdfList body = BdfList.of(1, someClientSupports, someServerSupports, + propsDict); context.checking(new Expectations() {{ oneOf(db).getContact(txn, contact.getId()); will(returnValue(contact)); - oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, - MAJOR_VERSION, contact); + oneOf(contactGroupFactory) + .createContactGroup(CLIENT_ID, MAJOR_VERSION, contact); will(returnValue(contactGroup)); oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, fooUpdateId); - will(returnValue(fooUpdate)); - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - propsDict); - will(returnValue(props)); + oneOf(clientHelper).getMessageAsList(txn, messageId); + will(returnValue(body)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, someServerSupports, propsDict); + will(returnValue(updateWithMailbox)); }}); - MailboxPropertyManagerImpl t = createInstance(); - MailboxPropertiesUpdate remote = - t.getRemoteProperties(txn, contact.getId()); - assertTrue(mailboxPropertiesUpdateEqual(remote, props)); + MailboxUpdateManagerImpl t = createInstance(); + MailboxUpdate remote = t.getRemoteUpdate(txn, contact.getId()); + assertTrue(mailboxUpdateEqual(remote, updateWithMailbox)); } @Test - public void testGetRemotePropertiesReturnsNullBecauseNoUpdate() + public void testGetRemoteUpdateReturnsNullBecauseNoUpdate() throws Exception { Transaction txn = new Transaction(null, false); Contact contact = getContact(); @@ -544,13 +592,12 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { will(returnValue(emptyMessageMetadata)); }}); - MailboxPropertyManagerImpl t = createInstance(); - assertNull(t.getRemoteProperties(txn, contact.getId())); + MailboxUpdateManagerImpl t = createInstance(); + assertNull(t.getRemoteUpdate(txn, contact.getId())); } @Test - public void testGetRemotePropertiesReturnsNullBecauseEmptyUpdate() - throws Exception { + public void testGetRemoteUpdateNoMailbox() throws Exception { Transaction txn = new Transaction(null, false); Contact contact = getContact(); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); @@ -559,9 +606,10 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { new BdfEntry(MSG_KEY_LOCAL, false) ); Map messageMetadata = new LinkedHashMap<>(); - MessageId fooUpdateId = new MessageId(getRandomId()); - messageMetadata.put(fooUpdateId, metaDictionary); - BdfList fooUpdate = BdfList.of(1, emptyPropsDict); + MessageId messageId = new MessageId(getRandomId()); + messageMetadata.put(messageId, metaDictionary); + BdfList body = BdfList.of(1, someClientSupports, emptyServerSupports, + emptyPropsDict); context.checking(new Expectations() {{ oneOf(db).getContact(txn, contact.getId()); @@ -572,20 +620,20 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, fooUpdateId); - will(returnValue(fooUpdate)); - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - emptyPropsDict); - will(returnValue(null)); + oneOf(clientHelper).getMessageAsList(txn, messageId); + will(returnValue(body)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, emptyServerSupports, emptyPropsDict); + will(returnValue(updateNoMailbox)); }}); - MailboxPropertyManagerImpl t = createInstance(); - assertNull(t.getRemoteProperties(txn, contact.getId())); + MailboxUpdateManagerImpl t = createInstance(); + MailboxUpdate remote = t.getRemoteUpdate(txn, contact.getId()); + assertTrue(mailboxUpdateEqual(remote, updateNoMailbox)); } @Test - public void testGetLocalProperties() - throws Exception { + public void testGetLocalUpdate() throws Exception { Transaction txn = new Transaction(null, false); Contact contact = getContact(); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); @@ -594,9 +642,10 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { new BdfEntry(MSG_KEY_LOCAL, true) ); Map messageMetadata = new LinkedHashMap<>(); - MessageId fooUpdateId = new MessageId(getRandomId()); - messageMetadata.put(fooUpdateId, metaDictionary); - BdfList fooUpdate = BdfList.of(1, propsDict); + MessageId messageId = new MessageId(getRandomId()); + messageMetadata.put(messageId, metaDictionary); + BdfList body = BdfList.of(1, someClientSupports, someServerSupports, + propsDict); context.checking(new Expectations() {{ oneOf(db).getContact(txn, contact.getId()); @@ -607,46 +656,20 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, fooUpdateId); - will(returnValue(fooUpdate)); - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - propsDict); - will(returnValue(props)); + oneOf(clientHelper).getMessageAsList(txn, messageId); + will(returnValue(body)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, someServerSupports, propsDict); + will(returnValue(updateWithMailbox)); }}); - MailboxPropertyManagerImpl t = createInstance(); - MailboxPropertiesUpdate local = - t.getLocalProperties(txn, contact.getId()); - assertTrue(mailboxPropertiesUpdateEqual(local, props)); + MailboxUpdateManagerImpl t = createInstance(); + MailboxUpdate local = t.getLocalUpdate(txn, contact.getId()); + assertTrue(mailboxUpdateEqual(local, updateWithMailbox)); } @Test - public void testGetLocalPropertiesReturnsNullBecauseNoUpdate() - throws Exception { - Transaction txn = new Transaction(null, false); - Contact contact = getContact(); - Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); - Map emptyMessageMetadata = - new LinkedHashMap<>(); - - context.checking(new Expectations() {{ - oneOf(db).getContact(txn, contact.getId()); - will(returnValue(contact)); - oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, - MAJOR_VERSION, contact); - will(returnValue(contactGroup)); - oneOf(clientHelper).getMessageMetadataAsDictionary(txn, - contactGroup.getId()); - will(returnValue(emptyMessageMetadata)); - }}); - - MailboxPropertyManagerImpl t = createInstance(); - assertNull(t.getLocalProperties(txn, contact.getId())); - } - - @Test - public void testGetLocalPropertiesReturnsNullBecauseEmptyUpdate() - throws Exception { + public void testGetLocalUpdateNoMailbox() throws Exception { Transaction txn = new Transaction(null, false); Contact contact = getContact(); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); @@ -655,9 +678,10 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { new BdfEntry(MSG_KEY_LOCAL, true) ); Map messageMetadata = new LinkedHashMap<>(); - MessageId fooUpdateId = new MessageId(getRandomId()); - messageMetadata.put(fooUpdateId, metaDictionary); - BdfList fooUpdate = BdfList.of(1, emptyPropsDict); + MessageId messageId = new MessageId(getRandomId()); + messageMetadata.put(messageId, metaDictionary); + BdfList body = BdfList.of(1, someClientSupports, emptyServerSupports, + emptyPropsDict); context.checking(new Expectations() {{ oneOf(db).getContact(txn, contact.getId()); @@ -668,21 +692,24 @@ public class MailboxPropertyManagerImplTest extends BrambleMockTestCase { oneOf(clientHelper).getMessageMetadataAsDictionary(txn, contactGroup.getId()); will(returnValue(messageMetadata)); - oneOf(clientHelper).getMessageAsList(txn, fooUpdateId); - will(returnValue(fooUpdate)); - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - emptyPropsDict); - will(returnValue(null)); + oneOf(clientHelper).getMessageAsList(txn, messageId); + will(returnValue(body)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, emptyServerSupports, emptyPropsDict); + will(returnValue(updateNoMailbox)); }}); - MailboxPropertyManagerImpl t = createInstance(); - assertNull(t.getLocalProperties(txn, contact.getId())); + MailboxUpdateManagerImpl t = createInstance(); + MailboxUpdate local = t.getLocalUpdate(txn, contact.getId()); + assertTrue(mailboxUpdateEqual(local, updateNoMailbox)); } private void expectStoreMessage(Transaction txn, GroupId g, - BdfDictionary properties, long version, boolean local) + long version, BdfList clientSupports, BdfList serverSupports, + BdfDictionary properties, boolean local) throws Exception { - BdfList body = BdfList.of(version, properties); + BdfList body = BdfList.of(version, clientSupports, serverSupports, + properties); Message message = getMessage(g); long timestamp = message.getTimestamp(); BdfDictionary meta = BdfDictionary.of( diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPropertyValidatorTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxUpdateValidatorTest.java similarity index 51% rename from bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPropertyValidatorTest.java rename to bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxUpdateValidatorTest.java index 0ee1747da..8c489dccb 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPropertyValidatorTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxUpdateValidatorTest.java @@ -8,8 +8,10 @@ import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.MetadataEncoder; import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFolderId; -import org.briarproject.bramble.api.mailbox.MailboxPropertiesUpdate; -import org.briarproject.bramble.api.mailbox.MailboxPropertyManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdate; +import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; +import org.briarproject.bramble.api.mailbox.MailboxUpdateWithMailbox; +import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.system.Clock; @@ -18,82 +20,101 @@ import org.jmock.Expectations; import org.junit.Test; import java.io.IOException; +import java.util.List; +import static java.util.Collections.singletonList; import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.junit.Assert.assertEquals; -public class MailboxPropertyValidatorTest extends BrambleMockTestCase { +public class MailboxUpdateValidatorTest extends BrambleMockTestCase { private final ClientHelper clientHelper = context.mock(ClientHelper.class); private final BdfDictionary bdfDict; - private final MailboxPropertiesUpdate mailboxProps; + private final BdfList emptyServerSupports; + private final BdfList someClientSupports; + private final List someClientSupportsList; + private final BdfList someServerSupports; + private final MailboxUpdateWithMailbox updateMailbox; + private final MailboxUpdate updateNoMailbox; private final Group group; private final Message message; - private final MailboxPropertyValidator mpv; + private final MailboxUpdateValidator muv; - public MailboxPropertyValidatorTest() { + public MailboxUpdateValidatorTest() { // Just dummies, clientHelper is mocked so our test is a bit shallow; // not testing - // {@link ClientHelper#parseAndValidateMailboxPropertiesUpdate(BdfDictionary)} + // {@link ClientHelper#parseAndValidateMailboxUpdate(BdfList, BdfList, BdfDictionary)} + emptyServerSupports = new BdfList(); + someClientSupports = BdfList.of(BdfList.of(1, 0)); + someClientSupportsList = singletonList(new MailboxVersion(1, 0)); + someServerSupports = BdfList.of(BdfList.of(1, 0)); bdfDict = BdfDictionary.of(new BdfEntry("foo", "bar")); - mailboxProps = new MailboxPropertiesUpdate("baz", + + updateMailbox = new MailboxUpdateWithMailbox( + singletonList(new MailboxVersion(1, 0)), + singletonList(new MailboxVersion(1, 0)), + "baz", new MailboxAuthToken(getRandomId()), new MailboxFolderId(getRandomId()), new MailboxFolderId(getRandomId())); + updateNoMailbox = new MailboxUpdate(someClientSupportsList); - group = getGroup(MailboxPropertyManager.CLIENT_ID, - MailboxPropertyManager.MAJOR_VERSION); + + group = getGroup(MailboxUpdateManager.CLIENT_ID, + MailboxUpdateManager.MAJOR_VERSION); message = getMessage(group.getId()); MetadataEncoder metadataEncoder = context.mock(MetadataEncoder.class); Clock clock = context.mock(Clock.class); - mpv = new MailboxPropertyValidator(clientHelper, metadataEncoder, + muv = new MailboxUpdateValidator(clientHelper, metadataEncoder, clock); } @Test public void testValidateMessageBody() throws IOException { - BdfList body = BdfList.of(4, bdfDict); + BdfList body = + BdfList.of(4, someClientSupports, someServerSupports, bdfDict); context.checking(new Expectations() {{ - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - bdfDict); - will(returnValue(mailboxProps)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, someServerSupports, bdfDict); + will(returnValue(updateMailbox)); }}); BdfDictionary result = - mpv.validateMessage(message, group, body).getDictionary(); + muv.validateMessage(message, group, body).getDictionary(); assertEquals(4, result.getLong("version").longValue()); } @Test(expected = FormatException.class) public void testValidateWrongVersionValue() throws IOException { BdfList body = BdfList.of(-1, bdfDict); - mpv.validateMessage(message, group, body); + muv.validateMessage(message, group, body); } @Test(expected = FormatException.class) public void testValidateWrongVersionType() throws IOException { BdfList body = BdfList.of(bdfDict, bdfDict); - mpv.validateMessage(message, group, body); + muv.validateMessage(message, group, body); } @Test - public void testEmptyPropertiesReturnsNull() throws IOException { + public void testEmptyProperties() throws IOException { BdfDictionary emptyBdfDict = new BdfDictionary(); - BdfList body = BdfList.of(42, emptyBdfDict); + BdfList body = BdfList.of(42, someClientSupports, emptyServerSupports, + emptyBdfDict); context.checking(new Expectations() {{ - oneOf(clientHelper).parseAndValidateMailboxPropertiesUpdate( - emptyBdfDict); - will(returnValue(null)); + oneOf(clientHelper).parseAndValidateMailboxUpdate( + someClientSupports, emptyServerSupports, emptyBdfDict); + will(returnValue(updateNoMailbox)); }}); BdfDictionary result = - mpv.validateMessage(message, group, body).getDictionary(); + muv.validateMessage(message, group, body).getDictionary(); assertEquals(42, result.getLong("version").longValue()); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementIntegrationTest.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementIntegrationTest.java index d16b6052c..21bfb7df4 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementIntegrationTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/agreement/TransportKeyAgreementIntegrationTest.java @@ -345,11 +345,12 @@ public class TransportKeyAgreementIntegrationTest .canSendOutgoingStreams(aliceId, DUPLEX_TRANSPORT_ID)); } - // Sync initial client versioning updates + // Sync initial client versioning updates and mailbox updates syncMessage(alice, bob, bobId, 1, true); syncMessage(bob, alice, aliceId, 1, true); - syncMessage(alice, bob, bobId, 1, true); - sendAcks(bob, alice, aliceId, 1); + syncMessage(alice, bob, bobId, 2, true); + syncMessage(bob, alice, aliceId, 1, true); + sendAcks(alice, bob, bobId, 1); return new Pair<>(aliceId, bobId); } diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java index 29131fe8b..88e13b57a 100644 --- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionIntegrationTest.java @@ -1051,11 +1051,12 @@ public class IntroductionIntegrationTest true); contact0From1 = contactManager1.getContact(contactId0From1); - // Sync initial client versioning updates and transport properties + // Sync initial client versioning updates, mailbox updates, and + // transport properties sync0To1(1, true); sync1To0(1, true); - sync0To1(2, true); - sync1To0(1, true); + sync0To1(3, true); + sync1To0(2, true); // a new introduction should be possible assertTrue(introductionManager0 diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java index 599ebef07..2dd294b79 100644 --- a/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarIntegrationTest.java @@ -172,16 +172,18 @@ public abstract class BriarIntegrationTest