From 75776eb7dededb326f98128ac82b70388782278b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 18 Apr 2019 18:09:09 +0100 Subject: [PATCH 01/17] Generate handshake keys when creating local author. --- .../bramble/api/identity/AuthorFactory.java | 11 ++---- .../bramble/identity/AuthorFactoryImpl.java | 27 ++++++++------ .../bramble/identity/IdentityManagerImpl.java | 13 ++----- .../identity/IdentityManagerImplTest.java | 36 ++----------------- .../briar/feed/FeedFactoryImpl.java | 16 +++------ .../briar/test/TestDataCreatorImpl.java | 33 ++++++----------- .../blog/BlogManagerIntegrationTest.java | 6 +--- .../IntroductionCryptoIntegrationTest.java | 6 ++-- .../messaging/MessageSizeIntegrationTest.java | 7 +--- .../briar/test/BriarTestUtils.java | 19 +++++----- 10 files changed, 50 insertions(+), 124 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java index 5566a2c95..a46d386a2 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java @@ -18,14 +18,7 @@ public interface AuthorFactory { /** * Creates a local author with the current format version and the given - * name and keys. + * name. */ - LocalAuthor createLocalAuthor(String name, byte[] publicKey, - byte[] privateKey); - - /** - * Creates a local author with the given format version, name and keys. - */ - LocalAuthor createLocalAuthor(int formatVersion, String name, - byte[] publicKey, byte[] privateKey); + LocalAuthor createLocalAuthor(String name, boolean handshakeKeys); } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java index bbd2ae65c..0f444c74a 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java @@ -1,6 +1,7 @@ package org.briarproject.bramble.identity; import org.briarproject.bramble.api.crypto.CryptoComponent; +import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorId; @@ -43,17 +44,21 @@ class AuthorFactoryImpl implements AuthorFactory { } @Override - public LocalAuthor createLocalAuthor(String name, byte[] publicKey, - byte[] privateKey) { - return createLocalAuthor(FORMAT_VERSION, name, publicKey, privateKey); - } - - @Override - public LocalAuthor createLocalAuthor(int formatVersion, String name, - byte[] publicKey, byte[] privateKey) { - AuthorId id = getId(formatVersion, name, publicKey); - return new LocalAuthor(id, formatVersion, name, publicKey, privateKey, - clock.currentTimeMillis()); + public LocalAuthor createLocalAuthor(String name, boolean handshakeKeys) { + KeyPair signatureKeyPair = crypto.generateSignatureKeyPair(); + byte[] sigPub = signatureKeyPair.getPublic().getEncoded(); + byte[] sigPriv = signatureKeyPair.getPrivate().getEncoded(); + AuthorId id = getId(FORMAT_VERSION, name, sigPub); + if (handshakeKeys) { + KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); + byte[] handPub = handshakeKeyPair.getPublic().getEncoded(); + byte[] handPriv = handshakeKeyPair.getPrivate().getEncoded(); + return new LocalAuthor(id, FORMAT_VERSION, name, sigPub, sigPriv, + handPub, handPriv, clock.currentTimeMillis()); + } else { + return new LocalAuthor(id, FORMAT_VERSION, name, sigPub, sigPriv, + clock.currentTimeMillis()); + } } private AuthorId getId(int formatVersion, String name, byte[] publicKey) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index d98f5d503..a7d515d28 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -1,7 +1,5 @@ package org.briarproject.bramble.identity; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; @@ -27,7 +25,6 @@ class IdentityManagerImpl implements IdentityManager { Logger.getLogger(IdentityManagerImpl.class.getName()); private final DatabaseComponent db; - private final CryptoComponent crypto; private final AuthorFactory authorFactory; // The local author is immutable so we can cache it @@ -35,21 +32,15 @@ class IdentityManagerImpl implements IdentityManager { private volatile LocalAuthor cachedAuthor; @Inject - IdentityManagerImpl(DatabaseComponent db, CryptoComponent crypto, - AuthorFactory authorFactory) { + IdentityManagerImpl(DatabaseComponent db, AuthorFactory authorFactory) { this.db = db; - this.crypto = crypto; this.authorFactory = authorFactory; } @Override public LocalAuthor createLocalAuthor(String name) { long start = now(); - KeyPair keyPair = crypto.generateSignatureKeyPair(); - byte[] publicKey = keyPair.getPublic().getEncoded(); - byte[] privateKey = keyPair.getPrivate().getEncoded(); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(name, - publicKey, privateKey); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(name, true); logDuration(LOG, "Creating local author", start); return localAuthor; } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java index 0ed0b8d22..896b49156 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java @@ -1,9 +1,5 @@ package org.briarproject.bramble.identity; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.KeyPair; -import org.briarproject.bramble.api.crypto.PrivateKey; -import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; @@ -12,56 +8,30 @@ import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.DbExpectations; -import org.jmock.Expectations; import org.junit.Before; import org.junit.Test; import java.util.Collection; -import java.util.Collections; +import static java.util.Collections.singletonList; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.junit.Assert.assertEquals; public class IdentityManagerImplTest extends BrambleMockTestCase { private final DatabaseComponent db = context.mock(DatabaseComponent.class); - private final CryptoComponent crypto = context.mock(CryptoComponent.class); private final AuthorFactory authorFactory = context.mock(AuthorFactory.class); - private final PublicKey publicKey = context.mock(PublicKey.class); - private final PrivateKey privateKey = context.mock(PrivateKey.class); private final Transaction txn = new Transaction(null, false); private final LocalAuthor localAuthor = getLocalAuthor(); private final Collection localAuthors = - Collections.singletonList(localAuthor); - private final String authorName = localAuthor.getName(); - private final KeyPair keyPair = new KeyPair(publicKey, privateKey); - private final byte[] publicKeyBytes = localAuthor.getPublicKey(); - private final byte[] privateKeyBytes = localAuthor.getPrivateKey(); + singletonList(localAuthor); private IdentityManager identityManager; @Before public void setUp() { - identityManager = new IdentityManagerImpl(db, crypto, authorFactory); - } - - @Test - public void testCreateLocalAuthor() { - context.checking(new Expectations() {{ - oneOf(crypto).generateSignatureKeyPair(); - will(returnValue(keyPair)); - oneOf(publicKey).getEncoded(); - will(returnValue(publicKeyBytes)); - oneOf(privateKey).getEncoded(); - will(returnValue(privateKeyBytes)); - oneOf(authorFactory).createLocalAuthor(authorName, - publicKeyBytes, privateKeyBytes); - will(returnValue(localAuthor)); - }}); - - assertEquals(localAuthor, - identityManager.createLocalAuthor(authorName)); + identityManager = new IdentityManagerImpl(db, authorFactory); } @Test diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java index 5e131632f..de73abc2d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java @@ -4,8 +4,6 @@ import com.rometools.rome.feed.synd.SyndFeed; import org.briarproject.bramble.api.FormatException; import org.briarproject.bramble.api.client.ClientHelper; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.data.BdfEntry; import org.briarproject.bramble.api.data.BdfList; @@ -32,17 +30,14 @@ import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL; class FeedFactoryImpl implements FeedFactory { - private final CryptoComponent cryptoComponent; private final AuthorFactory authorFactory; private final BlogFactory blogFactory; private final ClientHelper clientHelper; private final Clock clock; @Inject - FeedFactoryImpl(CryptoComponent cryptoComponent, - AuthorFactory authorFactory, BlogFactory blogFactory, + FeedFactoryImpl(AuthorFactory authorFactory, BlogFactory blogFactory, ClientHelper clientHelper, Clock clock) { - this.cryptoComponent = cryptoComponent; this.authorFactory = authorFactory; this.blogFactory = blogFactory; this.clientHelper = clientHelper; @@ -55,10 +50,7 @@ class FeedFactoryImpl implements FeedFactory { if (title == null) title = "RSS"; else title = StringUtils.truncateUtf8(title, MAX_AUTHOR_NAME_LENGTH); - KeyPair keyPair = cryptoComponent.generateSignatureKeyPair(); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(title, - keyPair.getPublic().getEncoded(), - keyPair.getPrivate().getEncoded()); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(title, false); Blog blog = blogFactory.createFeedBlog(localAuthor); long added = clock.currentTimeMillis(); @@ -80,9 +72,9 @@ class FeedFactoryImpl implements FeedFactory { BdfList authorList = d.getList(KEY_FEED_AUTHOR); byte[] privateKey = d.getRaw(KEY_FEED_PRIVATE_KEY); Author author = clientHelper.parseAndValidateAuthor(authorList); - LocalAuthor localAuthor = authorFactory.createLocalAuthor( + LocalAuthor localAuthor = new LocalAuthor(author.getId(), author.getFormatVersion(), author.getName(), - author.getPublicKey(), privateKey); + author.getPublicKey(), privateKey, 0); Blog blog = blogFactory.createFeedBlog(localAuthor); String desc = d.getOptionalString(KEY_FEED_DESC); diff --git a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java index 851b78f69..6cfdf6b7a 100644 --- a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java @@ -5,8 +5,6 @@ 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.ContactManager; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.data.BdfDictionary; import org.briarproject.bramble.api.db.DatabaseComponent; @@ -74,7 +72,6 @@ public class TestDataCreatorImpl implements TestDataCreator { private final ClientHelper clientHelper; private final MessageTracker messageTracker; private final BlogPostFactory blogPostFactory; - private final CryptoComponent cryptoComponent; private final DatabaseComponent db; private final IdentityManager identityManager; @@ -94,9 +91,8 @@ public class TestDataCreatorImpl implements TestDataCreator { TestDataCreatorImpl(AuthorFactory authorFactory, Clock clock, PrivateMessageFactory privateMessageFactory, ClientHelper clientHelper, MessageTracker messageTracker, - BlogPostFactory blogPostFactory, CryptoComponent cryptoComponent, - DatabaseComponent db, IdentityManager identityManager, - ContactManager contactManager, + BlogPostFactory blogPostFactory, DatabaseComponent db, + IdentityManager identityManager, ContactManager contactManager, TransportPropertyManager transportPropertyManager, MessagingManager messagingManager, BlogManager blogManager, ForumManager forumManager, @IoExecutor Executor ioExecutor) { @@ -106,7 +102,6 @@ public class TestDataCreatorImpl implements TestDataCreator { this.clientHelper = clientHelper; this.messageTracker = messageTracker; this.blogPostFactory = blogPostFactory; - this.cryptoComponent = cryptoComponent; this.db = db; this.identityManager = identityManager; this.contactManager = contactManager; @@ -150,14 +145,14 @@ public class TestDataCreatorImpl implements TestDataCreator { List contacts = new ArrayList<>(numContacts); LocalAuthor localAuthor = identityManager.getLocalAuthor(); for (int i = 0; i < numContacts; i++) { - LocalAuthor author = getRandomAuthor(); - Contact contact = addContact(localAuthor.getId(), author); + LocalAuthor remote = getRandomAuthor(); + Contact contact = addContact(localAuthor.getId(), remote); contacts.add(contact); } return contacts; } - private Contact addContact(AuthorId localAuthorId, LocalAuthor author) + private Contact addContact(AuthorId localAuthorId, LocalAuthor remote) throws DbException { // prepare to add contact @@ -173,7 +168,7 @@ public class TestDataCreatorImpl implements TestDataCreator { Transaction txn = db.startTransaction(false); try { ContactId contactId = contactManager - .addContact(txn, author, localAuthorId, secretKey, + .addContact(txn, remote, localAuthorId, secretKey, timestamp, true, verified, true); if (random.nextBoolean()) { contactManager @@ -187,24 +182,18 @@ public class TestDataCreatorImpl implements TestDataCreator { } if (LOG.isLoggable(INFO)) { - LOG.info("Added contact " + author.getName()); + LOG.info("Added contact " + remote.getName()); LOG.info("with transport properties: " + props.toString()); } - localAuthors.put(contact, author); + localAuthors.put(contact, remote); return contact; } @Override public Contact addContact(String name) throws DbException { LocalAuthor localAuthor = identityManager.getLocalAuthor(); - return addContact(localAuthor.getId(), getAuthor(name)); - } - - private LocalAuthor getAuthor(String name) { - KeyPair keyPair = cryptoComponent.generateSignatureKeyPair(); - byte[] publicKey = keyPair.getPublic().getEncoded(); - byte[] privateKey = keyPair.getPrivate().getEncoded(); - return authorFactory.createLocalAuthor(name, publicKey, privateKey); + LocalAuthor remote = authorFactory.createLocalAuthor(name, false); + return addContact(localAuthor.getId(), remote); } private String getRandomAuthorName() { @@ -213,7 +202,7 @@ public class TestDataCreatorImpl implements TestDataCreator { } private LocalAuthor getRandomAuthor() { - return getAuthor(getRandomAuthorName()); + return authorFactory.createLocalAuthor(getRandomAuthorName(), false); } private SecretKey getSecretKey() { diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java index 7e6638a5a..98e984275 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java @@ -21,9 +21,7 @@ import java.util.Iterator; import static junit.framework.Assert.assertNotNull; 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.AuthorInfo.Status.NONE; -import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.briar.api.blog.MessageType.COMMENT; import static org.briarproject.briar.api.blog.MessageType.POST; @@ -51,9 +49,7 @@ public class BlogManagerIntegrationTest author0 = identityManager0.getLocalAuthor(); author1 = identityManager1.getLocalAuthor(); rssAuthor = c0.getAuthorFactory().createLocalAuthor( - getRandomString(MAX_AUTHOR_NAME_LENGTH), - getRandomBytes(MAX_PUBLIC_KEY_LENGTH), - getRandomBytes(123)); + getRandomString(MAX_AUTHOR_NAME_LENGTH), false); blogManager0 = c0.getBlogManager(); blogManager1 = c1.getBlogManager(); diff --git a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionCryptoIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionCryptoIntegrationTest.java index 81c2ae01c..c256d102b 100644 --- a/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionCryptoIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/introduction/IntroductionCryptoIntegrationTest.java @@ -58,10 +58,8 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase { crypto = new IntroductionCryptoImpl(cryptoComponent, clientHelper); introducer = getRealAuthor(authorFactory); - LocalAuthor introducee1 = - getRealLocalAuthor(cryptoComponent, authorFactory); - LocalAuthor introducee2 = - getRealLocalAuthor(cryptoComponent, authorFactory); + LocalAuthor introducee1 = getRealLocalAuthor(authorFactory); + LocalAuthor introducee2 = getRealLocalAuthor(authorFactory); boolean isAlice = crypto.isAlice(introducee1.getId(), introducee2.getId()); alice = isAlice ? introducee1 : introducee2; diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java index 086f7f2b1..4b9357fe3 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java @@ -2,7 +2,6 @@ package org.briarproject.briar.messaging; import org.briarproject.bramble.api.UniqueId; import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.PrivateKey; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.sync.GroupId; @@ -70,12 +69,8 @@ public class MessageSizeIntegrationTest extends BriarTestCase { @Test public void testForumPostFitsIntoRecord() throws Exception { // Create a maximum-length author - int formatVersion = Integer.MAX_VALUE; String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH); - byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH]; - PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate(); - LocalAuthor author = authorFactory.createLocalAuthor(formatVersion, - authorName, authorPublic, privateKey.getEncoded()); + LocalAuthor author = authorFactory.createLocalAuthor(authorName, false); // Create a maximum-length forum post GroupId groupId = new GroupId(getRandomId()); long timestamp = Long.MAX_VALUE; diff --git a/briar-core/src/test/java/org/briarproject/briar/test/BriarTestUtils.java b/briar-core/src/test/java/org/briarproject/briar/test/BriarTestUtils.java index 9f71087eb..595d6a005 100644 --- a/briar-core/src/test/java/org/briarproject/briar/test/BriarTestUtils.java +++ b/briar-core/src/test/java/org/briarproject/briar/test/BriarTestUtils.java @@ -1,7 +1,5 @@ package org.briarproject.briar.test; -import org.briarproject.bramble.api.crypto.CryptoComponent; -import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorFactory; @@ -10,6 +8,7 @@ import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.client.MessageTracker.GroupCount; +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.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.util.StringUtils.getRandomString; @@ -27,23 +26,21 @@ public class BriarTestUtils { } public static void assertGroupCount(MessageTracker tracker, GroupId g, - long msgCount, long unreadCount) throws DbException { + long msgCount, long unreadCount) throws DbException { GroupCount c1 = tracker.getGroupCount(g); assertEquals(msgCount, c1.getMsgCount()); assertEquals(unreadCount, c1.getUnreadCount()); } public static Author getRealAuthor(AuthorFactory authorFactory) { - return authorFactory.createAuthor(getRandomString(5), - getRandomBytes(MAX_PUBLIC_KEY_LENGTH)); + String name = getRandomString(MAX_AUTHOR_NAME_LENGTH); + byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); + return authorFactory.createAuthor(name, publicKey); } - public static LocalAuthor getRealLocalAuthor( - CryptoComponent cryptoComponent, AuthorFactory authorFactory) { - KeyPair keyPair = cryptoComponent.generateSignatureKeyPair(); - return authorFactory.createLocalAuthor(getRandomString(5), - keyPair.getPublic().getEncoded(), - keyPair.getPrivate().getEncoded()); + public static LocalAuthor getRealLocalAuthor(AuthorFactory authorFactory) { + String name = getRandomString(MAX_AUTHOR_NAME_LENGTH); + return authorFactory.createLocalAuthor(name, false); } } From 00bc8ac768b751d97e7afc723d38d8595c6ac28b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 19 Apr 2019 13:34:15 +0100 Subject: [PATCH 02/17] Include handshake keys when loading all local authors. --- .../java/org/briarproject/bramble/db/JdbcDatabase.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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 2f755838c..020805c59 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 @@ -1782,7 +1782,8 @@ abstract class JdbcDatabase implements Database { ResultSet rs = null; try { String sql = "SELECT authorId, formatVersion, name, publicKey," - + " privateKey, created" + + " privateKey, handshakePublicKey, handshakePrivateKey," + + " created" + " FROM localAuthors"; ps = txn.prepareStatement(sql); rs = ps.executeQuery(); @@ -1793,9 +1794,12 @@ abstract class JdbcDatabase implements Database { String name = rs.getString(3); byte[] publicKey = rs.getBytes(4); byte[] privateKey = rs.getBytes(5); - long created = rs.getLong(6); + byte[] handshakePublicKey = rs.getBytes(6); + byte[] handshakePrivateKey = rs.getBytes(7); + long created = rs.getLong(8); authors.add(new LocalAuthor(authorId, formatVersion, name, - publicKey, privateKey, created)); + publicKey, privateKey, handshakePublicKey, + handshakePrivateKey, created)); } rs.close(); ps.close(); From f6611daf7bca072a281cfbc063edb874cb38dc3b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 22 Apr 2019 16:18:35 +0100 Subject: [PATCH 03/17] Replace Client interface with OpenDatabaseHook. --- .../bramble/api/identity/IdentityManager.java | 14 ++--- .../api/lifecycle/LifecycleManager.java | 35 +++++++----- .../briarproject/bramble/api/sync/Client.java | 14 ----- .../bramble/identity/IdentityManagerImpl.java | 11 ++-- .../bramble/identity/IdentityModule.java | 6 +- .../lifecycle/LifecycleManagerImpl.java | 57 ++++++++++--------- .../bramble/properties/PropertiesModule.java | 4 +- .../TransportPropertyManagerImpl.java | 7 ++- .../ClientVersioningManagerImpl.java | 8 +-- .../bramble/versioning/VersioningModule.java | 4 +- .../identity/IdentityManagerImplTest.java | 16 ++++-- .../TransportPropertyManagerImplTest.java | 4 +- .../bramble/test/TestLifecycleModule.java | 5 +- .../ClientVersioningManagerImplTest.java | 4 +- .../briarproject/briar/android/AppModule.java | 3 +- .../briar/android/RecentEmojiImpl.java | 6 +- .../briar/blog/BlogManagerImpl.java | 6 +- .../briarproject/briar/blog/BlogModule.java | 3 +- .../briar/feed/FeedManagerImpl.java | 9 +-- .../briarproject/briar/feed/FeedModule.java | 5 +- .../introduction/IntroductionManagerImpl.java | 6 +- .../introduction/IntroductionModule.java | 3 +- .../briar/messaging/MessagingManagerImpl.java | 7 ++- .../briar/messaging/MessagingModule.java | 3 +- .../GroupInvitationManagerImpl.java | 6 +- .../invitation/GroupInvitationModule.java | 4 +- .../briar/sharing/SharingManagerImpl.java | 6 +- .../briar/sharing/SharingModule.java | 6 +- .../briar/blog/BlogManagerImplTest.java | 4 +- .../GroupInvitationManagerImplTest.java | 8 +-- .../sharing/BlogSharingManagerImplTest.java | 8 +-- 31 files changed, 152 insertions(+), 130 deletions(-) delete mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/sync/Client.java diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java index c3bd5fcf2..5c44bcc89 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java @@ -1,8 +1,10 @@ package org.briarproject.bramble.api.identity; import org.briarproject.bramble.api.crypto.CryptoExecutor; +import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @NotNullByDefault @@ -15,17 +17,13 @@ public interface IdentityManager { LocalAuthor createLocalAuthor(String name); /** - * Registers the given local identity with the manager. The identity is - * not stored until {@link #storeLocalAuthor()} is called. + * Registers the given local identity with the manager. This method should + * be called before {@link LifecycleManager#startServices(SecretKey)}. The + * identity is stored when {@link LifecycleManager#startServices(SecretKey)} + * is called. */ void registerLocalAuthor(LocalAuthor a); - /** - * Stores the local identity registered with - * {@link #registerLocalAuthor(LocalAuthor)}, if any. - */ - void storeLocalAuthor() throws DbException; - /** * Returns the cached local identity or loads it from the database. */ diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java index 2ef340a87..4abd4b8e3 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java @@ -2,16 +2,17 @@ package org.briarproject.bramble.api.lifecycle; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import java.util.concurrent.ExecutorService; /** - * Manages the lifecycle of the app, starting {@link Client Clients}, starting - * and stopping {@link Service Services}, shutting down - * {@link ExecutorService ExecutorServices}, and opening and closing the - * {@link DatabaseComponent}. + * Manages the lifecycle of the app: opening and closing the + * {@link DatabaseComponent} starting and stopping {@link Service Services}, + * and shutting down {@link ExecutorService ExecutorServices}. */ @NotNullByDefault public interface LifecycleManager { @@ -42,18 +43,19 @@ public interface LifecycleManager { } } + /** + * Registers a hook to be called after the database is opened and before + * {@link Service services} are started. This method should be called + * before {@link #startServices(SecretKey)}. + */ + void registerOpenDatabaseHook(OpenDatabaseHook hook, Priority p); + /** * Registers a {@link Service} to be started and stopped. This method * should be called before {@link #startServices(SecretKey)}. */ void registerService(Service s); - /** - * Registers a {@link Client} to be started. This method should be called - * before {@link #startServices(SecretKey)}. - */ - void registerClient(Client c); - /** * Registers an {@link ExecutorService} to be shut down. This method * should be called before {@link #startServices(SecretKey)}. @@ -62,7 +64,7 @@ public interface LifecycleManager { /** * Opens the {@link DatabaseComponent} using the given key and starts any - * registered {@link Client Clients} and {@link Service Services}. + * registered {@link Service Services}. */ StartResult startServices(SecretKey dbKey); @@ -80,8 +82,7 @@ public interface LifecycleManager { /** * Waits for the {@link DatabaseComponent} to be opened and all registered - * {@link Client Clients} and {@link Service Services} to start before - * returning. + * {@link Service Services} to start before returning. */ void waitForStartup() throws InterruptedException; @@ -97,4 +98,10 @@ public interface LifecycleManager { */ LifecycleState getLifecycleState(); + interface OpenDatabaseHook { + + enum Priority {EARLY, NORMAL, LATE} + + void onDatabaseOpened(Transaction txn) throws DbException; + } } \ No newline at end of file diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/Client.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/Client.java deleted file mode 100644 index 956d876a3..000000000 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/Client.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.briarproject.bramble.api.sync; - -import org.briarproject.bramble.api.db.DbException; -import org.briarproject.bramble.api.db.Transaction; -import org.briarproject.bramble.api.nullsafety.NotNullByDefault; - -@NotNullByDefault -public interface Client { - - /** - * Called at startup to create any local state needed by the client. - */ - void createLocalState(Transaction txn) throws DbException; -} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index a7d515d28..4207ecb53 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -6,6 +6,7 @@ import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.util.logging.Logger; @@ -14,15 +15,16 @@ import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.now; @ThreadSafe @NotNullByDefault -class IdentityManagerImpl implements IdentityManager { +class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { private static final Logger LOG = - Logger.getLogger(IdentityManagerImpl.class.getName()); + getLogger(IdentityManagerImpl.class.getName()); private final DatabaseComponent db; private final AuthorFactory authorFactory; @@ -52,13 +54,13 @@ class IdentityManagerImpl implements IdentityManager { } @Override - public void storeLocalAuthor() throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { LocalAuthor cached = cachedAuthor; if (cached == null) { LOG.info("No local author to store"); return; } - db.transaction(false, txn -> db.addLocalAuthor(txn, cached)); + db.addLocalAuthor(txn, cached); LOG.info("Local author stored"); } @@ -89,5 +91,4 @@ class IdentityManagerImpl implements IdentityManager { private LocalAuthor loadLocalAuthor(Transaction txn) throws DbException { return db.getLocalAuthors(txn).iterator().next(); } - } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java index 950c0f383..1457b89e0 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java @@ -2,6 +2,7 @@ package org.briarproject.bramble.identity; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.IdentityManager; +import org.briarproject.bramble.api.lifecycle.LifecycleManager; import javax.inject.Inject; import javax.inject.Singleton; @@ -9,6 +10,8 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.EARLY; + @Module public class IdentityModule { @@ -24,8 +27,9 @@ public class IdentityModule { @Provides @Singleton - IdentityManager provideIdentityManager( + IdentityManager provideIdentityManager(LifecycleManager lifecycleManager, IdentityManagerImpl identityManager) { + lifecycleManager.registerOpenDatabaseHook(identityManager, EARLY); return identityManager; } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java index da55a780c..a87d6bdf2 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java @@ -1,5 +1,6 @@ package org.briarproject.bramble.lifecycle; +import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DataTooNewException; import org.briarproject.bramble.api.db.DataTooOldException; @@ -7,14 +8,14 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.event.EventBus; -import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -25,9 +26,11 @@ import java.util.logging.Logger; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; +import static java.util.Collections.sort; import static java.util.logging.Level.FINE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; @@ -49,14 +52,13 @@ import static org.briarproject.bramble.util.LogUtils.now; class LifecycleManagerImpl implements LifecycleManager, MigrationListener { private static final Logger LOG = - Logger.getLogger(LifecycleManagerImpl.class.getName()); + getLogger(LifecycleManagerImpl.class.getName()); private final DatabaseComponent db; private final EventBus eventBus; private final List services; - private final List clients; + private final List> openDatabaseHooks; private final List executors; - private final IdentityManager identityManager; private final Semaphore startStopSemaphore = new Semaphore(1); private final CountDownLatch dbLatch = new CountDownLatch(1); private final CountDownLatch startupLatch = new CountDownLatch(1); @@ -65,13 +67,11 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener { private volatile LifecycleState state = STARTING; @Inject - LifecycleManagerImpl(DatabaseComponent db, EventBus eventBus, - IdentityManager identityManager) { + LifecycleManagerImpl(DatabaseComponent db, EventBus eventBus) { this.db = db; this.eventBus = eventBus; - this.identityManager = identityManager; services = new CopyOnWriteArrayList<>(); - clients = new CopyOnWriteArrayList<>(); + openDatabaseHooks = new CopyOnWriteArrayList<>(); executors = new CopyOnWriteArrayList<>(); } @@ -83,10 +83,12 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener { } @Override - public void registerClient(Client c) { - if (LOG.isLoggable(INFO)) - LOG.info("Registering client " + c.getClass().getSimpleName()); - clients.add(c); + public void registerOpenDatabaseHook(OpenDatabaseHook hook, Priority p) { + if (LOG.isLoggable(INFO)) { + LOG.info("Registering open database hook " + + hook.getClass().getSimpleName()); + } + openDatabaseHooks.add(new Pair<>(hook, p)); } @Override @@ -102,28 +104,31 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener { return ALREADY_RUNNING; } try { - LOG.info("Starting services"); + LOG.info("Opening database"); long start = now(); - boolean reopened = db.open(dbKey, this); if (reopened) logDuration(LOG, "Reopening database", start); else logDuration(LOG, "Creating database", start); - identityManager.storeLocalAuthor(); + List> hooks = + new ArrayList<>(openDatabaseHooks); + sort(hooks, (a, b) -> a.getSecond().compareTo(b.getSecond())); + db.transaction(false, txn -> { + for (Pair pair : hooks) { + long start1 = now(); + OpenDatabaseHook hook = pair.getFirst(); + hook.onDatabaseOpened(txn); + if (LOG.isLoggable(FINE)) { + logDuration(LOG, "Calling open database hook " + + hook.getClass().getSimpleName(), start1); + } + } + }); + LOG.info("Starting services"); state = STARTING_SERVICES; dbLatch.countDown(); eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES)); - db.transaction(false, txn -> { - for (Client c : clients) { - long start1 = now(); - c.createLocalState(txn); - if (LOG.isLoggable(FINE)) { - logDuration(LOG, "Starting client " - + c.getClass().getSimpleName(), start1); - } - } - }); for (Service s : services) { start = now(); s.startService(); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java index a208f5881..5e668f295 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java @@ -15,6 +15,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID; import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION; import static org.briarproject.bramble.api.properties.TransportPropertyManager.MINOR_VERSION; @@ -48,7 +49,8 @@ public class PropertiesModule { ValidationManager validationManager, ContactManager contactManager, ClientVersioningManager clientVersioningManager, TransportPropertyManagerImpl transportPropertyManager) { - lifecycleManager.registerClient(transportPropertyManager); + lifecycleManager.registerOpenDatabaseHook(transportPropertyManager, + NORMAL); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, transportPropertyManager); contactManager.registerContactHook(transportPropertyManager); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java index 92cc32ed8..6549f070c 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/TransportPropertyManagerImpl.java @@ -13,11 +13,11 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportPropertyManager; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.GroupId; @@ -40,7 +40,8 @@ import javax.inject.Inject; @Immutable @NotNullByDefault class TransportPropertyManagerImpl implements TransportPropertyManager, - Client, ContactHook, ClientVersioningHook, IncomingMessageHook { + OpenDatabaseHook, ContactHook, ClientVersioningHook, + IncomingMessageHook { private final DatabaseComponent db; private final ClientHelper clientHelper; @@ -67,7 +68,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager, } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { if (db.containsGroup(txn, localGroup.getId())) return; db.addGroup(txn, localGroup); // Set things up for any pre-existing contacts diff --git a/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java index ccc7b41bb..7e6dd41d5 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/versioning/ClientVersioningManagerImpl.java @@ -12,10 +12,10 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; @@ -53,8 +53,8 @@ import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_ import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_KEY_UPDATE_VERSION; @NotNullByDefault -class ClientVersioningManagerImpl implements ClientVersioningManager, Client, - Service, ContactHook, IncomingMessageHook { +class ClientVersioningManagerImpl implements ClientVersioningManager, + Service, OpenDatabaseHook, ContactHook, IncomingMessageHook { private final DatabaseComponent db; private final ClientHelper clientHelper; @@ -124,7 +124,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client, } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { if (db.containsGroup(txn, localGroup.getId())) return; db.addGroup(txn, localGroup); // Set things up for any pre-existing contacts diff --git a/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java b/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java index 070e90c76..dda209e37 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java @@ -14,6 +14,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.bramble.api.versioning.ClientVersioningManager.CLIENT_ID; import static org.briarproject.bramble.api.versioning.ClientVersioningManager.MAJOR_VERSION; @@ -34,7 +35,8 @@ public class VersioningModule { ClientVersioningManagerImpl clientVersioningManager, LifecycleManager lifecycleManager, ContactManager contactManager, ValidationManager validationManager) { - lifecycleManager.registerClient(clientVersioningManager); + lifecycleManager.registerOpenDatabaseHook(clientVersioningManager, + NORMAL); lifecycleManager.registerService(clientVersioningManager); contactManager.registerContactHook(clientVersioningManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java index 896b49156..7d8e22059 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java @@ -4,7 +4,6 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.AuthorFactory; -import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.DbExpectations; @@ -27,7 +26,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { private final LocalAuthor localAuthor = getLocalAuthor(); private final Collection localAuthors = singletonList(localAuthor); - private IdentityManager identityManager; + private IdentityManagerImpl identityManager; @Before public void setUp() { @@ -35,15 +34,20 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { } @Test - public void testRegisterAndStoreLocalAuthor() throws Exception { + public void testOpenDatabaseHookWithoutLocalAuthorRegistered() + throws Exception { + identityManager.onDatabaseOpened(txn); + } + + @Test + public void testOpenDatabaseHookWithLocalAuthorRegistered() + throws Exception { context.checking(new DbExpectations() {{ - oneOf(db).transaction(with(false), withDbRunnable(txn)); oneOf(db).addLocalAuthor(txn, localAuthor); }}); identityManager.registerLocalAuthor(localAuthor); - assertEquals(localAuthor, identityManager.getLocalAuthor()); - identityManager.storeLocalAuthor(); + identityManager.onDatabaseOpened(txn); } @Test diff --git a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java index 80e338259..8ec2e8631 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/properties/TransportPropertyManagerImplTest.java @@ -115,7 +115,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { 1, true, true); TransportPropertyManagerImpl t = createInstance(); - t.createLocalState(txn); + t.onDatabaseOpened(txn); } @Test @@ -129,7 +129,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { }}); TransportPropertyManagerImpl t = createInstance(); - t.createLocalState(txn); + t.onDatabaseOpened(txn); } @Test diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java index 21f6ccfe9..5d4d627b2 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java @@ -3,10 +3,10 @@ package org.briarproject.bramble.test; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ShutdownManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -32,7 +32,8 @@ public class TestLifecycleModule { } @Override - public void registerClient(Client c) { + public void registerOpenDatabaseHook(OpenDatabaseHook hook, + Priority p) { } @Override diff --git a/bramble-core/src/test/java/org/briarproject/bramble/versioning/ClientVersioningManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/versioning/ClientVersioningManagerImplTest.java index 6a1590791..dd85557ea 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/versioning/ClientVersioningManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/versioning/ClientVersioningManagerImplTest.java @@ -83,7 +83,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase { expectAddingContact(); ClientVersioningManagerImpl c = createInstance(); - c.createLocalState(txn); + c.onDatabaseOpened(txn); } @Test @@ -95,7 +95,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase { }}); ClientVersioningManagerImpl c = createInstance(); - c.createLocalState(txn); + c.onDatabaseOpened(txn); } @Test diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index d19d6d7ea..c82cd4d30 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -56,6 +56,7 @@ import dagger.Provides; import static android.content.Context.MODE_PRIVATE; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONION_ADDRESS; import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX; @@ -226,7 +227,7 @@ public class AppModule { @Singleton RecentEmoji provideRecentEmoji(LifecycleManager lifecycleManager, RecentEmojiImpl recentEmoji) { - lifecycleManager.registerClient(recentEmoji); + lifecycleManager.registerOpenDatabaseHook(recentEmoji, NORMAL); return recentEmoji; } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/RecentEmojiImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/RecentEmojiImpl.java index ee349c1a5..f751b46d6 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/RecentEmojiImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/RecentEmojiImpl.java @@ -8,11 +8,11 @@ import com.vanniktech.emoji.emoji.Emoji; import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.settings.Settings; import org.briarproject.bramble.api.settings.SettingsManager; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.system.AndroidExecutor; import org.briarproject.bramble.util.StringUtils; @@ -30,7 +30,7 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_ @MethodsNotNullByDefault @ParametersNotNullByDefault -class RecentEmojiImpl implements RecentEmoji, Client { +class RecentEmojiImpl implements RecentEmoji, OpenDatabaseHook { private static final Logger LOG = Logger.getLogger(RecentEmojiImpl.class.getName()); @@ -72,7 +72,7 @@ class RecentEmojiImpl implements RecentEmoji, Client { } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { Settings settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE); String serialized = settings.get(EMOJI_LRU_PREFERENCE); diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java index de11cb1ea..3b24d49b2 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogManagerImpl.java @@ -18,8 +18,8 @@ import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorInfo; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.Message; @@ -68,7 +68,7 @@ import static org.briarproject.briar.api.blog.MessageType.WRAPPED_POST; @NotNullByDefault class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, - ContactHook, Client { + OpenDatabaseHook, ContactHook { private final ContactManager contactManager; private final IdentityManager identityManager; @@ -90,7 +90,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager, } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { // Create our personal blog if necessary LocalAuthor a = identityManager.getLocalAuthor(txn); Blog b = blogFactory.createBlog(a); diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java index 7e3873f36..ff60e9dd8 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java @@ -18,6 +18,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID; import static org.briarproject.briar.api.blog.BlogManager.MAJOR_VERSION; @@ -36,7 +37,7 @@ public class BlogModule { BlogManager provideBlogManager(BlogManagerImpl blogManager, LifecycleManager lifecycleManager, ContactManager contactManager, ValidationManager validationManager) { - lifecycleManager.registerClient(blogManager); + lifecycleManager.registerOpenDatabaseHook(blogManager, NORMAL); contactManager.registerContactHook(blogManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, blogManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java index cea1e169f..04350c8a6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedManagerImpl.java @@ -20,11 +20,11 @@ import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.IoExecutor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.system.Clock; @@ -32,6 +32,7 @@ import org.briarproject.bramble.api.system.Scheduler; import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.BlogManager; +import org.briarproject.briar.api.blog.BlogManager.RemoveBlogHook; import org.briarproject.briar.api.blog.BlogPost; import org.briarproject.briar.api.blog.BlogPostFactory; import org.briarproject.briar.api.feed.Feed; @@ -75,8 +76,8 @@ import static org.briarproject.briar.util.HtmlUtils.clean; @ThreadSafe @NotNullByDefault -class FeedManagerImpl implements FeedManager, Client, EventListener, - BlogManager.RemoveBlogHook { +class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook, + RemoveBlogHook { private static final Logger LOG = Logger.getLogger(FeedManagerImpl.class.getName()); @@ -136,7 +137,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener, } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { Group g = getLocalGroup(); // Return if we've already set the local group up if (db.containsGroup(txn, g.getId())) return; diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java index c4b567c18..5b82fa948 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java @@ -11,6 +11,8 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; + @Module public class FeedModule { @@ -24,8 +26,7 @@ public class FeedModule { FeedManager provideFeedManager(FeedManagerImpl feedManager, LifecycleManager lifecycleManager, EventBus eventBus, BlogManager blogManager) { - - lifecycleManager.registerClient(feedManager); + lifecycleManager.registerOpenDatabaseHook(feedManager, NORMAL); eventBus.addListener(feedManager); blogManager.registerRemoveBlogHook(feedManager); return feedManager; diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java index fd9f00804..abe54aa7a 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionManagerImpl.java @@ -19,8 +19,8 @@ import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorInfo; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.GroupId; @@ -67,7 +67,7 @@ import static org.briarproject.briar.introduction.MessageType.REQUEST; @Immutable @NotNullByDefault class IntroductionManagerImpl extends ConversationClientImpl - implements IntroductionManager, Client, ContactHook, + implements IntroductionManager, OpenDatabaseHook, ContactHook, ClientVersioningHook { private final ClientVersioningManager clientVersioningManager; @@ -115,7 +115,7 @@ class IntroductionManagerImpl extends ConversationClientImpl } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { // Create a local group to store protocol sessions if (db.containsGroup(txn, localGroup.getId())) return; db.addGroup(txn, localGroup); diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java index be80647d5..4f326ba2e 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java @@ -16,6 +16,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID; import static org.briarproject.briar.api.introduction.IntroductionManager.MAJOR_VERSION; import static org.briarproject.briar.api.introduction.IntroductionManager.MINOR_VERSION; @@ -51,7 +52,7 @@ public class IntroductionModule { ConversationManager conversationManager, ClientVersioningManager clientVersioningManager, IntroductionManagerImpl introductionManager) { - lifecycleManager.registerClient(introductionManager); + lifecycleManager.registerOpenDatabaseHook(introductionManager, NORMAL); contactManager.registerContactHook(introductionManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, introductionManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java index 2dbd584be..44073b377 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingManagerImpl.java @@ -12,8 +12,8 @@ import org.briarproject.bramble.api.data.MetadataParser; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.GroupId; @@ -50,7 +50,8 @@ import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ @Immutable @NotNullByDefault class MessagingManagerImpl extends ConversationClientImpl - implements MessagingManager, Client, ContactHook, ClientVersioningHook { + implements MessagingManager, OpenDatabaseHook, ContactHook, + ClientVersioningHook { private final ClientVersioningManager clientVersioningManager; private final ContactGroupFactory contactGroupFactory; @@ -66,7 +67,7 @@ class MessagingManagerImpl extends ConversationClientImpl } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { // Create a local group to indicate that we've set this client up Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID, MAJOR_VERSION); diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java index c806ebea3..2a64fd1cd 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java @@ -17,6 +17,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.messaging.MessagingManager.CLIENT_ID; import static org.briarproject.briar.api.messaging.MessagingManager.MAJOR_VERSION; import static org.briarproject.briar.api.messaging.MessagingManager.MINOR_VERSION; @@ -58,7 +59,7 @@ public class MessagingModule { ConversationManager conversationManager, ClientVersioningManager clientVersioningManager, MessagingManagerImpl messagingManager) { - lifecycleManager.registerClient(messagingManager); + lifecycleManager.registerOpenDatabaseHook(messagingManager, NORMAL); contactManager.registerContactHook(messagingManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, messagingManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java index c252ac787..8cd75d090 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImpl.java @@ -14,8 +14,8 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.GroupId; @@ -62,7 +62,7 @@ import static org.briarproject.briar.privategroup.invitation.Role.PEER; @Immutable @NotNullByDefault class GroupInvitationManagerImpl extends ConversationClientImpl - implements GroupInvitationManager, Client, ContactHook, + implements GroupInvitationManager, OpenDatabaseHook, ContactHook, PrivateGroupHook, ClientVersioningHook { private final ClientVersioningManager clientVersioningManager; @@ -101,7 +101,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl } @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { // Create a local group to indicate that we've set this client up Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID, MAJOR_VERSION); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java index 6960dae6b..7ec8512c6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java @@ -19,6 +19,7 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager.CLIENT_ID; import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager.MAJOR_VERSION; import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager.MINOR_VERSION; @@ -42,7 +43,8 @@ public class GroupInvitationModule { PrivateGroupManager privateGroupManager, ConversationManager conversationManager, ClientVersioningManager clientVersioningManager) { - lifecycleManager.registerClient(groupInvitationManager); + lifecycleManager.registerOpenDatabaseHook(groupInvitationManager, + NORMAL); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, groupInvitationManager); contactManager.registerContactHook(groupInvitationManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java index 38a45c5e5..481d65f09 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingManagerImpl.java @@ -13,8 +13,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group.Visibility; @@ -55,7 +55,7 @@ import static org.briarproject.briar.sharing.State.SHARING; @NotNullByDefault abstract class SharingManagerImpl extends ConversationClientImpl - implements SharingManager, Client, ContactHook, + implements SharingManager, OpenDatabaseHook, ContactHook, ClientVersioningHook { private final ClientVersioningManager clientVersioningManager; @@ -92,7 +92,7 @@ abstract class SharingManagerImpl protected abstract int getShareableMajorVersion(); @Override - public void createLocalState(Transaction txn) throws DbException { + public void onDatabaseOpened(Transaction txn) throws DbException { // Create a local group to indicate that we've set this client up Group localGroup = contactGroupFactory.createLocalGroup(getClientId(), getMajorVersion()); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java index a71d215af..8d460f369 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java @@ -25,6 +25,8 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; + @Module public class SharingModule { @@ -76,7 +78,7 @@ public class SharingModule { ConversationManager conversationManager, BlogManager blogManager, ClientVersioningManager clientVersioningManager, BlogSharingManagerImpl blogSharingManager) { - lifecycleManager.registerClient(blogSharingManager); + lifecycleManager.registerOpenDatabaseHook(blogSharingManager, NORMAL); contactManager.registerContactHook(blogSharingManager); validationManager.registerIncomingMessageHook( BlogSharingManager.CLIENT_ID, BlogSharingManager.MAJOR_VERSION, @@ -135,7 +137,7 @@ public class SharingModule { ConversationManager conversationManager, ForumManager forumManager, ClientVersioningManager clientVersioningManager, ForumSharingManagerImpl forumSharingManager) { - lifecycleManager.registerClient(forumSharingManager); + lifecycleManager.registerOpenDatabaseHook(forumSharingManager, NORMAL); contactManager.registerContactHook(forumSharingManager); validationManager.registerIncomingMessageHook( ForumSharingManager.CLIENT_ID, diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java index 7099c5ed7..b40573815 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerImplTest.java @@ -112,7 +112,7 @@ public class BlogManagerImplTest extends BriarTestCase { } @Test - public void testCreateLocalState() throws DbException { + public void testOpenDatabaseHook() throws DbException { Transaction txn = new Transaction(null, false); context.checking(new Expectations() {{ @@ -123,7 +123,7 @@ public class BlogManagerImplTest extends BriarTestCase { oneOf(db).addGroup(txn, blog1.getGroup()); }}); - blogManager.createLocalState(txn); + blogManager.onDatabaseOpened(txn); context.assertIsSatisfied(); } diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java index ca88b7285..bba390590 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/GroupInvitationManagerImplTest.java @@ -149,7 +149,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { } @Test - public void testCreateLocalStateFirstTime() throws Exception { + public void testDatabaseOpenHookFirstTime() throws Exception { context.checking(new Expectations() {{ oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID, MAJOR_VERSION); @@ -161,11 +161,11 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { will(returnValue(Collections.singletonList(contact))); }}); expectAddingContact(contact); - groupInvitationManager.createLocalState(txn); + groupInvitationManager.onDatabaseOpened(txn); } @Test - public void testCreateLocalStateSubsequentTime() throws Exception { + public void testOpenDatabaseHookSubsequentTime() throws Exception { context.checking(new Expectations() {{ oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID, MAJOR_VERSION); @@ -173,7 +173,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { oneOf(db).containsGroup(txn, localGroup.getId()); will(returnValue(true)); }}); - groupInvitationManager.createLocalState(txn); + groupInvitationManager.onDatabaseOpened(txn); } private void expectAddingContact(Contact c) throws Exception { diff --git a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java index ab14d8fdf..e89e37c0d 100644 --- a/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/sharing/BlogSharingManagerImplTest.java @@ -94,7 +94,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase { } @Test - public void testCreateLocalStateFirstTimeWithExistingContact() + public void testOpenDatabaseHookFirstTimeWithExistingContact() throws Exception { Transaction txn = new Transaction(null, false); @@ -113,7 +113,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase { // Set things up for the contact expectAddingContact(txn); - blogSharingManager.createLocalState(txn); + blogSharingManager.onDatabaseOpened(txn); } private void expectAddingContact(Transaction txn) throws Exception { @@ -149,7 +149,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase { } @Test - public void testCreateLocalStateSubsequentTime() throws Exception { + public void testOpenDatabaseHookSubsequentTime() throws Exception { Transaction txn = new Transaction(null, false); context.checking(new Expectations() {{ @@ -161,7 +161,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase { will(returnValue(true)); }}); - blogSharingManager.createLocalState(txn); + blogSharingManager.onDatabaseOpened(txn); } @Test From 8183a48ebb3a5760afc3bd14646c2a9289d848bf Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 22 Apr 2019 16:35:35 +0100 Subject: [PATCH 04/17] Add unit test for OpenDatabaseHook priority. --- .../lifecycle/LifecycleManagerImplTest.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java diff --git a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java new file mode 100644 index 000000000..37706d051 --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java @@ -0,0 +1,61 @@ +package org.briarproject.bramble.lifecycle; + +import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; +import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent; +import org.briarproject.bramble.test.BrambleMockTestCase; +import org.briarproject.bramble.test.DbExpectations; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.EARLY; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.LATE; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS; +import static org.briarproject.bramble.test.TestUtils.getSecretKey; +import static org.junit.Assert.assertEquals; + +public class LifecycleManagerImplTest extends BrambleMockTestCase { + + private final DatabaseComponent db = context.mock(DatabaseComponent.class); + private final EventBus eventBus = context.mock(EventBus.class); + + private final SecretKey dbKey = getSecretKey(); + + private LifecycleManagerImpl lifecycleManager; + + @Before + public void setUp() { + lifecycleManager = new LifecycleManagerImpl(db, eventBus); + } + + @Test + public void testOpenDatabaseHooksRunInOrderOfPriority() throws Exception { + Transaction txn = new Transaction(null, false); + List results = new ArrayList<>(); + OpenDatabaseHook hook1 = transaction -> results.add(1); + OpenDatabaseHook hook2 = transaction -> results.add(2); + OpenDatabaseHook hook3 = transaction -> results.add(3); + + context.checking(new DbExpectations() {{ + oneOf(db).open(dbKey, lifecycleManager); + will(returnValue(false)); + oneOf(db).transaction(with(false), withDbRunnable(txn)); + allowing(eventBus).broadcast(with(any(LifecycleEvent.class))); + }}); + + lifecycleManager.registerOpenDatabaseHook(hook1, LATE); + lifecycleManager.registerOpenDatabaseHook(hook2, NORMAL); + lifecycleManager.registerOpenDatabaseHook(hook3, EARLY); + + assertEquals(SUCCESS, lifecycleManager.startServices(dbKey)); + assertEquals(asList(3, 2, 1), results); + } +} From 8c315382e2322354bab436aed4f15e35041ce90d Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 22 Apr 2019 16:59:36 +0100 Subject: [PATCH 05/17] Add DB method for setting local handshake key pair. --- .../bramble/api/db/DatabaseComponent.java | 6 ++++ .../org/briarproject/bramble/db/Database.java | 6 ++++ .../bramble/db/DatabaseComponentImpl.java | 10 ++++++ .../briarproject/bramble/db/JdbcDatabase.java | 35 +++++++++++++++++-- .../bramble/db/DatabaseComponentImplTest.java | 19 ++++++++-- .../bramble/db/JdbcDatabaseTest.java | 25 +++++++++++++ 6 files changed, 95 insertions(+), 6 deletions(-) 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 15be93c50..b03eb316a 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 @@ -619,6 +619,12 @@ public interface DatabaseComponent { void addMessageDependencies(Transaction txn, Message dependent, Collection dependencies) throws DbException; + /** + * Sets the handshake key pair for the local pseudonym with the given ID. + */ + void setHandshakeKeyPair(Transaction txn, AuthorId local, byte[] publicKey, + byte[] privateKey) throws DbException; + /** * Sets the reordering window for the given transport key set in the given * time period. 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 cdad152ad..5652a1e89 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 @@ -685,6 +685,12 @@ interface Database { void setGroupVisibility(T txn, ContactId c, GroupId g, boolean shared) throws DbException; + /** + * Sets the handshake key pair for the local pseudonym with the given ID. + */ + void setHandshakeKeyPair(T txn, AuthorId local, byte[] publicKey, + byte[] privateKey) throws DbException; + /** * Marks the given message as shared. */ 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 17c3395b1..ea7973a48 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 @@ -1035,6 +1035,16 @@ class DatabaseComponentImpl implements DatabaseComponent { } } + @Override + public void setHandshakeKeyPair(Transaction transaction, AuthorId local, + byte[] publicKey, byte[] privateKey) throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsLocalAuthor(txn, local)) + throw new NoSuchLocalAuthorException(); + db.setHandshakeKeyPair(txn, local, publicKey, privateKey); + } + @Override public void setReorderingWindow(Transaction transaction, TransportKeySetId k, TransportId t, long timePeriod, long base, 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 020805c59..e87c0b34d 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 @@ -1681,10 +1681,18 @@ abstract class JdbcDatabase implements Database { byte[] handshakePublicKey = rs.getBytes(5); byte[] handshakePrivateKey = rs.getBytes(6); long created = rs.getLong(7); - LocalAuthor localAuthor = new LocalAuthor(a, formatVersion, name, - publicKey, privateKey, handshakePublicKey, - handshakePrivateKey, created); if (rs.next()) throw new DbStateException(); + LocalAuthor localAuthor; + if (handshakePublicKey == null) { + if (handshakePrivateKey != null) throw new DbStateException(); + localAuthor = new LocalAuthor(a, formatVersion, name, + publicKey, privateKey, created); + } else { + if (handshakePrivateKey == null) throw new DbStateException(); + localAuthor = new LocalAuthor(a, formatVersion, name, + publicKey, privateKey, handshakePublicKey, + handshakePrivateKey, created); + } rs.close(); ps.close(); return localAuthor; @@ -3180,6 +3188,27 @@ abstract class JdbcDatabase implements Database { } } + @Override + public void setHandshakeKeyPair(Connection txn, AuthorId local, + byte[] publicKey, byte[] privateKey) throws DbException { + PreparedStatement ps = null; + try { + String sql = "UPDATE localAuthors" + + " SET handshakePublicKey = ?, handshakePrivateKey = ?" + + " WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, publicKey); + ps.setBytes(2, privateKey); + ps.setBytes(3, local.getBytes()); + int affected = ps.executeUpdate(); + if (affected < 0 || affected > 1) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public void setMessageShared(Connection txn, MessageId m) 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 b74260e32..c7cccf1bf 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 @@ -65,6 +65,7 @@ import java.util.concurrent.atomic.AtomicReference; import static java.util.Arrays.asList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonList; +import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; @@ -79,6 +80,7 @@ import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; 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.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTransportId; @@ -436,12 +438,12 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { throws Exception { context.checking(new Expectations() {{ // Check whether the pseudonym is in the DB (which it's not) - exactly(3).of(database).startTransaction(); + exactly(4).of(database).startTransaction(); will(returnValue(txn)); - exactly(3).of(database).containsLocalAuthor(txn, + exactly(4).of(database).containsLocalAuthor(txn, localAuthor.getId()); will(returnValue(false)); - exactly(3).of(database).abortTransaction(txn); + exactly(4).of(database).abortTransaction(txn); }}); DatabaseComponent db = createDatabaseComponent(database, eventBus, eventExecutor, shutdownManager); @@ -470,6 +472,17 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { } catch (NoSuchLocalAuthorException expected) { // Expected } + + try { + byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); + byte[] privateKey = getRandomBytes(123); + db.transaction(false, transaction -> + db.setHandshakeKeyPair(transaction, localAuthor.getId(), + publicKey, privateKey)); + fail(); + } catch (NoSuchLocalAuthorException expected) { + // Expected + } } @Test 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 6daece520..0dacd18af 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 @@ -57,6 +57,7 @@ import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; import static java.util.concurrent.TimeUnit.SECONDS; import static org.briarproject.bramble.api.contact.PendingContactState.FAILED; +import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES; import static org.briarproject.bramble.api.db.Metadata.REMOVE; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE; @@ -76,6 +77,7 @@ import static org.briarproject.bramble.test.TestUtils.getGroup; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getPendingContact; +import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTestDirectory; @@ -2237,6 +2239,29 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { db.close(); } + @Test + public void testSetHandshakeKeyPair() throws Exception { + assertNull(localAuthor.getHandshakePublicKey()); + assertNull(localAuthor.getHandshakePrivateKey()); + byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); + byte[] privateKey = getRandomBytes(123); + + Database db = open(false); + Connection txn = db.startTransaction(); + + db.addLocalAuthor(txn, localAuthor); + LocalAuthor retrieved = db.getLocalAuthor(txn, localAuthor.getId()); + assertNull(retrieved.getHandshakePublicKey()); + assertNull(retrieved.getHandshakePrivateKey()); + db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey); + retrieved = db.getLocalAuthor(txn, localAuthor.getId()); + assertArrayEquals(publicKey, retrieved.getHandshakePublicKey()); + assertArrayEquals(privateKey, retrieved.getHandshakePrivateKey()); + + db.commitTransaction(txn); + db.close(); + } + private Database open(boolean resume) throws Exception { return open(resume, new TestMessageFactory(), new SystemClock()); } From 8b2b7599f9d41345388d39e90fe00bd1cd55b1ba Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 22 Apr 2019 17:55:20 +0100 Subject: [PATCH 06/17] Generate and store handshake keys at startup if needed. --- .../briarproject/bramble/test/TestUtils.java | 25 ++++-- .../bramble/identity/IdentityManagerImpl.java | 52 +++++++++---- .../identity/IdentityManagerImplTest.java | 78 +++++++++++++++---- 3 files changed, 117 insertions(+), 38 deletions(-) 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 c14cfdb72..15e0d06b6 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 @@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static java.util.Arrays.asList; import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION; +import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES; 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; @@ -100,24 +101,32 @@ public class TestUtils { } public static LocalAuthor getLocalAuthor() { - return getLocalAuthor(1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH)); + return getLocalAuthor(false); } - public static LocalAuthor getLocalAuthor(int nameLength) { + public static LocalAuthor getLocalAuthor(boolean withHandshakeKeys) { AuthorId id = new AuthorId(getRandomId()); + int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH); String name = getRandomString(nameLength); byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); - return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey, - timestamp); + if (withHandshakeKeys) { + byte[] handshakePublicKey = + getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); + byte[] handshakePrivateKey = + getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); + return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, + privateKey, handshakePublicKey, handshakePrivateKey, + timestamp); + } else { + return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, + privateKey, timestamp); + } } public static Author getAuthor() { - return getAuthor(1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH)); - } - - public static Author getAuthor(int nameLength) { AuthorId id = new AuthorId(getRandomId()); + int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH); String name = getRandomString(nameLength); byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); return new Author(id, FORMAT_VERSION, name, publicKey); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 4207ecb53..7fec3d53d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -1,5 +1,7 @@ package org.briarproject.bramble.identity; +import org.briarproject.bramble.api.crypto.CryptoComponent; +import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; @@ -9,6 +11,7 @@ import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import java.util.Collection; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -27,6 +30,7 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { getLogger(IdentityManagerImpl.class.getName()); private final DatabaseComponent db; + private final CryptoComponent crypto; private final AuthorFactory authorFactory; // The local author is immutable so we can cache it @@ -34,8 +38,10 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { private volatile LocalAuthor cachedAuthor; @Inject - IdentityManagerImpl(DatabaseComponent db, AuthorFactory authorFactory) { + IdentityManagerImpl(DatabaseComponent db, CryptoComponent crypto, + AuthorFactory authorFactory) { this.db = db; + this.crypto = crypto; this.authorFactory = authorFactory; } @@ -57,38 +63,56 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { public void onDatabaseOpened(Transaction txn) throws DbException { LocalAuthor cached = cachedAuthor; if (cached == null) { - LOG.info("No local author to store"); - return; + LocalAuthor loaded = loadLocalAuthor(txn); + if (loaded.getHandshakePublicKey() == null) { + KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); + byte[] handshakePublicKey = + handshakeKeyPair.getPublic().getEncoded(); + byte[] handshakePrivateKey = + handshakeKeyPair.getPrivate().getEncoded(); + db.setHandshakeKeyPair(txn, loaded.getId(), + handshakePublicKey, handshakePrivateKey); + cachedAuthor = new LocalAuthor(loaded.getId(), + loaded.getFormatVersion(), loaded.getName(), + loaded.getPublicKey(), loaded.getPrivateKey(), + handshakePublicKey, handshakePrivateKey, + loaded.getTimeCreated()); + LOG.info("Handshake key pair added"); + } else { + cachedAuthor = loaded; + LOG.info("Local author loaded"); + } + } else { + db.addLocalAuthor(txn, cached); + LOG.info("Local author stored"); } - db.addLocalAuthor(txn, cached); - LOG.info("Local author stored"); } @Override public LocalAuthor getLocalAuthor() throws DbException { - if (cachedAuthor == null) { - cachedAuthor = + LocalAuthor cached = cachedAuthor; + if (cached == null) { + cachedAuthor = cached = db.transactionWithResult(true, this::loadLocalAuthor); LOG.info("Local author loaded"); } - LocalAuthor cached = cachedAuthor; - if (cached == null) throw new AssertionError(); return cached; } @Override public LocalAuthor getLocalAuthor(Transaction txn) throws DbException { - if (cachedAuthor == null) { - cachedAuthor = loadLocalAuthor(txn); + LocalAuthor cached = cachedAuthor; + if (cached == null) { + cachedAuthor = cached = loadLocalAuthor(txn); LOG.info("Local author loaded"); } - LocalAuthor cached = cachedAuthor; - if (cached == null) throw new AssertionError(); return cached; } private LocalAuthor loadLocalAuthor(Transaction txn) throws DbException { - return db.getLocalAuthors(txn).iterator().next(); + Collection authors = db.getLocalAuthors(txn); + if (authors.size() != 1) throw new IllegalStateException(); + return authors.iterator().next(); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java index 7d8e22059..f1b8e000c 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java @@ -1,5 +1,9 @@ package org.briarproject.bramble.identity; +import org.briarproject.bramble.api.crypto.CryptoComponent; +import org.briarproject.bramble.api.crypto.KeyPair; +import org.briarproject.bramble.api.crypto.PrivateKey; +import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; @@ -7,42 +11,48 @@ import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.DbExpectations; +import org.jmock.Expectations; import org.junit.Before; import org.junit.Test; -import java.util.Collection; - import static java.util.Collections.singletonList; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class IdentityManagerImplTest extends BrambleMockTestCase { private final DatabaseComponent db = context.mock(DatabaseComponent.class); + private final CryptoComponent crypto = context.mock(CryptoComponent.class); private final AuthorFactory authorFactory = context.mock(AuthorFactory.class); + private final PublicKey handshakePublicKey = context.mock(PublicKey.class); + private final PrivateKey handshakePrivateKey = + context.mock(PrivateKey.class); private final Transaction txn = new Transaction(null, false); - private final LocalAuthor localAuthor = getLocalAuthor(); - private final Collection localAuthors = - singletonList(localAuthor); + private final LocalAuthor localAuthor = getLocalAuthor(true); + private final LocalAuthor localAuthorWithoutHandshakeKeys = + new LocalAuthor(localAuthor.getId(), localAuthor.getFormatVersion(), + localAuthor.getName(), localAuthor.getPublicKey(), + localAuthor.getPrivateKey(), localAuthor.getTimeCreated()); + private final KeyPair handshakeKeyPair = + new KeyPair(handshakePublicKey, handshakePrivateKey); + private final byte[] handshakePublicKeyBytes = + localAuthor.getHandshakePublicKey(); + private final byte[] handshakePrivateKeyBytes = + localAuthor.getHandshakePrivateKey(); + private IdentityManagerImpl identityManager; @Before public void setUp() { - identityManager = new IdentityManagerImpl(db, authorFactory); + identityManager = new IdentityManagerImpl(db, crypto, authorFactory); } @Test - public void testOpenDatabaseHookWithoutLocalAuthorRegistered() - throws Exception { - identityManager.onDatabaseOpened(txn); - } - - @Test - public void testOpenDatabaseHookWithLocalAuthorRegistered() - throws Exception { - context.checking(new DbExpectations() {{ + public void testOpenDatabaseHookLocalAuthorRegistered() throws Exception { + context.checking(new Expectations() {{ oneOf(db).addLocalAuthor(txn, localAuthor); }}); @@ -50,12 +60,48 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { identityManager.onDatabaseOpened(txn); } + @Test + public void testOpenDatabaseHookNoLocalAuthorRegisteredHandshakeKeys() + throws Exception { + context.checking(new Expectations() {{ + oneOf(db).getLocalAuthors(txn); + will(returnValue(singletonList(localAuthor))); + }}); + + identityManager.onDatabaseOpened(txn); + } + + @Test + public void testOpenDatabaseHookNoLocalAuthorRegisteredNoHandshakeKeys() + throws Exception { + context.checking(new Expectations() {{ + oneOf(db).getLocalAuthors(txn); + will(returnValue(singletonList(localAuthorWithoutHandshakeKeys))); + oneOf(crypto).generateAgreementKeyPair(); + will(returnValue(handshakeKeyPair)); + oneOf(handshakePublicKey).getEncoded(); + will(returnValue(handshakePublicKeyBytes)); + oneOf(handshakePrivateKey).getEncoded(); + will(returnValue(handshakePrivateKeyBytes)); + oneOf(db).setHandshakeKeyPair(txn, localAuthor.getId(), + handshakePublicKeyBytes, handshakePrivateKeyBytes); + }}); + + identityManager.onDatabaseOpened(txn); + + LocalAuthor cached = identityManager.getLocalAuthor(); + assertArrayEquals(handshakePublicKeyBytes, + cached.getHandshakePublicKey()); + assertArrayEquals(handshakePrivateKeyBytes, + cached.getHandshakePrivateKey()); + } + @Test public void testGetLocalAuthor() throws Exception { context.checking(new DbExpectations() {{ oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).getLocalAuthors(txn); - will(returnValue(localAuthors)); + will(returnValue(singletonList(localAuthor))); }}); assertEquals(localAuthor, identityManager.getLocalAuthor()); } From 251eb9e7122831d4a7bf4d60ca227f19c26e5122 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 23 Apr 2019 16:26:13 +0100 Subject: [PATCH 07/17] Add javadoc for handshakeKeys flag. --- .../org/briarproject/bramble/api/identity/AuthorFactory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java index a46d386a2..748d4c37a 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java @@ -19,6 +19,9 @@ public interface AuthorFactory { /** * Creates a local author with the current format version and the given * name. + * + * @param handshakeKeys true if the local author should include handshake + * keys. */ LocalAuthor createLocalAuthor(String name, boolean handshakeKeys); } From 56fbc93962ef2116703e601946c3f658f5b81d79 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 26 Apr 2019 15:08:40 +0100 Subject: [PATCH 08/17] Move handshake keys from LocalAuthor to Account. --- .../bramble/api/db/DatabaseComponent.java | 67 ++-- .../bramble/api/identity/Account.java | 96 ++++++ .../bramble/api/identity/AuthorFactory.java | 5 +- .../bramble/api/identity/IdentityManager.java | 17 +- .../bramble/api/identity/LocalAuthor.java | 49 +-- .../briarproject/bramble/test/TestUtils.java | 23 +- .../bramble/account/AccountManagerImpl.java | 6 +- .../org/briarproject/bramble/db/Database.java | 66 ++-- .../bramble/db/DatabaseComponentImpl.java | 102 +++---- .../briarproject/bramble/db/JdbcDatabase.java | 285 +++++++++--------- .../bramble/identity/AuthorFactoryImpl.java | 24 +- .../bramble/identity/IdentityManagerImpl.java | 91 +++--- .../account/AccountManagerImplTest.java | 12 +- .../bramble/db/DatabaseComponentImplTest.java | 46 +-- .../bramble/db/DatabasePerformanceTest.java | 26 +- .../bramble/db/JdbcDatabaseTest.java | 93 +++--- .../identity/IdentityManagerImplTest.java | 52 ++-- .../briar/feed/FeedFactoryImpl.java | 4 +- .../briar/test/TestDataCreatorImpl.java | 4 +- .../blog/BlogManagerIntegrationTest.java | 4 +- .../feed/FeedManagerIntegrationTest.java | 6 +- .../messaging/MessageSizeIntegrationTest.java | 2 +- .../SimplexMessagingIntegrationTest.java | 19 +- .../briar/test/BriarIntegrationTest.java | 16 +- .../briar/test/BriarTestUtils.java | 7 +- 25 files changed, 582 insertions(+), 540 deletions(-) create mode 100644 bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java 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 b03eb316a..d1620e2cc 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 @@ -5,9 +5,9 @@ import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; -import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.settings.Settings; @@ -101,6 +101,11 @@ public interface DatabaseComponent { R transactionWithNullableResult(boolean readOnly, NullableDbCallable task) throws DbException, E; + /** + * Stores an account. + */ + void addAccount(Transaction txn, Account a) throws DbException; + /** * Stores a contact associated with the given local and remote pseudonyms, * and returns an ID for the contact. @@ -127,11 +132,6 @@ public interface DatabaseComponent { HandshakeKeySetId addHandshakeKeys(Transaction txn, PendingContactId p, HandshakeKeys k) throws DbException; - /** - * Stores a local pseudonym. - */ - void addLocalAuthor(Transaction txn, LocalAuthor a) throws DbException; - /** * Stores a local message. */ @@ -157,6 +157,13 @@ public interface DatabaseComponent { TransportKeySetId addTransportKeys(Transaction txn, ContactId c, TransportKeys k) throws DbException; + /** + * Returns true if the database contains an account for the given pseudonym. + *

+ * Read-only. + */ + boolean containsAccount(Transaction txn, AuthorId local) throws DbException; + /** * Returns true if the database contains the given contact for the given * local pseudonym. @@ -173,14 +180,6 @@ public interface DatabaseComponent { */ boolean containsGroup(Transaction txn, GroupId g) throws DbException; - /** - * Returns true if the database contains the given local author. - *

- * Read-only. - */ - boolean containsLocalAuthor(Transaction txn, AuthorId local) - throws DbException; - /** * Returns true if the database contains the given pending contact. *

@@ -247,6 +246,20 @@ public interface DatabaseComponent { Collection generateRequestedBatch(Transaction txn, ContactId c, int maxLength, int maxLatency) throws DbException; + /** + * Returns the account for the local pseudonym with the given ID. + *

+ * Read-only. + */ + Account getAccount(Transaction txn, AuthorId a) throws DbException; + + /** + * Returns the accounts for all local pseudonyms. + *

+ * Read-only. + */ + Collection getAccounts(Transaction txn) throws DbException; + /** * Returns the contact with the given ID. *

@@ -316,20 +329,6 @@ public interface DatabaseComponent { Collection getHandshakeKeys(Transaction txn, TransportId t) throws DbException; - /** - * Returns the local pseudonym with the given ID. - *

- * Read-only. - */ - LocalAuthor getLocalAuthor(Transaction txn, AuthorId a) throws DbException; - - /** - * Returns all local pseudonyms. - *

- * Read-only. - */ - Collection getLocalAuthors(Transaction txn) throws DbException; - /** * Returns the message with the given ID. *

@@ -542,6 +541,11 @@ public interface DatabaseComponent { void receiveRequest(Transaction txn, ContactId c, Request r) throws DbException; + /** + * Removes an account (and all associated state) from the database. + */ + void removeAccount(Transaction txn, AuthorId a) throws DbException; + /** * Removes a contact (and all associated state) from the database. */ @@ -558,11 +562,6 @@ public interface DatabaseComponent { void removeHandshakeKeys(Transaction txn, TransportId t, HandshakeKeySetId k) throws DbException; - /** - * Removes a local pseudonym (and all associated state) from the database. - */ - void removeLocalAuthor(Transaction txn, AuthorId a) throws DbException; - /** * Removes a message (and all associated state) from the database. */ @@ -620,7 +619,7 @@ public interface DatabaseComponent { Collection dependencies) throws DbException; /** - * Sets the handshake key pair for the local pseudonym with the given ID. + * Sets the handshake key pair for the account with the given ID. */ void setHandshakeKeyPair(Transaction txn, AuthorId local, byte[] publicKey, byte[] privateKey) throws DbException; diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java new file mode 100644 index 000000000..dac57d197 --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java @@ -0,0 +1,96 @@ +package org.briarproject.bramble.api.identity; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; + +import java.util.Arrays; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES; + +@Immutable +@NotNullByDefault +public class Account { + + private final LocalAuthor localAuthor; + @Nullable + private final byte[] handshakePublicKey, handshakePrivateKey; + private final long created; + + public Account(LocalAuthor localAuthor, + @Nullable byte[] handshakePublicKey, + @Nullable byte[] handshakePrivateKey, long created) { + if (handshakePublicKey != null) { + int keyLength = handshakePublicKey.length; + if (keyLength == 0 || keyLength > MAX_AGREEMENT_PUBLIC_KEY_BYTES) + throw new IllegalArgumentException(); + } + this.localAuthor = localAuthor; + this.handshakePublicKey = handshakePublicKey; + this.handshakePrivateKey = handshakePrivateKey; + this.created = created; + } + + /** + * Returns the ID of the user's pseudonym. + */ + public AuthorId getId() { + return localAuthor.getId(); + } + + /** + * Returns the user's pseudonym. + */ + public LocalAuthor getLocalAuthor() { + return localAuthor; + } + + /** + * Returns true if the account has a handshake key pair. + */ + public boolean hasHandshakeKeyPair() { + return handshakePublicKey != null && handshakePrivateKey != null; + } + + /** + * Returns the public key used for handshaking, or null if no key exists. + */ + @Nullable + public byte[] getHandshakePublicKey() { + return handshakePublicKey; + } + + /** + * Returns the private key used for handshaking, or null if no key exists. + */ + @Nullable + public byte[] getHandshakePrivateKey() { + return handshakePrivateKey; + } + + /** + * Returns the time the account was created, in milliseconds since the + * Unix epoch. + */ + public long getTimeCreated() { + return created; + } + + @Override + public int hashCode() { + return localAuthor.getId().hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof Account) { + Account a = (Account) o; + return created == a.created && + localAuthor.equals(a.localAuthor) && + Arrays.equals(handshakePublicKey, a.handshakePublicKey) && + Arrays.equals(handshakePrivateKey, a.handshakePrivateKey); + } + return false; + } +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java index 748d4c37a..6423562e8 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/AuthorFactory.java @@ -19,9 +19,6 @@ public interface AuthorFactory { /** * Creates a local author with the current format version and the given * name. - * - * @param handshakeKeys true if the local author should include handshake - * keys. */ - LocalAuthor createLocalAuthor(String name, boolean handshakeKeys); + LocalAuthor createLocalAuthor(String name); } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java index 5c44bcc89..cfbdf1e68 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java @@ -17,12 +17,19 @@ public interface IdentityManager { LocalAuthor createLocalAuthor(String name); /** - * Registers the given local identity with the manager. This method should - * be called before {@link LifecycleManager#startServices(SecretKey)}. The - * identity is stored when {@link LifecycleManager#startServices(SecretKey)} - * is called. + * Creates an account with the given name. The account includes a handshake + * key pair. */ - void registerLocalAuthor(LocalAuthor a); + @CryptoExecutor + Account createAccount(String name); + + /** + * Registers the given account with the manager. This method should be + * called before {@link LifecycleManager#startServices(SecretKey)}. The + * account is stored when {@link LifecycleManager#startServices(SecretKey)} + * is called. The account must include a handshake key pair. + */ + void registerAccount(Account a); /** * Returns the cached local identity or loads it from the database. diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/LocalAuthor.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/LocalAuthor.java index 6fa29ddde..5eb9775ac 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/LocalAuthor.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/LocalAuthor.java @@ -2,11 +2,8 @@ package org.briarproject.bramble.api.identity; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; -import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; - /** * A pseudonym for the local user. */ @@ -15,31 +12,11 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K public class LocalAuthor extends Author { private final byte[] privateKey; - @Nullable - private final byte[] handshakePublicKey, handshakePrivateKey; - private final long created; public LocalAuthor(AuthorId id, int formatVersion, String name, - byte[] publicKey, byte[] privateKey, long created) { + byte[] publicKey, byte[] privateKey) { super(id, formatVersion, name, publicKey); this.privateKey = privateKey; - this.created = created; - handshakePublicKey = null; - handshakePrivateKey = null; - } - - public LocalAuthor(AuthorId id, int formatVersion, String name, - byte[] publicKey, byte[] privateKey, byte[] handshakePublicKey, - byte[] handshakePrivateKey, long created) { - super(id, formatVersion, name, publicKey); - if (handshakePublicKey.length == 0 || - handshakePublicKey.length > MAX_PUBLIC_KEY_LENGTH) { - throw new IllegalArgumentException(); - } - this.privateKey = privateKey; - this.handshakePublicKey = handshakePublicKey; - this.handshakePrivateKey = handshakePrivateKey; - this.created = created; } /** @@ -48,28 +25,4 @@ public class LocalAuthor extends Author { public byte[] getPrivateKey() { return privateKey; } - - /** - * Returns the public key used for handshaking, or null if no key exists. - */ - @Nullable - public byte[] getHandshakePublicKey() { - return handshakePublicKey; - } - - /** - * Returns the private key used for handshaking, or null if no key exists. - */ - @Nullable - public byte[] getHandshakePrivateKey() { - return handshakePrivateKey; - } - - /** - * Returns the time the pseudonym was created, in milliseconds since the - * Unix epoch. - */ - public long getTimeCreated() { - return created; - } } 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 15e0d06b6..4b765b6b0 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 @@ -6,6 +6,7 @@ import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.crypto.SecretKey; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.LocalAuthor; @@ -100,28 +101,20 @@ public class TestUtils { return new SecretKey(getRandomBytes(SecretKey.LENGTH)); } - public static LocalAuthor getLocalAuthor() { - return getLocalAuthor(false); + public static Account getAccount() { + LocalAuthor localAuthor = getLocalAuthor(); + byte[] handshakePub = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); + byte[] handshakePriv = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); + return new Account(localAuthor, handshakePub, handshakePriv, timestamp); } - public static LocalAuthor getLocalAuthor(boolean withHandshakeKeys) { + public static LocalAuthor getLocalAuthor() { AuthorId id = new AuthorId(getRandomId()); int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH); String name = getRandomString(nameLength); byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH); - if (withHandshakeKeys) { - byte[] handshakePublicKey = - getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); - byte[] handshakePrivateKey = - getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); - return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, - privateKey, handshakePublicKey, handshakePrivateKey, - timestamp); - } else { - return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, - privateKey, timestamp); - } + return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey); } public static Author getAuthor() { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java index 63c24088e..623ce50c7 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java @@ -4,8 +4,8 @@ import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseConfig; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.util.IoUtils; @@ -161,8 +161,8 @@ class AccountManagerImpl implements AccountManager { synchronized (stateChangeLock) { if (hasDatabaseKey()) throw new AssertionError("Already have a database key"); - LocalAuthor localAuthor = identityManager.createLocalAuthor(name); - identityManager.registerLocalAuthor(localAuthor); + Account account = identityManager.createAccount(name); + identityManager.registerAccount(account); SecretKey key = crypto.generateSecretKey(); if (!encryptAndStoreDatabaseKey(key, password)) return false; databaseKey = key; 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 5652a1e89..7a04daa51 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 @@ -13,9 +13,9 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MessageDeletedException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.MigrationListener; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; -import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.settings.Settings; @@ -86,6 +86,11 @@ interface Database { */ void commitTransaction(T txn) throws DbException; + /** + * Stores an account. + */ + void addAccount(T txn, Account a) throws DbException; + /** * Stores a contact associated with the given local and remote pseudonyms, * and returns an ID for the contact. @@ -119,11 +124,6 @@ interface Database { HandshakeKeySetId addHandshakeKeys(T txn, PendingContactId p, HandshakeKeys k) throws DbException; - /** - * Stores a local pseudonym. - */ - void addLocalAuthor(T txn, LocalAuthor a) throws DbException; - /** * Stores a message. * @@ -163,6 +163,13 @@ interface Database { TransportKeySetId addTransportKeys(T txn, ContactId c, TransportKeys k) throws DbException; + /** + * Returns true if the database contains an account for the given pseudonym. + *

+ * Read-only. + */ + boolean containsAccount(T txn, AuthorId a) throws DbException; + /** * Returns true if the database contains the given contact for the given * local pseudonym. @@ -186,13 +193,6 @@ interface Database { */ boolean containsGroup(T txn, GroupId g) throws DbException; - /** - * Returns true if the database contains the given local pseudonym. - *

- * Read-only. - */ - boolean containsLocalAuthor(T txn, AuthorId a) throws DbException; - /** * Returns true if the database contains the given message. *

@@ -245,6 +245,20 @@ interface Database { */ void deleteMessageMetadata(T txn, MessageId m) throws DbException; + /** + * Returns the account for local pseudonym with the given ID. + *

+ * Read-only. + */ + Account getAccount(T txn, AuthorId a) throws DbException; + + /** + * Returns the accounts for all local pseudonyms. + *

+ * Read-only. + */ + Collection getAccounts(T txn) throws DbException; + /** * Returns the contact with the given ID. *

@@ -322,20 +336,6 @@ interface Database { Collection getHandshakeKeys(T txn, TransportId t) throws DbException; - /** - * Returns the local pseudonym with the given ID. - *

- * Read-only. - */ - LocalAuthor getLocalAuthor(T txn, AuthorId a) throws DbException; - - /** - * Returns all local pseudonyms. - *

- * Read-only. - */ - Collection getLocalAuthors(T txn) throws DbException; - /** * Returns the message with the given ID. *

@@ -605,6 +605,11 @@ interface Database { */ void raiseSeenFlag(T txn, ContactId c, MessageId m) throws DbException; + /** + * Removes an account (and all associated state) from the database. + */ + void removeAccount(T txn, AuthorId a) throws DbException; + /** * Removes a contact from the database. */ @@ -628,11 +633,6 @@ interface Database { void removeHandshakeKeys(T txn, TransportId t, HandshakeKeySetId k) throws DbException; - /** - * Removes a local pseudonym (and all associated state) from the database. - */ - void removeLocalAuthor(T txn, AuthorId a) throws DbException; - /** * Removes a message (and all associated state) from the database. */ @@ -686,7 +686,7 @@ interface Database { throws DbException; /** - * Sets the handshake key pair for the local pseudonym with the given ID. + * Sets the handshake key pair for the account with the given ID. */ void setHandshakeKeyPair(T txn, AuthorId local, byte[] publicKey, byte[] privateKey) throws DbException; 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 ea7973a48..d6a240c35 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 @@ -30,9 +30,9 @@ import org.briarproject.bramble.api.db.TaskAction; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventExecutor; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; -import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent; import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent; import org.briarproject.bramble.api.lifecycle.ShutdownManager; @@ -231,15 +231,26 @@ class DatabaseComponentImpl implements DatabaseComponent { return txnClass.cast(transaction.unbox()); } + @Override + public void addAccount(Transaction transaction, Account a) + throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsAccount(txn, a.getId())) { + db.addAccount(txn, a); + transaction.attach(new LocalAuthorAddedEvent(a.getId())); + } + } + @Override public ContactId addContact(Transaction transaction, Author remote, AuthorId local, boolean verified) throws DbException { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, local)) + if (!db.containsAccount(txn, local)) throw new NoSuchLocalAuthorException(); - if (db.containsLocalAuthor(txn, remote.getId())) + if (db.containsAccount(txn, remote.getId())) throw new ContactExistsException(); if (db.containsContact(txn, remote.getId(), local)) throw new ContactExistsException(); @@ -282,17 +293,6 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.addHandshakeKeys(txn, p, k); } - @Override - public void addLocalAuthor(Transaction transaction, LocalAuthor a) - throws DbException { - if (transaction.isReadOnly()) throw new IllegalArgumentException(); - T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, a.getId())) { - db.addLocalAuthor(txn, a); - transaction.attach(new LocalAuthorAddedEvent(a.getId())); - } - } - @Override public void addLocalMessage(Transaction transaction, Message m, Metadata meta, boolean shared) throws DbException { @@ -341,11 +341,18 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.addTransportKeys(txn, c, k); } + @Override + public boolean containsAccount(Transaction transaction, AuthorId local) + throws DbException { + T txn = unbox(transaction); + return db.containsAccount(txn, local); + } + @Override public boolean containsContact(Transaction transaction, AuthorId remote, AuthorId local) throws DbException { T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, local)) + if (!db.containsAccount(txn, local)) throw new NoSuchLocalAuthorException(); return db.containsContact(txn, remote, local); } @@ -357,13 +364,6 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.containsGroup(txn, g); } - @Override - public boolean containsLocalAuthor(Transaction transaction, AuthorId local) - throws DbException { - T txn = unbox(transaction); - return db.containsLocalAuthor(txn, local); - } - @Override public boolean containsPendingContact(Transaction transaction, PendingContactId p) throws DbException { @@ -478,6 +478,22 @@ class DatabaseComponentImpl implements DatabaseComponent { return messages; } + @Override + public Account getAccount(Transaction transaction, AuthorId a) + throws DbException { + T txn = unbox(transaction); + if (!db.containsAccount(txn, a)) + throw new NoSuchLocalAuthorException(); + return db.getAccount(txn, a); + } + + @Override + public Collection getAccounts(Transaction transaction) + throws DbException { + T txn = unbox(transaction); + return db.getAccounts(txn); + } + @Override public Contact getContact(Transaction transaction, ContactId c) throws DbException { @@ -505,7 +521,7 @@ class DatabaseComponentImpl implements DatabaseComponent { public Collection getContacts(Transaction transaction, AuthorId a) throws DbException { T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, a)) + if (!db.containsAccount(txn, a)) throw new NoSuchLocalAuthorException(); return db.getContacts(txn, a); } @@ -553,22 +569,6 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.getHandshakeKeys(txn, t); } - @Override - public LocalAuthor getLocalAuthor(Transaction transaction, AuthorId a) - throws DbException { - T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, a)) - throw new NoSuchLocalAuthorException(); - return db.getLocalAuthor(txn, a); - } - - @Override - public Collection getLocalAuthors(Transaction transaction) - throws DbException { - T txn = unbox(transaction); - return db.getLocalAuthors(txn); - } - @Override public Message getMessage(Transaction transaction, MessageId m) throws DbException { @@ -868,6 +868,17 @@ class DatabaseComponentImpl implements DatabaseComponent { if (requested) transaction.attach(new MessageRequestedEvent(c)); } + @Override + public void removeAccount(Transaction transaction, AuthorId a) + throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsAccount(txn, a)) + throw new NoSuchLocalAuthorException(); + db.removeAccount(txn, a); + transaction.attach(new LocalAuthorRemovedEvent(a)); + } + @Override public void removeContact(Transaction transaction, ContactId c) throws DbException { @@ -904,17 +915,6 @@ class DatabaseComponentImpl implements DatabaseComponent { db.removeHandshakeKeys(txn, t, k); } - @Override - public void removeLocalAuthor(Transaction transaction, AuthorId a) - throws DbException { - if (transaction.isReadOnly()) throw new IllegalArgumentException(); - T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, a)) - throw new NoSuchLocalAuthorException(); - db.removeLocalAuthor(txn, a); - transaction.attach(new LocalAuthorRemovedEvent(a)); - } - @Override public void removeMessage(Transaction transaction, MessageId m) throws DbException { @@ -1040,7 +1040,7 @@ class DatabaseComponentImpl implements DatabaseComponent { byte[] publicKey, byte[] privateKey) throws DbException { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); - if (!db.containsLocalAuthor(txn, local)) + if (!db.containsAccount(txn, local)) throw new NoSuchLocalAuthorException(); db.setHandshakeKeyPair(txn, local, publicKey, privateKey); } 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 e87c0b34d..755d7e8ab 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 @@ -13,6 +13,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MessageDeletedException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.MigrationListener; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.LocalAuthor; @@ -661,6 +662,35 @@ abstract class JdbcDatabase implements Database { if (interrupted) Thread.currentThread().interrupt(); } + @Override + public void addAccount(Connection txn, Account a) throws DbException { + PreparedStatement ps = null; + try { + String sql = "INSERT INTO localAuthors" + + " (authorId, formatVersion, name, publicKey, privateKey," + + " handshakePublicKey, handshakePrivateKey, created)" + + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + ps = txn.prepareStatement(sql); + LocalAuthor local = a.getLocalAuthor(); + ps.setBytes(1, local.getId().getBytes()); + ps.setInt(2, local.getFormatVersion()); + ps.setString(3, local.getName()); + ps.setBytes(4, local.getPublicKey()); + ps.setBytes(5, local.getPrivateKey()); + if (a.getHandshakePublicKey() == null) ps.setNull(6, BINARY); + else ps.setBytes(6, a.getHandshakePublicKey()); + if (a.getHandshakePrivateKey() == null) ps.setNull(7, BINARY); + else ps.setBytes(7, a.getHandshakePrivateKey()); + ps.setLong(8, a.getTimeCreated()); + int affected = ps.executeUpdate(); + if (affected != 1) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public ContactId addContact(Connection txn, Author remote, AuthorId local, boolean verified) throws DbException { @@ -873,35 +903,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public void addLocalAuthor(Connection txn, LocalAuthor a) - throws DbException { - PreparedStatement ps = null; - try { - String sql = "INSERT INTO localAuthors" - + " (authorId, formatVersion, name, publicKey, privateKey," - + " handshakePublicKey, handshakePrivateKey, created)" - + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getId().getBytes()); - ps.setInt(2, a.getFormatVersion()); - ps.setString(3, a.getName()); - ps.setBytes(4, a.getPublicKey()); - ps.setBytes(5, a.getPrivateKey()); - if (a.getHandshakePublicKey() == null) ps.setNull(6, BINARY); - else ps.setBytes(6, a.getHandshakePublicKey()); - if (a.getHandshakePrivateKey() == null) ps.setNull(7, BINARY); - else ps.setBytes(7, a.getHandshakePrivateKey()); - ps.setLong(8, a.getTimeCreated()); - int affected = ps.executeUpdate(); - if (affected != 1) throw new DbStateException(); - ps.close(); - } catch (SQLException e) { - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public void addMessage(Connection txn, Message m, MessageState state, boolean messageShared, @Nullable ContactId sender) @@ -1179,6 +1180,28 @@ abstract class JdbcDatabase implements Database { } } + @Override + public boolean containsAccount(Connection txn, AuthorId a) + throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT NULL FROM localAuthors WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, a.getBytes()); + rs = ps.executeQuery(); + boolean found = rs.next(); + if (rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + return found; + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public boolean containsContact(Connection txn, AuthorId remote, AuthorId local) throws DbException { @@ -1247,28 +1270,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public boolean containsLocalAuthor(Connection txn, AuthorId a) - throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - String sql = "SELECT NULL FROM localAuthors WHERE authorId = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getBytes()); - rs = ps.executeQuery(); - boolean found = rs.next(); - if (rs.next()) throw new DbStateException(); - rs.close(); - ps.close(); - return found; - } catch (SQLException e) { - tryToClose(rs, LOG, WARNING); - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public boolean containsMessage(Connection txn, MessageId m) throws DbException { @@ -1426,6 +1427,76 @@ abstract class JdbcDatabase implements Database { } } + @Override + public Account getAccount(Connection txn, AuthorId a) throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT formatVersion, name, publicKey, privateKey," + + " handshakePublicKey, handshakePrivateKey, created" + + " FROM localAuthors" + + " WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, a.getBytes()); + rs = ps.executeQuery(); + if (!rs.next()) throw new DbStateException(); + int formatVersion = rs.getInt(1); + String name = rs.getString(2); + byte[] publicKey = rs.getBytes(3); + byte[] privateKey = rs.getBytes(4); + byte[] handshakePublicKey = rs.getBytes(5); + byte[] handshakePrivateKey = rs.getBytes(6); + long created = rs.getLong(7); + if (rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + LocalAuthor local = new LocalAuthor(a, formatVersion, name, + publicKey, privateKey); + return new Account(local, handshakePublicKey, handshakePrivateKey, + created); + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + + @Override + public Collection getAccounts(Connection txn) throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT authorId, formatVersion, name, publicKey," + + " privateKey, handshakePublicKey, handshakePrivateKey," + + " created" + + " FROM localAuthors"; + ps = txn.prepareStatement(sql); + rs = ps.executeQuery(); + List accounts = new ArrayList<>(); + while (rs.next()) { + AuthorId authorId = new AuthorId(rs.getBytes(1)); + int formatVersion = rs.getInt(2); + String name = rs.getString(3); + byte[] publicKey = rs.getBytes(4); + byte[] privateKey = rs.getBytes(5); + byte[] handshakePublicKey = rs.getBytes(6); + byte[] handshakePrivateKey = rs.getBytes(7); + long created = rs.getLong(8); + LocalAuthor local = new LocalAuthor(authorId, formatVersion, + name, publicKey, privateKey); + accounts.add(new Account(local, handshakePublicKey, + handshakePrivateKey, created)); + } + rs.close(); + ps.close(); + return accounts; + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public Contact getContact(Connection txn, ContactId c) throws DbException { PreparedStatement ps = null; @@ -1660,49 +1731,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public LocalAuthor getLocalAuthor(Connection txn, AuthorId a) - throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - String sql = "SELECT formatVersion, name, publicKey, privateKey," - + " handshakePublicKey, handshakePrivateKey, created" - + " FROM localAuthors" - + " WHERE authorId = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getBytes()); - rs = ps.executeQuery(); - if (!rs.next()) throw new DbStateException(); - int formatVersion = rs.getInt(1); - String name = rs.getString(2); - byte[] publicKey = rs.getBytes(3); - byte[] privateKey = rs.getBytes(4); - byte[] handshakePublicKey = rs.getBytes(5); - byte[] handshakePrivateKey = rs.getBytes(6); - long created = rs.getLong(7); - if (rs.next()) throw new DbStateException(); - LocalAuthor localAuthor; - if (handshakePublicKey == null) { - if (handshakePrivateKey != null) throw new DbStateException(); - localAuthor = new LocalAuthor(a, formatVersion, name, - publicKey, privateKey, created); - } else { - if (handshakePrivateKey == null) throw new DbStateException(); - localAuthor = new LocalAuthor(a, formatVersion, name, - publicKey, privateKey, handshakePublicKey, - handshakePrivateKey, created); - } - rs.close(); - ps.close(); - return localAuthor; - } catch (SQLException e) { - tryToClose(rs, LOG, WARNING); - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public Collection getHandshakeKeys(Connection txn, TransportId t) throws DbException { @@ -1783,42 +1811,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public Collection getLocalAuthors(Connection txn) - throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - String sql = "SELECT authorId, formatVersion, name, publicKey," - + " privateKey, handshakePublicKey, handshakePrivateKey," - + " created" - + " FROM localAuthors"; - ps = txn.prepareStatement(sql); - rs = ps.executeQuery(); - List authors = new ArrayList<>(); - while (rs.next()) { - AuthorId authorId = new AuthorId(rs.getBytes(1)); - int formatVersion = rs.getInt(2); - String name = rs.getString(3); - byte[] publicKey = rs.getBytes(4); - byte[] privateKey = rs.getBytes(5); - byte[] handshakePublicKey = rs.getBytes(6); - byte[] handshakePrivateKey = rs.getBytes(7); - long created = rs.getLong(8); - authors.add(new LocalAuthor(authorId, formatVersion, name, - publicKey, privateKey, handshakePublicKey, - handshakePrivateKey, created)); - } - rs.close(); - ps.close(); - return authors; - } catch (SQLException e) { - tryToClose(rs, LOG, WARNING); - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public Message getMessage(Connection txn, MessageId m) throws DbException { PreparedStatement ps = null; @@ -2887,6 +2879,22 @@ abstract class JdbcDatabase implements Database { } } + @Override + public void removeAccount(Connection txn, AuthorId a) throws DbException { + PreparedStatement ps = null; + try { + String sql = "DELETE FROM localAuthors WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, a.getBytes()); + int affected = ps.executeUpdate(); + if (affected != 1) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public void removeContact(Connection txn, ContactId c) throws DbException { @@ -2969,23 +2977,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public void removeLocalAuthor(Connection txn, AuthorId a) - throws DbException { - PreparedStatement ps = null; - try { - String sql = "DELETE FROM localAuthors WHERE authorId = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getBytes()); - int affected = ps.executeUpdate(); - if (affected != 1) throw new DbStateException(); - ps.close(); - } catch (SQLException e) { - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public void removeMessage(Connection txn, MessageId m) throws DbException { PreparedStatement ps = null; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java index 0f444c74a..c0a125a1d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/AuthorFactoryImpl.java @@ -7,7 +7,6 @@ import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.util.ByteUtils; import org.briarproject.bramble.util.StringUtils; @@ -23,12 +22,10 @@ import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES; class AuthorFactoryImpl implements AuthorFactory { private final CryptoComponent crypto; - private final Clock clock; @Inject - AuthorFactoryImpl(CryptoComponent crypto, Clock clock) { + AuthorFactoryImpl(CryptoComponent crypto) { this.crypto = crypto; - this.clock = clock; } @Override @@ -44,21 +41,12 @@ class AuthorFactoryImpl implements AuthorFactory { } @Override - public LocalAuthor createLocalAuthor(String name, boolean handshakeKeys) { + public LocalAuthor createLocalAuthor(String name) { KeyPair signatureKeyPair = crypto.generateSignatureKeyPair(); - byte[] sigPub = signatureKeyPair.getPublic().getEncoded(); - byte[] sigPriv = signatureKeyPair.getPrivate().getEncoded(); - AuthorId id = getId(FORMAT_VERSION, name, sigPub); - if (handshakeKeys) { - KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); - byte[] handPub = handshakeKeyPair.getPublic().getEncoded(); - byte[] handPriv = handshakeKeyPair.getPrivate().getEncoded(); - return new LocalAuthor(id, FORMAT_VERSION, name, sigPub, sigPriv, - handPub, handPriv, clock.currentTimeMillis()); - } else { - return new LocalAuthor(id, FORMAT_VERSION, name, sigPub, sigPriv, - clock.currentTimeMillis()); - } + byte[] publicKey = signatureKeyPair.getPublic().getEncoded(); + byte[] privateKey = signatureKeyPair.getPrivate().getEncoded(); + AuthorId id = getId(FORMAT_VERSION, name, publicKey); + return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey); } private AuthorId getId(int formatVersion, String name, byte[] publicKey) { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 7fec3d53d..3f2c0a6f9 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -5,11 +5,13 @@ import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.api.system.Clock; import java.util.Collection; import java.util.logging.Logger; @@ -32,87 +34,94 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { private final DatabaseComponent db; private final CryptoComponent crypto; private final AuthorFactory authorFactory; + private final Clock clock; - // The local author is immutable so we can cache it @Nullable - private volatile LocalAuthor cachedAuthor; + private volatile Account cachedAccount; @Inject IdentityManagerImpl(DatabaseComponent db, CryptoComponent crypto, - AuthorFactory authorFactory) { + AuthorFactory authorFactory, Clock clock) { this.db = db; this.crypto = crypto; this.authorFactory = authorFactory; + this.clock = clock; } @Override public LocalAuthor createLocalAuthor(String name) { long start = now(); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(name, true); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(name); logDuration(LOG, "Creating local author", start); return localAuthor; } @Override - public void registerLocalAuthor(LocalAuthor a) { - cachedAuthor = a; - LOG.info("Local author registered"); + public Account createAccount(String name) { + long start = now(); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(name); + KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); + byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); + byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded(); + logDuration(LOG, "Creating account", start); + return new Account(localAuthor, handshakePub, handshakePriv, + clock.currentTimeMillis()); + } + + @Override + public void registerAccount(Account a) { + if (!a.hasHandshakeKeyPair()) throw new IllegalArgumentException(); + cachedAccount = a; + LOG.info("Account registered"); } @Override public void onDatabaseOpened(Transaction txn) throws DbException { - LocalAuthor cached = cachedAuthor; + Account cached = cachedAccount; if (cached == null) { - LocalAuthor loaded = loadLocalAuthor(txn); - if (loaded.getHandshakePublicKey() == null) { - KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); - byte[] handshakePublicKey = - handshakeKeyPair.getPublic().getEncoded(); - byte[] handshakePrivateKey = - handshakeKeyPair.getPrivate().getEncoded(); - db.setHandshakeKeyPair(txn, loaded.getId(), - handshakePublicKey, handshakePrivateKey); - cachedAuthor = new LocalAuthor(loaded.getId(), - loaded.getFormatVersion(), loaded.getName(), - loaded.getPublicKey(), loaded.getPrivateKey(), - handshakePublicKey, handshakePrivateKey, - loaded.getTimeCreated()); - LOG.info("Handshake key pair added"); + cached = loadAccount(txn); + if (cached.hasHandshakeKeyPair()) { + cachedAccount = cached; + LOG.info("Account loaded"); } else { - cachedAuthor = loaded; - LOG.info("Local author loaded"); + KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); + byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); + byte[] handshakePriv = + handshakeKeyPair.getPrivate().getEncoded(); + db.setHandshakeKeyPair(txn, cached.getId(), handshakePub, + handshakePriv); + LOG.info("Handshake key pair stored"); } } else { - db.addLocalAuthor(txn, cached); - LOG.info("Local author stored"); + db.addAccount(txn, cached); + LOG.info("Account stored"); } } @Override public LocalAuthor getLocalAuthor() throws DbException { - LocalAuthor cached = cachedAuthor; + Account cached = cachedAccount; if (cached == null) { - cachedAuthor = cached = - db.transactionWithResult(true, this::loadLocalAuthor); - LOG.info("Local author loaded"); + cachedAccount = cached = + db.transactionWithResult(true, this::loadAccount); + LOG.info("Account loaded"); } - return cached; + return cached.getLocalAuthor(); } - @Override public LocalAuthor getLocalAuthor(Transaction txn) throws DbException { - LocalAuthor cached = cachedAuthor; + Account cached = cachedAccount; if (cached == null) { - cachedAuthor = cached = loadLocalAuthor(txn); - LOG.info("Local author loaded"); + cachedAccount = cached = loadAccount(txn); + LOG.info("Account loaded"); } - return cached; + return cached.getLocalAuthor(); } - private LocalAuthor loadLocalAuthor(Transaction txn) throws DbException { - Collection authors = db.getLocalAuthors(txn); - if (authors.size() != 1) throw new IllegalStateException(); - return authors.iterator().next(); + private Account loadAccount(Transaction txn) throws DbException { + Collection accounts = db.getAccounts(txn); + if (accounts.size() != 1) throw new DbException(); + return accounts.iterator().next(); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java index 84c5da72f..f1e5f84ff 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java @@ -3,6 +3,7 @@ package org.briarproject.bramble.account; import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseConfig; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.test.BrambleMockTestCase; @@ -24,7 +25,7 @@ import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; -import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; +import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTestDirectory; @@ -47,7 +48,8 @@ public class AccountManagerImplTest extends BrambleMockTestCase { private final String encryptedKeyHex = toHexString(encryptedKey); private final byte[] newEncryptedKey = getRandomBytes(123); private final String newEncryptedKeyHex = toHexString(newEncryptedKey); - private final LocalAuthor localAuthor = getLocalAuthor(); + private final Account account = getAccount(); + private final LocalAuthor localAuthor = account.getLocalAuthor(); private final String authorName = localAuthor.getName(); private final String password = getRandomString(10); private final String newPassword = getRandomString(10); @@ -251,9 +253,9 @@ public class AccountManagerImplTest extends BrambleMockTestCase { @Test public void testCreateAccountStoresDbKey() throws Exception { context.checking(new Expectations() {{ - oneOf(identityManager).createLocalAuthor(authorName); - will(returnValue(localAuthor)); - oneOf(identityManager).registerLocalAuthor(localAuthor); + oneOf(identityManager).createAccount(authorName); + will(returnValue(account)); + oneOf(identityManager).registerAccount(account); oneOf(crypto).generateSecretKey(); will(returnValue(key)); oneOf(crypto).encryptWithPassword(key.getBytes(), password); 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 c7cccf1bf..cfd71418e 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 @@ -17,6 +17,7 @@ import org.briarproject.bramble.api.db.NoSuchPendingContactException; import org.briarproject.bramble.api.db.NoSuchTransportException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventBus; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent; @@ -74,11 +75,11 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERE import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN; import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE; import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES; +import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getGroup; -import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; @@ -106,6 +107,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { private final GroupId groupId; private final Group group; private final Author author; + private final Account account; private final LocalAuthor localAuthor; private final String alias; private final Message message, message1; @@ -124,7 +126,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { group = getGroup(clientId, majorVersion); groupId = group.getId(); author = getAuthor(); - localAuthor = getLocalAuthor(); + account = getAccount(); + localAuthor = account.getLocalAuthor(); message = getMessage(groupId); message1 = getMessage(groupId); messageId = message.getId(); @@ -159,15 +162,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { // startTransaction() oneOf(database).startTransaction(); will(returnValue(txn)); - // registerLocalAuthor() - oneOf(database).containsLocalAuthor(txn, localAuthor.getId()); + // addAccount() + oneOf(database).containsAccount(txn, localAuthor.getId()); will(returnValue(false)); - oneOf(database).addLocalAuthor(txn, localAuthor); + oneOf(database).addAccount(txn, account); oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class))); // addContact() - oneOf(database).containsLocalAuthor(txn, localAuthor.getId()); + oneOf(database).containsAccount(txn, localAuthor.getId()); will(returnValue(true)); - oneOf(database).containsLocalAuthor(txn, author.getId()); + oneOf(database).containsAccount(txn, author.getId()); will(returnValue(false)); oneOf(database).containsContact(txn, author.getId(), localAuthor.getId()); @@ -203,10 +206,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { will(returnValue(true)); oneOf(database).removeContact(txn, contactId); oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class))); - // removeLocalAuthor() - oneOf(database).containsLocalAuthor(txn, localAuthor.getId()); + // removeAccount() + oneOf(database).containsAccount(txn, localAuthor.getId()); will(returnValue(true)); - oneOf(database).removeLocalAuthor(txn, localAuthor.getId()); + oneOf(database).removeAccount(txn, localAuthor.getId()); oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class))); // endTransaction() oneOf(database).commitTransaction(txn); @@ -218,7 +221,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { assertFalse(db.open(key, null)); db.transaction(false, transaction -> { - db.addLocalAuthor(transaction, localAuthor); + db.addAccount(transaction, account); assertEquals(contactId, db.addContact(transaction, author, localAuthor.getId(), true)); assertEquals(singletonList(contact), @@ -229,7 +232,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.getGroups(transaction, clientId, majorVersion)); db.removeGroup(transaction, group); db.removeContact(transaction, contactId); - db.removeLocalAuthor(transaction, localAuthor.getId()); + db.removeAccount(transaction, localAuthor.getId()); }); db.close(); } @@ -434,14 +437,13 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { } @Test - public void testVariousMethodsThrowExceptionIfLocalAuthorIsMissing() + public void testVariousMethodsThrowExceptionIfAccountIsMissing() throws Exception { context.checking(new Expectations() {{ - // Check whether the pseudonym is in the DB (which it's not) + // Check whether the account is in the DB (which it's not) exactly(4).of(database).startTransaction(); will(returnValue(txn)); - exactly(4).of(database).containsLocalAuthor(txn, - localAuthor.getId()); + exactly(4).of(database).containsAccount(txn, localAuthor.getId()); will(returnValue(false)); exactly(4).of(database).abortTransaction(txn); }}); @@ -459,7 +461,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { try { db.transaction(false, transaction -> - db.getLocalAuthor(transaction, localAuthor.getId())); + db.getAccount(transaction, localAuthor.getId())); fail(); } catch (NoSuchLocalAuthorException expected) { // Expected @@ -467,7 +469,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { try { db.transaction(false, transaction -> - db.removeLocalAuthor(transaction, localAuthor.getId())); + db.removeAccount(transaction, localAuthor.getId())); fail(); } catch (NoSuchLocalAuthorException expected) { // Expected @@ -1416,10 +1418,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { context.checking(new Expectations() {{ oneOf(database).startTransaction(); will(returnValue(txn)); - oneOf(database).containsLocalAuthor(txn, localAuthor.getId()); + oneOf(database).containsAccount(txn, localAuthor.getId()); will(returnValue(true)); // Contact is a local identity - oneOf(database).containsLocalAuthor(txn, author.getId()); + oneOf(database).containsAccount(txn, author.getId()); will(returnValue(true)); oneOf(database).abortTransaction(txn); }}); @@ -1442,9 +1444,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { context.checking(new Expectations() {{ oneOf(database).startTransaction(); will(returnValue(txn)); - oneOf(database).containsLocalAuthor(txn, localAuthor.getId()); + oneOf(database).containsAccount(txn, localAuthor.getId()); will(returnValue(true)); - oneOf(database).containsLocalAuthor(txn, author.getId()); + oneOf(database).containsAccount(txn, author.getId()); will(returnValue(false)); // Contact already exists for this local identity oneOf(database).containsContact(txn, author.getId(), diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java index 055f29050..bdc3cc0a1 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java @@ -4,6 +4,7 @@ import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Metadata; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.sync.ClientId; @@ -35,9 +36,9 @@ import static java.util.logging.Level.OFF; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS; import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; +import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getGroup; -import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; @@ -161,11 +162,11 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { } @Test - public void testContainsLocalAuthor() throws Exception { - String name = "containsLocalAuthor(T, AuthorId)"; + public void testContainsAccount() throws Exception { + String name = "containsAccount(T, AuthorId)"; benchmark(name, db -> { Connection txn = db.startTransaction(); - db.containsLocalAuthor(txn, localAuthor.getId()); + db.containsAccount(txn, localAuthor.getId()); db.commitTransaction(txn); }); } @@ -295,21 +296,21 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { } @Test - public void testGetLocalAuthor() throws Exception { - String name = "getLocalAuthor(T, AuthorId)"; + public void testGetAccount() throws Exception { + String name = "getAccount(T, AuthorId)"; benchmark(name, db -> { Connection txn = db.startTransaction(); - db.getLocalAuthor(txn, localAuthor.getId()); + db.getAccount(txn, localAuthor.getId()); db.commitTransaction(txn); }); } @Test - public void testGetLocalAuthors() throws Exception { - String name = "getLocalAuthors(T)"; + public void testGetAccounts() throws Exception { + String name = "getAccounts(T)"; benchmark(name, db -> { Connection txn = db.startTransaction(); - db.getLocalAuthors(txn); + db.getAccounts(txn); db.commitTransaction(txn); }); } @@ -531,7 +532,8 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { } void populateDatabase(Database db) throws DbException { - localAuthor = getLocalAuthor(); + Account account = getAccount(); + localAuthor = account.getLocalAuthor(); clientIds = new ArrayList<>(); contacts = new ArrayList<>(); groups = new ArrayList<>(); @@ -543,7 +545,7 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { for (int i = 0; i < CLIENTS; i++) clientIds.add(getClientId()); Connection txn = db.startTransaction(); - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); for (int i = 0; i < CONTACTS; i++) { ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(), random.nextBoolean()); 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 0dacd18af..db6223c05 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 @@ -8,6 +8,7 @@ import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MessageDeletedException; import org.briarproject.bramble.api.db.Metadata; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.plugin.TransportId; @@ -71,10 +72,10 @@ import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPAC import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY; import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; +import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getGroup; -import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getPendingContact; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; @@ -105,6 +106,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { private final int majorVersion; private final Group group; private final Author author; + private final Account account; private final LocalAuthor localAuthor; private final Message message; private final MessageId messageId; @@ -121,7 +123,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { group = getGroup(clientId, majorVersion); groupId = group.getId(); author = getAuthor(); - localAuthor = getLocalAuthor(); + account = getAccount(); + localAuthor = account.getLocalAuthor(); message = getMessage(groupId); messageId = message.getId(); transportId = getTransportId(); @@ -147,7 +150,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); assertFalse(db.containsContact(txn, contactId)); - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); assertTrue(db.containsContact(txn, contactId)); @@ -210,7 +213,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -241,7 +244,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared but unvalidated message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -286,7 +289,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, an invisible group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -337,7 +340,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and an unshared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -368,7 +371,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -395,7 +398,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact and a visible group - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -436,7 +439,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -568,7 +571,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact and a shared group - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -588,7 +591,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); @@ -606,7 +609,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, an invisible group and a message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -625,7 +628,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact and a group - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -677,7 +680,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); // Add the contact, the transport and the transport keys - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -778,7 +781,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(emptyList(), db.getHandshakeKeys(txn, transportId)); // Add the contact, the transport and the handshake keys - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -931,7 +934,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and transport keys - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -975,7 +978,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and handshake keys - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -1022,7 +1025,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and transport keys - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -1069,7 +1072,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and handshake keys - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -1111,8 +1114,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); - // Add a local author - no contacts should be associated - db.addLocalAuthor(txn, localAuthor); + // Add an account for a local author - no contacts should be associated + db.addAccount(txn, account); // Add a contact associated with the local author assertEquals(contactId, @@ -1138,8 +1141,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); - // Add a local author - no contacts should be associated - db.addLocalAuthor(txn, localAuthor); + // Add an account for a local author - no contacts should be associated + db.addAccount(txn, account); Collection contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(emptyList(), contacts); @@ -1150,8 +1153,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(singletonList(contactId), contacts); - // Remove the local author - the contact should be removed - db.removeLocalAuthor(txn, localAuthor.getId()); + // Remove the account - the contact should be removed + db.removeAccount(txn, localAuthor.getId()); contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(emptyList(), contacts); assertFalse(db.containsContact(txn, contactId)); @@ -1166,7 +1169,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact - initially there should be no offered messages - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); assertEquals(0, db.countOfferedMessages(txn, contactId)); @@ -1750,7 +1753,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -1852,14 +1855,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { @Test public void testDifferentLocalAuthorsCanHaveTheSameContact() throws Exception { - LocalAuthor localAuthor1 = getLocalAuthor(); + Account account1 = getAccount(); + LocalAuthor localAuthor1 = account1.getLocalAuthor(); Database db = open(false); Connection txn = db.startTransaction(); - // Add two local authors - db.addLocalAuthor(txn, localAuthor); - db.addLocalAuthor(txn, localAuthor1); + // Add accounts for two local authors + db.addAccount(txn, account); + db.addAccount(txn, account1); // Add the same contact for each local author ContactId contactId = @@ -1883,7 +1887,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -1937,7 +1941,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); @@ -1994,7 +1998,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a group and a message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -2078,7 +2082,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -2123,7 +2127,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addLocalAuthor(txn, localAuthor); + db.addAccount(txn, account); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -2241,20 +2245,21 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { @Test public void testSetHandshakeKeyPair() throws Exception { - assertNull(localAuthor.getHandshakePublicKey()); - assertNull(localAuthor.getHandshakePrivateKey()); + Account withoutKeys = + new Account(localAuthor, null, null, account.getTimeCreated()); + assertFalse(withoutKeys.hasHandshakeKeyPair()); byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); byte[] privateKey = getRandomBytes(123); Database db = open(false); Connection txn = db.startTransaction(); - db.addLocalAuthor(txn, localAuthor); - LocalAuthor retrieved = db.getLocalAuthor(txn, localAuthor.getId()); - assertNull(retrieved.getHandshakePublicKey()); - assertNull(retrieved.getHandshakePrivateKey()); + db.addAccount(txn, withoutKeys); + Account retrieved = db.getAccount(txn, localAuthor.getId()); + assertFalse(retrieved.hasHandshakeKeyPair()); db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey); - retrieved = db.getLocalAuthor(txn, localAuthor.getId()); + retrieved = db.getAccount(txn, localAuthor.getId()); + assertTrue(retrieved.hasHandshakeKeyPair()); assertArrayEquals(publicKey, retrieved.getHandshakePublicKey()); assertArrayEquals(privateKey, retrieved.getHandshakePrivateKey()); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java index f1b8e000c..76f5189c0 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java @@ -7,8 +7,10 @@ import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.LocalAuthor; +import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.DbExpectations; import org.jmock.Expectations; @@ -16,8 +18,7 @@ import org.junit.Before; import org.junit.Test; import static java.util.Collections.singletonList; -import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; -import static org.junit.Assert.assertArrayEquals; +import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.junit.Assert.assertEquals; public class IdentityManagerImplTest extends BrambleMockTestCase { @@ -26,57 +27,58 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { private final CryptoComponent crypto = context.mock(CryptoComponent.class); private final AuthorFactory authorFactory = context.mock(AuthorFactory.class); + private final Clock clock = context.mock(Clock.class); private final PublicKey handshakePublicKey = context.mock(PublicKey.class); private final PrivateKey handshakePrivateKey = context.mock(PrivateKey.class); private final Transaction txn = new Transaction(null, false); - private final LocalAuthor localAuthor = getLocalAuthor(true); - private final LocalAuthor localAuthorWithoutHandshakeKeys = - new LocalAuthor(localAuthor.getId(), localAuthor.getFormatVersion(), - localAuthor.getName(), localAuthor.getPublicKey(), - localAuthor.getPrivateKey(), localAuthor.getTimeCreated()); + private final Account accountWithKeys = getAccount(); + private final LocalAuthor localAuthor = accountWithKeys.getLocalAuthor(); + private final Account accountWithoutKeys = new Account(localAuthor, + null, null, accountWithKeys.getTimeCreated()); private final KeyPair handshakeKeyPair = new KeyPair(handshakePublicKey, handshakePrivateKey); private final byte[] handshakePublicKeyBytes = - localAuthor.getHandshakePublicKey(); + accountWithKeys.getHandshakePublicKey(); private final byte[] handshakePrivateKeyBytes = - localAuthor.getHandshakePrivateKey(); + accountWithKeys.getHandshakePrivateKey(); private IdentityManagerImpl identityManager; @Before public void setUp() { - identityManager = new IdentityManagerImpl(db, crypto, authorFactory); + identityManager = + new IdentityManagerImpl(db, crypto, authorFactory, clock); } @Test - public void testOpenDatabaseHookLocalAuthorRegistered() throws Exception { + public void testOpenDatabaseHookAccountRegistered() throws Exception { context.checking(new Expectations() {{ - oneOf(db).addLocalAuthor(txn, localAuthor); + oneOf(db).addAccount(txn, accountWithKeys); }}); - identityManager.registerLocalAuthor(localAuthor); + identityManager.registerAccount(accountWithKeys); identityManager.onDatabaseOpened(txn); } @Test - public void testOpenDatabaseHookNoLocalAuthorRegisteredHandshakeKeys() + public void testOpenDatabaseHookNoAccountRegisteredHandshakeKeys() throws Exception { context.checking(new Expectations() {{ - oneOf(db).getLocalAuthors(txn); - will(returnValue(singletonList(localAuthor))); + oneOf(db).getAccounts(txn); + will(returnValue(singletonList(accountWithKeys))); }}); identityManager.onDatabaseOpened(txn); } @Test - public void testOpenDatabaseHookNoLocalAuthorRegisteredNoHandshakeKeys() + public void testOpenDatabaseHookNoAccountRegisteredNoHandshakeKeys() throws Exception { context.checking(new Expectations() {{ - oneOf(db).getLocalAuthors(txn); - will(returnValue(singletonList(localAuthorWithoutHandshakeKeys))); + oneOf(db).getAccounts(txn); + will(returnValue(singletonList(accountWithoutKeys))); oneOf(crypto).generateAgreementKeyPair(); will(returnValue(handshakeKeyPair)); oneOf(handshakePublicKey).getEncoded(); @@ -88,27 +90,21 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { }}); identityManager.onDatabaseOpened(txn); - - LocalAuthor cached = identityManager.getLocalAuthor(); - assertArrayEquals(handshakePublicKeyBytes, - cached.getHandshakePublicKey()); - assertArrayEquals(handshakePrivateKeyBytes, - cached.getHandshakePrivateKey()); } @Test public void testGetLocalAuthor() throws Exception { context.checking(new DbExpectations() {{ oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); - oneOf(db).getLocalAuthors(txn); - will(returnValue(singletonList(localAuthor))); + oneOf(db).getAccounts(txn); + will(returnValue(singletonList(accountWithKeys))); }}); assertEquals(localAuthor, identityManager.getLocalAuthor()); } @Test public void testGetCachedLocalAuthor() throws DbException { - identityManager.registerLocalAuthor(localAuthor); + identityManager.registerAccount(accountWithKeys); assertEquals(localAuthor, identityManager.getLocalAuthor()); } diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java index de73abc2d..8a0b41776 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedFactoryImpl.java @@ -50,7 +50,7 @@ class FeedFactoryImpl implements FeedFactory { if (title == null) title = "RSS"; else title = StringUtils.truncateUtf8(title, MAX_AUTHOR_NAME_LENGTH); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(title, false); + LocalAuthor localAuthor = authorFactory.createLocalAuthor(title); Blog blog = blogFactory.createFeedBlog(localAuthor); long added = clock.currentTimeMillis(); @@ -74,7 +74,7 @@ class FeedFactoryImpl implements FeedFactory { Author author = clientHelper.parseAndValidateAuthor(authorList); LocalAuthor localAuthor = new LocalAuthor(author.getId(), author.getFormatVersion(), author.getName(), - author.getPublicKey(), privateKey, 0); + author.getPublicKey(), privateKey); Blog blog = blogFactory.createFeedBlog(localAuthor); String desc = d.getOptionalString(KEY_FEED_DESC); diff --git a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java index 6cfdf6b7a..ea9512aa9 100644 --- a/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/test/TestDataCreatorImpl.java @@ -192,7 +192,7 @@ public class TestDataCreatorImpl implements TestDataCreator { @Override public Contact addContact(String name) throws DbException { LocalAuthor localAuthor = identityManager.getLocalAuthor(); - LocalAuthor remote = authorFactory.createLocalAuthor(name, false); + LocalAuthor remote = authorFactory.createLocalAuthor(name); return addContact(localAuthor.getId(), remote); } @@ -202,7 +202,7 @@ public class TestDataCreatorImpl implements TestDataCreator { } private LocalAuthor getRandomAuthor() { - return authorFactory.createLocalAuthor(getRandomAuthorName(), false); + return authorFactory.createLocalAuthor(getRandomAuthorName()); } private SecretKey getSecretKey() { diff --git a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java index 98e984275..feff9a197 100644 --- a/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/blog/BlogManagerIntegrationTest.java @@ -48,8 +48,8 @@ public class BlogManagerIntegrationTest author0 = identityManager0.getLocalAuthor(); author1 = identityManager1.getLocalAuthor(); - rssAuthor = c0.getAuthorFactory().createLocalAuthor( - getRandomString(MAX_AUTHOR_NAME_LENGTH), false); + String rssTitle = getRandomString(MAX_AUTHOR_NAME_LENGTH); + rssAuthor = c0.getAuthorFactory().createLocalAuthor(rssTitle); blogManager0 = c0.getBlogManager(); blogManager1 = c1.getBlogManager(); diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java index 09498c5c6..53187d0e8 100644 --- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java @@ -1,7 +1,7 @@ package org.briarproject.briar.feed; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.contact.ContactModule; import org.briarproject.bramble.crypto.CryptoExecutorModule; @@ -51,8 +51,8 @@ public class FeedManagerIntegrationTest extends BriarTestCase { injectEagerSingletons(component); IdentityManager identityManager = component.getIdentityManager(); - LocalAuthor localAuthor = identityManager.createLocalAuthor("feedTest"); - identityManager.registerLocalAuthor(localAuthor); + Account account = identityManager.createAccount("feedTest"); + identityManager.registerAccount(account); lifecycleManager = component.getLifecycleManager(); lifecycleManager.startServices(getSecretKey()); diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java index 4b9357fe3..d0b6ea1de 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/MessageSizeIntegrationTest.java @@ -70,7 +70,7 @@ public class MessageSizeIntegrationTest extends BriarTestCase { public void testForumPostFitsIntoRecord() throws Exception { // Create a maximum-length author String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH); - LocalAuthor author = authorFactory.createLocalAuthor(authorName, false); + LocalAuthor author = authorFactory.createLocalAuthor(authorName); // Create a maximum-length forum post GroupId groupId = new GroupId(getRandomId()); long timestamp = Long.MAX_VALUE; diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java index bbe1baaf3..1be17fbb9 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java @@ -5,9 +5,9 @@ import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.IdentityManager; -import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; @@ -75,13 +75,14 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase { @Test public void testWriteAndRead() throws Exception { // Create the identities - LocalAuthor aliceAuthor = - alice.getIdentityManager().createLocalAuthor("Alice"); - LocalAuthor bobAuthor = - bob.getIdentityManager().createLocalAuthor("Bob"); + Account aliceAccount = + alice.getIdentityManager().createAccount("Alice"); + Account bobAccount = bob.getIdentityManager().createAccount("Bob"); // Set up the devices and get the contact IDs - ContactId bobId = setUp(alice, aliceAuthor, bobAuthor, true); - ContactId aliceId = setUp(bob, bobAuthor, aliceAuthor, false); + ContactId bobId = setUp(alice, aliceAccount, + bobAccount.getLocalAuthor(), true); + ContactId aliceId = setUp(bob, bobAccount, + aliceAccount.getLocalAuthor(), false); // Add a private message listener PrivateMessageListener listener = new PrivateMessageListener(); bob.getEventBus().addListener(listener); @@ -100,10 +101,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase { } private ContactId setUp(SimplexMessagingIntegrationTestComponent device, - LocalAuthor local, Author remote, boolean alice) throws Exception { + Account local, Author remote, boolean alice) throws Exception { // Add an identity for the user IdentityManager identityManager = device.getIdentityManager(); - identityManager.registerLocalAuthor(local); + identityManager.registerAccount(local); // Start the lifecycle manager LifecycleManager lifecycleManager = device.getLifecycleManager(); lifecycleManager.startServices(getSecretKey()); 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 2c5e6505c..e92a416ca 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 @@ -15,6 +15,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; +import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; @@ -274,12 +275,15 @@ public abstract class BriarIntegrationTest Date: Fri, 26 Apr 2019 16:42:36 +0100 Subject: [PATCH 09/17] Add javadocs to DB hook interfaces. --- .../bramble/api/client/BdfIncomingMessageHook.java | 3 ++- .../bramble/api/contact/ContactManager.java | 12 ++++++++++++ .../bramble/api/lifecycle/LifecycleManager.java | 3 +++ .../api/sync/validation/IncomingMessageHook.java | 3 ++- .../api/versioning/ClientVersioningManager.java | 9 ++++++++- .../briarproject/briar/api/blog/BlogManager.java | 6 ++++++ .../briarproject/briar/api/forum/ForumManager.java | 6 ++++++ .../briar/api/privategroup/PrivateGroupManager.java | 13 +++++++++++++ 8 files changed, 52 insertions(+), 3 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfIncomingMessageHook.java b/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfIncomingMessageHook.java index 4b3f76795..e99aec8ba 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfIncomingMessageHook.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/client/BdfIncomingMessageHook.java @@ -33,7 +33,8 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook { /** * Called once for each incoming message that passes validation. * - * @return whether or not this message should be shared + * @param txn A read-write transaction + * @return Whether or not this message should be shared * @throws DbException Should only be used for real database errors. * If this is thrown, delivery will be attempted again at next startup, * whereas if a FormatException is thrown, the message will be permanently 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 75e61ccc1..dc60fc5c0 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 @@ -164,8 +164,20 @@ public interface ContactManager { interface ContactHook { + /** + * Called when a contact is being added. + * + * @param txn A read-write transaction + * @param c The contact that is being added + */ void addingContact(Transaction txn, Contact c) throws DbException; + /** + * Called when a contact is being removed + * + * @param txn A read-write transaction + * @param c The contact that is being removed + */ void removingContact(Transaction txn, Contact c) throws DbException; } } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java index 4abd4b8e3..4bc82918a 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java @@ -102,6 +102,9 @@ public interface LifecycleManager { enum Priority {EARLY, NORMAL, LATE} + /** + * @param txn A read-write transaction + */ void onDatabaseOpened(Transaction txn) throws DbException; } } \ No newline at end of file diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/validation/IncomingMessageHook.java b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/validation/IncomingMessageHook.java index 9d14b1a1e..356f54248 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/sync/validation/IncomingMessageHook.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/sync/validation/IncomingMessageHook.java @@ -11,7 +11,8 @@ public interface IncomingMessageHook { /** * Called once for each incoming message that passes validation. * - * @return whether or not this message should be shared + * @param txn A read-write transaction + * @return Whether or not this message should be shared * @throws DbException Should only be used for real database errors. * If this is thrown, delivery will be attempted again at next startup, * whereas if an InvalidMessageException is thrown, diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/versioning/ClientVersioningManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/versioning/ClientVersioningManager.java index 76b261d1b..53baed068 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/versioning/ClientVersioningManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/versioning/ClientVersioningManager.java @@ -46,7 +46,14 @@ public interface ClientVersioningManager { ClientId clientId, int majorVersion) throws DbException; interface ClientVersioningHook { - + /** + * Called when the visibility of a client with respect to a contact is + * changing. + * + * @param txn A read-write transaction + * @param c The contact affected by the visibility change + * @param v The new visibility of the client + */ void onClientVisibilityChanging(Transaction txn, Contact c, Visibility v) throws DbException; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java index 27ac12bac..78d4fc354 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/blog/BlogManager.java @@ -124,6 +124,12 @@ public interface BlogManager { void registerRemoveBlogHook(RemoveBlogHook hook); interface RemoveBlogHook { + /** + * Called when a blog is being removed. + * + * @param txn A read-write transaction + * @param b The blog that is being removed + */ void removingBlog(Transaction txn, Blog b) throws DbException; } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumManager.java b/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumManager.java index 75297693a..b8b9f5ca2 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/forum/ForumManager.java @@ -100,6 +100,12 @@ public interface ForumManager { void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException; interface RemoveForumHook { + /** + * Called when a forum is being removed. + * + * @param txn A read-write transaction + * @param f The forum that is being removed + */ void removingForum(Transaction txn, Forum f) throws DbException; } } diff --git a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/PrivateGroupManager.java b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/PrivateGroupManager.java index 6ef9e0259..d47c49f9a 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/privategroup/PrivateGroupManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/privategroup/PrivateGroupManager.java @@ -140,9 +140,22 @@ public interface PrivateGroupManager { @NotNullByDefault interface PrivateGroupHook { + /** + * Called when a member is being added to a private group. + * + * @param txn A read-write transaction + * @param g The ID of the private group + * @param a The member that is being added + */ void addingMember(Transaction txn, GroupId g, Author a) throws DbException; + /** + * Called when a private group is being removed. + * + * @param txn A read-write transaction + * @param g The ID of the private group that is being removed + */ void removingGroup(Transaction txn, GroupId g) throws DbException; } From faba9a6b70d004de9541ae1e34fd19a6ab6bf6c6 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 26 Apr 2019 17:49:07 +0100 Subject: [PATCH 10/17] Generate handshake keys on demand, store when DB is opened. --- .../bramble/api/identity/IdentityManager.java | 11 +++ .../bramble/identity/IdentityManagerImpl.java | 82 +++++++++++++------ .../identity/IdentityManagerImplTest.java | 56 ++++++++----- 3 files changed, 106 insertions(+), 43 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java index cfbdf1e68..6856fbbb8 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java @@ -38,7 +38,18 @@ public interface IdentityManager { /** * Returns the cached local identity or loads it from the database. + *

+ * Read-only. */ LocalAuthor getLocalAuthor(Transaction txn) throws DbException; + /** + * Returns the cached handshake keys or loads them from the database. + *

+ * Read-only. + * + * @return A two-element array containing the public key in the first + * element and the private key in the second + */ + byte[][] getHandshakeKeys(Transaction txn) throws DbException; } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 3f2c0a6f9..e1662b570 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -21,6 +21,7 @@ import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull; import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.now; @@ -36,8 +37,27 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { private final AuthorFactory authorFactory; private final Clock clock; + /** + * The user's account, or null if no account has been registered or loaded. + * If non-null, this account always has handshake keys. + */ @Nullable - private volatile Account cachedAccount; + private volatile Account cachedAccount = null; + + /** + * True if {@code cachedAccount} was registered via + * {@link #registerAccount(Account)} and should be stored when + * {@link #onDatabaseOpened(Transaction)} is called. + */ + + private volatile boolean shouldStoreAccount = false; + + /** + * True if the handshake keys in {@code cachedAccount} were generated when + * the account was loaded and should be stored when + * {@link #onDatabaseOpened(Transaction)} is called. + */ + private volatile boolean shouldStoreKeys = false; @Inject IdentityManagerImpl(DatabaseComponent db, CryptoComponent crypto, @@ -72,29 +92,24 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { public void registerAccount(Account a) { if (!a.hasHandshakeKeyPair()) throw new IllegalArgumentException(); cachedAccount = a; + shouldStoreAccount = true; LOG.info("Account registered"); } @Override public void onDatabaseOpened(Transaction txn) throws DbException { Account cached = cachedAccount; - if (cached == null) { - cached = loadAccount(txn); - if (cached.hasHandshakeKeyPair()) { - cachedAccount = cached; - LOG.info("Account loaded"); - } else { - KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); - byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); - byte[] handshakePriv = - handshakeKeyPair.getPrivate().getEncoded(); - db.setHandshakeKeyPair(txn, cached.getId(), handshakePub, - handshakePriv); - LOG.info("Handshake key pair stored"); - } - } else { + if (cached == null) + cachedAccount = cached = loadAccountWithKeyPair(txn); + if (shouldStoreAccount) { db.addAccount(txn, cached); LOG.info("Account stored"); + } else if (shouldStoreKeys) { + requireNonNull(cached); + byte[] publicKey = requireNonNull(cached.getHandshakePublicKey()); + byte[] privateKey = requireNonNull(cached.getHandshakePrivateKey()); + db.setHandshakeKeyPair(txn, cached.getId(), publicKey, privateKey); + LOG.info("Handshake key pair stored"); } } @@ -102,9 +117,8 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { public LocalAuthor getLocalAuthor() throws DbException { Account cached = cachedAccount; if (cached == null) { - cachedAccount = cached = - db.transactionWithResult(true, this::loadAccount); - LOG.info("Account loaded"); + cachedAccount = cached = db.transactionWithResult(true, + this::loadAccountWithKeyPair); } return cached.getLocalAuthor(); } @@ -112,13 +126,35 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { @Override public LocalAuthor getLocalAuthor(Transaction txn) throws DbException { Account cached = cachedAccount; - if (cached == null) { - cachedAccount = cached = loadAccount(txn); - LOG.info("Account loaded"); - } + if (cached == null) + cachedAccount = cached = loadAccountWithKeyPair(txn); return cached.getLocalAuthor(); } + @Override + public byte[][] getHandshakeKeys(Transaction txn) throws DbException { + Account cached = cachedAccount; + if (cached == null) + cachedAccount = cached = loadAccountWithKeyPair(txn); + return new byte[][] { + cached.getHandshakePublicKey(), + cached.getHandshakePrivateKey() + }; + } + + private Account loadAccountWithKeyPair(Transaction txn) throws DbException { + Account a = loadAccount(txn); + LOG.info("Account loaded"); + if (a.hasHandshakeKeyPair()) return a; + KeyPair keyPair = crypto.generateAgreementKeyPair(); + byte[] publicKey = keyPair.getPublic().getEncoded(); + byte[] privateKey = keyPair.getPrivate().getEncoded(); + LOG.info("Handshake key pair generated"); + shouldStoreKeys = true; + return new Account(a.getLocalAuthor(), publicKey, privateKey, + a.getTimeCreated()); + } + private Account loadAccount(Transaction txn) throws DbException { Collection accounts = db.getAccounts(txn); if (accounts.size() != 1) throw new DbException(); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java index 76f5189c0..5333cba7e 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java @@ -53,7 +53,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { } @Test - public void testOpenDatabaseHookAccountRegistered() throws Exception { + public void testOpenDatabaseAccountRegistered() throws Exception { context.checking(new Expectations() {{ oneOf(db).addAccount(txn, accountWithKeys); }}); @@ -63,19 +63,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { } @Test - public void testOpenDatabaseHookNoAccountRegisteredHandshakeKeys() - throws Exception { - context.checking(new Expectations() {{ - oneOf(db).getAccounts(txn); - will(returnValue(singletonList(accountWithKeys))); - }}); - - identityManager.onDatabaseOpened(txn); - } - - @Test - public void testOpenDatabaseHookNoAccountRegisteredNoHandshakeKeys() - throws Exception { + public void testOpenDatabaseHandshakeKeysGenerated() throws Exception { context.checking(new Expectations() {{ oneOf(db).getAccounts(txn); will(returnValue(singletonList(accountWithoutKeys))); @@ -93,18 +81,46 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { } @Test - public void testGetLocalAuthor() throws Exception { + public void testOpenDatabaseNoHandshakeKeysGenerated() throws Exception { + context.checking(new Expectations() {{ + oneOf(db).getAccounts(txn); + will(returnValue(singletonList(accountWithKeys))); + }}); + + identityManager.onDatabaseOpened(txn); + } + + @Test + public void testGetLocalAuthorAccountRegistered() throws DbException { + identityManager.registerAccount(accountWithKeys); + assertEquals(localAuthor, identityManager.getLocalAuthor()); + } + + @Test + public void testGetLocalAuthorHandshakeKeysGenerated() throws Exception { + context.checking(new DbExpectations() {{ + oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); + oneOf(db).getAccounts(txn); + will(returnValue(singletonList(accountWithoutKeys))); + oneOf(crypto).generateAgreementKeyPair(); + will(returnValue(handshakeKeyPair)); + oneOf(handshakePublicKey).getEncoded(); + will(returnValue(handshakePublicKeyBytes)); + oneOf(handshakePrivateKey).getEncoded(); + will(returnValue(handshakePrivateKeyBytes)); + }}); + + assertEquals(localAuthor, identityManager.getLocalAuthor()); + } + + @Test + public void testGetLocalAuthorNoHandshakeKeysGenerated() throws Exception { context.checking(new DbExpectations() {{ oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).getAccounts(txn); will(returnValue(singletonList(accountWithKeys))); }}); - assertEquals(localAuthor, identityManager.getLocalAuthor()); - } - @Test - public void testGetCachedLocalAuthor() throws DbException { - identityManager.registerAccount(accountWithKeys); assertEquals(localAuthor, identityManager.getLocalAuthor()); } From 0c99ef0e5b8b304423b094bd8e7c6544c12b5239 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 26 Apr 2019 17:56:31 +0100 Subject: [PATCH 11/17] Clean up some duplicated code. --- .../bramble/identity/IdentityManagerImpl.java | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index e1662b570..6f342bbda 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -98,9 +98,7 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { @Override public void onDatabaseOpened(Transaction txn) throws DbException { - Account cached = cachedAccount; - if (cached == null) - cachedAccount = cached = loadAccountWithKeyPair(txn); + Account cached = getCachedAccount(txn); if (shouldStoreAccount) { db.addAccount(txn, cached); LOG.info("Account stored"); @@ -116,32 +114,32 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { @Override public LocalAuthor getLocalAuthor() throws DbException { Account cached = cachedAccount; - if (cached == null) { - cachedAccount = cached = db.transactionWithResult(true, - this::loadAccountWithKeyPair); - } + if (cached == null) + cached = db.transactionWithResult(true, this::getCachedAccount); return cached.getLocalAuthor(); } @Override public LocalAuthor getLocalAuthor(Transaction txn) throws DbException { - Account cached = cachedAccount; - if (cached == null) - cachedAccount = cached = loadAccountWithKeyPair(txn); - return cached.getLocalAuthor(); + return getCachedAccount(txn).getLocalAuthor(); } @Override public byte[][] getHandshakeKeys(Transaction txn) throws DbException { - Account cached = cachedAccount; - if (cached == null) - cachedAccount = cached = loadAccountWithKeyPair(txn); + Account cached = getCachedAccount(txn); return new byte[][] { cached.getHandshakePublicKey(), cached.getHandshakePrivateKey() }; } + private Account getCachedAccount(Transaction txn) throws DbException { + Account cached = cachedAccount; + if (cached == null) + cachedAccount = cached = loadAccountWithKeyPair(txn); + return cached; + } + private Account loadAccountWithKeyPair(Transaction txn) throws DbException { Account a = loadAccount(txn); LOG.info("Account loaded"); From ebae1037be9cd3ba0337efedcf042b1058db8df7 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 26 Apr 2019 17:58:08 +0100 Subject: [PATCH 12/17] Remove unnecessary null check. --- .../org/briarproject/bramble/identity/IdentityManagerImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 6f342bbda..13c7f3a93 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -103,7 +103,6 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { db.addAccount(txn, cached); LOG.info("Account stored"); } else if (shouldStoreKeys) { - requireNonNull(cached); byte[] publicKey = requireNonNull(cached.getHandshakePublicKey()); byte[] privateKey = requireNonNull(cached.getHandshakePrivateKey()); db.setHandshakeKeyPair(txn, cached.getId(), publicKey, privateKey); From 2cce0f5fe20e48e171dbaf871bcde4293b8fa5c9 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 29 Apr 2019 12:02:10 +0100 Subject: [PATCH 13/17] Remove OpenDatabaseHook priorities. --- .../api/lifecycle/LifecycleManager.java | 9 ++++---- .../bramble/identity/IdentityModule.java | 4 +--- .../lifecycle/LifecycleManagerImpl.java | 17 +++++--------- .../bramble/properties/PropertiesModule.java | 4 +--- .../bramble/versioning/VersioningModule.java | 4 +--- .../lifecycle/LifecycleManagerImplTest.java | 22 ++++++------------- .../bramble/test/TestLifecycleModule.java | 4 +--- .../briarproject/briar/android/AppModule.java | 3 +-- .../briarproject/briar/blog/BlogModule.java | 3 +-- .../briarproject/briar/feed/FeedModule.java | 4 +--- .../introduction/IntroductionModule.java | 3 +-- .../briar/messaging/MessagingModule.java | 3 +-- .../invitation/GroupInvitationModule.java | 4 +--- .../briar/sharing/SharingModule.java | 6 ++--- 14 files changed, 28 insertions(+), 62 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java index 4bc82918a..b5980e4ba 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java @@ -4,7 +4,6 @@ import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; -import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.util.concurrent.ExecutorService; @@ -48,7 +47,7 @@ public interface LifecycleManager { * {@link Service services} are started. This method should be called * before {@link #startServices(SecretKey)}. */ - void registerOpenDatabaseHook(OpenDatabaseHook hook, Priority p); + void registerOpenDatabaseHook(OpenDatabaseHook hook); /** * Registers a {@link Service} to be started and stopped. This method @@ -99,10 +98,10 @@ public interface LifecycleManager { LifecycleState getLifecycleState(); interface OpenDatabaseHook { - - enum Priority {EARLY, NORMAL, LATE} - /** + * Called when the database is being opened, before + * {@link #waitForDatabase()} returns. + * * @param txn A read-write transaction */ void onDatabaseOpened(Transaction txn) throws DbException; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java index 1457b89e0..725e931e9 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityModule.java @@ -10,8 +10,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.EARLY; - @Module public class IdentityModule { @@ -29,7 +27,7 @@ public class IdentityModule { @Singleton IdentityManager provideIdentityManager(LifecycleManager lifecycleManager, IdentityManagerImpl identityManager) { - lifecycleManager.registerOpenDatabaseHook(identityManager, EARLY); + lifecycleManager.registerOpenDatabaseHook(identityManager); return identityManager; } } diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java index a87d6bdf2..d749f616a 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java @@ -1,6 +1,5 @@ package org.briarproject.bramble.lifecycle; -import org.briarproject.bramble.api.Pair; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DataTooNewException; import org.briarproject.bramble.api.db.DataTooOldException; @@ -9,13 +8,11 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -26,7 +23,6 @@ import java.util.logging.Logger; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; -import static java.util.Collections.sort; import static java.util.logging.Level.FINE; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; @@ -57,7 +53,7 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener { private final DatabaseComponent db; private final EventBus eventBus; private final List services; - private final List> openDatabaseHooks; + private final List openDatabaseHooks; private final List executors; private final Semaphore startStopSemaphore = new Semaphore(1); private final CountDownLatch dbLatch = new CountDownLatch(1); @@ -83,12 +79,12 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener { } @Override - public void registerOpenDatabaseHook(OpenDatabaseHook hook, Priority p) { + public void registerOpenDatabaseHook(OpenDatabaseHook hook) { if (LOG.isLoggable(INFO)) { LOG.info("Registering open database hook " + hook.getClass().getSimpleName()); } - openDatabaseHooks.add(new Pair<>(hook, p)); + openDatabaseHooks.add(hook); } @Override @@ -109,13 +105,10 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener { boolean reopened = db.open(dbKey, this); if (reopened) logDuration(LOG, "Reopening database", start); else logDuration(LOG, "Creating database", start); - List> hooks = - new ArrayList<>(openDatabaseHooks); - sort(hooks, (a, b) -> a.getSecond().compareTo(b.getSecond())); + db.transaction(false, txn -> { - for (Pair pair : hooks) { + for (OpenDatabaseHook hook : openDatabaseHooks) { long start1 = now(); - OpenDatabaseHook hook = pair.getFirst(); hook.onDatabaseOpened(txn); if (LOG.isLoggable(FINE)) { logDuration(LOG, "Calling open database hook " diff --git a/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java b/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java index 5e668f295..80d4778f4 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/properties/PropertiesModule.java @@ -15,7 +15,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_ID; import static org.briarproject.bramble.api.properties.TransportPropertyManager.MAJOR_VERSION; import static org.briarproject.bramble.api.properties.TransportPropertyManager.MINOR_VERSION; @@ -49,8 +48,7 @@ public class PropertiesModule { ValidationManager validationManager, ContactManager contactManager, ClientVersioningManager clientVersioningManager, TransportPropertyManagerImpl transportPropertyManager) { - lifecycleManager.registerOpenDatabaseHook(transportPropertyManager, - NORMAL); + lifecycleManager.registerOpenDatabaseHook(transportPropertyManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, transportPropertyManager); contactManager.registerContactHook(transportPropertyManager); diff --git a/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java b/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java index dda209e37..e00b85f47 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/versioning/VersioningModule.java @@ -14,7 +14,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.bramble.api.versioning.ClientVersioningManager.CLIENT_ID; import static org.briarproject.bramble.api.versioning.ClientVersioningManager.MAJOR_VERSION; @@ -35,8 +34,7 @@ public class VersioningModule { ClientVersioningManagerImpl clientVersioningManager, LifecycleManager lifecycleManager, ContactManager contactManager, ValidationManager validationManager) { - lifecycleManager.registerOpenDatabaseHook(clientVersioningManager, - NORMAL); + lifecycleManager.registerOpenDatabaseHook(clientVersioningManager); lifecycleManager.registerService(clientVersioningManager); contactManager.registerContactHook(clientVersioningManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, diff --git a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java index 37706d051..ee6e4ae55 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/lifecycle/LifecycleManagerImplTest.java @@ -11,13 +11,9 @@ import org.briarproject.bramble.test.DbExpectations; import org.junit.Before; import org.junit.Test; -import java.util.ArrayList; -import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; -import static java.util.Arrays.asList; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.EARLY; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.LATE; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; +import static junit.framework.TestCase.assertTrue; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.junit.Assert.assertEquals; @@ -37,12 +33,10 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase { } @Test - public void testOpenDatabaseHooksRunInOrderOfPriority() throws Exception { + public void testOpenDatabaseHooksAreCalledAtStartup() throws Exception { Transaction txn = new Transaction(null, false); - List results = new ArrayList<>(); - OpenDatabaseHook hook1 = transaction -> results.add(1); - OpenDatabaseHook hook2 = transaction -> results.add(2); - OpenDatabaseHook hook3 = transaction -> results.add(3); + AtomicBoolean called = new AtomicBoolean(false); + OpenDatabaseHook hook = transaction -> called.set(true); context.checking(new DbExpectations() {{ oneOf(db).open(dbKey, lifecycleManager); @@ -51,11 +45,9 @@ public class LifecycleManagerImplTest extends BrambleMockTestCase { allowing(eventBus).broadcast(with(any(LifecycleEvent.class))); }}); - lifecycleManager.registerOpenDatabaseHook(hook1, LATE); - lifecycleManager.registerOpenDatabaseHook(hook2, NORMAL); - lifecycleManager.registerOpenDatabaseHook(hook3, EARLY); + lifecycleManager.registerOpenDatabaseHook(hook); assertEquals(SUCCESS, lifecycleManager.startServices(dbKey)); - assertEquals(asList(3, 2, 1), results); + assertTrue(called.get()); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java b/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java index 5d4d627b2..70430a94c 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/TestLifecycleModule.java @@ -3,7 +3,6 @@ package org.briarproject.bramble.test; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; -import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ShutdownManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @@ -32,8 +31,7 @@ public class TestLifecycleModule { } @Override - public void registerOpenDatabaseHook(OpenDatabaseHook hook, - Priority p) { + public void registerOpenDatabaseHook(OpenDatabaseHook hook) { } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java index c82cd4d30..c3ccaa9cc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java @@ -56,7 +56,6 @@ import dagger.Provides; import static android.content.Context.MODE_PRIVATE; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_ONION_ADDRESS; import static org.briarproject.bramble.api.reporting.ReportingConstants.DEV_PUBLIC_KEY_HEX; @@ -227,7 +226,7 @@ public class AppModule { @Singleton RecentEmoji provideRecentEmoji(LifecycleManager lifecycleManager, RecentEmojiImpl recentEmoji) { - lifecycleManager.registerOpenDatabaseHook(recentEmoji, NORMAL); + lifecycleManager.registerOpenDatabaseHook(recentEmoji); return recentEmoji; } } diff --git a/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java b/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java index ff60e9dd8..081df929d 100644 --- a/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/blog/BlogModule.java @@ -18,7 +18,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID; import static org.briarproject.briar.api.blog.BlogManager.MAJOR_VERSION; @@ -37,7 +36,7 @@ public class BlogModule { BlogManager provideBlogManager(BlogManagerImpl blogManager, LifecycleManager lifecycleManager, ContactManager contactManager, ValidationManager validationManager) { - lifecycleManager.registerOpenDatabaseHook(blogManager, NORMAL); + lifecycleManager.registerOpenDatabaseHook(blogManager); contactManager.registerContactHook(blogManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, blogManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java b/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java index 5b82fa948..d873c0cd6 100644 --- a/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/feed/FeedModule.java @@ -11,8 +11,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; - @Module public class FeedModule { @@ -26,7 +24,7 @@ public class FeedModule { FeedManager provideFeedManager(FeedManagerImpl feedManager, LifecycleManager lifecycleManager, EventBus eventBus, BlogManager blogManager) { - lifecycleManager.registerOpenDatabaseHook(feedManager, NORMAL); + lifecycleManager.registerOpenDatabaseHook(feedManager); eventBus.addListener(feedManager); blogManager.registerRemoveBlogHook(feedManager); return feedManager; diff --git a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java index 4f326ba2e..89d1f1fb7 100644 --- a/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/introduction/IntroductionModule.java @@ -16,7 +16,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.introduction.IntroductionManager.CLIENT_ID; import static org.briarproject.briar.api.introduction.IntroductionManager.MAJOR_VERSION; import static org.briarproject.briar.api.introduction.IntroductionManager.MINOR_VERSION; @@ -52,7 +51,7 @@ public class IntroductionModule { ConversationManager conversationManager, ClientVersioningManager clientVersioningManager, IntroductionManagerImpl introductionManager) { - lifecycleManager.registerOpenDatabaseHook(introductionManager, NORMAL); + lifecycleManager.registerOpenDatabaseHook(introductionManager); contactManager.registerContactHook(introductionManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, introductionManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java index 2a64fd1cd..8e2e4e042 100644 --- a/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/messaging/MessagingModule.java @@ -17,7 +17,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.messaging.MessagingManager.CLIENT_ID; import static org.briarproject.briar.api.messaging.MessagingManager.MAJOR_VERSION; import static org.briarproject.briar.api.messaging.MessagingManager.MINOR_VERSION; @@ -59,7 +58,7 @@ public class MessagingModule { ConversationManager conversationManager, ClientVersioningManager clientVersioningManager, MessagingManagerImpl messagingManager) { - lifecycleManager.registerOpenDatabaseHook(messagingManager, NORMAL); + lifecycleManager.registerOpenDatabaseHook(messagingManager); contactManager.registerContactHook(messagingManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, messagingManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java index 7ec8512c6..0628357e3 100644 --- a/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/privategroup/invitation/GroupInvitationModule.java @@ -19,7 +19,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager.CLIENT_ID; import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager.MAJOR_VERSION; import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager.MINOR_VERSION; @@ -43,8 +42,7 @@ public class GroupInvitationModule { PrivateGroupManager privateGroupManager, ConversationManager conversationManager, ClientVersioningManager clientVersioningManager) { - lifecycleManager.registerOpenDatabaseHook(groupInvitationManager, - NORMAL); + lifecycleManager.registerOpenDatabaseHook(groupInvitationManager); validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION, groupInvitationManager); contactManager.registerContactHook(groupInvitationManager); diff --git a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java index 8d460f369..0bab71a49 100644 --- a/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java +++ b/briar-core/src/main/java/org/briarproject/briar/sharing/SharingModule.java @@ -25,8 +25,6 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; -import static org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook.Priority.NORMAL; - @Module public class SharingModule { @@ -78,7 +76,7 @@ public class SharingModule { ConversationManager conversationManager, BlogManager blogManager, ClientVersioningManager clientVersioningManager, BlogSharingManagerImpl blogSharingManager) { - lifecycleManager.registerOpenDatabaseHook(blogSharingManager, NORMAL); + lifecycleManager.registerOpenDatabaseHook(blogSharingManager); contactManager.registerContactHook(blogSharingManager); validationManager.registerIncomingMessageHook( BlogSharingManager.CLIENT_ID, BlogSharingManager.MAJOR_VERSION, @@ -137,7 +135,7 @@ public class SharingModule { ConversationManager conversationManager, ForumManager forumManager, ClientVersioningManager clientVersioningManager, ForumSharingManagerImpl forumSharingManager) { - lifecycleManager.registerOpenDatabaseHook(forumSharingManager, NORMAL); + lifecycleManager.registerOpenDatabaseHook(forumSharingManager); contactManager.registerContactHook(forumSharingManager); validationManager.registerIncomingMessageHook( ForumSharingManager.CLIENT_ID, From 5553b7d0e42b1d1ece9658dd811ed297945780dc Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 1 May 2019 10:21:11 +0100 Subject: [PATCH 14/17] Remove unused method. --- .../bramble/api/identity/IdentityManager.java | 6 ------ .../bramble/identity/IdentityManagerImpl.java | 8 -------- 2 files changed, 14 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java index 6856fbbb8..dbd5da45e 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java @@ -10,12 +10,6 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @NotNullByDefault public interface IdentityManager { - /** - * Creates a local identity with the given name. - */ - @CryptoExecutor - LocalAuthor createLocalAuthor(String name); - /** * Creates an account with the given name. The account includes a handshake * key pair. diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 13c7f3a93..893344c38 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -68,14 +68,6 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { this.clock = clock; } - @Override - public LocalAuthor createLocalAuthor(String name) { - long start = now(); - LocalAuthor localAuthor = authorFactory.createLocalAuthor(name); - logDuration(LOG, "Creating local author", start); - return localAuthor; - } - @Override public Account createAccount(String name) { long start = now(); From 9c08073e4917e0a892a50099c827b7ae2aa61312 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 3 May 2019 13:46:02 +0100 Subject: [PATCH 15/17] Rename account to identity. --- .../bramble/api/db/DatabaseComponent.java | 67 ++--- .../identity/{Account.java => Identity.java} | 20 +- .../bramble/api/identity/IdentityManager.java | 14 +- .../briarproject/bramble/test/TestUtils.java | 7 +- .../bramble/account/AccountManagerImpl.java | 6 +- .../org/briarproject/bramble/db/Database.java | 67 ++--- .../bramble/db/DatabaseComponentImpl.java | 102 +++---- .../briarproject/bramble/db/JdbcDatabase.java | 277 +++++++++--------- .../bramble/identity/IdentityManagerImpl.java | 77 ++--- .../account/AccountManagerImplTest.java | 14 +- .../bramble/db/DatabaseComponentImplTest.java | 49 ++-- .../bramble/db/DatabasePerformanceTest.java | 28 +- .../bramble/db/JdbcDatabaseTest.java | 96 +++--- .../identity/IdentityManagerImplTest.java | 42 +-- .../feed/FeedManagerIntegrationTest.java | 6 +- .../SimplexMessagingIntegrationTest.java | 20 +- .../briar/test/BriarIntegrationTest.java | 20 +- 17 files changed, 459 insertions(+), 453 deletions(-) rename bramble-api/src/main/java/org/briarproject/bramble/api/identity/{Account.java => Identity.java} (80%) 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 d1620e2cc..16094da18 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 @@ -5,9 +5,9 @@ import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.crypto.SecretKey; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.settings.Settings; @@ -101,11 +101,6 @@ public interface DatabaseComponent { R transactionWithNullableResult(boolean readOnly, NullableDbCallable task) throws DbException, E; - /** - * Stores an account. - */ - void addAccount(Transaction txn, Account a) throws DbException; - /** * Stores a contact associated with the given local and remote pseudonyms, * and returns an ID for the contact. @@ -132,6 +127,11 @@ public interface DatabaseComponent { HandshakeKeySetId addHandshakeKeys(Transaction txn, PendingContactId p, HandshakeKeys k) throws DbException; + /** + * Stores an identity. + */ + void addIdentity(Transaction txn, Identity i) throws DbException; + /** * Stores a local message. */ @@ -157,13 +157,6 @@ public interface DatabaseComponent { TransportKeySetId addTransportKeys(Transaction txn, ContactId c, TransportKeys k) throws DbException; - /** - * Returns true if the database contains an account for the given pseudonym. - *

- * Read-only. - */ - boolean containsAccount(Transaction txn, AuthorId local) throws DbException; - /** * Returns true if the database contains the given contact for the given * local pseudonym. @@ -180,6 +173,14 @@ public interface DatabaseComponent { */ boolean containsGroup(Transaction txn, GroupId g) throws DbException; + /** + * Returns true if the database contains an identity for the given + * pseudonym. + *

+ * Read-only. + */ + boolean containsIdentity(Transaction txn, AuthorId a) throws DbException; + /** * Returns true if the database contains the given pending contact. *

@@ -246,20 +247,6 @@ public interface DatabaseComponent { Collection generateRequestedBatch(Transaction txn, ContactId c, int maxLength, int maxLatency) throws DbException; - /** - * Returns the account for the local pseudonym with the given ID. - *

- * Read-only. - */ - Account getAccount(Transaction txn, AuthorId a) throws DbException; - - /** - * Returns the accounts for all local pseudonyms. - *

- * Read-only. - */ - Collection getAccounts(Transaction txn) throws DbException; - /** * Returns the contact with the given ID. *

@@ -329,6 +316,20 @@ public interface DatabaseComponent { Collection getHandshakeKeys(Transaction txn, TransportId t) throws DbException; + /** + * Returns the identity for the local pseudonym with the given ID. + *

+ * Read-only. + */ + Identity getIdentity(Transaction txn, AuthorId a) throws DbException; + + /** + * Returns the identities for all local pseudonyms. + *

+ * Read-only. + */ + Collection getIdentities(Transaction txn) throws DbException; + /** * Returns the message with the given ID. *

@@ -541,11 +542,6 @@ public interface DatabaseComponent { void receiveRequest(Transaction txn, ContactId c, Request r) throws DbException; - /** - * Removes an account (and all associated state) from the database. - */ - void removeAccount(Transaction txn, AuthorId a) throws DbException; - /** * Removes a contact (and all associated state) from the database. */ @@ -562,6 +558,11 @@ public interface DatabaseComponent { void removeHandshakeKeys(Transaction txn, TransportId t, HandshakeKeySetId k) throws DbException; + /** + * Removes an identity (and all associated state) from the database. + */ + void removeIdentity(Transaction txn, AuthorId a) throws DbException; + /** * Removes a message (and all associated state) from the database. */ @@ -619,7 +620,7 @@ public interface DatabaseComponent { Collection dependencies) throws DbException; /** - * Sets the handshake key pair for the account with the given ID. + * Sets the handshake key pair for the identity with the given ID. */ void setHandshakeKeyPair(Transaction txn, AuthorId local, byte[] publicKey, byte[] privateKey) throws DbException; diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Identity.java similarity index 80% rename from bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/identity/Identity.java index dac57d197..48e42d756 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Account.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/Identity.java @@ -11,14 +11,14 @@ import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_ @Immutable @NotNullByDefault -public class Account { +public class Identity { private final LocalAuthor localAuthor; @Nullable private final byte[] handshakePublicKey, handshakePrivateKey; private final long created; - public Account(LocalAuthor localAuthor, + public Identity(LocalAuthor localAuthor, @Nullable byte[] handshakePublicKey, @Nullable byte[] handshakePrivateKey, long created) { if (handshakePublicKey != null) { @@ -47,7 +47,7 @@ public class Account { } /** - * Returns true if the account has a handshake key pair. + * Returns true if the identity has a handshake key pair. */ public boolean hasHandshakeKeyPair() { return handshakePublicKey != null && handshakePrivateKey != null; @@ -70,7 +70,7 @@ public class Account { } /** - * Returns the time the account was created, in milliseconds since the + * Returns the time the identity was created, in milliseconds since the * Unix epoch. */ public long getTimeCreated() { @@ -84,12 +84,12 @@ public class Account { @Override public boolean equals(Object o) { - if (o instanceof Account) { - Account a = (Account) o; - return created == a.created && - localAuthor.equals(a.localAuthor) && - Arrays.equals(handshakePublicKey, a.handshakePublicKey) && - Arrays.equals(handshakePrivateKey, a.handshakePrivateKey); + if (o instanceof Identity) { + Identity i = (Identity) o; + return created == i.created && + localAuthor.equals(i.localAuthor) && + Arrays.equals(handshakePublicKey, i.handshakePublicKey) && + Arrays.equals(handshakePrivateKey, i.handshakePrivateKey); } return false; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java index dbd5da45e..2d25a561a 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/IdentityManager.java @@ -11,19 +11,19 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; public interface IdentityManager { /** - * Creates an account with the given name. The account includes a handshake - * key pair. + * Creates an identity with the given name. The identity includes a + * handshake key pair. */ @CryptoExecutor - Account createAccount(String name); + Identity createIdentity(String name); /** - * Registers the given account with the manager. This method should be + * Registers the given identity with the manager. This method should be * called before {@link LifecycleManager#startServices(SecretKey)}. The - * account is stored when {@link LifecycleManager#startServices(SecretKey)} - * is called. The account must include a handshake key pair. + * identity is stored when {@link LifecycleManager#startServices(SecretKey)} + * is called. The identity must include a handshake key pair. */ - void registerAccount(Account a); + void registerIdentity(Identity i); /** * Returns the cached local identity or loads it from the database. 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 4b765b6b0..65a1e3869 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 @@ -6,9 +6,9 @@ import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.PendingContact; import org.briarproject.bramble.api.contact.PendingContactId; import org.briarproject.bramble.api.crypto.SecretKey; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; 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.plugin.TransportId; import org.briarproject.bramble.api.properties.TransportProperties; @@ -101,11 +101,12 @@ public class TestUtils { return new SecretKey(getRandomBytes(SecretKey.LENGTH)); } - public static Account getAccount() { + public static Identity getIdentity() { LocalAuthor localAuthor = getLocalAuthor(); byte[] handshakePub = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); byte[] handshakePriv = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); - return new Account(localAuthor, handshakePub, handshakePriv, timestamp); + return new Identity(localAuthor, handshakePub, handshakePriv, + timestamp); } public static LocalAuthor getLocalAuthor() { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java index 623ce50c7..c4b75b6c3 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/account/AccountManagerImpl.java @@ -4,7 +4,7 @@ import org.briarproject.bramble.api.account.AccountManager; import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseConfig; -import org.briarproject.bramble.api.identity.Account; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; @@ -161,8 +161,8 @@ class AccountManagerImpl implements AccountManager { synchronized (stateChangeLock) { if (hasDatabaseKey()) throw new AssertionError("Already have a database key"); - Account account = identityManager.createAccount(name); - identityManager.registerAccount(account); + Identity identity = identityManager.createIdentity(name); + identityManager.registerIdentity(identity); SecretKey key = crypto.generateSecretKey(); if (!encryptAndStoreDatabaseKey(key, password)) return false; databaseKey = key; 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 7a04daa51..c59230802 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 @@ -13,9 +13,9 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MessageDeletedException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.MigrationListener; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.settings.Settings; @@ -86,11 +86,6 @@ interface Database { */ void commitTransaction(T txn) throws DbException; - /** - * Stores an account. - */ - void addAccount(T txn, Account a) throws DbException; - /** * Stores a contact associated with the given local and remote pseudonyms, * and returns an ID for the contact. @@ -124,6 +119,11 @@ interface Database { HandshakeKeySetId addHandshakeKeys(T txn, PendingContactId p, HandshakeKeys k) throws DbException; + /** + * Stores an identity. + */ + void addIdentity(T txn, Identity i) throws DbException; + /** * Stores a message. * @@ -163,13 +163,6 @@ interface Database { TransportKeySetId addTransportKeys(T txn, ContactId c, TransportKeys k) throws DbException; - /** - * Returns true if the database contains an account for the given pseudonym. - *

- * Read-only. - */ - boolean containsAccount(T txn, AuthorId a) throws DbException; - /** * Returns true if the database contains the given contact for the given * local pseudonym. @@ -193,6 +186,14 @@ interface Database { */ boolean containsGroup(T txn, GroupId g) throws DbException; + /** + * Returns true if the database contains an identity for the given + * pseudonym. + *

+ * Read-only. + */ + boolean containsIdentity(T txn, AuthorId a) throws DbException; + /** * Returns true if the database contains the given message. *

@@ -245,20 +246,6 @@ interface Database { */ void deleteMessageMetadata(T txn, MessageId m) throws DbException; - /** - * Returns the account for local pseudonym with the given ID. - *

- * Read-only. - */ - Account getAccount(T txn, AuthorId a) throws DbException; - - /** - * Returns the accounts for all local pseudonyms. - *

- * Read-only. - */ - Collection getAccounts(T txn) throws DbException; - /** * Returns the contact with the given ID. *

@@ -336,6 +323,20 @@ interface Database { Collection getHandshakeKeys(T txn, TransportId t) throws DbException; + /** + * Returns the identity for local pseudonym with the given ID. + *

+ * Read-only. + */ + Identity getIdentity(T txn, AuthorId a) throws DbException; + + /** + * Returns the identities for all local pseudonyms. + *

+ * Read-only. + */ + Collection getIdentities(T txn) throws DbException; + /** * Returns the message with the given ID. *

@@ -605,11 +606,6 @@ interface Database { */ void raiseSeenFlag(T txn, ContactId c, MessageId m) throws DbException; - /** - * Removes an account (and all associated state) from the database. - */ - void removeAccount(T txn, AuthorId a) throws DbException; - /** * Removes a contact from the database. */ @@ -633,6 +629,11 @@ interface Database { void removeHandshakeKeys(T txn, TransportId t, HandshakeKeySetId k) throws DbException; + /** + * Removes an identity (and all associated state) from the database. + */ + void removeIdentity(T txn, AuthorId a) throws DbException; + /** * Removes a message (and all associated state) from the database. */ @@ -686,7 +687,7 @@ interface Database { throws DbException; /** - * Sets the handshake key pair for the account with the given ID. + * Sets the handshake key pair for the identity with the given ID. */ void setHandshakeKeyPair(T txn, AuthorId local, byte[] publicKey, byte[] privateKey) throws DbException; 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 d6a240c35..48597320b 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 @@ -30,9 +30,9 @@ import org.briarproject.bramble.api.db.TaskAction; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.event.EventExecutor; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent; import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent; import org.briarproject.bramble.api.lifecycle.ShutdownManager; @@ -231,26 +231,15 @@ class DatabaseComponentImpl implements DatabaseComponent { return txnClass.cast(transaction.unbox()); } - @Override - public void addAccount(Transaction transaction, Account a) - throws DbException { - if (transaction.isReadOnly()) throw new IllegalArgumentException(); - T txn = unbox(transaction); - if (!db.containsAccount(txn, a.getId())) { - db.addAccount(txn, a); - transaction.attach(new LocalAuthorAddedEvent(a.getId())); - } - } - @Override public ContactId addContact(Transaction transaction, Author remote, AuthorId local, boolean verified) throws DbException { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); - if (!db.containsAccount(txn, local)) + if (!db.containsIdentity(txn, local)) throw new NoSuchLocalAuthorException(); - if (db.containsAccount(txn, remote.getId())) + if (db.containsIdentity(txn, remote.getId())) throw new ContactExistsException(); if (db.containsContact(txn, remote.getId(), local)) throw new ContactExistsException(); @@ -293,6 +282,17 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.addHandshakeKeys(txn, p, k); } + @Override + public void addIdentity(Transaction transaction, Identity i) + throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsIdentity(txn, i.getId())) { + db.addIdentity(txn, i); + transaction.attach(new LocalAuthorAddedEvent(i.getId())); + } + } + @Override public void addLocalMessage(Transaction transaction, Message m, Metadata meta, boolean shared) throws DbException { @@ -341,18 +341,11 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.addTransportKeys(txn, c, k); } - @Override - public boolean containsAccount(Transaction transaction, AuthorId local) - throws DbException { - T txn = unbox(transaction); - return db.containsAccount(txn, local); - } - @Override public boolean containsContact(Transaction transaction, AuthorId remote, AuthorId local) throws DbException { T txn = unbox(transaction); - if (!db.containsAccount(txn, local)) + if (!db.containsIdentity(txn, local)) throw new NoSuchLocalAuthorException(); return db.containsContact(txn, remote, local); } @@ -364,6 +357,13 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.containsGroup(txn, g); } + @Override + public boolean containsIdentity(Transaction transaction, AuthorId a) + throws DbException { + T txn = unbox(transaction); + return db.containsIdentity(txn, a); + } + @Override public boolean containsPendingContact(Transaction transaction, PendingContactId p) throws DbException { @@ -478,22 +478,6 @@ class DatabaseComponentImpl implements DatabaseComponent { return messages; } - @Override - public Account getAccount(Transaction transaction, AuthorId a) - throws DbException { - T txn = unbox(transaction); - if (!db.containsAccount(txn, a)) - throw new NoSuchLocalAuthorException(); - return db.getAccount(txn, a); - } - - @Override - public Collection getAccounts(Transaction transaction) - throws DbException { - T txn = unbox(transaction); - return db.getAccounts(txn); - } - @Override public Contact getContact(Transaction transaction, ContactId c) throws DbException { @@ -521,7 +505,7 @@ class DatabaseComponentImpl implements DatabaseComponent { public Collection getContacts(Transaction transaction, AuthorId a) throws DbException { T txn = unbox(transaction); - if (!db.containsAccount(txn, a)) + if (!db.containsIdentity(txn, a)) throw new NoSuchLocalAuthorException(); return db.getContacts(txn, a); } @@ -569,6 +553,22 @@ class DatabaseComponentImpl implements DatabaseComponent { return db.getHandshakeKeys(txn, t); } + @Override + public Identity getIdentity(Transaction transaction, AuthorId a) + throws DbException { + T txn = unbox(transaction); + if (!db.containsIdentity(txn, a)) + throw new NoSuchLocalAuthorException(); + return db.getIdentity(txn, a); + } + + @Override + public Collection getIdentities(Transaction transaction) + throws DbException { + T txn = unbox(transaction); + return db.getIdentities(txn); + } + @Override public Message getMessage(Transaction transaction, MessageId m) throws DbException { @@ -868,17 +868,6 @@ class DatabaseComponentImpl implements DatabaseComponent { if (requested) transaction.attach(new MessageRequestedEvent(c)); } - @Override - public void removeAccount(Transaction transaction, AuthorId a) - throws DbException { - if (transaction.isReadOnly()) throw new IllegalArgumentException(); - T txn = unbox(transaction); - if (!db.containsAccount(txn, a)) - throw new NoSuchLocalAuthorException(); - db.removeAccount(txn, a); - transaction.attach(new LocalAuthorRemovedEvent(a)); - } - @Override public void removeContact(Transaction transaction, ContactId c) throws DbException { @@ -915,6 +904,17 @@ class DatabaseComponentImpl implements DatabaseComponent { db.removeHandshakeKeys(txn, t, k); } + @Override + public void removeIdentity(Transaction transaction, AuthorId a) + throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsIdentity(txn, a)) + throw new NoSuchLocalAuthorException(); + db.removeIdentity(txn, a); + transaction.attach(new LocalAuthorRemovedEvent(a)); + } + @Override public void removeMessage(Transaction transaction, MessageId m) throws DbException { @@ -1040,7 +1040,7 @@ class DatabaseComponentImpl implements DatabaseComponent { byte[] publicKey, byte[] privateKey) throws DbException { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); - if (!db.containsAccount(txn, local)) + if (!db.containsIdentity(txn, local)) throw new NoSuchLocalAuthorException(); db.setHandshakeKeyPair(txn, local, publicKey, privateKey); } 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 755d7e8ab..e7d3a5a49 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 @@ -13,9 +13,9 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MessageDeletedException; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.MigrationListener; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; 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.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; @@ -662,35 +662,6 @@ abstract class JdbcDatabase implements Database { if (interrupted) Thread.currentThread().interrupt(); } - @Override - public void addAccount(Connection txn, Account a) throws DbException { - PreparedStatement ps = null; - try { - String sql = "INSERT INTO localAuthors" - + " (authorId, formatVersion, name, publicKey, privateKey," - + " handshakePublicKey, handshakePrivateKey, created)" - + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; - ps = txn.prepareStatement(sql); - LocalAuthor local = a.getLocalAuthor(); - ps.setBytes(1, local.getId().getBytes()); - ps.setInt(2, local.getFormatVersion()); - ps.setString(3, local.getName()); - ps.setBytes(4, local.getPublicKey()); - ps.setBytes(5, local.getPrivateKey()); - if (a.getHandshakePublicKey() == null) ps.setNull(6, BINARY); - else ps.setBytes(6, a.getHandshakePublicKey()); - if (a.getHandshakePrivateKey() == null) ps.setNull(7, BINARY); - else ps.setBytes(7, a.getHandshakePrivateKey()); - ps.setLong(8, a.getTimeCreated()); - int affected = ps.executeUpdate(); - if (affected != 1) throw new DbStateException(); - ps.close(); - } catch (SQLException e) { - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public ContactId addContact(Connection txn, Author remote, AuthorId local, boolean verified) throws DbException { @@ -903,6 +874,35 @@ abstract class JdbcDatabase implements Database { } } + @Override + public void addIdentity(Connection txn, Identity i) throws DbException { + PreparedStatement ps = null; + try { + String sql = "INSERT INTO localAuthors" + + " (authorId, formatVersion, name, publicKey, privateKey," + + " handshakePublicKey, handshakePrivateKey, created)" + + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + ps = txn.prepareStatement(sql); + LocalAuthor local = i.getLocalAuthor(); + ps.setBytes(1, local.getId().getBytes()); + ps.setInt(2, local.getFormatVersion()); + ps.setString(3, local.getName()); + ps.setBytes(4, local.getPublicKey()); + ps.setBytes(5, local.getPrivateKey()); + if (i.getHandshakePublicKey() == null) ps.setNull(6, BINARY); + else ps.setBytes(6, i.getHandshakePublicKey()); + if (i.getHandshakePrivateKey() == null) ps.setNull(7, BINARY); + else ps.setBytes(7, i.getHandshakePrivateKey()); + ps.setLong(8, i.getTimeCreated()); + int affected = ps.executeUpdate(); + if (affected != 1) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public void addMessage(Connection txn, Message m, MessageState state, boolean messageShared, @Nullable ContactId sender) @@ -1180,28 +1180,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public boolean containsAccount(Connection txn, AuthorId a) - throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - String sql = "SELECT NULL FROM localAuthors WHERE authorId = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getBytes()); - rs = ps.executeQuery(); - boolean found = rs.next(); - if (rs.next()) throw new DbStateException(); - rs.close(); - ps.close(); - return found; - } catch (SQLException e) { - tryToClose(rs, LOG, WARNING); - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public boolean containsContact(Connection txn, AuthorId remote, AuthorId local) throws DbException { @@ -1270,6 +1248,28 @@ abstract class JdbcDatabase implements Database { } } + @Override + public boolean containsIdentity(Connection txn, AuthorId a) + throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT NULL FROM localAuthors WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, a.getBytes()); + rs = ps.executeQuery(); + boolean found = rs.next(); + if (rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + return found; + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public boolean containsMessage(Connection txn, MessageId m) throws DbException { @@ -1427,76 +1427,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public Account getAccount(Connection txn, AuthorId a) throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - String sql = "SELECT formatVersion, name, publicKey, privateKey," - + " handshakePublicKey, handshakePrivateKey, created" - + " FROM localAuthors" - + " WHERE authorId = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getBytes()); - rs = ps.executeQuery(); - if (!rs.next()) throw new DbStateException(); - int formatVersion = rs.getInt(1); - String name = rs.getString(2); - byte[] publicKey = rs.getBytes(3); - byte[] privateKey = rs.getBytes(4); - byte[] handshakePublicKey = rs.getBytes(5); - byte[] handshakePrivateKey = rs.getBytes(6); - long created = rs.getLong(7); - if (rs.next()) throw new DbStateException(); - rs.close(); - ps.close(); - LocalAuthor local = new LocalAuthor(a, formatVersion, name, - publicKey, privateKey); - return new Account(local, handshakePublicKey, handshakePrivateKey, - created); - } catch (SQLException e) { - tryToClose(rs, LOG, WARNING); - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - - @Override - public Collection getAccounts(Connection txn) throws DbException { - PreparedStatement ps = null; - ResultSet rs = null; - try { - String sql = "SELECT authorId, formatVersion, name, publicKey," - + " privateKey, handshakePublicKey, handshakePrivateKey," - + " created" - + " FROM localAuthors"; - ps = txn.prepareStatement(sql); - rs = ps.executeQuery(); - List accounts = new ArrayList<>(); - while (rs.next()) { - AuthorId authorId = new AuthorId(rs.getBytes(1)); - int formatVersion = rs.getInt(2); - String name = rs.getString(3); - byte[] publicKey = rs.getBytes(4); - byte[] privateKey = rs.getBytes(5); - byte[] handshakePublicKey = rs.getBytes(6); - byte[] handshakePrivateKey = rs.getBytes(7); - long created = rs.getLong(8); - LocalAuthor local = new LocalAuthor(authorId, formatVersion, - name, publicKey, privateKey); - accounts.add(new Account(local, handshakePublicKey, - handshakePrivateKey, created)); - } - rs.close(); - ps.close(); - return accounts; - } catch (SQLException e) { - tryToClose(rs, LOG, WARNING); - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public Contact getContact(Connection txn, ContactId c) throws DbException { PreparedStatement ps = null; @@ -1811,6 +1741,77 @@ abstract class JdbcDatabase implements Database { } } + @Override + public Identity getIdentity(Connection txn, AuthorId a) throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT formatVersion, name, publicKey, privateKey," + + " handshakePublicKey, handshakePrivateKey, created" + + " FROM localAuthors" + + " WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, a.getBytes()); + rs = ps.executeQuery(); + if (!rs.next()) throw new DbStateException(); + int formatVersion = rs.getInt(1); + String name = rs.getString(2); + byte[] publicKey = rs.getBytes(3); + byte[] privateKey = rs.getBytes(4); + byte[] handshakePublicKey = rs.getBytes(5); + byte[] handshakePrivateKey = rs.getBytes(6); + long created = rs.getLong(7); + if (rs.next()) throw new DbStateException(); + rs.close(); + ps.close(); + LocalAuthor local = new LocalAuthor(a, formatVersion, name, + publicKey, privateKey); + return new Identity(local, handshakePublicKey, handshakePrivateKey, + created); + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + + @Override + public Collection getIdentities(Connection txn) + throws DbException { + PreparedStatement ps = null; + ResultSet rs = null; + try { + String sql = "SELECT authorId, formatVersion, name, publicKey," + + " privateKey, handshakePublicKey, handshakePrivateKey," + + " created" + + " FROM localAuthors"; + ps = txn.prepareStatement(sql); + rs = ps.executeQuery(); + List identities = new ArrayList<>(); + while (rs.next()) { + AuthorId authorId = new AuthorId(rs.getBytes(1)); + int formatVersion = rs.getInt(2); + String name = rs.getString(3); + byte[] publicKey = rs.getBytes(4); + byte[] privateKey = rs.getBytes(5); + byte[] handshakePublicKey = rs.getBytes(6); + byte[] handshakePrivateKey = rs.getBytes(7); + long created = rs.getLong(8); + LocalAuthor local = new LocalAuthor(authorId, formatVersion, + name, publicKey, privateKey); + identities.add(new Identity(local, handshakePublicKey, + handshakePrivateKey, created)); + } + rs.close(); + ps.close(); + return identities; + } catch (SQLException e) { + tryToClose(rs, LOG, WARNING); + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public Message getMessage(Connection txn, MessageId m) throws DbException { PreparedStatement ps = null; @@ -2879,22 +2880,6 @@ abstract class JdbcDatabase implements Database { } } - @Override - public void removeAccount(Connection txn, AuthorId a) throws DbException { - PreparedStatement ps = null; - try { - String sql = "DELETE FROM localAuthors WHERE authorId = ?"; - ps = txn.prepareStatement(sql); - ps.setBytes(1, a.getBytes()); - int affected = ps.executeUpdate(); - if (affected != 1) throw new DbStateException(); - ps.close(); - } catch (SQLException e) { - tryToClose(ps, LOG, WARNING); - throw new DbException(e); - } - } - @Override public void removeContact(Connection txn, ContactId c) throws DbException { @@ -2977,6 +2962,22 @@ abstract class JdbcDatabase implements Database { } } + @Override + public void removeIdentity(Connection txn, AuthorId a) throws DbException { + PreparedStatement ps = null; + try { + String sql = "DELETE FROM localAuthors WHERE authorId = ?"; + ps = txn.prepareStatement(sql); + ps.setBytes(1, a.getBytes()); + int affected = ps.executeUpdate(); + if (affected != 1) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(ps, LOG, WARNING); + throw new DbException(e); + } + } + @Override public void removeMessage(Connection txn, MessageId m) throws DbException { PreparedStatement ps = null; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 893344c38..1b742e24b 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -5,8 +5,8 @@ import org.briarproject.bramble.api.crypto.KeyPair; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.AuthorFactory; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook; @@ -38,23 +38,23 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { private final Clock clock; /** - * The user's account, or null if no account has been registered or loaded. - * If non-null, this account always has handshake keys. + * The user's identity, or null if no identity has been registered or + * loaded. If non-null, this identity always has handshake keys. */ @Nullable - private volatile Account cachedAccount = null; + private volatile Identity cachedIdentity = null; /** - * True if {@code cachedAccount} was registered via - * {@link #registerAccount(Account)} and should be stored when + * True if {@code cachedIdentity} was registered via + * {@link #registerIdentity(Identity)} and should be stored when * {@link #onDatabaseOpened(Transaction)} is called. */ - private volatile boolean shouldStoreAccount = false; + private volatile boolean shouldStoreIdentity = false; /** - * True if the handshake keys in {@code cachedAccount} were generated when - * the account was loaded and should be stored when + * True if the handshake keys in {@code cachedIdentity} were generated + * when the identity was loaded and should be stored when * {@link #onDatabaseOpened(Transaction)} is called. */ private volatile boolean shouldStoreKeys = false; @@ -69,31 +69,31 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { } @Override - public Account createAccount(String name) { + public Identity createIdentity(String name) { long start = now(); LocalAuthor localAuthor = authorFactory.createLocalAuthor(name); KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded(); - logDuration(LOG, "Creating account", start); - return new Account(localAuthor, handshakePub, handshakePriv, + logDuration(LOG, "Creating identity", start); + return new Identity(localAuthor, handshakePub, handshakePriv, clock.currentTimeMillis()); } @Override - public void registerAccount(Account a) { - if (!a.hasHandshakeKeyPair()) throw new IllegalArgumentException(); - cachedAccount = a; - shouldStoreAccount = true; - LOG.info("Account registered"); + public void registerIdentity(Identity i) { + if (!i.hasHandshakeKeyPair()) throw new IllegalArgumentException(); + cachedIdentity = i; + shouldStoreIdentity = true; + LOG.info("Identity registered"); } @Override public void onDatabaseOpened(Transaction txn) throws DbException { - Account cached = getCachedAccount(txn); - if (shouldStoreAccount) { - db.addAccount(txn, cached); - LOG.info("Account stored"); + Identity cached = getCachedIdentity(txn); + if (shouldStoreIdentity) { + db.addIdentity(txn, cached); + LOG.info("Identity stored"); } else if (shouldStoreKeys) { byte[] publicKey = requireNonNull(cached.getHandshakePublicKey()); byte[] privateKey = requireNonNull(cached.getHandshakePrivateKey()); @@ -104,49 +104,50 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { @Override public LocalAuthor getLocalAuthor() throws DbException { - Account cached = cachedAccount; + Identity cached = cachedIdentity; if (cached == null) - cached = db.transactionWithResult(true, this::getCachedAccount); + cached = db.transactionWithResult(true, this::getCachedIdentity); return cached.getLocalAuthor(); } @Override public LocalAuthor getLocalAuthor(Transaction txn) throws DbException { - return getCachedAccount(txn).getLocalAuthor(); + return getCachedIdentity(txn).getLocalAuthor(); } @Override public byte[][] getHandshakeKeys(Transaction txn) throws DbException { - Account cached = getCachedAccount(txn); + Identity cached = getCachedIdentity(txn); return new byte[][] { cached.getHandshakePublicKey(), cached.getHandshakePrivateKey() }; } - private Account getCachedAccount(Transaction txn) throws DbException { - Account cached = cachedAccount; + private Identity getCachedIdentity(Transaction txn) throws DbException { + Identity cached = cachedIdentity; if (cached == null) - cachedAccount = cached = loadAccountWithKeyPair(txn); + cachedIdentity = cached = loadIdentityWithKeyPair(txn); return cached; } - private Account loadAccountWithKeyPair(Transaction txn) throws DbException { - Account a = loadAccount(txn); - LOG.info("Account loaded"); - if (a.hasHandshakeKeyPair()) return a; + private Identity loadIdentityWithKeyPair(Transaction txn) + throws DbException { + Identity i = loadIdentity(txn); + LOG.info("Identity loaded"); + if (i.hasHandshakeKeyPair()) return i; KeyPair keyPair = crypto.generateAgreementKeyPair(); byte[] publicKey = keyPair.getPublic().getEncoded(); byte[] privateKey = keyPair.getPrivate().getEncoded(); LOG.info("Handshake key pair generated"); shouldStoreKeys = true; - return new Account(a.getLocalAuthor(), publicKey, privateKey, - a.getTimeCreated()); + return new Identity(i.getLocalAuthor(), publicKey, privateKey, + i.getTimeCreated()); } - private Account loadAccount(Transaction txn) throws DbException { - Collection accounts = db.getAccounts(txn); - if (accounts.size() != 1) throw new DbException(); - return accounts.iterator().next(); + private Identity loadIdentity(Transaction txn) throws DbException { + Collection identities = db.getIdentities(txn); + if (identities.size() != 1) throw new DbException(); + return identities.iterator().next(); } } diff --git a/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java index f1e5f84ff..e1c1c1bb1 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/account/AccountManagerImplTest.java @@ -3,7 +3,7 @@ package org.briarproject.bramble.account; import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseConfig; -import org.briarproject.bramble.api.identity.Account; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.test.BrambleMockTestCase; @@ -25,7 +25,7 @@ import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; -import static org.briarproject.bramble.test.TestUtils.getAccount; +import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTestDirectory; @@ -48,8 +48,8 @@ public class AccountManagerImplTest extends BrambleMockTestCase { private final String encryptedKeyHex = toHexString(encryptedKey); private final byte[] newEncryptedKey = getRandomBytes(123); private final String newEncryptedKeyHex = toHexString(newEncryptedKey); - private final Account account = getAccount(); - private final LocalAuthor localAuthor = account.getLocalAuthor(); + private final Identity identity = getIdentity(); + private final LocalAuthor localAuthor = identity.getLocalAuthor(); private final String authorName = localAuthor.getName(); private final String password = getRandomString(10); private final String newPassword = getRandomString(10); @@ -253,9 +253,9 @@ public class AccountManagerImplTest extends BrambleMockTestCase { @Test public void testCreateAccountStoresDbKey() throws Exception { context.checking(new Expectations() {{ - oneOf(identityManager).createAccount(authorName); - will(returnValue(account)); - oneOf(identityManager).registerAccount(account); + oneOf(identityManager).createIdentity(authorName); + will(returnValue(identity)); + oneOf(identityManager).registerIdentity(identity); oneOf(crypto).generateSecretKey(); will(returnValue(key)); oneOf(crypto).encryptWithPassword(key.getBytes(), password); 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 cfd71418e..c609bf2a0 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 @@ -17,8 +17,8 @@ import org.briarproject.bramble.api.db.NoSuchPendingContactException; import org.briarproject.bramble.api.db.NoSuchTransportException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventBus; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent; import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent; @@ -75,11 +75,11 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERE import static org.briarproject.bramble.api.sync.validation.MessageState.UNKNOWN; import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE; import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES; -import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getGroup; +import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; @@ -107,7 +107,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { private final GroupId groupId; private final Group group; private final Author author; - private final Account account; + private final Identity identity; private final LocalAuthor localAuthor; private final String alias; private final Message message, message1; @@ -126,8 +126,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { group = getGroup(clientId, majorVersion); groupId = group.getId(); author = getAuthor(); - account = getAccount(); - localAuthor = account.getLocalAuthor(); + identity = getIdentity(); + localAuthor = identity.getLocalAuthor(); message = getMessage(groupId); message1 = getMessage(groupId); messageId = message.getId(); @@ -162,15 +162,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { // startTransaction() oneOf(database).startTransaction(); will(returnValue(txn)); - // addAccount() - oneOf(database).containsAccount(txn, localAuthor.getId()); + // addIdentity() + oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(false)); - oneOf(database).addAccount(txn, account); + oneOf(database).addIdentity(txn, identity); oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class))); // addContact() - oneOf(database).containsAccount(txn, localAuthor.getId()); + oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(true)); - oneOf(database).containsAccount(txn, author.getId()); + oneOf(database).containsIdentity(txn, author.getId()); will(returnValue(false)); oneOf(database).containsContact(txn, author.getId(), localAuthor.getId()); @@ -206,10 +206,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { will(returnValue(true)); oneOf(database).removeContact(txn, contactId); oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class))); - // removeAccount() - oneOf(database).containsAccount(txn, localAuthor.getId()); + // removeIdentity() + oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(true)); - oneOf(database).removeAccount(txn, localAuthor.getId()); + oneOf(database).removeIdentity(txn, localAuthor.getId()); oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class))); // endTransaction() oneOf(database).commitTransaction(txn); @@ -221,7 +221,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { assertFalse(db.open(key, null)); db.transaction(false, transaction -> { - db.addAccount(transaction, account); + db.addIdentity(transaction, identity); assertEquals(contactId, db.addContact(transaction, author, localAuthor.getId(), true)); assertEquals(singletonList(contact), @@ -232,7 +232,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.getGroups(transaction, clientId, majorVersion)); db.removeGroup(transaction, group); db.removeContact(transaction, contactId); - db.removeAccount(transaction, localAuthor.getId()); + db.removeIdentity(transaction, localAuthor.getId()); }); db.close(); } @@ -437,13 +437,13 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { } @Test - public void testVariousMethodsThrowExceptionIfAccountIsMissing() + public void testVariousMethodsThrowExceptionIfIdentityIsMissing() throws Exception { context.checking(new Expectations() {{ - // Check whether the account is in the DB (which it's not) + // Check whether the identity is in the DB (which it's not) exactly(4).of(database).startTransaction(); will(returnValue(txn)); - exactly(4).of(database).containsAccount(txn, localAuthor.getId()); + exactly(4).of(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(false)); exactly(4).of(database).abortTransaction(txn); }}); @@ -461,7 +461,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { try { db.transaction(false, transaction -> - db.getAccount(transaction, localAuthor.getId())); + db.getIdentity(transaction, localAuthor.getId())); fail(); } catch (NoSuchLocalAuthorException expected) { // Expected @@ -469,7 +469,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { try { db.transaction(false, transaction -> - db.removeAccount(transaction, localAuthor.getId())); + db.removeIdentity(transaction, localAuthor.getId())); fail(); } catch (NoSuchLocalAuthorException expected) { // Expected @@ -1418,10 +1418,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { context.checking(new Expectations() {{ oneOf(database).startTransaction(); will(returnValue(txn)); - oneOf(database).containsAccount(txn, localAuthor.getId()); + oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(true)); // Contact is a local identity - oneOf(database).containsAccount(txn, author.getId()); + oneOf(database).containsIdentity(txn, author.getId()); will(returnValue(true)); oneOf(database).abortTransaction(txn); }}); @@ -1444,9 +1444,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { context.checking(new Expectations() {{ oneOf(database).startTransaction(); will(returnValue(txn)); - oneOf(database).containsAccount(txn, localAuthor.getId()); + oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(true)); - oneOf(database).containsAccount(txn, author.getId()); + oneOf(database).containsIdentity(txn, author.getId()); will(returnValue(false)); // Contact already exists for this local identity oneOf(database).containsContact(txn, author.getId(), @@ -1469,7 +1469,6 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { } @Test - @SuppressWarnings("unchecked") public void testMessageDependencies() throws Exception { int shutdownHandle = 12345; MessageId messageId2 = new MessageId(getRandomId()); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java index bdc3cc0a1..fe060e3df 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/db/DatabasePerformanceTest.java @@ -4,8 +4,8 @@ import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Metadata; -import org.briarproject.bramble.api.identity.Account; 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.sync.ClientId; import org.briarproject.bramble.api.sync.Group; @@ -36,9 +36,9 @@ import static java.util.logging.Level.OFF; import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS; import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERED; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; -import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getGroup; +import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomId; @@ -162,11 +162,11 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { } @Test - public void testContainsAccount() throws Exception { - String name = "containsAccount(T, AuthorId)"; + public void testContainsIdentity() throws Exception { + String name = "containsIdentity(T, AuthorId)"; benchmark(name, db -> { Connection txn = db.startTransaction(); - db.containsAccount(txn, localAuthor.getId()); + db.containsIdentity(txn, localAuthor.getId()); db.commitTransaction(txn); }); } @@ -296,21 +296,21 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { } @Test - public void testGetAccount() throws Exception { - String name = "getAccount(T, AuthorId)"; + public void testGetIdentity() throws Exception { + String name = "getIdentity(T, AuthorId)"; benchmark(name, db -> { Connection txn = db.startTransaction(); - db.getAccount(txn, localAuthor.getId()); + db.getIdentity(txn, localAuthor.getId()); db.commitTransaction(txn); }); } @Test - public void testGetAccounts() throws Exception { - String name = "getAccounts(T)"; + public void testGetIdentities() throws Exception { + String name = "getIdentities(T)"; benchmark(name, db -> { Connection txn = db.startTransaction(); - db.getAccounts(txn); + db.getIdentities(txn); db.commitTransaction(txn); }); } @@ -532,8 +532,8 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { } void populateDatabase(Database db) throws DbException { - Account account = getAccount(); - localAuthor = account.getLocalAuthor(); + Identity identity = getIdentity(); + localAuthor = identity.getLocalAuthor(); clientIds = new ArrayList<>(); contacts = new ArrayList<>(); groups = new ArrayList<>(); @@ -545,7 +545,7 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase { for (int i = 0; i < CLIENTS; i++) clientIds.add(getClientId()); Connection txn = db.startTransaction(); - db.addAccount(txn, account); + db.addIdentity(txn, identity); for (int i = 0; i < CONTACTS; i++) { ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(), random.nextBoolean()); 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 db6223c05..9093baa07 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 @@ -8,8 +8,8 @@ import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.MessageDeletedException; import org.briarproject.bramble.api.db.Metadata; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.settings.Settings; @@ -72,10 +72,10 @@ import static org.briarproject.bramble.db.DatabaseConstants.DB_SETTINGS_NAMESPAC import static org.briarproject.bramble.db.DatabaseConstants.LAST_COMPACTED_KEY; import static org.briarproject.bramble.db.DatabaseConstants.MAX_COMPACTION_INTERVAL_MS; import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory; -import static org.briarproject.bramble.test.TestUtils.getAccount; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getGroup; +import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getPendingContact; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; @@ -106,7 +106,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { private final int majorVersion; private final Group group; private final Author author; - private final Account account; + private final Identity identity; private final LocalAuthor localAuthor; private final Message message; private final MessageId messageId; @@ -123,8 +123,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { group = getGroup(clientId, majorVersion); groupId = group.getId(); author = getAuthor(); - account = getAccount(); - localAuthor = account.getLocalAuthor(); + identity = getIdentity(); + localAuthor = identity.getLocalAuthor(); message = getMessage(groupId); messageId = message.getId(); transportId = getTransportId(); @@ -150,7 +150,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); assertFalse(db.containsContact(txn, contactId)); - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); assertTrue(db.containsContact(txn, contactId)); @@ -213,7 +213,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -244,7 +244,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared but unvalidated message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -289,7 +289,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, an invisible group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -340,7 +340,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and an unshared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -371,7 +371,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -398,7 +398,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact and a visible group - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -439,7 +439,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -571,7 +571,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact and a shared group - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -591,7 +591,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); @@ -609,7 +609,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, an invisible group and a message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -628,7 +628,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact and a group - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -680,7 +680,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); // Add the contact, the transport and the transport keys - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -781,7 +781,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { assertEquals(emptyList(), db.getHandshakeKeys(txn, transportId)); // Add the contact, the transport and the handshake keys - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -934,7 +934,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and transport keys - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -978,7 +978,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and handshake keys - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -1025,7 +1025,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and transport keys - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -1072,7 +1072,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add the contact, transport and handshake keys - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addTransport(txn, transportId, 123); @@ -1114,14 +1114,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); - // Add an account for a local author - no contacts should be associated - db.addAccount(txn, account); + // Add an identity for a local author - no contacts should be + // associated + db.addIdentity(txn, identity); // Add a contact associated with the local author assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); - // Ensure contact is returned from database by Author ID + // Ensure contact is returned from database by author ID Collection contacts = db.getContactsByAuthorId(txn, author.getId()); assertEquals(1, contacts.size()); @@ -1141,8 +1142,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); - // Add an account for a local author - no contacts should be associated - db.addAccount(txn, account); + // Add an identity for a local author - no contacts should be + // associated + db.addIdentity(txn, identity); Collection contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(emptyList(), contacts); @@ -1153,8 +1155,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(singletonList(contactId), contacts); - // Remove the account - the contact should be removed - db.removeAccount(txn, localAuthor.getId()); + // Remove the identity - the contact should be removed + db.removeIdentity(txn, localAuthor.getId()); contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(emptyList(), contacts); assertFalse(db.containsContact(txn, contactId)); @@ -1169,7 +1171,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact - initially there should be no offered messages - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); assertEquals(0, db.countOfferedMessages(txn, contactId)); @@ -1753,7 +1755,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -1855,15 +1857,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { @Test public void testDifferentLocalAuthorsCanHaveTheSameContact() throws Exception { - Account account1 = getAccount(); - LocalAuthor localAuthor1 = account1.getLocalAuthor(); + Identity identity1 = getIdentity(); + LocalAuthor localAuthor1 = identity1.getLocalAuthor(); Database db = open(false); Connection txn = db.startTransaction(); - // Add accounts for two local authors - db.addAccount(txn, account); - db.addAccount(txn, account1); + // Add identities for two local authors + db.addIdentity(txn, identity); + db.addIdentity(txn, identity1); // Add the same contact for each local author ContactId contactId = @@ -1887,7 +1889,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -1941,7 +1943,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); @@ -1998,7 +2000,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a group and a message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -2082,7 +2084,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -2127,7 +2129,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Connection txn = db.startTransaction(); // Add a contact, a shared group and a shared message - db.addAccount(txn, account); + db.addIdentity(txn, identity); assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), true)); db.addGroup(txn, group); @@ -2245,8 +2247,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { @Test public void testSetHandshakeKeyPair() throws Exception { - Account withoutKeys = - new Account(localAuthor, null, null, account.getTimeCreated()); + Identity withoutKeys = + new Identity(localAuthor, null, null, identity.getTimeCreated()); assertFalse(withoutKeys.hasHandshakeKeyPair()); byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES); byte[] privateKey = getRandomBytes(123); @@ -2254,11 +2256,11 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { Database db = open(false); Connection txn = db.startTransaction(); - db.addAccount(txn, withoutKeys); - Account retrieved = db.getAccount(txn, localAuthor.getId()); + db.addIdentity(txn, withoutKeys); + Identity retrieved = db.getIdentity(txn, localAuthor.getId()); assertFalse(retrieved.hasHandshakeKeyPair()); db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey); - retrieved = db.getAccount(txn, localAuthor.getId()); + retrieved = db.getIdentity(txn, localAuthor.getId()); assertTrue(retrieved.hasHandshakeKeyPair()); assertArrayEquals(publicKey, retrieved.getHandshakePublicKey()); assertArrayEquals(privateKey, retrieved.getHandshakePrivateKey()); diff --git a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java index 5333cba7e..05a8c5ec2 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/identity/IdentityManagerImplTest.java @@ -7,8 +7,8 @@ import org.briarproject.bramble.api.crypto.PublicKey; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.AuthorFactory; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.test.BrambleMockTestCase; @@ -18,7 +18,7 @@ import org.junit.Before; import org.junit.Test; import static java.util.Collections.singletonList; -import static org.briarproject.bramble.test.TestUtils.getAccount; +import static org.briarproject.bramble.test.TestUtils.getIdentity; import static org.junit.Assert.assertEquals; public class IdentityManagerImplTest extends BrambleMockTestCase { @@ -33,16 +33,16 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { context.mock(PrivateKey.class); private final Transaction txn = new Transaction(null, false); - private final Account accountWithKeys = getAccount(); - private final LocalAuthor localAuthor = accountWithKeys.getLocalAuthor(); - private final Account accountWithoutKeys = new Account(localAuthor, - null, null, accountWithKeys.getTimeCreated()); + private final Identity identityWithKeys = getIdentity(); + private final LocalAuthor localAuthor = identityWithKeys.getLocalAuthor(); + private final Identity identityWithoutKeys = new Identity(localAuthor, + null, null, identityWithKeys.getTimeCreated()); private final KeyPair handshakeKeyPair = new KeyPair(handshakePublicKey, handshakePrivateKey); private final byte[] handshakePublicKeyBytes = - accountWithKeys.getHandshakePublicKey(); + identityWithKeys.getHandshakePublicKey(); private final byte[] handshakePrivateKeyBytes = - accountWithKeys.getHandshakePrivateKey(); + identityWithKeys.getHandshakePrivateKey(); private IdentityManagerImpl identityManager; @@ -53,20 +53,20 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { } @Test - public void testOpenDatabaseAccountRegistered() throws Exception { + public void testOpenDatabaseIdentityRegistered() throws Exception { context.checking(new Expectations() {{ - oneOf(db).addAccount(txn, accountWithKeys); + oneOf(db).addIdentity(txn, identityWithKeys); }}); - identityManager.registerAccount(accountWithKeys); + identityManager.registerIdentity(identityWithKeys); identityManager.onDatabaseOpened(txn); } @Test public void testOpenDatabaseHandshakeKeysGenerated() throws Exception { context.checking(new Expectations() {{ - oneOf(db).getAccounts(txn); - will(returnValue(singletonList(accountWithoutKeys))); + oneOf(db).getIdentities(txn); + will(returnValue(singletonList(identityWithoutKeys))); oneOf(crypto).generateAgreementKeyPair(); will(returnValue(handshakeKeyPair)); oneOf(handshakePublicKey).getEncoded(); @@ -83,16 +83,16 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { @Test public void testOpenDatabaseNoHandshakeKeysGenerated() throws Exception { context.checking(new Expectations() {{ - oneOf(db).getAccounts(txn); - will(returnValue(singletonList(accountWithKeys))); + oneOf(db).getIdentities(txn); + will(returnValue(singletonList(identityWithKeys))); }}); identityManager.onDatabaseOpened(txn); } @Test - public void testGetLocalAuthorAccountRegistered() throws DbException { - identityManager.registerAccount(accountWithKeys); + public void testGetLocalAuthorIdentityRegistered() throws DbException { + identityManager.registerIdentity(identityWithKeys); assertEquals(localAuthor, identityManager.getLocalAuthor()); } @@ -100,8 +100,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { public void testGetLocalAuthorHandshakeKeysGenerated() throws Exception { context.checking(new DbExpectations() {{ oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); - oneOf(db).getAccounts(txn); - will(returnValue(singletonList(accountWithoutKeys))); + oneOf(db).getIdentities(txn); + will(returnValue(singletonList(identityWithoutKeys))); oneOf(crypto).generateAgreementKeyPair(); will(returnValue(handshakeKeyPair)); oneOf(handshakePublicKey).getEncoded(); @@ -117,8 +117,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { public void testGetLocalAuthorNoHandshakeKeysGenerated() throws Exception { context.checking(new DbExpectations() {{ oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); - oneOf(db).getAccounts(txn); - will(returnValue(singletonList(accountWithKeys))); + oneOf(db).getIdentities(txn); + will(returnValue(singletonList(identityWithKeys))); }}); assertEquals(localAuthor, identityManager.getLocalAuthor()); diff --git a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java index 53187d0e8..7bcefce13 100644 --- a/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/feed/FeedManagerIntegrationTest.java @@ -1,6 +1,6 @@ package org.briarproject.briar.feed; -import org.briarproject.bramble.api.identity.Account; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.contact.ContactModule; @@ -51,8 +51,8 @@ public class FeedManagerIntegrationTest extends BriarTestCase { injectEagerSingletons(component); IdentityManager identityManager = component.getIdentityManager(); - Account account = identityManager.createAccount("feedTest"); - identityManager.registerAccount(account); + Identity identity = identityManager.createIdentity("feedTest"); + identityManager.registerIdentity(identity); lifecycleManager = component.getLifecycleManager(); lifecycleManager.startServices(getSecretKey()); diff --git a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java index 1be17fbb9..26bba204c 100644 --- a/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/messaging/SimplexMessagingIntegrationTest.java @@ -5,8 +5,8 @@ import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; -import org.briarproject.bramble.api.identity.Account; import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @@ -75,14 +75,14 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase { @Test public void testWriteAndRead() throws Exception { // Create the identities - Account aliceAccount = - alice.getIdentityManager().createAccount("Alice"); - Account bobAccount = bob.getIdentityManager().createAccount("Bob"); + Identity aliceIdentity = + alice.getIdentityManager().createIdentity("Alice"); + Identity bobIdentity = bob.getIdentityManager().createIdentity("Bob"); // Set up the devices and get the contact IDs - ContactId bobId = setUp(alice, aliceAccount, - bobAccount.getLocalAuthor(), true); - ContactId aliceId = setUp(bob, bobAccount, - aliceAccount.getLocalAuthor(), false); + ContactId bobId = setUp(alice, aliceIdentity, + bobIdentity.getLocalAuthor(), true); + ContactId aliceId = setUp(bob, bobIdentity, + aliceIdentity.getLocalAuthor(), false); // Add a private message listener PrivateMessageListener listener = new PrivateMessageListener(); bob.getEventBus().addListener(listener); @@ -101,10 +101,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase { } private ContactId setUp(SimplexMessagingIntegrationTestComponent device, - Account local, Author remote, boolean alice) throws Exception { + Identity local, Author remote, boolean alice) throws Exception { // Add an identity for the user IdentityManager identityManager = device.getIdentityManager(); - identityManager.registerAccount(local); + identityManager.registerIdentity(local); // Start the lifecycle manager LifecycleManager lifecycleManager = device.getLifecycleManager(); lifecycleManager.startServices(getSecretKey()); 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 e92a416ca..742987779 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 @@ -15,7 +15,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; -import org.briarproject.bramble.api.identity.Account; +import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.lifecycle.LifecycleManager; @@ -275,15 +275,15 @@ public abstract class BriarIntegrationTest Date: Fri, 3 May 2019 13:49:26 +0100 Subject: [PATCH 16/17] Rename exceptions and events. --- ...tion.java => NoSuchIdentityException.java} | 4 ++-- ...ddedEvent.java => IdentityAddedEvent.java} | 6 ++--- ...edEvent.java => IdentityRemovedEvent.java} | 6 ++--- .../bramble/db/DatabaseComponentImpl.java | 22 +++++++++---------- .../bramble/db/DatabaseComponentImplTest.java | 18 +++++++-------- 5 files changed, 28 insertions(+), 28 deletions(-) rename bramble-api/src/main/java/org/briarproject/bramble/api/db/{NoSuchLocalAuthorException.java => NoSuchIdentityException.java} (58%) rename bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/{LocalAuthorAddedEvent.java => IdentityAddedEvent.java} (72%) rename bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/{LocalAuthorRemovedEvent.java => IdentityRemovedEvent.java} (71%) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/NoSuchLocalAuthorException.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/NoSuchIdentityException.java similarity index 58% rename from bramble-api/src/main/java/org/briarproject/bramble/api/db/NoSuchLocalAuthorException.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/db/NoSuchIdentityException.java index 3ce99c1db..c09d8ae28 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/NoSuchLocalAuthorException.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/NoSuchIdentityException.java @@ -1,9 +1,9 @@ package org.briarproject.bramble.api.db; /** - * Thrown when a database operation is attempted for a pseudonym that is not in + * Thrown when a database operation is attempted for an identity that is not in * the database. This exception may occur due to concurrent updates and does * not indicate a database error. */ -public class NoSuchLocalAuthorException extends DbException { +public class NoSuchIdentityException extends DbException { } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/LocalAuthorAddedEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/IdentityAddedEvent.java similarity index 72% rename from bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/LocalAuthorAddedEvent.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/IdentityAddedEvent.java index a12d232f2..d6f09697e 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/LocalAuthorAddedEvent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/IdentityAddedEvent.java @@ -7,15 +7,15 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import javax.annotation.concurrent.Immutable; /** - * An event that is broadcast when a local pseudonym is added. + * An event that is broadcast when an identity is added. */ @Immutable @NotNullByDefault -public class LocalAuthorAddedEvent extends Event { +public class IdentityAddedEvent extends Event { private final AuthorId authorId; - public LocalAuthorAddedEvent(AuthorId authorId) { + public IdentityAddedEvent(AuthorId authorId) { this.authorId = authorId; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/LocalAuthorRemovedEvent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/IdentityRemovedEvent.java similarity index 71% rename from bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/LocalAuthorRemovedEvent.java rename to bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/IdentityRemovedEvent.java index 31c93c300..1c232c642 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/LocalAuthorRemovedEvent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/identity/event/IdentityRemovedEvent.java @@ -7,15 +7,15 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import javax.annotation.concurrent.Immutable; /** - * An event that is broadcast when a local pseudonym is removed. + * An event that is broadcast when an identity is removed. */ @Immutable @NotNullByDefault -public class LocalAuthorRemovedEvent extends Event { +public class IdentityRemovedEvent extends Event { private final AuthorId authorId; - public LocalAuthorRemovedEvent(AuthorId authorId) { + public IdentityRemovedEvent(AuthorId authorId) { this.authorId = authorId; } 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 48597320b..475e9da5a 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 @@ -20,7 +20,7 @@ import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.MigrationListener; import org.briarproject.bramble.api.db.NoSuchContactException; import org.briarproject.bramble.api.db.NoSuchGroupException; -import org.briarproject.bramble.api.db.NoSuchLocalAuthorException; +import org.briarproject.bramble.api.db.NoSuchIdentityException; import org.briarproject.bramble.api.db.NoSuchMessageException; import org.briarproject.bramble.api.db.NoSuchPendingContactException; import org.briarproject.bramble.api.db.NoSuchTransportException; @@ -33,8 +33,8 @@ import org.briarproject.bramble.api.event.EventExecutor; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.Identity; -import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent; -import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent; +import org.briarproject.bramble.api.identity.event.IdentityAddedEvent; +import org.briarproject.bramble.api.identity.event.IdentityRemovedEvent; import org.briarproject.bramble.api.lifecycle.ShutdownManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.TransportId; @@ -238,7 +238,7 @@ class DatabaseComponentImpl implements DatabaseComponent { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); if (!db.containsIdentity(txn, local)) - throw new NoSuchLocalAuthorException(); + throw new NoSuchIdentityException(); if (db.containsIdentity(txn, remote.getId())) throw new ContactExistsException(); if (db.containsContact(txn, remote.getId(), local)) @@ -289,7 +289,7 @@ class DatabaseComponentImpl implements DatabaseComponent { T txn = unbox(transaction); if (!db.containsIdentity(txn, i.getId())) { db.addIdentity(txn, i); - transaction.attach(new LocalAuthorAddedEvent(i.getId())); + transaction.attach(new IdentityAddedEvent(i.getId())); } } @@ -346,7 +346,7 @@ class DatabaseComponentImpl implements DatabaseComponent { AuthorId local) throws DbException { T txn = unbox(transaction); if (!db.containsIdentity(txn, local)) - throw new NoSuchLocalAuthorException(); + throw new NoSuchIdentityException(); return db.containsContact(txn, remote, local); } @@ -506,7 +506,7 @@ class DatabaseComponentImpl implements DatabaseComponent { AuthorId a) throws DbException { T txn = unbox(transaction); if (!db.containsIdentity(txn, a)) - throw new NoSuchLocalAuthorException(); + throw new NoSuchIdentityException(); return db.getContacts(txn, a); } @@ -558,7 +558,7 @@ class DatabaseComponentImpl implements DatabaseComponent { throws DbException { T txn = unbox(transaction); if (!db.containsIdentity(txn, a)) - throw new NoSuchLocalAuthorException(); + throw new NoSuchIdentityException(); return db.getIdentity(txn, a); } @@ -910,9 +910,9 @@ class DatabaseComponentImpl implements DatabaseComponent { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); if (!db.containsIdentity(txn, a)) - throw new NoSuchLocalAuthorException(); + throw new NoSuchIdentityException(); db.removeIdentity(txn, a); - transaction.attach(new LocalAuthorRemovedEvent(a)); + transaction.attach(new IdentityRemovedEvent(a)); } @Override @@ -1041,7 +1041,7 @@ class DatabaseComponentImpl implements DatabaseComponent { if (transaction.isReadOnly()) throw new IllegalArgumentException(); T txn = unbox(transaction); if (!db.containsIdentity(txn, local)) - throw new NoSuchLocalAuthorException(); + throw new NoSuchIdentityException(); db.setHandshakeKeyPair(txn, local, publicKey, privateKey); } 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 c609bf2a0..4968bf81e 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 @@ -11,7 +11,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.NoSuchContactException; import org.briarproject.bramble.api.db.NoSuchGroupException; -import org.briarproject.bramble.api.db.NoSuchLocalAuthorException; +import org.briarproject.bramble.api.db.NoSuchIdentityException; import org.briarproject.bramble.api.db.NoSuchMessageException; import org.briarproject.bramble.api.db.NoSuchPendingContactException; import org.briarproject.bramble.api.db.NoSuchTransportException; @@ -20,8 +20,8 @@ import org.briarproject.bramble.api.event.EventBus; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.identity.LocalAuthor; -import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent; -import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent; +import org.briarproject.bramble.api.identity.event.IdentityAddedEvent; +import org.briarproject.bramble.api.identity.event.IdentityRemovedEvent; import org.briarproject.bramble.api.lifecycle.ShutdownManager; import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.settings.Settings; @@ -166,7 +166,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(false)); oneOf(database).addIdentity(txn, identity); - oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class))); + oneOf(eventBus).broadcast(with(any(IdentityAddedEvent.class))); // addContact() oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(true)); @@ -210,7 +210,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { oneOf(database).containsIdentity(txn, localAuthor.getId()); will(returnValue(true)); oneOf(database).removeIdentity(txn, localAuthor.getId()); - oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class))); + oneOf(eventBus).broadcast(with(any(IdentityRemovedEvent.class))); // endTransaction() oneOf(database).commitTransaction(txn); // close() @@ -455,7 +455,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.addContact(transaction, author, localAuthor.getId(), true)); fail(); - } catch (NoSuchLocalAuthorException expected) { + } catch (NoSuchIdentityException expected) { // Expected } @@ -463,7 +463,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.transaction(false, transaction -> db.getIdentity(transaction, localAuthor.getId())); fail(); - } catch (NoSuchLocalAuthorException expected) { + } catch (NoSuchIdentityException expected) { // Expected } @@ -471,7 +471,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.transaction(false, transaction -> db.removeIdentity(transaction, localAuthor.getId())); fail(); - } catch (NoSuchLocalAuthorException expected) { + } catch (NoSuchIdentityException expected) { // Expected } @@ -482,7 +482,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.setHandshakeKeyPair(transaction, localAuthor.getId(), publicKey, privateKey)); fail(); - } catch (NoSuchLocalAuthorException expected) { + } catch (NoSuchIdentityException expected) { // Expected } } From 43787deafd6439f1b886ed45248309698e28f16b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Tue, 14 May 2019 15:55:42 +0100 Subject: [PATCH 17/17] Address review comments. --- .../bramble/identity/IdentityManagerImpl.java | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java index 1b742e24b..15f7a613f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/identity/IdentityManagerImpl.java @@ -92,12 +92,18 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { public void onDatabaseOpened(Transaction txn) throws DbException { Identity cached = getCachedIdentity(txn); if (shouldStoreIdentity) { + // The identity was registered at startup - store it db.addIdentity(txn, cached); LOG.info("Identity stored"); } else if (shouldStoreKeys) { - byte[] publicKey = requireNonNull(cached.getHandshakePublicKey()); - byte[] privateKey = requireNonNull(cached.getHandshakePrivateKey()); - db.setHandshakeKeyPair(txn, cached.getId(), publicKey, privateKey); + // Handshake keys were generated when loading the identity - + // store them + byte[] handshakePub = + requireNonNull(cached.getHandshakePublicKey()); + byte[] handshakePriv = + requireNonNull(cached.getHandshakePrivateKey()); + db.setHandshakeKeyPair(txn, cached.getId(), handshakePub, + handshakePriv); LOG.info("Handshake key pair stored"); } } @@ -124,6 +130,15 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { }; } + /** + * Loads the identity if necessary and returns it. If + * {@code cachedIdentity} was not already set by calling + * {@link #registerIdentity(Identity)}, this method sets it. If + * {@code cachedIdentity} was already set, either by calling + * {@link #registerIdentity(Identity)} or by a previous call to this + * method, then this method returns the cached identity without hitting + * the database. + */ private Identity getCachedIdentity(Transaction txn) throws DbException { Identity cached = cachedIdentity; if (cached == null) @@ -131,23 +146,24 @@ class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook { return cached; } + /** + * Loads and returns the identity, generating a handshake key pair if + * necessary and setting {@code shouldStoreKeys} if a handshake key pair + * was generated. + */ private Identity loadIdentityWithKeyPair(Transaction txn) throws DbException { - Identity i = loadIdentity(txn); - LOG.info("Identity loaded"); - if (i.hasHandshakeKeyPair()) return i; - KeyPair keyPair = crypto.generateAgreementKeyPair(); - byte[] publicKey = keyPair.getPublic().getEncoded(); - byte[] privateKey = keyPair.getPrivate().getEncoded(); - LOG.info("Handshake key pair generated"); - shouldStoreKeys = true; - return new Identity(i.getLocalAuthor(), publicKey, privateKey, - i.getTimeCreated()); - } - - private Identity loadIdentity(Transaction txn) throws DbException { Collection identities = db.getIdentities(txn); if (identities.size() != 1) throw new DbException(); - return identities.iterator().next(); + Identity i = identities.iterator().next(); + LOG.info("Identity loaded"); + if (i.hasHandshakeKeyPair()) return i; + KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair(); + byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded(); + byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded(); + LOG.info("Handshake key pair generated"); + shouldStoreKeys = true; + return new Identity(i.getLocalAuthor(), handshakePub, handshakePriv, + i.getTimeCreated()); } }