diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java index 2b18a17a5..16761d28d 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/ContactManager.java @@ -32,12 +32,23 @@ public interface ContactManager { * derives and stores transport keys for each transport, and returns an ID * for the contact. * - * @param alice true if the local party is Alice + * @param alice True if the local party is Alice */ ContactId addContact(Transaction txn, Author remote, AuthorId local, SecretKey rootKey, long timestamp, boolean alice, boolean verified, boolean active) throws DbException; + /** + * Stores a contact associated with the given local and remote pseudonyms, + * replacing the given pending contact, derives and stores transport keys + * for each transport, and returns an ID for the contact. + * + * @param alice True if the local party is Alice + */ + ContactId addContact(Transaction txn, PendingContactId p, Author remote, + AuthorId local, SecretKey rootKey, long timestamp, boolean alice, + boolean verified, boolean active) throws DbException; + /** * Stores a contact associated with the given local and remote pseudonyms * and returns an ID for the contact. @@ -50,7 +61,7 @@ public interface ContactManager { * derives and stores transport keys for each transport, and returns an ID * for the contact. * - * @param alice true if the local party is Alice + * @param alice True if the local party is Alice */ ContactId addContact(Author remote, AuthorId local, SecretKey rootKey, long timestamp, boolean alice, boolean verified, boolean active) @@ -132,13 +143,13 @@ public interface ContactManager { void removeContact(Transaction txn, ContactId c) throws DbException; /** - * Sets an alias name for the contact or unsets it if alias is null. + * Sets an alias for the contact or unsets it if alias is null. */ void setContactAlias(Transaction txn, ContactId c, @Nullable String alias) throws DbException; /** - * Sets an alias name for the contact or unsets it if alias is null. + * Sets an alias for the contact or unsets it if alias is null. */ void setContactAlias(ContactId c, @Nullable String alias) throws DbException; diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedEvent.java index e741777db..76550bea3 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedEvent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedEvent.java @@ -14,12 +14,18 @@ import javax.annotation.concurrent.Immutable; public class ContactAddedEvent extends Event { private final ContactId contactId; + private final boolean verified; - public ContactAddedEvent(ContactId contactId) { + public ContactAddedEvent(ContactId contactId, boolean verified) { this.contactId = contactId; + this.verified = verified; } public ContactId getContactId() { return contactId; } + + public boolean isVerified() { + return verified; + } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedRemotelyEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedRemotelyEvent.java deleted file mode 100644 index b657d568d..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/event/ContactAddedRemotelyEvent.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.briarproject.bramble.api.contact.event; - -import org.briarproject.bramble.api.contact.Contact; -import org.briarproject.bramble.api.event.Event; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -import javax.annotation.concurrent.Immutable; - -@Immutable -@NotNullByDefault -public class ContactAddedRemotelyEvent extends Event { - - private final Contact contact; - - public ContactAddedRemotelyEvent(Contact contact) { - this.contact = contact; - } - - public Contact getContact() { - return contact; - } -} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java index a5e57224d..2112beb2b 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java @@ -63,6 +63,13 @@ public interface DatabaseComponent extends TransactionManager { ContactId addContact(Transaction txn, Author remote, AuthorId local, boolean verified) throws DbException; + /** + * Stores a contact associated with the given local and remote pseudonyms, + * replacing the given pending contact, and returns an ID for the contact. + */ + ContactId addContact(Transaction txn, PendingContactId p, Author remote, + AuthorId local, boolean verified) throws DbException; + /** * Stores a group. */ diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java index 510be77a0..24c09cef2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java @@ -81,6 +81,19 @@ class ContactManagerImpl implements ContactManager { return c; } + @Override + public ContactId addContact(Transaction txn, PendingContactId p, + Author remote, AuthorId local, SecretKey rootKey, long timestamp, + boolean alice, boolean verified, boolean active) + throws DbException { + ContactId c = db.addContact(txn, p, remote, local, verified); + keyManager.addContactWithRotationKeys(txn, c, rootKey, timestamp, + alice, active); + Contact contact = db.getContact(txn, c); + for (ContactHook hook : hooks) hook.addingContact(txn, contact); + return c; + } + @Override public ContactId addContact(Transaction txn, Author remote, AuthorId local, boolean verified) throws DbException { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java index 7f7ad07c4..4a61a9360 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java @@ -630,7 +630,8 @@ interface Database { /** * Removes the given transport keys from the database. */ - void removeTransportKeys(T txn, TransportId t, KeySetId k) throws DbException; + void removeTransportKeys(T txn, TransportId t, KeySetId k) + throws DbException; /** * Resets the transmission count and expiry time of the given message with @@ -686,6 +687,14 @@ interface Database { void setTransportKeysActive(T txn, TransportId t, KeySetId k) throws DbException; + /** + * Transfers ownership of any transport keys from the given pending contact + * to the given contact and copies the pending contact's handshake public + * key to the contact. + */ + void transferKeys(T txn, PendingContactId p, ContactId c) + throws DbException; + /** * Updates the transmission count, expiry time and estimated time of arrival * of the given message with respect to the given contact, using the latency diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java index 275d04147..2d90894f3 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/DatabaseComponentImpl.java @@ -244,7 +244,29 @@ class DatabaseComponentImpl implements DatabaseComponent { if (db.containsContact(txn, remote.getId(), local)) throw new ContactExistsException(local, remote); ContactId c = db.addContact(txn, remote, local, verified); - transaction.attach(new ContactAddedEvent(c)); + transaction.attach(new ContactAddedEvent(c, verified)); + return c; + } + + @Override + public ContactId addContact(Transaction transaction, PendingContactId p, + Author remote, AuthorId local, boolean verified) + throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsPendingContact(txn, p)) + throw new NoSuchPendingContactException(); + if (!db.containsIdentity(txn, local)) + throw new NoSuchIdentityException(); + if (db.containsIdentity(txn, remote.getId())) + throw new ContactExistsException(local, remote); + if (db.containsContact(txn, remote.getId(), local)) + throw new ContactExistsException(local, remote); + ContactId c = db.addContact(txn, remote, local, verified); + db.transferKeys(txn, p, c); + db.removePendingContact(txn, p); + transaction.attach(new ContactAddedEvent(c, verified)); + transaction.attach(new PendingContactRemovedEvent(p)); return c; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java index 0a154d859..536eaf4e8 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/JdbcDatabase.java @@ -3115,6 +3115,48 @@ abstract class JdbcDatabase implements Database { } } + @Override + public void transferKeys(Connection txn, PendingContactId p, ContactId c) + throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + // Transfer the handshake public key + String sql = "SELECT publicKey from pendingContacts" + + " WHERE pendingContactId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, p.getBytes()); + rs = ps.executeQuery(); + if (!rs.next()) throw new DbStateException(); + byte[] publicKey = rs.getBytes(1); + if (rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + sql = "UPDATE contacts SET handshakePublicKey = ?" + + " WHERE contactId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, publicKey); + ps.setInt(2, c.getInt()); + int affected = ps.executeUpdate(); + if (affected < 0 || affected > 1) throw new DbStateException(); + ps.close(); + // Transfer the transport keys + sql = "UPDATE outgoingKeys" + + " SET contactId = ?, pendingContactId = NULL" + + " WHERE pendingContactId = ?"; + ps = txn.prepareStatement(sql); + ps.setInt(1, c.getInt()); + ps.setBytes(2, p.getBytes()); + affected = ps.executeUpdate(); + if (affected < 0) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public void updateExpiryTimeAndEta(Connection txn, ContactId c, MessageId m, int maxLatency) throws DbException { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java index 24c363e22..ab634d036 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabaseComponentImplTest.java @@ -763,16 +763,25 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { throws Exception { context.checking(new Expectations() {{ // Check whether the pending contact is in the DB (which it's not) - exactly(2).of(database).startTransaction(); + exactly(3).of(database).startTransaction(); will(returnValue(txn)); - exactly(2).of(database).containsPendingContact(txn, + exactly(3).of(database).containsPendingContact(txn, pendingContactId); will(returnValue(false)); - exactly(2).of(database).abortTransaction(txn); + exactly(3).of(database).abortTransaction(txn); }}); DatabaseComponent db = createDatabaseComponent(database, eventBus, eventExecutor, shutdownManager); + try { + db.transaction(false, transaction -> + db.addContact(transaction, pendingContactId, author, + localAuthor.getId(), true)); + fail(); + } catch (NoSuchPendingContactException expected) { + // Expected + } + try { db.transaction(false, transaction -> db.addTransportKeys(transaction, pendingContactId, @@ -1494,6 +1503,69 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { } } + @Test + public void testCannotAddLocalIdentityAsContactFromPendingContact() + throws Exception { + context.checking(new Expectations() {{ + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).containsPendingContact(txn, pendingContactId); + will(returnValue(true)); + oneOf(database).containsIdentity(txn, localAuthor.getId()); + will(returnValue(true)); + // Contact is a local identity + oneOf(database).containsIdentity(txn, author.getId()); + will(returnValue(true)); + oneOf(database).abortTransaction(txn); + }}); + + DatabaseComponent db = createDatabaseComponent(database, eventBus, + eventExecutor, shutdownManager); + + try { + db.transaction(false, transaction -> + db.addContact(transaction, pendingContactId, author, + localAuthor.getId(), true)); + fail(); + } catch (ContactExistsException expected) { + assertEquals(localAuthor.getId(), expected.getLocalAuthorId()); + assertEquals(author, expected.getRemoteAuthor()); + } + } + + @Test + public void testCannotAddDuplicateContactFromPendingContact() + throws Exception { + context.checking(new Expectations() {{ + oneOf(database).startTransaction(); + will(returnValue(txn)); + oneOf(database).containsPendingContact(txn, pendingContactId); + will(returnValue(true)); + oneOf(database).containsIdentity(txn, localAuthor.getId()); + will(returnValue(true)); + oneOf(database).containsIdentity(txn, author.getId()); + will(returnValue(false)); + // Contact already exists for this local identity + oneOf(database).containsContact(txn, author.getId(), + localAuthor.getId()); + will(returnValue(true)); + oneOf(database).abortTransaction(txn); + }}); + + DatabaseComponent db = createDatabaseComponent(database, eventBus, + eventExecutor, shutdownManager); + + try { + db.transaction(false, transaction -> + db.addContact(transaction, pendingContactId, author, + localAuthor.getId(), true)); + fail(); + } catch (ContactExistsException expected) { + assertEquals(localAuthor.getId(), expected.getLocalAuthorId()); + assertEquals(author, expected.getRemoteAuthor()); + } + } + @Test public void testMessageDependencies() throws Exception { int shutdownHandle = 12345; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java index 2fc0ab5b1..4bb66f114 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/JdbcDatabaseTest.java @@ -2204,12 +2204,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(emptyList(), db.getPendingContacts(txn)); db.addPendingContact(txn, pendingContact); - Collection pendingContacts = - db.getPendingContacts(txn); + Collection pendingContacts = db.getPendingContacts(txn); assertEquals(1, pendingContacts.size()); PendingContact retrieved = pendingContacts.iterator().next(); assertEquals(pendingContact.getId(), retrieved.getId()); assertEquals(pendingContact.getAlias(), retrieved.getAlias()); + assertArrayEquals(pendingContact.getPublicKey().getEncoded(), + retrieved.getPublicKey().getEncoded()); assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp()); db.removePendingContact(txn, pendingContact.getId()); @@ -2219,6 +2220,60 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { db.close(); } + @Test + public void testTransferKeys() throws Exception { + boolean alice = random.nextBoolean(); + TransportKeys transportKeys = + createHandshakeKeys(1000, getSecretKey(), alice); + + Database db = open(false); + Connection txn = db.startTransaction(); + + // Add the pending contact, the transport and the handshake keys + db.addPendingContact(txn, pendingContact); + db.addTransport(txn, transportId, 123); + assertEquals(keySetId, db.addTransportKeys(txn, pendingContact.getId(), + transportKeys)); + + Collection allKeys = + db.getTransportKeys(txn, transportId); + assertEquals(1, allKeys.size()); + TransportKeySet ks = allKeys.iterator().next(); + assertEquals(keySetId, ks.getKeySetId()); + assertNull(ks.getContactId()); + assertEquals(pendingContact.getId(), ks.getPendingContactId()); + + // Add a contact + db.addIdentity(txn, identity); + assertEquals(contactId, + db.addContact(txn, author, localAuthor.getId(), true)); + + // The contact shouldn't have a handshake public key + Contact contact = db.getContact(txn, contactId); + assertNull(contact.getHandshakePublicKey()); + + // Transfer the keys to the contact + db.transferKeys(txn, pendingContact.getId(), contactId); + + // The handshake public key should have been copied to the contact + contact = db.getContact(txn, contactId); + PublicKey handshakePublicKey = contact.getHandshakePublicKey(); + assertNotNull(handshakePublicKey); + assertArrayEquals(pendingContact.getPublicKey().getEncoded(), + handshakePublicKey.getEncoded()); + + // The transport keys should have been transferred to the contact + allKeys = db.getTransportKeys(txn, transportId); + assertEquals(1, allKeys.size()); + ks = allKeys.iterator().next(); + assertEquals(keySetId, ks.getKeySetId()); + assertEquals(contactId, ks.getContactId()); + assertNull(ks.getPendingContactId()); + + db.commitTransaction(txn); + db.close(); + } + @Test public void testSetHandshakeKeyPair() throws Exception { Identity withoutKeys = new Identity(localAuthor, null, null, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java index 481de6755..255635a13 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/plugin/PollerImplTest.java @@ -153,7 +153,7 @@ public class PollerImplTest extends BrambleMockTestCase { will(returnValue(false)); }}); - poller.eventOccurred(new ContactAddedEvent(contactId)); + poller.eventOccurred(new ContactAddedEvent(contactId, true)); } @Test diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java index e2912f920..cf0b74416 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java @@ -16,6 +16,7 @@ import android.support.v4.app.TaskStackBuilder; import org.briarproject.bramble.api.Multiset; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; @@ -42,7 +43,6 @@ import org.briarproject.briar.api.android.AndroidNotificationManager; import org.briarproject.briar.api.blog.event.BlogPostAddedEvent; import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent; -import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent; import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent; import java.util.Set; @@ -230,8 +230,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, } else if (e instanceof BlogPostAddedEvent) { BlogPostAddedEvent b = (BlogPostAddedEvent) e; if (!b.isLocal()) showBlogPostNotification(b.getGroupId()); - } else if (e instanceof ContactAddedRemotelyEvent) { - showContactAddedNotification(); + } else if (e instanceof ContactAddedEvent) { + ContactAddedEvent c = (ContactAddedEvent) e; + // Don't show notifications for contacts added in person + if (!c.isVerified()) showContactAddedNotification(); } } diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java index 26e5da41d..a1b0964ad 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroduceeProtocolEngine.java @@ -5,7 +5,6 @@ import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.client.ContactGroupFactory; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactManager; -import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent; import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.PrivateKey; import org.briarproject.bramble.api.crypto.PublicKey; @@ -453,10 +452,6 @@ class IntroduceeProtocolEngine //noinspection ConstantConditions transportPropertyManager.addRemoteProperties(txn, c.getId(), s.getRemote().transportProperties); - - // Broadcast IntroductionSucceededEvent, because contact got added - ContactAddedRemotelyEvent e = new ContactAddedRemotelyEvent(c); - txn.attach(e); } catch (ContactExistsException e) { // Ignore this, because the other introducee might have deleted us. // So we still want updated transport properties 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 7e313436b..6cf552c03 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 @@ -6,6 +6,7 @@ import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.contact.event.ContactAddedEvent; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfList; @@ -32,7 +33,6 @@ import org.briarproject.briar.api.introduction.IntroductionResponse; import org.briarproject.briar.api.introduction.event.IntroductionAbortedEvent; import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent; import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent; -import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent; import org.briarproject.briar.test.BriarIntegrationTest; import org.junit.Before; import org.junit.Test; @@ -1217,7 +1217,6 @@ public class IntroductionIntegrationTest volatile boolean aborted = false; volatile Event latestEvent; - @SuppressWarnings("WeakerAccess") IntroductionResponse getResponse() { assertTrue( latestEvent instanceof IntroductionResponseReceivedEvent); @@ -1273,12 +1272,11 @@ public class IntroductionIntegrationTest // only broadcast for DECLINE messages in introducee role latestEvent = e; eventWaiter.resume(); - } else if (e instanceof ContactAddedRemotelyEvent) { + } else if (e instanceof ContactAddedEvent) { latestEvent = e; succeeded = true; - Contact contact = ((ContactAddedRemotelyEvent) e).getContact(); - eventWaiter - .assertFalse(contact.getId().equals(contactId0From1)); + ContactId contactId = ((ContactAddedEvent) e).getContactId(); + eventWaiter.assertFalse(contactId.equals(contactId0From1)); eventWaiter.resume(); } else if (e instanceof IntroductionAbortedEvent) { latestEvent = e; @@ -1357,13 +1355,10 @@ public class IntroductionIntegrationTest Message m = ch.getMessage(id); BdfList body = ch.getMessageAsList(id); if (type == ACCEPT) { - //noinspection ConstantConditions return c0.getMessageParser().parseAcceptMessage(m, body); } else if (type == DECLINE) { - //noinspection ConstantConditions return c0.getMessageParser().parseDeclineMessage(m, body); } else if (type == AUTH) { - //noinspection ConstantConditions return c0.getMessageParser().parseAuthMessage(m, body); } else throw new AssertionError("Not implemented"); } diff --git a/briar-headless/README.md b/briar-headless/README.md index 8779db912..0804e6d26 100644 --- a/briar-headless/README.md +++ b/briar-headless/README.md @@ -143,7 +143,7 @@ The following events are relevant here: * `PendingContactAddedEvent` * `PendingContactStateChangedEvent` * `PendingContactRemovedEvent` - * `ContactAddedRemotelyEvent` (when the pending contact becomes an actual contact) + * `ContactAddedEvent` (when the pending contact becomes an actual contact) To remove a pending contact and abort the process of adding it: @@ -287,28 +287,15 @@ it will send a JSON object to connected websocket clients: Note that the JSON object in `data` is exactly what the REST API returns when listing private messages. -### A new contact was added remotely - -When the Briar peer adds a new contact remotely, -it will send a JSON object representing the new contact to connected websocket clients: +### A new contact was added ```json { "data": { - "contact": { - "author": { - "formatVersion": 1, - "id": "y1wkIzAimAbYoCGgWxkWlr6vnq1F8t1QRA/UMPgI0E0=", - "name": "Test", - "publicKey": "BDu6h1S02bF4W6rgoZfZ6BMjTj/9S9hNN7EQoV05qUo=" - }, - "contactId": 1, - "alias" : "A local nickname", - "handshakePublicKey": "XnYRd7a7E4CTqgAvh4hCxh/YZ0EPscxknB9ZcEOpSzY=", - "verified": true - } + "contactId": 1, + "verified": false }, - "name": "ContactAddedRemotelyEvent", + "name": "ContactAddedEvent", "type": "event" } ``` @@ -334,8 +321,8 @@ it will send a JSON object representing the new contact to connected websocket c ```json { "data": { - "pendingContactId":"YqKjsczCuxScXohb5+RAYtFEwK71icoB4ldztV2gh7M=", - "state":"waiting_for_connection" + "pendingContactId": "YqKjsczCuxScXohb5+RAYtFEwK71icoB4ldztV2gh7M=", + "state": "waiting_for_connection" }, "name": "PendingContactStateChangedEvent", "type": "event" diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/contact/ContactControllerImpl.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/contact/ContactControllerImpl.kt index d1b1a757b..4d05471ae 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/contact/ContactControllerImpl.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/contact/ContactControllerImpl.kt @@ -7,7 +7,7 @@ import io.javalin.NotFoundResponse import org.briarproject.bramble.api.contact.ContactManager import org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX import org.briarproject.bramble.api.contact.PendingContactId -import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent +import org.briarproject.bramble.api.contact.event.ContactAddedEvent import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent @@ -27,7 +27,7 @@ import javax.annotation.concurrent.Immutable import javax.inject.Inject import javax.inject.Singleton -internal const val EVENT_CONTACT_ADDED_REMOTELY = "ContactAddedRemotelyEvent" +internal const val EVENT_CONTACT_ADDED = "ContactAddedEvent" internal const val EVENT_PENDING_CONTACT_STATE_CHANGED = "PendingContactStateChangedEvent" internal const val EVENT_PENDING_CONTACT_ADDED = "PendingContactAddedEvent" internal const val EVENT_PENDING_CONTACT_REMOVED = "PendingContactRemovedEvent" @@ -43,8 +43,8 @@ constructor( ) : ContactController, EventListener { override fun eventOccurred(e: Event) = when (e) { - is ContactAddedRemotelyEvent -> { - webSocket.sendEvent(EVENT_CONTACT_ADDED_REMOTELY, e.output()) + is ContactAddedEvent -> { + webSocket.sendEvent(EVENT_CONTACT_ADDED, e.output()) } is PendingContactStateChangedEvent -> { webSocket.sendEvent(EVENT_PENDING_CONTACT_STATE_CHANGED, e.output()) diff --git a/briar-headless/src/main/java/org/briarproject/briar/headless/contact/OutputContact.kt b/briar-headless/src/main/java/org/briarproject/briar/headless/contact/OutputContact.kt index 7f5f35f54..444950fe9 100644 --- a/briar-headless/src/main/java/org/briarproject/briar/headless/contact/OutputContact.kt +++ b/briar-headless/src/main/java/org/briarproject/briar/headless/contact/OutputContact.kt @@ -1,7 +1,7 @@ package org.briarproject.briar.headless.contact import org.briarproject.bramble.api.contact.Contact -import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent +import org.briarproject.bramble.api.contact.event.ContactAddedEvent import org.briarproject.bramble.identity.output import org.briarproject.briar.headless.json.JsonDict @@ -14,6 +14,7 @@ internal fun Contact.output() = JsonDict( handshakePublicKey?.let { put("handshakePublicKey", it.encoded) } } -internal fun ContactAddedRemotelyEvent.output() = JsonDict( - "contact" to contact.output() +internal fun ContactAddedEvent.output() = JsonDict( + "contactId" to contactId.int, + "verified" to isVerified ) diff --git a/briar-headless/src/test/java/org/briarproject/briar/headless/contact/ContactControllerTest.kt b/briar-headless/src/test/java/org/briarproject/briar/headless/contact/ContactControllerTest.kt index 3b2d2dcb5..0186323cc 100644 --- a/briar-headless/src/test/java/org/briarproject/briar/headless/contact/ContactControllerTest.kt +++ b/briar-headless/src/test/java/org/briarproject/briar/headless/contact/ContactControllerTest.kt @@ -13,7 +13,7 @@ import org.briarproject.bramble.api.contact.ContactId import org.briarproject.bramble.api.contact.PendingContactId import org.briarproject.bramble.api.contact.PendingContactState.FAILED import org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION -import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent +import org.briarproject.bramble.api.contact.event.ContactAddedEvent import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent @@ -207,12 +207,12 @@ internal class ContactControllerTest : ControllerTest() { } @Test - fun testContactAddedRemotelyEvent() { - val event = ContactAddedRemotelyEvent(contact) + fun testContactAddedEvent() { + val event = ContactAddedEvent(contact.id, contact.isVerified) every { webSocketController.sendEvent( - EVENT_CONTACT_ADDED_REMOTELY, + EVENT_CONTACT_ADDED, event.output() ) } just runs @@ -291,11 +291,12 @@ internal class ContactControllerTest : ControllerTest() { } @Test - fun testOutputContactAddedRemotelyEvent() { - val event = ContactAddedRemotelyEvent(contact) + fun testOutputContactAddedEvent() { + val event = ContactAddedEvent(contact.id, contact.isVerified) val json = """ { - "contact": ${toJson(contact.output())} + "contactId": ${contact.id.int}, + "verified": ${contact.isVerified} } """ assertJsonEquals(json, event.output())