diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/Contact.java b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/Contact.java index 1d921e8017f62e03100fda3e16f53692eac31155..558035a52ddb73097d2de523abf208badc6aa06b 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/contact/Contact.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/contact/Contact.java @@ -4,8 +4,12 @@ import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; 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_AUTHOR_NAME_LENGTH; +import static org.briarproject.bramble.util.StringUtils.toUtf8; + @Immutable @NotNullByDefault public class Contact { @@ -13,13 +17,21 @@ public class Contact { private final ContactId id; private final Author author; private final AuthorId localAuthorId; + @Nullable + private final String alias; private final boolean verified, active; public Contact(ContactId id, Author author, AuthorId localAuthorId, - boolean verified, boolean active) { + @Nullable String alias, boolean verified, boolean active) { + if (alias != null) { + int aliasLength = toUtf8(alias).length; + if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH) + throw new IllegalArgumentException(); + } this.id = id; this.author = author; this.localAuthorId = localAuthorId; + this.alias = alias; this.verified = verified; this.active = active; } @@ -36,6 +48,11 @@ public class Contact { return localAuthorId; } + @Nullable + public String getAlias() { + return alias; + } + public boolean isVerified() { return verified; } 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 517dcb89f3647d9d95b9c90fe3acc2461b442407..2f4a21800d3e160ab3109968da555e788f43ab15 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 @@ -10,6 +10,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.util.Collection; +import javax.annotation.Nullable; + @NotNullByDefault public interface ContactManager { @@ -93,6 +95,12 @@ public interface ContactManager { void setContactActive(Transaction txn, ContactId c, boolean active) throws DbException; + /** + * Sets an alias name for the contact or unsets it if alias is null. + */ + void setContactAlias(ContactId c, @Nullable String alias) + throws DbException; + /** * Return true if a contact with this name and public key already exists */ 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 3fff5f9d624d9a123ea73b98dfd17202b1bbf013..681e8ec016df7e491637d0bf1ec8daecb6b7dc00 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 @@ -515,6 +515,12 @@ public interface DatabaseComponent { void setContactActive(Transaction txn, ContactId c, boolean active) throws DbException; + /** + * Sets an alias name for the contact or unsets it if alias is null. + */ + void setContactAlias(Transaction txn, ContactId c, @Nullable String alias) + throws DbException; + /** * Sets the given group's visibility to the given contact. */ diff --git a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java index 02c94fc750aa1cef2edf7673b34d4fa40e65f94d..a6397f659924a1fdabfe4511808bb9163ae6ed10 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/contact/ContactManagerImpl.java @@ -18,9 +18,13 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import javax.annotation.Nullable; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; +import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; +import static org.briarproject.bramble.util.StringUtils.toUtf8; + @ThreadSafe @NotNullByDefault class ContactManagerImpl implements ContactManager { @@ -148,6 +152,17 @@ class ContactManagerImpl implements ContactManager { db.setContactActive(txn, c, active); } + @Override + public void setContactAlias(ContactId c, @Nullable String alias) + throws DbException { + if (alias != null) { + int aliasLength = toUtf8(alias).length; + if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH) + throw new IllegalArgumentException(); + } + db.transaction(false, txn -> db.setContactAlias(txn, c, alias)); + } + @Override public boolean contactExists(Transaction txn, AuthorId remoteAuthorId, AuthorId localAuthorId) throws DbException { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Database.java index ca958a7ed573b48c7fe4542be2b1d8156cd5132a..45764418bf06274a1705d806f89018e99e22c9c6 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 @@ -616,6 +616,12 @@ interface Database<T> { void setContactActive(T txn, ContactId c, boolean active) throws DbException; + /** + * Sets an alias name for a contact. + */ + void setContactAlias(T txn, ContactId c, @Nullable String alias) + throws DbException; + /** * Sets the given group's visibility to the given contact to either * {@link Visibility VISIBLE} or {@link Visibility 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 829433ba5cd8827852190169d24d2dc78c474d94..f6fbcd7e7f025d1fadaf96cb311bd863fd2667b0 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 @@ -859,6 +859,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { transaction.attach(new ContactStatusChangedEvent(c, active)); } + @Override + public void setContactAlias(Transaction transaction, ContactId c, + String alias) throws DbException { + if (transaction.isReadOnly()) throw new IllegalArgumentException(); + T txn = unbox(transaction); + if (!db.containsContact(txn, c)) + throw new NoSuchContactException(); + db.setContactAlias(txn, c, alias); + } + @Override public void setGroupVisibility(Transaction transaction, ContactId c, GroupId g, Visibility v) throws DbException { 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 c6e2f7bc9b1305787f4b8587abe40806205b576d..e9d388d9fa6f5854ba08caa912aa0f7a5a9b39b5 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 @@ -56,6 +56,7 @@ import java.util.logging.Logger; import javax.annotation.Nullable; import static java.sql.Types.INTEGER; +import static java.sql.Types.VARCHAR; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.db.Metadata.REMOVE; @@ -83,7 +84,7 @@ import static org.briarproject.bramble.util.LogUtils.now; abstract class JdbcDatabase implements Database<Connection> { // Package access for testing - static final int CODE_SCHEMA_VERSION = 40; + static final int CODE_SCHEMA_VERSION = 41; // Rotation period offsets for incoming transport keys private static final int OFFSET_PREV = -1; @@ -113,6 +114,7 @@ abstract class JdbcDatabase implements Database<Connection> { + " authorId _HASH NOT NULL," + " formatVersion INT NOT NULL," + " name _STRING NOT NULL," + + " alias _STRING," // Null if no alias exists + " publicKey _BINARY NOT NULL," + " localAuthorId _HASH NOT NULL," + " verified BOOLEAN NOT NULL," @@ -427,7 +429,11 @@ abstract class JdbcDatabase implements Database<Connection> { // Package access for testing List<Migration<Connection>> getMigrations() { - return Arrays.asList(new Migration38_39(), new Migration39_40()); + return Arrays.asList( + new Migration38_39(), + new Migration39_40(), + new Migration40_41() + ); } private boolean isCompactionDue(Settings s) { @@ -1258,8 +1264,8 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; ResultSet rs = null; try { - String sql = "SELECT authorId, formatVersion, name, publicKey," - + " localAuthorId, verified, active" + String sql = "SELECT authorId, formatVersion, name, alias," + + " publicKey, localAuthorId, verified, active" + " FROM contacts" + " WHERE contactId = ?"; ps = txn.prepareStatement(sql); @@ -1269,15 +1275,17 @@ abstract class JdbcDatabase implements Database<Connection> { AuthorId authorId = new AuthorId(rs.getBytes(1)); int formatVersion = rs.getInt(2); String name = rs.getString(3); - byte[] publicKey = rs.getBytes(4); - AuthorId localAuthorId = new AuthorId(rs.getBytes(5)); - boolean verified = rs.getBoolean(6); - boolean active = rs.getBoolean(7); + String alias = rs.getString(4); + byte[] publicKey = rs.getBytes(5); + AuthorId localAuthorId = new AuthorId(rs.getBytes(6)); + boolean verified = rs.getBoolean(7); + boolean active = rs.getBoolean(8); rs.close(); ps.close(); Author author = new Author(authorId, formatVersion, name, publicKey); - return new Contact(c, author, localAuthorId, verified, active); + return new Contact(c, author, localAuthorId, alias, verified, + active); } catch (SQLException e) { tryToClose(rs); tryToClose(ps); @@ -1292,7 +1300,7 @@ abstract class JdbcDatabase implements Database<Connection> { ResultSet rs = null; try { String sql = "SELECT contactId, authorId, formatVersion, name," - + " publicKey, localAuthorId, verified, active" + + " alias, publicKey, localAuthorId, verified, active" + " FROM contacts"; ps = txn.prepareStatement(sql); rs = ps.executeQuery(); @@ -1302,14 +1310,15 @@ abstract class JdbcDatabase implements Database<Connection> { AuthorId authorId = new AuthorId(rs.getBytes(2)); int formatVersion = rs.getInt(3); String name = rs.getString(4); - byte[] publicKey = rs.getBytes(5); + String alias = rs.getString(5); + byte[] publicKey = rs.getBytes(6); Author author = new Author(authorId, formatVersion, name, publicKey); - AuthorId localAuthorId = new AuthorId(rs.getBytes(6)); - boolean verified = rs.getBoolean(7); - boolean active = rs.getBoolean(8); + AuthorId localAuthorId = new AuthorId(rs.getBytes(7)); + boolean verified = rs.getBoolean(8); + boolean active = rs.getBoolean(9); contacts.add(new Contact(contactId, author, localAuthorId, - verified, active)); + alias, verified, active)); } rs.close(); ps.close(); @@ -1350,8 +1359,8 @@ abstract class JdbcDatabase implements Database<Connection> { PreparedStatement ps = null; ResultSet rs = null; try { - String sql = "SELECT contactId, formatVersion, name, publicKey," - + " localAuthorId, verified, active" + String sql = "SELECT contactId, formatVersion, name, alias," + + " publicKey, localAuthorId, verified, active" + " FROM contacts" + " WHERE authorId = ?"; ps = txn.prepareStatement(sql); @@ -1362,14 +1371,15 @@ abstract class JdbcDatabase implements Database<Connection> { ContactId c = new ContactId(rs.getInt(1)); int formatVersion = rs.getInt(2); String name = rs.getString(3); - byte[] publicKey = rs.getBytes(4); - AuthorId localAuthorId = new AuthorId(rs.getBytes(5)); - boolean verified = rs.getBoolean(6); - boolean active = rs.getBoolean(7); + String alias = rs.getString(4); + byte[] publicKey = rs.getBytes(5); + AuthorId localAuthorId = new AuthorId(rs.getBytes(6)); + boolean verified = rs.getBoolean(7); + boolean active = rs.getBoolean(8); Author author = new Author(remote, formatVersion, name, publicKey); - contacts.add(new Contact(c, author, localAuthorId, verified, - active)); + contacts.add(new Contact(c, author, localAuthorId, alias, + verified, active)); } rs.close(); ps.close(); @@ -2794,6 +2804,25 @@ abstract class JdbcDatabase implements Database<Connection> { } } + @Override + public void setContactAlias(Connection txn, ContactId c, + @Nullable String alias) throws DbException { + PreparedStatement ps = null; + try { + String sql = "UPDATE contacts SET alias = ? WHERE contactId = ?"; + ps = txn.prepareStatement(sql); + if (alias == null) ps.setNull(1, VARCHAR); + else ps.setString(1, alias); + ps.setInt(2, c.getInt()); + int affected = ps.executeUpdate(); + if (affected < 0 || affected > 1) throw new DbStateException(); + ps.close(); + } catch (SQLException e) { + tryToClose(ps); + throw new DbException(e); + } + } + @Override public void setGroupVisibility(Connection txn, ContactId c, GroupId g, boolean shared) throws DbException { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/db/Migration40_41.java b/bramble-core/src/main/java/org/briarproject/bramble/db/Migration40_41.java new file mode 100644 index 0000000000000000000000000000000000000000..4d5ecea18a16234f4b75706927daa6d7019be599 --- /dev/null +++ b/bramble-core/src/main/java/org/briarproject/bramble/db/Migration40_41.java @@ -0,0 +1,51 @@ +package org.briarproject.bramble.db; + +import org.briarproject.bramble.api.db.DbException; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.logging.Logger; + +import javax.annotation.Nullable; + +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.LogUtils.logException; + +class Migration40_41 implements Migration<Connection> { + + private static final Logger LOG = getLogger(Migration40_41.class.getName()); + + @Override + public int getStartVersion() { + return 40; + } + + @Override + public int getEndVersion() { + return 41; + } + + @Override + public void migrate(Connection txn) throws DbException { + Statement s = null; + try { + s = txn.createStatement(); + s.execute("ALTER TABLE contacts" + // TODO how to insertTypeNames _STRING ? + + " ADD alias VARCHAR"); + } catch (SQLException e) { + tryToClose(s); + throw new DbException(e); + } + } + + private void tryToClose(@Nullable Statement s) { + try { + if (s != null) s.close(); + } catch (SQLException e) { + logException(LOG, WARNING, e); + } + } +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java index a90d685b185bfb565f34a9d78a275a0953ae0330..e2a997f426dd4574fd4620a2cf5ed2c3aafce20a 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/contact/ContactManagerImplTest.java @@ -11,6 +11,7 @@ import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.transport.KeyManager; import org.briarproject.bramble.test.BrambleMockTestCase; +import org.briarproject.bramble.test.DbExpectations; import org.jmock.Expectations; import org.jmock.Mockery; import org.junit.Test; @@ -20,9 +21,11 @@ import java.util.Collection; import java.util.Collections; import java.util.Random; +import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getSecretKey; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -35,9 +38,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase { private final ContactId contactId = new ContactId(42); private final Author remote = getAuthor(); private final AuthorId local = new AuthorId(getRandomId()); + private final String alias = getRandomString(MAX_AUTHOR_NAME_LENGTH); private final boolean verified = false, active = true; private final Contact contact = - new Contact(contactId, remote, local, verified, active); + new Contact(contactId, remote, local, alias, verified, active); public ContactManagerImplTest() { contactManager = new ContactManagerImpl(db, keyManager); @@ -131,7 +135,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase { public void testActiveContacts() throws Exception { Collection<Contact> activeContacts = Collections.singletonList(contact); Collection<Contact> contacts = new ArrayList<>(activeContacts); - contacts.add(new Contact(new ContactId(3), remote, local, true, false)); + contacts.add(new Contact(new ContactId(3), remote, local, alias, true, + false)); Transaction txn = new Transaction(null, true); context.checking(new Expectations() {{ oneOf(db).startTransaction(true); @@ -171,6 +176,23 @@ public class ContactManagerImplTest extends BrambleMockTestCase { contactManager.setContactActive(txn, contactId, active); } + @Test + public void testSetContactAlias() throws Exception { + Transaction txn = new Transaction(null, false); + context.checking(new DbExpectations() {{ + oneOf(db).transaction(with(equal(false)), withDbRunnable(txn)); + oneOf(db).setContactAlias(txn, contactId, alias); + }}); + + contactManager.setContactAlias(contactId, alias); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetContactAliasTooLong() throws Exception { + contactManager.setContactAlias(contactId, + getRandomString(MAX_AUTHOR_NAME_LENGTH + 1)); + } + @Test public void testContactExists() throws Exception { Transaction txn = new Transaction(null, true); 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 5096b91ec69053f8da303013be3c8f4aa9428c41..acf3a0212d7bf6cf4fda0f3e1e02655f6ad42a4d 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 @@ -77,6 +77,7 @@ import static org.briarproject.bramble.test.TestUtils.getMessage; import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTransportId; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -99,6 +100,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { private final Group group; private final Author author; private final LocalAuthor localAuthor; + private final String alias; private final Message message, message1; private final MessageId messageId, messageId1; private final Metadata metadata; @@ -115,6 +117,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { groupId = group.getId(); author = getAuthor(); localAuthor = getLocalAuthor(); + alias = getRandomString(5); message = getMessage(groupId); message1 = getMessage(groupId); messageId = message.getId(); @@ -124,7 +127,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { transportId = getTransportId(); maxLatency = Integer.MAX_VALUE; contactId = new ContactId(234); - contact = new Contact(contactId, author, localAuthor.getId(), + contact = new Contact(contactId, author, localAuthor.getId(), alias, true, true); keySetId = new KeySetId(345); } @@ -288,11 +291,11 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { throws Exception { context.checking(new Expectations() {{ // Check whether the contact is in the DB (which it's not) - exactly(16).of(database).startTransaction(); + exactly(17).of(database).startTransaction(); will(returnValue(txn)); - exactly(16).of(database).containsContact(txn, contactId); + exactly(17).of(database).containsContact(txn, contactId); will(returnValue(false)); - exactly(16).of(database).abortTransaction(txn); + exactly(17).of(database).abortTransaction(txn); }}); DatabaseComponent db = createDatabaseComponent(database, eventBus, shutdown); @@ -450,6 +453,16 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase { db.endTransaction(transaction); } + transaction = db.startTransaction(false); + try { + db.setContactAlias(transaction, contactId, alias); + fail(); + } catch (NoSuchContactException expected) { + // Expected + } finally { + db.endTransaction(transaction); + } + transaction = db.startTransaction(false); try { db.setGroupVisibility(transaction, contactId, groupId, SHARED); 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 05f8d0fa44804256fa7d7201209b214968d1588a..ba032aa725e8c807c36b4d7595e71caaa78138c5 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 @@ -53,6 +53,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.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; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE; @@ -74,6 +75,7 @@ import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getTestDirectory; import static org.briarproject.bramble.test.TestUtils.getTransportId; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -1713,6 +1715,39 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase { db.close(); } + @Test + public void testSetContactAlias() throws Exception { + Database<Connection> db = open(false); + Connection txn = db.startTransaction(); + + // Add a contact + db.addLocalAuthor(txn, localAuthor); + assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(), + true, true)); + + // The contact should have no alias + Contact contact = db.getContact(txn, contactId); + assertNull(contact.getAlias()); + + // Set a contact alias + String alias = getRandomString(MAX_AUTHOR_NAME_LENGTH); + db.setContactAlias(txn, contactId, alias); + + // The contact should have an alias + contact = db.getContact(txn, contactId); + assertEquals(alias, contact.getAlias()); + + // Set the contact alias null + db.setContactAlias(txn, contactId, null); + + // The contact should have no alias + contact = db.getContact(txn, contactId); + assertNull(contact.getAlias()); + + db.commitTransaction(txn); + db.close(); + } + @Test public void testSetMessageState() throws Exception { Database<Connection> db = open(false); 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 2926cd3f3edb00a88e05e0fa78bbe04c875b70b0..2d228cbdb99d6eee5211ef0bb460bec74787799c 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 @@ -29,6 +29,7 @@ import static org.briarproject.bramble.api.identity.Author.Status.UNVERIFIED; import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED; import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertEquals; public class IdentityManagerImplTest extends BrambleMockTestCase { @@ -126,7 +127,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { // add one unverified contact Contact contact = new Contact(new ContactId(1), author, - localAuthor.getId(), false, true); + localAuthor.getId(), getRandomString(5), false, true); contacts.add(contact); checkAuthorStatusContext(authorId, contacts); @@ -134,7 +135,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase { // add one verified contact Contact contact2 = new Contact(new ContactId(1), author, - localAuthor.getId(), true, true); + localAuthor.getId(), getRandomString(5), true, true); contacts.add(contact2); checkAuthorStatusContext(authorId, contacts); 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 99b444a708325e5da8615a61e7d18320a459a96c..8f6345e03a19202362970257c5a83b93252d2734 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 @@ -39,6 +39,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.getRandomId; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -612,7 +613,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase { private Contact getContact(boolean active) { ContactId c = new ContactId(nextContactId++); return new Contact(c, getAuthor(), localAuthor.getId(), - true, active); + getRandomString(5), true, active); } private void expectGetLocalProperties(Transaction txn) throws Exception { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/DbExpectations.java b/bramble-core/src/test/java/org/briarproject/bramble/test/DbExpectations.java new file mode 100644 index 0000000000000000000000000000000000000000..4493552d3a0f4d8842f42394a1c976bb32540f7c --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/DbExpectations.java @@ -0,0 +1,16 @@ +package org.briarproject.bramble.test; + +import org.briarproject.bramble.api.db.DbRunnable; +import org.briarproject.bramble.api.db.Transaction; +import org.jmock.Expectations; + +public class DbExpectations extends Expectations { + + protected <E extends Exception> DbRunnable<E> withDbRunnable( + Transaction txn) { + addParameterMatcher(any(DbRunnable.class)); + currentBuilder().setAction(new RunTransactionAction(txn)); + return null; + } + +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/test/RunTransactionAction.java b/bramble-core/src/test/java/org/briarproject/bramble/test/RunTransactionAction.java new file mode 100644 index 0000000000000000000000000000000000000000..7ee016201ec0a835110786d86bd533156a7d48ea --- /dev/null +++ b/bramble-core/src/test/java/org/briarproject/bramble/test/RunTransactionAction.java @@ -0,0 +1,30 @@ +package org.briarproject.bramble.test; + +import org.briarproject.bramble.api.db.DbRunnable; +import org.briarproject.bramble.api.db.Transaction; +import org.hamcrest.Description; +import org.jmock.api.Action; +import org.jmock.api.Invocation; + +public class RunTransactionAction implements Action { + + private final Transaction txn; + + @SuppressWarnings("WeakerAccess") + public RunTransactionAction(Transaction txn) { + this.txn = txn; + } + + @Override + public Object invoke(Invocation invocation) throws Throwable { + DbRunnable task = (DbRunnable) invocation.getParameter(1); + task.run(txn); + return null; + } + + @Override + public void describeTo(Description description) { + description.appendText("runs a task inside a database transaction"); + } + +} diff --git a/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java index dd91eb23796efb5218452f7e6121139f22428dc6..c11ca079142a831c1e009d8da1ad0c4e34507ca0 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/transport/KeyManagerImplTest.java @@ -33,6 +33,7 @@ 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; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.junit.Assert.assertEquals; public class KeyManagerImplTest extends BrambleMockTestCase { @@ -66,10 +67,10 @@ public class KeyManagerImplTest extends BrambleMockTestCase { Author remoteAuthor = getAuthor(); AuthorId localAuthorId = new AuthorId(getRandomId()); Collection<Contact> contacts = new ArrayList<>(); - contacts.add(new Contact(contactId, remoteAuthor, localAuthorId, true, - true)); + contacts.add(new Contact(contactId, remoteAuthor, localAuthorId, + getRandomString(5), true, true)); contacts.add(new Contact(inactiveContactId, remoteAuthor, localAuthorId, - true, false)); + getRandomString(5), true, false)); SimplexPluginFactory pluginFactory = context.mock(SimplexPluginFactory.class); Collection<SimplexPluginFactory> factories = 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 7494873d9c724fea0a516c96d358bf6902ce90cf..2a74c1e98c1febbb003c1a02a992b1d86952f4c5 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 @@ -38,6 +38,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.getRandomId; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.versioning.ClientVersioningConstants.GROUP_KEY_CONTACT_ID; import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_KEY_LOCAL; import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_KEY_UPDATE_VERSION; @@ -56,7 +57,8 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase { private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Contact contact = new Contact(new ContactId(123), - getAuthor(), getLocalAuthor().getId(), true, true); + getAuthor(), getLocalAuthor().getId(), getRandomString(5), true, + true); private final ClientId clientId = getClientId(); private final long now = System.currentTimeMillis(); private final Transaction txn = new Transaction(null, false); 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 a0f16d45b68bfea8e630d472918c66ddbf2d865a..0f1f94e5bd9bdf811a809a0737156d5d08e70dfc 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 @@ -124,7 +124,7 @@ public class BlogManagerImplTest extends BriarTestCase { ContactId contactId = new ContactId(0); Contact contact = new Contact(contactId, blog2.getAuthor(), - blog1.getAuthor().getId(), true, true); + blog1.getAuthor().getId(), getRandomString(5), true, true); context.checking(new Expectations() {{ oneOf(blogFactory).createBlog(blog2.getAuthor()); @@ -146,7 +146,7 @@ public class BlogManagerImplTest extends BriarTestCase { ContactId contactId = new ContactId(0); Contact contact = new Contact(contactId, blog2.getAuthor(), - blog1.getAuthor().getId(), true, true); + blog1.getAuthor().getId(), getRandomString(5), true, true); context.checking(new Expectations() {{ oneOf(blogFactory).createBlog(blog2.getAuthor()); diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java index 2c2d1e6354e67fee00dd8b67b71baefa08abd566..95158cfbd190b20d711102e323367e9186c6e530 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/AbstractProtocolEngineTest.java @@ -83,7 +83,7 @@ abstract class AbstractProtocolEngineTest extends BrambleMockTestCase { BdfDictionary.of(new BdfEntry("me", "ta")); final ContactId contactId = new ContactId(5); final Contact contact = new Contact(contactId, author, - new AuthorId(getRandomId()), true, true); + new AuthorId(getRandomId()), getRandomString(5), true, true); final InviteMessage inviteMessage = new InviteMessage(new MessageId(getRandomId()), contactGroupId, 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 8c06d942e60d8630998759608589c1473e2a8d08..801ec176df6898e249cfd2eaa86b2d19b05df01c 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 @@ -100,7 +100,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { private final ContactId contactId = new ContactId(0); private final Author author = getAuthor(); private final Contact contact = new Contact(contactId, author, - new AuthorId(getRandomId()), true, true); + new AuthorId(getRandomId()), getRandomString(5), true, true); private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group privateGroup = getGroup(CLIENT_ID, MAJOR_VERSION); @@ -845,9 +845,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase { @Test public void testRemovingGroupEndsSessions() throws Exception { Contact contact2 = new Contact(new ContactId(2), author, - author.getId(), true, true); + author.getId(), getRandomString(5), true, true); Contact contact3 = new Contact(new ContactId(3), author, - author.getId(), true, true); + author.getId(), getRandomString(5), true, true); Collection<Contact> contacts = Arrays.asList(contact, contact2, contact3); diff --git a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java index 4937695b2a67d6143a84d3b13222ae2480d49939..b620a6c193621a73bcca6d8d9192b638506ea2b6 100644 --- a/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java +++ b/briar-core/src/test/java/org/briarproject/briar/privategroup/invitation/InviteeProtocolEngineTest.java @@ -331,7 +331,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest { signature); Author notCreator = getAuthor(); Contact notCreatorContact = new Contact(contactId, notCreator, - localAuthor.getId(), true, true); + localAuthor.getId(), getRandomString(5), true, true); expectGetContactId(); context.checking(new Expectations() {{ 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 c44c1e23f11f765e49b274683ca709d99f6d1d29..c6422814e583ff5ac6da2613cd7fffa8e0b00bd6 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 @@ -38,6 +38,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.getRandomId; +import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.briar.api.blog.BlogSharingManager.CLIENT_ID; import static org.briarproject.briar.api.blog.BlogSharingManager.MAJOR_VERSION; import static org.briarproject.briar.sharing.SharingConstants.GROUP_KEY_CONTACT_ID; @@ -63,7 +64,8 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase { private final ContactId contactId = new ContactId(0); private final Author author = getAuthor(); private final Contact contact = - new Contact(contactId, author, localAuthor.getId(), true, true); + new Contact(contactId, author, localAuthor.getId(), + getRandomString(5), true, true); private final Collection<Contact> contacts = Collections.singletonList(contact); private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); diff --git a/briar-headless/src/test/java/org/briarproject/briar/headless/ControllerTest.kt b/briar-headless/src/test/java/org/briarproject/briar/headless/ControllerTest.kt index dc073910975f9e01adcd6532869d1792adfb4aa7..a2a8655838cbb2eaac44f56d04d99b5149aa445a 100644 --- a/briar-headless/src/test/java/org/briarproject/briar/headless/ControllerTest.kt +++ b/briar-headless/src/test/java/org/briarproject/briar/headless/ControllerTest.kt @@ -36,7 +36,8 @@ abstract class ControllerTest { protected val group: Group = getGroup(getClientId(), 0) protected val author: Author = getAuthor() protected val localAuthor: LocalAuthor = getLocalAuthor() - protected val contact = Contact(ContactId(1), author, localAuthor.id, true, true) + protected val contact = + Contact(ContactId(1), author, localAuthor.id, getRandomString(5), true, true) protected val message: Message = getMessage(group.id) protected val text: String = getRandomString(5) protected val timestamp = 42L