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