Compare commits

...

1 Commits

Author SHA1 Message Date
akwizgran
3c290a320e Remove local author from contacts. 2019-04-23 15:50:04 +01:00
51 changed files with 760 additions and 877 deletions

View File

@@ -18,11 +18,10 @@ public interface ContactGroupFactory {
* Creates a group for the given client to share with the given contact. * Creates a group for the given client to share with the given contact.
*/ */
Group createContactGroup(ClientId clientId, int majorVersion, Group createContactGroup(ClientId clientId, int majorVersion,
Contact contact); Contact contact, AuthorId local);
/** /**
* Creates a group for the given client to share between the given authors * Creates a group for the given client to share between the given authors.
* identified by their AuthorIds.
*/ */
Group createContactGroup(ClientId clientId, int majorVersion, Group createContactGroup(ClientId clientId, int majorVersion,
AuthorId authorId1, AuthorId authorId2); AuthorId authorId1, AuthorId authorId2);

View File

@@ -1,7 +1,6 @@
package org.briarproject.bramble.api.contact; package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -17,16 +16,14 @@ public class Contact {
private final ContactId id; private final ContactId id;
private final Author author; private final Author author;
private final AuthorId localAuthorId;
@Nullable @Nullable
private final String alias; private final String alias;
@Nullable @Nullable
private final byte[] handshakePublicKey; private final byte[] handshakePublicKey;
private final boolean verified; private final boolean verified;
public Contact(ContactId id, Author author, AuthorId localAuthorId, public Contact(ContactId id, Author author, @Nullable String alias,
@Nullable String alias, @Nullable byte[] handshakePublicKey, @Nullable byte[] handshakePublicKey, boolean verified) {
boolean verified) {
if (alias != null) { if (alias != null) {
int aliasLength = toUtf8(alias).length; int aliasLength = toUtf8(alias).length;
if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH) if (aliasLength == 0 || aliasLength > MAX_AUTHOR_NAME_LENGTH)
@@ -38,7 +35,6 @@ public class Contact {
} }
this.id = id; this.id = id;
this.author = author; this.author = author;
this.localAuthorId = localAuthorId;
this.alias = alias; this.alias = alias;
this.handshakePublicKey = handshakePublicKey; this.handshakePublicKey = handshakePublicKey;
this.verified = verified; this.verified = verified;
@@ -52,10 +48,6 @@ public class Contact {
return author; return author;
} }
public AuthorId getLocalAuthorId() {
return localAuthorId;
}
@Nullable @Nullable
public String getAlias() { public String getAlias() {
return alias; return alias;

View File

@@ -24,34 +24,31 @@ public interface ContactManager {
void registerContactHook(ContactHook hook); void registerContactHook(ContactHook hook);
/** /**
* Stores a contact associated with the given local and remote pseudonyms, * Stores a contact with the given pseudonym, derives and stores transport
* derives and stores transport keys for each transport, and returns an ID * keys for each transport, and returns an ID for the contact.
* for the contact.
* *
* @param alice true if the local party is Alice * @param alice true if the local party is Alice
*/ */
ContactId addContact(Transaction txn, Author remote, AuthorId local, ContactId addContact(Transaction txn, Author a, SecretKey rootKey,
SecretKey rootKey, long timestamp, boolean alice, boolean verified,
boolean active) throws DbException;
/**
* Stores a contact associated with the given local and remote pseudonyms
* and returns an ID for the contact.
*/
ContactId addContact(Transaction txn, Author remote, AuthorId local,
boolean verified) throws DbException;
/**
* Stores a contact associated with the given local and remote pseudonyms,
* derives and stores transport keys for each transport, and returns an ID
* for the contact.
*
* @param alice true if the local party is Alice
*/
ContactId addContact(Author remote, AuthorId local, SecretKey rootKey,
long timestamp, boolean alice, boolean verified, boolean active) long timestamp, boolean alice, boolean verified, boolean active)
throws DbException; throws DbException;
/**
* Stores a contact with the given pseudonym and returns an ID for the
* contact.
*/
ContactId addContact(Transaction txn, Author a, boolean verified)
throws DbException;
/**
* Stores a contact with the given pseudonym, derives and stores transport
* keys for each transport, and returns an ID for the contact.
*
* @param alice true if the local party is Alice
*/
ContactId addContact(Author a, SecretKey rootKey, long timestamp,
boolean alice, boolean verified, boolean active) throws DbException;
/** /**
* Returns the static link that needs to be sent to the contact to be added. * Returns the static link that needs to be sent to the contact to be added.
*/ */
@@ -88,22 +85,14 @@ public interface ContactManager {
Contact getContact(ContactId c) throws DbException; Contact getContact(ContactId c) throws DbException;
/** /**
* Returns the contact with the given remoteAuthorId * Returns the contact with the given ID.
* that was added by the LocalAuthor with the given localAuthorId
*
* @throws org.briarproject.bramble.api.db.NoSuchContactException
*/ */
Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId) Contact getContact(AuthorId a) throws DbException;
throws DbException;
/** /**
* Returns the contact with the given remoteAuthorId * Returns the contact with the given ID.
* that was added by the LocalAuthor with the given localAuthorId
*
* @throws org.briarproject.bramble.api.db.NoSuchContactException
*/ */
Contact getContact(Transaction txn, AuthorId remoteAuthorId, Contact getContact(Transaction txn, AuthorId a) throws DbException;
AuthorId localAuthorId) throws DbException;
/** /**
* Returns all active contacts. * Returns all active contacts.
@@ -133,16 +122,14 @@ public interface ContactManager {
throws DbException; throws DbException;
/** /**
* Return true if a contact with this name and public key already exists * Returns true if a contact with this pseudonym already exists.
*/ */
boolean contactExists(Transaction txn, AuthorId remoteAuthorId, boolean contactExists(Transaction txn, AuthorId a) throws DbException;
AuthorId localAuthorId) throws DbException;
/** /**
* Return true if a contact with this name and public key already exists * Returns true if a contact with this pseudonym already exists.
*/ */
boolean contactExists(AuthorId remoteAuthorId, AuthorId localAuthorId) boolean contactExists(AuthorId a) throws DbException;
throws DbException;
/** /**
* Returns the {@link AuthorInfo} for the given author. * Returns the {@link AuthorInfo} for the given author.

View File

@@ -102,11 +102,11 @@ public interface DatabaseComponent {
NullableDbCallable<R, E> task) throws DbException, E; NullableDbCallable<R, E> task) throws DbException, E;
/** /**
* Stores a contact associated with the given local and remote pseudonyms, * Stores a contact with the given pseudonym and returns an ID for the
* and returns an ID for the contact. * contact.
*/ */
ContactId addContact(Transaction txn, Author remote, AuthorId local, ContactId addContact(Transaction txn, Author a, boolean verified)
boolean verified) throws DbException; throws DbException;
/** /**
* Stores a group. * Stores a group.
@@ -158,13 +158,11 @@ public interface DatabaseComponent {
TransportKeys k) throws DbException; TransportKeys k) throws DbException;
/** /**
* Returns true if the database contains the given contact for the given * Returns true if the database contains the given contact.
* local pseudonym.
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
boolean containsContact(Transaction txn, AuthorId remote, AuthorId local) boolean containsContact(Transaction txn, AuthorId a) throws DbException;
throws DbException;
/** /**
* Returns true if the database contains the given group. * Returns true if the database contains the given group.
@@ -254,6 +252,13 @@ public interface DatabaseComponent {
*/ */
Contact getContact(Transaction txn, ContactId c) throws DbException; Contact getContact(Transaction txn, ContactId c) throws DbException;
/**
* Returns the contact with the given author ID.
* <p/>
* Read-only.
*/
Contact getContact(Transaction txn, AuthorId a) throws DbException;
/** /**
* Returns all contacts. * Returns all contacts.
* <p/> * <p/>
@@ -261,22 +266,6 @@ public interface DatabaseComponent {
*/ */
Collection<Contact> getContacts(Transaction txn) throws DbException; Collection<Contact> getContacts(Transaction txn) throws DbException;
/**
* Returns a possibly empty collection of contacts with the given author ID.
* <p/>
* Read-only.
*/
Collection<Contact> getContactsByAuthorId(Transaction txn, AuthorId remote)
throws DbException;
/**
* Returns all contacts associated with the given local pseudonym.
* <p/>
* Read-only.
*/
Collection<ContactId> getContacts(Transaction txn, AuthorId a)
throws DbException;
/** /**
* Returns the group with the given ID. * Returns the group with the given ID.
* <p/> * <p/>

View File

@@ -163,19 +163,15 @@ public class TestUtils {
} }
public static Contact getContact() { public static Contact getContact() {
return getContact(getAuthor(), new AuthorId(getRandomId()), return getContact(getAuthor(), random.nextBoolean());
random.nextBoolean());
} }
public static Contact getContact(Author remote, AuthorId local, public static Contact getContact(Author a, boolean verified) {
boolean verified) { return getContact(getContactId(), a, verified);
return getContact(getContactId(), remote, local, verified);
} }
public static Contact getContact(ContactId c, Author remote, AuthorId local, public static Contact getContact(ContactId c, Author a, boolean verified) {
boolean verified) { return new Contact(c, a, getRandomString(MAX_AUTHOR_NAME_LENGTH),
return new Contact(c, remote, local,
getRandomString(MAX_AUTHOR_NAME_LENGTH),
getRandomBytes(MAX_PUBLIC_KEY_LENGTH), verified); getRandomBytes(MAX_PUBLIC_KEY_LENGTH), verified);
} }

View File

@@ -39,8 +39,7 @@ class ContactGroupFactoryImpl implements ContactGroupFactory {
@Override @Override
public Group createContactGroup(ClientId clientId, int majorVersion, public Group createContactGroup(ClientId clientId, int majorVersion,
Contact contact) { Contact contact, AuthorId local) {
AuthorId local = contact.getLocalAuthorId();
AuthorId remote = contact.getAuthor().getId(); AuthorId remote = contact.getAuthor().getId();
byte[] descriptor = createGroupDescriptor(local, remote); byte[] descriptor = createGroupDescriptor(local, remote);
return groupFactory.createGroup(clientId, majorVersion, descriptor); return groupFactory.createGroup(clientId, majorVersion, descriptor);

View File

@@ -293,8 +293,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
throws DbException { throws DbException {
return db.transactionWithResult(false, txn -> { return db.transactionWithResult(false, txn -> {
ContactId contactId = contactManager.addContact(txn, remoteAuthor, ContactId contactId = contactManager.addContact(txn, remoteAuthor,
localAuthor.getId(), masterKey, timestamp, alice, masterKey, timestamp, alice, true, true);
true, true);
transportPropertyManager.addRemoteProperties(txn, contactId, transportPropertyManager.addRemoteProperties(txn, contactId,
remoteProperties); remoteProperties);
return contactId; return contactId;

View File

@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.NoSuchContactException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
@@ -68,10 +67,10 @@ class ContactManagerImpl implements ContactManager {
} }
@Override @Override
public ContactId addContact(Transaction txn, Author remote, AuthorId local, public ContactId addContact(Transaction txn, Author a, SecretKey rootKey,
SecretKey rootKey, long timestamp, boolean alice, boolean verified, long timestamp, boolean alice, boolean verified, boolean active)
boolean active) throws DbException { throws DbException {
ContactId c = db.addContact(txn, remote, local, verified); ContactId c = db.addContact(txn, a, verified);
keyManager.addContact(txn, c, rootKey, timestamp, alice, active); keyManager.addContact(txn, c, rootKey, timestamp, alice, active);
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
for (ContactHook hook : hooks) hook.addingContact(txn, contact); for (ContactHook hook : hooks) hook.addingContact(txn, contact);
@@ -79,20 +78,20 @@ class ContactManagerImpl implements ContactManager {
} }
@Override @Override
public ContactId addContact(Transaction txn, Author remote, AuthorId local, public ContactId addContact(Transaction txn, Author a, boolean verified)
boolean verified) throws DbException { throws DbException {
ContactId c = db.addContact(txn, remote, local, verified); ContactId c = db.addContact(txn, a, verified);
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
for (ContactHook hook : hooks) hook.addingContact(txn, contact); for (ContactHook hook : hooks) hook.addingContact(txn, contact);
return c; return c;
} }
@Override @Override
public ContactId addContact(Author remote, AuthorId local, public ContactId addContact(Author a, SecretKey rootKey, long timestamp,
SecretKey rootKey, long timestamp, boolean alice, boolean verified, boolean alice, boolean verified, boolean active)
boolean active) throws DbException { throws DbException {
return db.transactionWithResult(false, txn -> return db.transactionWithResult(false, txn ->
addContact(txn, remote, local, rootKey, timestamp, alice, addContact(txn, a, rootKey, timestamp, alice,
verified, active)); verified, active));
} }
@@ -144,23 +143,13 @@ class ContactManagerImpl implements ContactManager {
} }
@Override @Override
public Contact getContact(AuthorId remoteAuthorId, AuthorId localAuthorId) public Contact getContact(AuthorId a) throws DbException {
throws DbException { return db.transactionWithResult(true, txn -> getContact(txn, a));
return db.transactionWithResult(true, txn ->
getContact(txn, remoteAuthorId, localAuthorId));
} }
@Override @Override
public Contact getContact(Transaction txn, AuthorId remoteAuthorId, public Contact getContact(Transaction txn, AuthorId a) throws DbException {
AuthorId localAuthorId) throws DbException { return db.getContact(txn, a);
Collection<Contact> contacts =
db.getContactsByAuthorId(txn, remoteAuthorId);
for (Contact c : contacts) {
if (c.getLocalAuthorId().equals(localAuthorId)) {
return c;
}
}
throw new NoSuchContactException();
} }
@Override @Override
@@ -191,16 +180,14 @@ class ContactManagerImpl implements ContactManager {
} }
@Override @Override
public boolean contactExists(Transaction txn, AuthorId remoteAuthorId, public boolean contactExists(Transaction txn, AuthorId a)
AuthorId localAuthorId) throws DbException { throws DbException {
return db.containsContact(txn, remoteAuthorId, localAuthorId); return db.containsContact(txn, a);
} }
@Override @Override
public boolean contactExists(AuthorId remoteAuthorId, public boolean contactExists(AuthorId a) throws DbException {
AuthorId localAuthorId) throws DbException { return db.transactionWithResult(true, txn -> contactExists(txn, a));
return db.transactionWithResult(true, txn ->
contactExists(txn, remoteAuthorId, localAuthorId));
} }
@Override @Override
@@ -222,12 +209,12 @@ class ContactManagerImpl implements ContactManager {
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
if (localAuthor.getId().equals(authorId)) if (localAuthor.getId().equals(authorId))
return new AuthorInfo(OURSELVES); return new AuthorInfo(OURSELVES);
Collection<Contact> contacts = db.getContactsByAuthorId(txn, authorId); if (db.containsContact(txn, authorId)) {
if (contacts.isEmpty()) return new AuthorInfo(UNKNOWN); Contact c = db.getContact(txn, authorId);
if (contacts.size() > 1) throw new AssertionError();
Contact c = contacts.iterator().next();
if (c.isVerified()) return new AuthorInfo(VERIFIED, c.getAlias()); if (c.isVerified()) return new AuthorInfo(VERIFIED, c.getAlias());
else return new AuthorInfo(UNVERIFIED, c.getAlias()); else return new AuthorInfo(UNVERIFIED, c.getAlias());
} }
return new AuthorInfo(UNKNOWN);
}
} }

View File

@@ -87,11 +87,10 @@ interface Database<T> {
void commitTransaction(T txn) throws DbException; void commitTransaction(T txn) throws DbException;
/** /**
* Stores a contact associated with the given local and remote pseudonyms, * Stores a contact with the given pseudonym and returns an ID for the
* and returns an ID for the contact. * contact.
*/ */
ContactId addContact(T txn, Author remote, AuthorId local, boolean verified) ContactId addContact(T txn, Author a, boolean verified) throws DbException;
throws DbException;
/** /**
* Stores a group. * Stores a group.
@@ -164,13 +163,11 @@ interface Database<T> {
throws DbException; throws DbException;
/** /**
* Returns true if the database contains the given contact for the given * Returns true if the database contains the given contact.
* local pseudonym.
* <p/> * <p/>
* Read-only. * Read-only.
*/ */
boolean containsContact(T txn, AuthorId remote, AuthorId local) boolean containsContact(T txn, AuthorId a) throws DbException;
throws DbException;
/** /**
* Returns true if the database contains the given contact. * Returns true if the database contains the given contact.
@@ -252,6 +249,13 @@ interface Database<T> {
*/ */
Contact getContact(T txn, ContactId c) throws DbException; Contact getContact(T txn, ContactId c) throws DbException;
/**
* Returns the contact with the given author ID.
* <p/>
* Read-only.
*/
Contact getContact(T txn, AuthorId a) throws DbException;
/** /**
* Returns all contacts. * Returns all contacts.
* <p/> * <p/>
@@ -259,21 +263,6 @@ interface Database<T> {
*/ */
Collection<Contact> getContacts(T txn) throws DbException; Collection<Contact> getContacts(T txn) throws DbException;
/**
* Returns a possibly empty collection of contacts with the given author ID.
* <p/>
* Read-only.
*/
Collection<Contact> getContactsByAuthorId(T txn, AuthorId remote)
throws DbException;
/**
* Returns all contacts associated with the given local pseudonym.
* <p/>
* Read-only.
*/
Collection<ContactId> getContacts(T txn, AuthorId a) throws DbException;
/** /**
* Returns the group with the given ID. * Returns the group with the given ID.
* <p/> * <p/>

View File

@@ -232,18 +232,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
@Override @Override
public ContactId addContact(Transaction transaction, Author remote, public ContactId addContact(Transaction transaction, Author a,
AuthorId local, boolean verified) boolean verified) throws DbException {
throws DbException {
if (transaction.isReadOnly()) throw new IllegalArgumentException(); if (transaction.isReadOnly()) throw new IllegalArgumentException();
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsLocalAuthor(txn, local)) if (db.containsLocalAuthor(txn, a.getId()))
throw new NoSuchLocalAuthorException();
if (db.containsLocalAuthor(txn, remote.getId()))
throw new ContactExistsException(); throw new ContactExistsException();
if (db.containsContact(txn, remote.getId(), local)) if (db.containsContact(txn, a.getId()))
throw new ContactExistsException(); throw new ContactExistsException();
ContactId c = db.addContact(txn, remote, local, verified); ContactId c = db.addContact(txn, a, verified);
transaction.attach(new ContactAddedEvent(c)); transaction.attach(new ContactAddedEvent(c));
return c; return c;
} }
@@ -342,12 +339,10 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
@Override @Override
public boolean containsContact(Transaction transaction, AuthorId remote, public boolean containsContact(Transaction transaction, AuthorId a)
AuthorId local) throws DbException { throws DbException {
T txn = unbox(transaction); T txn = unbox(transaction);
if (!db.containsLocalAuthor(txn, local)) return db.containsContact(txn, a);
throw new NoSuchLocalAuthorException();
return db.containsContact(txn, remote, local);
} }
@Override @Override
@@ -487,6 +482,15 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.getContact(txn, c); return db.getContact(txn, c);
} }
@Override
public Contact getContact(Transaction transaction, AuthorId a)
throws DbException {
T txn = unbox(transaction);
if (!db.containsContact(txn, a))
throw new NoSuchContactException();
return db.getContact(txn, a);
}
@Override @Override
public Collection<Contact> getContacts(Transaction transaction) public Collection<Contact> getContacts(Transaction transaction)
throws DbException { throws DbException {
@@ -494,22 +498,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
return db.getContacts(txn); return db.getContacts(txn);
} }
@Override
public Collection<Contact> getContactsByAuthorId(Transaction transaction,
AuthorId remote) throws DbException {
T txn = unbox(transaction);
return db.getContactsByAuthorId(txn, remote);
}
@Override
public Collection<ContactId> getContacts(Transaction transaction,
AuthorId a) throws DbException {
T txn = unbox(transaction);
if (!db.containsLocalAuthor(txn, a))
throw new NoSuchLocalAuthorException();
return db.getContacts(txn, a);
}
@Override @Override
public Group getGroup(Transaction transaction, GroupId g) public Group getGroup(Transaction transaction, GroupId g)
throws DbException { throws DbException {

View File

@@ -92,7 +92,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
abstract class JdbcDatabase implements Database<Connection> { abstract class JdbcDatabase implements Database<Connection> {
// Package access for testing // Package access for testing
static final int CODE_SCHEMA_VERSION = 43; static final int CODE_SCHEMA_VERSION = 44;
// Time period offsets for incoming transport keys // Time period offsets for incoming transport keys
private static final int OFFSET_PREV = -1; private static final int OFFSET_PREV = -1;
@@ -127,12 +127,8 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " alias _STRING," // Null if no alias has been set + " alias _STRING," // Null if no alias has been set
+ " publicKey _BINARY NOT NULL," + " publicKey _BINARY NOT NULL,"
+ " handshakePublicKey _BINARY," // Null if key is unknown + " handshakePublicKey _BINARY," // Null if key is unknown
+ " localAuthorId _HASH NOT NULL,"
+ " verified BOOLEAN NOT NULL," + " verified BOOLEAN NOT NULL,"
+ " PRIMARY KEY (contactId)," + " PRIMARY KEY (contactId))";
+ " FOREIGN KEY (localAuthorId)"
+ " REFERENCES localAuthors (authorId)"
+ " ON DELETE CASCADE)";
private static final String CREATE_GROUPS = private static final String CREATE_GROUPS =
"CREATE TABLE groups" "CREATE TABLE groups"
@@ -486,7 +482,8 @@ abstract class JdbcDatabase implements Database<Connection> {
new Migration39_40(), new Migration39_40(),
new Migration40_41(dbTypes), new Migration40_41(dbTypes),
new Migration41_42(dbTypes), new Migration41_42(dbTypes),
new Migration42_43(dbTypes) new Migration42_43(dbTypes),
new Migration43_44()
); );
} }
@@ -662,23 +659,21 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
@Override @Override
public ContactId addContact(Connection txn, Author remote, AuthorId local, public ContactId addContact(Connection txn, Author a, boolean verified)
boolean verified) throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
// Create a contact row // Create a contact row
String sql = "INSERT INTO contacts" String sql = "INSERT INTO contacts"
+ " (authorId, formatVersion, name, publicKey," + " (authorId, formatVersion, name, publicKey, verified)"
+ " localAuthorId, verified)" + " VALUES (?, ?, ?, ?, ?)";
+ " VALUES (?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, remote.getId().getBytes()); ps.setBytes(1, a.getId().getBytes());
ps.setInt(2, remote.getFormatVersion()); ps.setInt(2, a.getFormatVersion());
ps.setString(3, remote.getName()); ps.setString(3, a.getName());
ps.setBytes(4, remote.getPublicKey()); ps.setBytes(4, a.getPublicKey());
ps.setBytes(5, local.getBytes()); ps.setBoolean(5, verified);
ps.setBoolean(6, verified);
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException(); if (affected != 1) throw new DbStateException();
ps.close(); ps.close();
@@ -1180,16 +1175,14 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
@Override @Override
public boolean containsContact(Connection txn, AuthorId remote, public boolean containsContact(Connection txn, AuthorId a)
AuthorId local) throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT NULL FROM contacts" String sql = "SELECT NULL FROM contacts WHERE authorId = ?";
+ " WHERE authorId = ? AND localAuthorId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, remote.getBytes()); ps.setBytes(1, a.getBytes());
ps.setBytes(2, local.getBytes());
rs = ps.executeQuery(); rs = ps.executeQuery();
boolean found = rs.next(); boolean found = rs.next();
if (rs.next()) throw new DbStateException(); if (rs.next()) throw new DbStateException();
@@ -1432,7 +1425,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT authorId, formatVersion, name, alias," String sql = "SELECT authorId, formatVersion, name, alias,"
+ " publicKey, handshakePublicKey, localAuthorId, verified" + " publicKey, handshakePublicKey, verified"
+ " FROM contacts" + " FROM contacts"
+ " WHERE contactId = ?"; + " WHERE contactId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
@@ -1445,14 +1438,44 @@ abstract class JdbcDatabase implements Database<Connection> {
String alias = rs.getString(4); String alias = rs.getString(4);
byte[] publicKey = rs.getBytes(5); byte[] publicKey = rs.getBytes(5);
byte[] handshakePublicKey = rs.getBytes(6); byte[] handshakePublicKey = rs.getBytes(6);
AuthorId localAuthorId = new AuthorId(rs.getBytes(7)); boolean verified = rs.getBoolean(7);
boolean verified = rs.getBoolean(8);
rs.close(); rs.close();
ps.close(); ps.close();
Author author = Author author =
new Author(authorId, formatVersion, name, publicKey); new Author(authorId, formatVersion, name, publicKey);
return new Contact(c, author, localAuthorId, alias, return new Contact(c, author, alias, handshakePublicKey, verified);
handshakePublicKey, verified); } catch (SQLException e) {
tryToClose(rs, LOG, WARNING);
tryToClose(ps, LOG, WARNING);
throw new DbException(e);
}
}
@Override
public Contact getContact(Connection txn, AuthorId a) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT contactId, formatVersion, name, alias,"
+ " publicKey, handshakePublicKey, verified"
+ " FROM contacts"
+ " WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getBytes());
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
ContactId contactId = new ContactId(rs.getInt(1));
int formatVersion = rs.getInt(2);
String name = rs.getString(3);
String alias = rs.getString(4);
byte[] publicKey = rs.getBytes(5);
byte[] handshakePublicKey = rs.getBytes(6);
boolean verified = rs.getBoolean(7);
rs.close();
ps.close();
Author author = new Author(a, formatVersion, name, publicKey);
return new Contact(contactId, author, alias, handshakePublicKey,
verified);
} catch (SQLException e) { } catch (SQLException e) {
tryToClose(rs, LOG, WARNING); tryToClose(rs, LOG, WARNING);
tryToClose(ps, LOG, WARNING); tryToClose(ps, LOG, WARNING);
@@ -1466,8 +1489,7 @@ abstract class JdbcDatabase implements Database<Connection> {
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT contactId, authorId, formatVersion, name," String sql = "SELECT contactId, authorId, formatVersion, name,"
+ " alias, publicKey, handshakePublicKey, localAuthorId," + " alias, publicKey, handshakePublicKey, verified"
+ " verified"
+ " FROM contacts"; + " FROM contacts";
s = txn.createStatement(); s = txn.createStatement();
rs = s.executeQuery(sql); rs = s.executeQuery(sql);
@@ -1480,12 +1502,11 @@ abstract class JdbcDatabase implements Database<Connection> {
String alias = rs.getString(5); String alias = rs.getString(5);
byte[] publicKey = rs.getBytes(6); byte[] publicKey = rs.getBytes(6);
byte[] handshakePublicKey = rs.getBytes(7); byte[] handshakePublicKey = rs.getBytes(7);
AuthorId localAuthorId = new AuthorId(rs.getBytes(8)); boolean verified = rs.getBoolean(8);
boolean verified = rs.getBoolean(9);
Author author = Author author =
new Author(authorId, formatVersion, name, publicKey); new Author(authorId, formatVersion, name, publicKey);
contacts.add(new Contact(contactId, author, localAuthorId, contacts.add(new Contact(contactId, author, alias,
alias, handshakePublicKey, verified)); handshakePublicKey, verified));
} }
rs.close(); rs.close();
s.close(); s.close();
@@ -1497,67 +1518,6 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
@Override
public Collection<ContactId> getContacts(Connection txn, AuthorId local)
throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT contactId FROM contacts"
+ " WHERE localAuthorId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, local.getBytes());
rs = ps.executeQuery();
List<ContactId> ids = new ArrayList<>();
while (rs.next()) ids.add(new ContactId(rs.getInt(1)));
rs.close();
ps.close();
return ids;
} catch (SQLException e) {
tryToClose(rs, LOG, WARNING);
tryToClose(ps, LOG, WARNING);
throw new DbException(e);
}
}
@Override
public Collection<Contact> getContactsByAuthorId(Connection txn,
AuthorId remote) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT contactId, formatVersion, name, alias,"
+ " publicKey, handshakePublicKey, localAuthorId, verified"
+ " FROM contacts"
+ " WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setBytes(1, remote.getBytes());
rs = ps.executeQuery();
List<Contact> contacts = new ArrayList<>();
while (rs.next()) {
ContactId contactId = new ContactId(rs.getInt(1));
int formatVersion = rs.getInt(2);
String name = rs.getString(3);
String alias = rs.getString(4);
byte[] publicKey = rs.getBytes(5);
byte[] handshakePublicKey = rs.getBytes(6);
AuthorId localAuthorId = new AuthorId(rs.getBytes(7));
boolean verified = rs.getBoolean(8);
Author author =
new Author(remote, formatVersion, name, publicKey);
contacts.add(new Contact(contactId, author, localAuthorId,
alias, handshakePublicKey, verified));
}
rs.close();
ps.close();
return contacts;
} catch (SQLException e) {
tryToClose(rs, LOG, WARNING);
tryToClose(ps, LOG, WARNING);
throw new DbException(e);
}
}
@Override @Override
public Group getGroup(Connection txn, GroupId g) throws DbException { public Group getGroup(Connection txn, GroupId g) throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;

View File

@@ -0,0 +1,40 @@
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 static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
class Migration43_44 implements Migration<Connection> {
private static final Logger LOG = getLogger(Migration43_44.class.getName());
@Override
public int getStartVersion() {
return 43;
}
@Override
public int getEndVersion() {
return 44;
}
@Override
public void migrate(Connection txn) throws DbException {
Statement s = null;
try {
s = txn.createStatement();
s.execute("ALTER TABLE contacts"
+ " DROP COLUMN localAuthorId");
} catch (SQLException e) {
tryToClose(s, LOG, WARNING);
throw new DbException(e);
}
}
}

View File

@@ -13,6 +13,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
@@ -44,6 +46,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
private final DatabaseComponent db; private final DatabaseComponent db;
private final ClientHelper clientHelper; private final ClientHelper clientHelper;
private final IdentityManager identityManager;
private final ClientVersioningManager clientVersioningManager; private final ClientVersioningManager clientVersioningManager;
private final MetadataParser metadataParser; private final MetadataParser metadataParser;
private final ContactGroupFactory contactGroupFactory; private final ContactGroupFactory contactGroupFactory;
@@ -53,11 +56,13 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Inject @Inject
TransportPropertyManagerImpl(DatabaseComponent db, TransportPropertyManagerImpl(DatabaseComponent db,
ClientHelper clientHelper, ClientHelper clientHelper,
IdentityManager identityManager,
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MetadataParser metadataParser,
ContactGroupFactory contactGroupFactory, Clock clock) { ContactGroupFactory contactGroupFactory, Clock clock) {
this.db = db; this.db = db;
this.clientHelper = clientHelper; this.clientHelper = clientHelper;
this.identityManager = identityManager;
this.clientVersioningManager = clientVersioningManager; this.clientVersioningManager = clientVersioningManager;
this.metadataParser = metadataParser; this.metadataParser = metadataParser;
this.contactGroupFactory = contactGroupFactory; this.contactGroupFactory = contactGroupFactory;
@@ -77,7 +82,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Override @Override
public void addingContact(Transaction txn, Contact c) throws DbException { public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group to share with the contact // Create a group to share with the contact
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.addGroup(txn, g); db.addGroup(txn, g);
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
@@ -93,14 +98,14 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Override @Override
public void removingContact(Transaction txn, Contact c) throws DbException { public void removingContact(Transaction txn, Contact c) throws DbException {
db.removeGroup(txn, getContactGroup(c)); db.removeGroup(txn, getContactGroup(c, getLocalAuthorId(txn)));
} }
@Override @Override
public void onClientVisibilityChanging(Transaction txn, Contact c, public void onClientVisibilityChanging(Transaction txn, Contact c,
Visibility v) throws DbException { Visibility v) throws DbException {
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.setGroupVisibility(txn, c.getId(), g.getId(), v); db.setGroupVisibility(txn, c.getId(), g.getId(), v);
} }
@@ -132,7 +137,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Override @Override
public void addRemoteProperties(Transaction txn, ContactId c, public void addRemoteProperties(Transaction txn, ContactId c,
Map<TransportId, TransportProperties> props) throws DbException { Map<TransportId, TransportProperties> props) throws DbException {
Group g = getContactGroup(db.getContact(txn, c)); Group g = getContactGroup(db.getContact(txn, c), getLocalAuthorId(txn));
for (Entry<TransportId, TransportProperties> e : props.entrySet()) { for (Entry<TransportId, TransportProperties> e : props.entrySet()) {
storeMessage(txn, g.getId(), e.getKey(), e.getValue(), 0, storeMessage(txn, g.getId(), e.getKey(), e.getValue(), 0,
false, false); false, false);
@@ -191,15 +196,16 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
TransportId t) throws DbException { TransportId t) throws DbException {
return db.transactionWithResult(true, txn -> { return db.transactionWithResult(true, txn -> {
Map<ContactId, TransportProperties> remote = new HashMap<>(); Map<ContactId, TransportProperties> remote = new HashMap<>();
AuthorId local = getLocalAuthorId(txn);
for (Contact c : db.getContacts(txn)) for (Contact c : db.getContacts(txn))
remote.put(c.getId(), getRemoteProperties(txn, c, t)); remote.put(c.getId(), getRemoteProperties(txn, c, local, t));
return remote; return remote;
}); });
} }
private TransportProperties getRemoteProperties(Transaction txn, Contact c, private TransportProperties getRemoteProperties(Transaction txn, Contact c,
TransportId t) throws DbException { AuthorId local, TransportId t) throws DbException {
Group g = getContactGroup(c); Group g = getContactGroup(c, local);
try { try {
// Find the latest remote update // Find the latest remote update
LatestUpdate latest = findLatest(txn, g.getId(), t, false); LatestUpdate latest = findLatest(txn, g.getId(), t, false);
@@ -216,8 +222,11 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
@Override @Override
public TransportProperties getRemoteProperties(ContactId c, TransportId t) public TransportProperties getRemoteProperties(ContactId c, TransportId t)
throws DbException { throws DbException {
return db.transactionWithResult(true, txn -> return db.transactionWithResult(true, txn -> {
getRemoteProperties(txn, db.getContact(txn, c), t)); Contact contact = db.getContact(txn ,c);
AuthorId local = getLocalAuthorId(txn);
return getRemoteProperties(txn, contact, local, t);
});
} }
@Override @Override
@@ -250,8 +259,9 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
if (latest != null) if (latest != null)
db.removeMessage(txn, latest.messageId); db.removeMessage(txn, latest.messageId);
// Store the merged properties in each contact's group // Store the merged properties in each contact's group
AuthorId localAuthorId = getLocalAuthorId(txn);
for (Contact c : db.getContacts(txn)) { for (Contact c : db.getContacts(txn)) {
Group g = getContactGroup(c); Group g = getContactGroup(c, localAuthorId);
latest = findLatest(txn, g.getId(), t, true); latest = findLatest(txn, g.getId(), t, true);
version = latest == null ? 1 : latest.version + 1; version = latest == null ? 1 : latest.version + 1;
storeMessage(txn, g.getId(), t, merged, version, storeMessage(txn, g.getId(), t, merged, version,
@@ -267,9 +277,13 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
} }
} }
private Group getContactGroup(Contact c) { private AuthorId getLocalAuthorId(Transaction txn) throws DbException {
return identityManager.getLocalAuthor(txn).getId();
}
private Group getContactGroup(Contact c, AuthorId local) {
return contactGroupFactory.createContactGroup(CLIENT_ID, return contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, c); MAJOR_VERSION, c, local);
} }
private void storeMessage(Transaction txn, GroupId g, TransportId t, private void storeMessage(Transaction txn, GroupId g, TransportId t,

View File

@@ -12,6 +12,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.Service;
import org.briarproject.bramble.api.lifecycle.ServiceException; import org.briarproject.bramble.api.lifecycle.ServiceException;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@@ -58,6 +60,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
private final DatabaseComponent db; private final DatabaseComponent db;
private final ClientHelper clientHelper; private final ClientHelper clientHelper;
private final IdentityManager identityManager;
private final ContactGroupFactory contactGroupFactory; private final ContactGroupFactory contactGroupFactory;
private final Clock clock; private final Clock clock;
private final Group localGroup; private final Group localGroup;
@@ -68,9 +71,11 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
@Inject @Inject
ClientVersioningManagerImpl(DatabaseComponent db, ClientHelper clientHelper, ClientVersioningManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
IdentityManager identityManager,
ContactGroupFactory contactGroupFactory, Clock clock) { ContactGroupFactory contactGroupFactory, Clock clock) {
this.db = db; this.db = db;
this.clientHelper = clientHelper; this.clientHelper = clientHelper;
this.identityManager = identityManager;
this.contactGroupFactory = contactGroupFactory; this.contactGroupFactory = contactGroupFactory;
this.clock = clock; this.clock = clock;
localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID, localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
@@ -154,7 +159,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
@Override @Override
public void addingContact(Transaction txn, Contact c) throws DbException { public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group and share it with the contact // Create a group and share it with the contact
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.addGroup(txn, g); db.addGroup(txn, g);
db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED); db.setGroupVisibility(txn, c.getId(), g.getId(), SHARED);
// Attach the contact ID to the group // Attach the contact ID to the group
@@ -173,7 +178,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
@Override @Override
public void removingContact(Transaction txn, Contact c) throws DbException { public void removingContact(Transaction txn, Contact c) throws DbException {
db.removeGroup(txn, getContactGroup(c)); db.removeGroup(txn, getContactGroup(c, getLocalAuthorId(txn)));
} }
@Override @Override
@@ -308,7 +313,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
List<ClientVersion> versions) throws DbException { List<ClientVersion> versions) throws DbException {
try { try {
// Find the latest local and remote updates // Find the latest local and remote updates
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
LatestUpdates latest = findLatestUpdates(txn, g.getId()); LatestUpdates latest = findLatestUpdates(txn, g.getId());
// Load and parse the latest local update // Load and parse the latest local update
if (latest.local == null) throw new DbException(); if (latest.local == null) throw new DbException();
@@ -344,16 +349,20 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
} }
} }
private Group getContactGroup(Contact c) { private AuthorId getLocalAuthorId(Transaction txn) throws DbException {
return identityManager.getLocalAuthor(txn).getId();
}
private Group getContactGroup(Contact c, AuthorId local) {
return contactGroupFactory.createContactGroup(CLIENT_ID, return contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, c); MAJOR_VERSION, c, local);
} }
@Nullable @Nullable
private LatestUpdates findLatestUpdates(Transaction txn, ContactId c) private LatestUpdates findLatestUpdates(Transaction txn, ContactId c)
throws DbException, FormatException { throws DbException, FormatException {
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
Group g = getContactGroup(contact); Group g = getContactGroup(contact, getLocalAuthorId(txn));
// Contact may be in the process of being added or removed, so // Contact may be in the process of being added or removed, so
// contact group may not exist // contact group may not exist
if (!db.containsGroup(txn, g.getId())) return null; if (!db.containsGroup(txn, g.getId())) return null;

View File

@@ -5,25 +5,20 @@ import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.NoSuchContactException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.AuthorInfo; import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.transport.KeyManager; import org.briarproject.bramble.api.transport.KeyManager;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.DbExpectations; import org.briarproject.bramble.test.DbExpectations;
import org.jmock.Expectations;
import org.jmock.Mockery; import org.jmock.Mockery;
import org.junit.Test; import org.junit.Test;
import java.util.Collection; import java.util.Collection;
import java.util.Random; import java.util.Random;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES; import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
@@ -33,7 +28,6 @@ import static org.briarproject.bramble.api.identity.AuthorInfo.Status.VERIFIED;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor; import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.test.TestUtils.getSecretKey; import static org.briarproject.bramble.test.TestUtils.getSecretKey;
import static org.briarproject.bramble.util.StringUtils.getRandomString; import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -48,11 +42,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
private final IdentityManager identityManager = private final IdentityManager identityManager =
context.mock(IdentityManager.class); context.mock(IdentityManager.class);
private final ContactManager contactManager; private final ContactManager contactManager;
private final Author remote = getAuthor(); private final Author author = getAuthor();
private final LocalAuthor localAuthor = getLocalAuthor(); private final LocalAuthor localAuthor = getLocalAuthor();
private final AuthorId local = localAuthor.getId();
private final boolean verified = false, active = true; private final boolean verified = false, active = true;
private final Contact contact = getContact(remote, local, verified); private final Contact contact = getContact(author, verified);
private final ContactId contactId = contact.getId(); private final ContactId contactId = contact.getId();
public ContactManagerImplTest() { public ContactManagerImplTest() {
@@ -69,7 +62,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(false), withDbCallable(txn)); oneOf(db).transactionWithResult(with(false), withDbCallable(txn));
oneOf(db).addContact(txn, remote, local, verified); oneOf(db).addContact(txn, author, verified);
will(returnValue(contactId)); will(returnValue(contactId));
oneOf(keyManager).addContact(txn, contactId, rootKey, timestamp, oneOf(keyManager).addContact(txn, contactId, rootKey, timestamp,
alice, active); alice, active);
@@ -77,12 +70,12 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
will(returnValue(contact)); will(returnValue(contact));
}}); }});
assertEquals(contactId, contactManager.addContact(remote, local, assertEquals(contactId, contactManager.addContact(author, rootKey,
rootKey, timestamp, alice, verified, active)); timestamp, alice, verified, active));
} }
@Test @Test
public void testGetContact() throws Exception { public void testGetContactByContactId() throws Exception {
Transaction txn = new Transaction(null, true); Transaction txn = new Transaction(null, true);
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
@@ -94,41 +87,15 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
} }
@Test @Test
public void testGetContactByAuthor() throws Exception { public void testGetContactByAuthorId() throws Exception {
Transaction txn = new Transaction(null, true);
Collection<Contact> contacts = singletonList(contact);
context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(db).getContactsByAuthorId(txn, remote.getId());
will(returnValue(contacts));
}});
assertEquals(contact, contactManager.getContact(remote.getId(), local));
}
@Test(expected = NoSuchContactException.class)
public void testGetContactByUnknownAuthor() throws Exception {
Transaction txn = new Transaction(null, true); Transaction txn = new Transaction(null, true);
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(db).getContactsByAuthorId(txn, remote.getId()); oneOf(db).getContact(txn, author.getId());
will(returnValue(emptyList())); will(returnValue(contact));
}}); }});
contactManager.getContact(remote.getId(), local); assertEquals(contact, contactManager.getContact(author.getId()));
}
@Test(expected = NoSuchContactException.class)
public void testGetContactByUnknownLocalAuthor() throws Exception {
Transaction txn = new Transaction(null, true);
Collection<Contact> contacts = singletonList(contact);
context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(db).getContactsByAuthorId(txn, remote.getId());
will(returnValue(contacts));
}});
contactManager.getContact(remote.getId(), new AuthorId(getRandomId()));
} }
@Test @Test
@@ -182,78 +149,82 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
Transaction txn = new Transaction(null, true); Transaction txn = new Transaction(null, true);
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(db).containsContact(txn, remote.getId(), local); oneOf(db).containsContact(txn, author.getId());
will(returnValue(true)); will(returnValue(true));
}}); }});
assertTrue(contactManager.contactExists(remote.getId(), local)); assertTrue(contactManager.contactExists(author.getId()));
} }
@Test @Test
public void testGetAuthorInfo() throws Exception { public void testGetAuthorInfoOurselves() throws Exception {
Transaction txn = new Transaction(null, true); Transaction txn = new Transaction(null, true);
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(identityManager).getLocalAuthor(txn); oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor)); will(returnValue(localAuthor));
oneOf(db).getContactsByAuthorId(txn, remote.getId());
will(returnValue(singletonList(contact)));
}}); }});
AuthorInfo authorInfo = AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, remote.getId()); contactManager.getAuthorInfo(txn, localAuthor.getId());
assertEquals(UNVERIFIED, authorInfo.getStatus());
assertEquals(contact.getAlias(), authorInfo.getAlias());
}
@Test
public void testGetAuthorInfoTransaction() throws DbException {
Transaction txn = new Transaction(null, true);
// check unknown author
context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContactsByAuthorId(txn, remote.getId());
will(returnValue(emptyList()));
}});
AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, remote.getId());
assertEquals(UNKNOWN, authorInfo.getStatus());
assertNull(authorInfo.getAlias());
// check unverified contact
checkAuthorInfoContext(txn, remote.getId(), singletonList(contact));
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
assertEquals(UNVERIFIED, authorInfo.getStatus());
assertEquals(contact.getAlias(), authorInfo.getAlias());
// check verified contact
Contact verified = getContact(remote, local, true);
checkAuthorInfoContext(txn, remote.getId(), singletonList(verified));
authorInfo = contactManager.getAuthorInfo(txn, remote.getId());
assertEquals(VERIFIED, authorInfo.getStatus());
assertEquals(verified.getAlias(), authorInfo.getAlias());
// check ourselves
context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
never(db).getContactsByAuthorId(txn, remote.getId());
}});
authorInfo = contactManager.getAuthorInfo(txn, localAuthor.getId());
assertEquals(OURSELVES, authorInfo.getStatus()); assertEquals(OURSELVES, authorInfo.getStatus());
assertNull(authorInfo.getAlias()); assertNull(authorInfo.getAlias());
} }
private void checkAuthorInfoContext(Transaction txn, AuthorId authorId, @Test
Collection<Contact> contacts) throws DbException { public void testGetAuthorInfoVerified() throws Exception {
context.checking(new Expectations() {{ Transaction txn = new Transaction(null, true);
Contact verified = getContact(author, true);
context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(identityManager).getLocalAuthor(txn); oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor)); will(returnValue(localAuthor));
oneOf(db).getContactsByAuthorId(txn, authorId); oneOf(db).containsContact(txn, author.getId());
will(returnValue(contacts)); will(returnValue(true));
oneOf(db).getContact(txn, author.getId());
will(returnValue(verified));
}}); }});
AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, author.getId());
assertEquals(VERIFIED, authorInfo.getStatus());
assertEquals(verified.getAlias(), authorInfo.getAlias());
} }
@Test
public void testGetAuthorInfoUnverified() throws Exception {
Transaction txn = new Transaction(null, true);
Contact unverified = getContact(author, false);
context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).containsContact(txn, author.getId());
will(returnValue(true));
oneOf(db).getContact(txn, author.getId());
will(returnValue(unverified));
}});
AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, author.getId());
assertEquals(UNVERIFIED, authorInfo.getStatus());
assertEquals(unverified.getAlias(), authorInfo.getAlias());
}
@Test
public void testGetAuthorInfoUnknown() throws Exception {
Transaction txn = new Transaction(null, true);
context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).containsContact(txn, author.getId());
will(returnValue(false));
}});
AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, author.getId());
assertEquals(UNKNOWN, authorInfo.getStatus());
assertNull(authorInfo.getAlias());
}
} }

View File

@@ -131,7 +131,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
metadata.put("foo", new byte[] {'b', 'a', 'r'}); metadata.put("foo", new byte[] {'b', 'a', 'r'});
transportId = getTransportId(); transportId = getTransportId();
maxLatency = Integer.MAX_VALUE; maxLatency = Integer.MAX_VALUE;
contact = getContact(author, localAuthor.getId(), true); contact = getContact(author, true);
contactId = contact.getId(); contactId = contact.getId();
alias = contact.getAlias(); alias = contact.getAlias();
keySetId = new TransportKeySetId(345); keySetId = new TransportKeySetId(345);
@@ -163,14 +163,11 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
oneOf(database).addLocalAuthor(txn, localAuthor); oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class))); oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
// addContact() // addContact()
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).containsLocalAuthor(txn, author.getId()); oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(false)); will(returnValue(false));
oneOf(database).containsContact(txn, author.getId(), oneOf(database).containsContact(txn, author.getId());
localAuthor.getId());
will(returnValue(false)); will(returnValue(false));
oneOf(database).addContact(txn, author, localAuthor.getId(), true); oneOf(database).addContact(txn, author, true);
will(returnValue(contactId)); will(returnValue(contactId));
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class))); oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
// getContacts() // getContacts()
@@ -217,8 +214,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
assertFalse(db.open(key, null)); assertFalse(db.open(key, null));
db.transaction(false, transaction -> { db.transaction(false, transaction -> {
db.addLocalAuthor(transaction, localAuthor); db.addLocalAuthor(transaction, localAuthor);
assertEquals(contactId, db.addContact(transaction, author, assertEquals(contactId, db.addContact(transaction, author, true));
localAuthor.getId(), true));
assertEquals(singletonList(contact), assertEquals(singletonList(contact),
db.getContacts(transaction)); db.getContacts(transaction));
db.addGroup(transaction, group); // First time - listeners called db.addGroup(transaction, group); // First time - listeners called
@@ -279,11 +275,13 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Check whether the contact is in the DB (which it's not) // Check whether the contact is in the DB (which it's not)
exactly(17).of(database).startTransaction(); exactly(18).of(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
exactly(17).of(database).containsContact(txn, contactId); exactly(17).of(database).containsContact(txn, contactId);
will(returnValue(false)); will(returnValue(false));
exactly(17).of(database).abortTransaction(txn); oneOf(database).containsContact(txn, author.getId());
will(returnValue(false));
exactly(18).of(database).abortTransaction(txn);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, eventBus, DatabaseComponent db = createDatabaseComponent(database, eventBus,
eventExecutor, shutdownManager); eventExecutor, shutdownManager);
@@ -346,6 +344,14 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
// Expected // Expected
} }
try {
db.transaction(false, transaction ->
db.getContact(transaction, author.getId()));
fail();
} catch (NoSuchContactException expected) {
// Expected
}
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.getMessageStatus(transaction, contactId, groupId)); db.getMessageStatus(transaction, contactId, groupId));
@@ -436,25 +442,16 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Check whether the pseudonym is in the DB (which it's not) // Check whether the pseudonym is in the DB (which it's not)
exactly(3).of(database).startTransaction(); exactly(2).of(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
exactly(3).of(database).containsLocalAuthor(txn, exactly(2).of(database).containsLocalAuthor(txn,
localAuthor.getId()); localAuthor.getId());
will(returnValue(false)); will(returnValue(false));
exactly(3).of(database).abortTransaction(txn); exactly(2).of(database).abortTransaction(txn);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, eventBus, DatabaseComponent db = createDatabaseComponent(database, eventBus,
eventExecutor, shutdownManager); eventExecutor, shutdownManager);
try {
db.transaction(false, transaction ->
db.addContact(transaction, author, localAuthor.getId(),
true));
fail();
} catch (NoSuchLocalAuthorException expected) {
// Expected
}
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.getLocalAuthor(transaction, localAuthor.getId())); db.getLocalAuthor(transaction, localAuthor.getId()));
@@ -1403,8 +1400,6 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
// Contact is a local identity // Contact is a local identity
oneOf(database).containsLocalAuthor(txn, author.getId()); oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(true)); will(returnValue(true));
@@ -1416,8 +1411,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.addContact(transaction, author, localAuthor.getId(), db.addContact(transaction, author, true));
true));
fail(); fail();
} catch (ContactExistsException expected) { } catch (ContactExistsException expected) {
// Expected // Expected
@@ -1429,13 +1423,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
will(returnValue(true));
oneOf(database).containsLocalAuthor(txn, author.getId()); oneOf(database).containsLocalAuthor(txn, author.getId());
will(returnValue(false)); will(returnValue(false));
// Contact already exists for this local identity // Contact already exists
oneOf(database).containsContact(txn, author.getId(), oneOf(database).containsContact(txn, author.getId());
localAuthor.getId());
will(returnValue(true)); will(returnValue(true));
oneOf(database).abortTransaction(txn); oneOf(database).abortTransaction(txn);
}}); }});
@@ -1445,8 +1436,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
try { try {
db.transaction(false, transaction -> db.transaction(false, transaction ->
db.addContact(transaction, author, localAuthor.getId(), db.addContact(transaction, author, true));
true));
fail(); fail();
} catch (ContactExistsException expected) { } catch (ContactExistsException expected) {
// Expected // Expected

View File

@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
@@ -131,11 +130,10 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
@Test @Test
public void testContainsContactByAuthorId() throws Exception { public void testContainsContactByAuthorId() throws Exception {
String name = "containsContact(T, AuthorId, AuthorId)"; String name = "containsContact(T, AuthorId)";
benchmark(name, db -> { benchmark(name, db -> {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
AuthorId remote = pickRandom(contacts).getAuthor().getId(); db.containsContact(txn, pickRandom(contacts).getAuthor().getId());
db.containsContact(txn, remote, localAuthor.getId());
db.commitTransaction(txn); db.commitTransaction(txn);
}); });
} }
@@ -202,7 +200,7 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
} }
@Test @Test
public void testGetContact() throws Exception { public void testGetContactByContactId() throws Exception {
String name = "getContact(T, ContactId)"; String name = "getContact(T, ContactId)";
benchmark(name, db -> { benchmark(name, db -> {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
@@ -211,6 +209,16 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
}); });
} }
@Test
public void testGetContactByAuthorId() throws Exception {
String name = "getContact(T, AuthorId)";
benchmark(name, db -> {
Connection txn = db.startTransaction();
db.getContact(txn, pickRandom(contacts).getAuthor().getId());
db.commitTransaction(txn);
});
}
@Test @Test
public void testGetContacts() throws Exception { public void testGetContacts() throws Exception {
String name = "getContacts(T)"; String name = "getContacts(T)";
@@ -221,27 +229,6 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
}); });
} }
@Test
public void testGetContactsByRemoteAuthorId() throws Exception {
String name = "getContactsByAuthorId(T, AuthorId)";
benchmark(name, db -> {
Connection txn = db.startTransaction();
AuthorId remote = pickRandom(contacts).getAuthor().getId();
db.getContactsByAuthorId(txn, remote);
db.commitTransaction(txn);
});
}
@Test
public void testGetContactsByLocalAuthorId() throws Exception {
String name = "getContacts(T, AuthorId)";
benchmark(name, db -> {
Connection txn = db.startTransaction();
db.getContacts(txn, localAuthor.getId());
db.commitTransaction(txn);
});
}
@Test @Test
public void testGetGroup() throws Exception { public void testGetGroup() throws Exception {
String name = "getGroup(T, GroupId)"; String name = "getGroup(T, GroupId)";
@@ -545,8 +532,7 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
db.addLocalAuthor(txn, localAuthor); db.addLocalAuthor(txn, localAuthor);
for (int i = 0; i < CONTACTS; i++) { for (int i = 0; i < CONTACTS; i++) {
ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(), ContactId c = db.addContact(txn, getAuthor(), random.nextBoolean());
random.nextBoolean());
contacts.add(db.getContact(txn, c)); contacts.add(db.getContact(txn, c));
contactGroups.put(c, new ArrayList<>()); contactGroups.put(c, new ArrayList<>());
for (int j = 0; j < GROUPS_PER_CONTACT; j++) { for (int j = 0; j < GROUPS_PER_CONTACT; j++) {

View File

@@ -84,7 +84,6 @@ import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -146,8 +145,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
assertFalse(db.containsContact(txn, contactId)); assertFalse(db.containsContact(txn, contactId));
db.addLocalAuthor(txn, localAuthor); db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, assertEquals(contactId, db.addContact(txn, author, true));
db.addContact(txn, author, localAuthor.getId(), true));
assertTrue(db.containsContact(txn, contactId)); assertTrue(db.containsContact(txn, contactId));
assertFalse(db.containsGroup(txn, groupId)); assertFalse(db.containsGroup(txn, groupId));
db.addGroup(txn, group); db.addGroup(txn, group);
@@ -208,9 +206,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -239,9 +235,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared but unvalidated message // Add a contact, a shared group and a shared but unvalidated message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, UNKNOWN, true, null); db.addMessage(txn, message, UNKNOWN, true, null);
@@ -284,9 +278,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, an invisible group and a shared message // Add a contact, an invisible group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -335,9 +327,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and an unshared message // Add a contact, a shared group and an unshared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, false, null); db.addMessage(txn, message, DELIVERED, false, null);
@@ -366,17 +356,14 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
// The message is sendable, but too large to send // The message is sendable, but too large to send
Collection<MessageId> ids = Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
db.getMessagesToSend(txn, contactId, message.getRawLength() - 1, message.getRawLength() - 1, MAX_LATENCY);
MAX_LATENCY);
assertTrue(ids.isEmpty()); assertTrue(ids.isEmpty());
// The message is just the right size to send // The message is just the right size to send
ids = db.getMessagesToSend(txn, contactId, message.getRawLength(), ids = db.getMessagesToSend(txn, contactId, message.getRawLength(),
@@ -393,9 +380,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact and a visible group // Add a contact and a visible group
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, false); db.addGroupVisibility(txn, contactId, groupId, false);
@@ -434,9 +419,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -566,9 +549,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact and a shared group // Add a contact and a shared group
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
@@ -586,9 +567,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact // Add a contact
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
// The group is not in the database // The group is not in the database
assertFalse(db.containsVisibleMessage(txn, contactId, messageId)); assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
@@ -604,9 +583,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, an invisible group and a message // Add a contact, an invisible group and a message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -623,9 +600,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact and a group // Add a contact and a group
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
// The group should not be visible to the contact // The group should not be visible to the contact
@@ -675,9 +650,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertEquals(emptyList(), db.getTransportKeys(txn, transportId)); assertEquals(emptyList(), db.getTransportKeys(txn, transportId));
// Add the contact, the transport and the transport keys // Add the contact, the transport and the transport keys
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1)); assertEquals(keySetId1, db.addTransportKeys(txn, contactId, keys1));
@@ -776,9 +749,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
assertEquals(emptyList(), db.getHandshakeKeys(txn, transportId)); assertEquals(emptyList(), db.getHandshakeKeys(txn, transportId));
// Add the contact, the transport and the handshake keys // Add the contact, the transport and the handshake keys
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(handshakeKeySetId, assertEquals(handshakeKeySetId,
db.addHandshakeKeys(txn, contactId, keys)); db.addHandshakeKeys(txn, contactId, keys));
@@ -929,9 +900,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add the contact, transport and transport keys // Add the contact, transport and transport keys
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
@@ -973,9 +942,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add the contact, transport and handshake keys // Add the contact, transport and handshake keys
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(handshakeKeySetId, assertEquals(handshakeKeySetId,
db.addHandshakeKeys(txn, contactId, keys)); db.addHandshakeKeys(txn, contactId, keys));
@@ -1020,9 +987,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add the contact, transport and transport keys // Add the contact, transport and transport keys
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys)); assertEquals(keySetId, db.addTransportKeys(txn, contactId, keys));
@@ -1067,9 +1032,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add the contact, transport and handshake keys // Add the contact, transport and handshake keys
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author,true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addTransport(txn, transportId, 123); db.addTransport(txn, transportId, 123);
assertEquals(handshakeKeySetId, assertEquals(handshakeKeySetId,
db.addHandshakeKeys(txn, contactId, keys)); db.addHandshakeKeys(txn, contactId, keys));
@@ -1105,54 +1068,42 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
} }
@Test @Test
public void testGetContactsByAuthorId() throws Exception { public void testGetContactByContactId() throws Exception {
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a local author - no contacts should be associated // Add a contact
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
// Add a contact associated with the local author // Check the contact is returned
assertEquals(contactId, Contact c = db.getContact(txn, contactId);
db.addContact(txn, author, localAuthor.getId(), true)); assertEquals(contactId, c.getId());
assertEquals(author.getId(), c.getAuthor().getId());
// Ensure contact is returned from database by Author ID assertEquals(author.getFormatVersion(),
Collection<Contact> contacts = c.getAuthor().getFormatVersion());
db.getContactsByAuthorId(txn, author.getId()); assertEquals(author.getName(), c.getAuthor().getName());
assertEquals(1, contacts.size()); assertArrayEquals(author.getPublicKey(), c.getAuthor().getPublicKey());
assertEquals(contactId, contacts.iterator().next().getId());
// Ensure no contacts are returned after contact was deleted
db.removeContact(txn, contactId);
contacts = db.getContactsByAuthorId(txn, author.getId());
assertEquals(0, contacts.size());
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();
} }
@Test @Test
public void testGetContactsByLocalAuthorId() throws Exception { public void testGetContactByAuthorId() throws Exception {
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a local author - no contacts should be associated // Add a contact
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
Collection<ContactId> contacts =
db.getContacts(txn, localAuthor.getId());
assertEquals(emptyList(), contacts);
// Add a contact associated with the local author // Check the contact is returned
assertEquals(contactId, Contact c = db.getContact(txn, author.getId());
db.addContact(txn, author, localAuthor.getId(), true)); assertEquals(contactId, c.getId());
contacts = db.getContacts(txn, localAuthor.getId()); assertEquals(author.getId(), c.getAuthor().getId());
assertEquals(singletonList(contactId), contacts); assertEquals(author.getFormatVersion(),
c.getAuthor().getFormatVersion());
// Remove the local author - the contact should be removed assertEquals(author.getName(), c.getAuthor().getName());
db.removeLocalAuthor(txn, localAuthor.getId()); assertArrayEquals(author.getPublicKey(), c.getAuthor().getPublicKey());
contacts = db.getContacts(txn, localAuthor.getId());
assertEquals(emptyList(), contacts);
assertFalse(db.containsContact(txn, contactId));
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();
@@ -1164,9 +1115,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact - initially there should be no offered messages // Add a contact - initially there should be no offered messages
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
assertEquals(0, db.countOfferedMessages(txn, contactId)); assertEquals(0, db.countOfferedMessages(txn, contactId));
// Add some offered messages and count them // Add some offered messages and count them
@@ -1748,9 +1697,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -1847,43 +1794,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
db.close(); db.close();
} }
@Test
public void testDifferentLocalAuthorsCanHaveTheSameContact()
throws Exception {
LocalAuthor localAuthor1 = getLocalAuthor();
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add two local authors
db.addLocalAuthor(txn, localAuthor);
db.addLocalAuthor(txn, localAuthor1);
// Add the same contact for each local author
ContactId contactId =
db.addContact(txn, author, localAuthor.getId(), true);
ContactId contactId1 =
db.addContact(txn, author, localAuthor1.getId(), true);
// The contacts should be distinct
assertNotEquals(contactId, contactId1);
assertEquals(2, db.getContacts(txn).size());
assertEquals(1, db.getContacts(txn, localAuthor.getId()).size());
assertEquals(1, db.getContacts(txn, localAuthor1.getId()).size());
db.commitTransaction(txn);
db.close();
}
@Test @Test
public void testDeleteMessage() throws Exception { public void testDeleteMessage() throws Exception {
Database<Connection> db = open(false); Database<Connection> db = open(false);
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -1935,9 +1852,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact // Add a contact
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
// The contact should have no alias // The contact should have no alias
Contact contact = db.getContact(txn, contactId); Contact contact = db.getContact(txn, contactId);
@@ -1992,9 +1907,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a group and a message // Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addMessage(txn, message, UNKNOWN, false, null); db.addMessage(txn, message, UNKNOWN, false, null);
@@ -2076,9 +1989,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);
@@ -2121,9 +2032,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Add a contact, a shared group and a shared message // Add a contact, a shared group and a shared message
db.addLocalAuthor(txn, localAuthor); assertEquals(contactId, db.addContact(txn, author, true));
assertEquals(contactId,
db.addContact(txn, author, localAuthor.getId(), true));
db.addGroup(txn, group); db.addGroup(txn, group);
db.addGroupVisibility(txn, contactId, groupId, true); db.addGroupVisibility(txn, contactId, groupId, true);
db.addMessage(txn, message, DELIVERED, true, null); db.addMessage(txn, message, DELIVERED, true, null);

View File

@@ -11,6 +11,8 @@ import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.bramble.api.properties.TransportProperties; import org.briarproject.bramble.api.properties.TransportProperties;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
@@ -37,6 +39,7 @@ import static org.briarproject.bramble.api.properties.TransportPropertyManager.M
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED; import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getGroup; 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.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -46,6 +49,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class); private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final ClientHelper clientHelper = context.mock(ClientHelper.class); private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final IdentityManager identityManager =
context.mock(IdentityManager.class);
private final ClientVersioningManager clientVersioningManager = private final ClientVersioningManager clientVersioningManager =
context.mock(ClientVersioningManager.class); context.mock(ClientVersioningManager.class);
private final MetadataParser metadataParser = private final MetadataParser metadataParser =
@@ -55,6 +60,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
private final Clock clock = context.mock(Clock.class); private final Clock clock = context.mock(Clock.class);
private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
private final LocalAuthor localAuthor = getLocalAuthor();
private final BdfDictionary fooPropertiesDict = BdfDictionary.of( private final BdfDictionary fooPropertiesDict = BdfDictionary.of(
new BdfEntry("fooKey1", "fooValue1"), new BdfEntry("fooKey1", "fooValue1"),
new BdfEntry("fooKey2", "fooValue2") new BdfEntry("fooKey2", "fooValue2")
@@ -81,8 +87,8 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
will(returnValue(localGroup)); will(returnValue(localGroup));
}}); }});
return new TransportPropertyManagerImpl(db, clientHelper, return new TransportPropertyManagerImpl(db, clientHelper,
clientVersioningManager, metadataParser, contactGroupFactory, identityManager, clientVersioningManager, metadataParser,
clock); contactGroupFactory, clock);
} }
@Test @Test
@@ -95,10 +101,12 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
oneOf(db).containsGroup(txn, localGroup.getId()); oneOf(db).containsGroup(txn, localGroup.getId());
will(returnValue(false)); will(returnValue(false));
oneOf(db).addGroup(txn, localGroup); oneOf(db).addGroup(txn, localGroup);
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(singletonList(contact))); will(returnValue(singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).addGroup(txn, contactGroup); oneOf(db).addGroup(txn, contactGroup);
oneOf(clientVersioningManager).getClientVisibility(txn, oneOf(clientVersioningManager).getClientVisibility(txn,
@@ -140,8 +148,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Create the group and share it with the contact // Create the group and share it with the contact
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).addGroup(txn, contactGroup); oneOf(db).addGroup(txn, contactGroup);
oneOf(clientVersioningManager).getClientVisibility(txn, oneOf(clientVersioningManager).getClientVisibility(txn,
@@ -168,8 +178,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).removeGroup(txn, contactGroup); oneOf(db).removeGroup(txn, contactGroup);
}}); }});
@@ -307,8 +319,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).getContact(txn, contact.getId()); oneOf(db).getContact(txn, contact.getId());
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
}}); }});
expectStoreMessage(txn, contactGroup.getId(), "foo", fooPropertiesDict, expectStoreMessage(txn, contactGroup.getId(), "foo", fooPropertiesDict,
@@ -432,18 +446,20 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
context.checking(new DbExpectations() {{ context.checking(new DbExpectations() {{
oneOf(db).transactionWithResult(with(true), withDbCallable(txn)); oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(contacts)); will(returnValue(contacts));
// First contact: no updates // First contact: no updates
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact1); MAJOR_VERSION, contact1, localAuthor.getId());
will(returnValue(contactGroup1)); will(returnValue(contactGroup1));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup1.getId()); contactGroup1.getId());
will(returnValue(Collections.emptyMap())); will(returnValue(Collections.emptyMap()));
// Second contact: returns an update // Second contact: returns an update
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact2); MAJOR_VERSION, contact2, localAuthor.getId());
will(returnValue(contactGroup2)); will(returnValue(contactGroup2));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup2.getId()); contactGroup2.getId());
@@ -510,10 +526,12 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
expectStoreMessage(txn, localGroup.getId(), "foo", expectStoreMessage(txn, localGroup.getId(), "foo",
fooPropertiesDict, 1, true, false); fooPropertiesDict, 1, true, false);
// Store the new properties in each contact's group, version 1 // Store the new properties in each contact's group, version 1
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(singletonList(contact))); will(returnValue(singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup.getId()); contactGroup.getId());
@@ -566,10 +584,12 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
// Delete the previous update // Delete the previous update
oneOf(db).removeMessage(txn, localGroupUpdateId); oneOf(db).removeMessage(txn, localGroupUpdateId);
// Store the merged properties in each contact's group, version 2 // Store the merged properties in each contact's group, version 2
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(singletonList(contact))); will(returnValue(singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup.getId()); contactGroup.getId());

View File

@@ -10,6 +10,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Group.Visibility; import org.briarproject.bramble.api.sync.Group.Visibility;
@@ -36,6 +38,7 @@ import static org.briarproject.bramble.api.versioning.ClientVersioningManager.MA
import static org.briarproject.bramble.test.TestUtils.getClientId; import static org.briarproject.bramble.test.TestUtils.getClientId;
import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getGroup; 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.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
import static org.briarproject.bramble.versioning.ClientVersioningConstants.GROUP_KEY_CONTACT_ID; import static org.briarproject.bramble.versioning.ClientVersioningConstants.GROUP_KEY_CONTACT_ID;
@@ -48,12 +51,15 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class); private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final ClientHelper clientHelper = context.mock(ClientHelper.class); private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final IdentityManager identityManager =
context.mock(IdentityManager.class);
private final ContactGroupFactory contactGroupFactory = private final ContactGroupFactory contactGroupFactory =
context.mock(ContactGroupFactory.class); context.mock(ContactGroupFactory.class);
private final Clock clock = context.mock(Clock.class); private final Clock clock = context.mock(Clock.class);
private final ClientVersioningHook hook = private final ClientVersioningHook hook =
context.mock(ClientVersioningHook.class); context.mock(ClientVersioningHook.class);
private final LocalAuthor localAuthor = getLocalAuthor();
private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
private final Contact contact = getContact(); private final Contact contact = getContact();
@@ -68,7 +74,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
will(returnValue(localGroup)); will(returnValue(localGroup));
}}); }});
return new ClientVersioningManagerImpl(db, clientHelper, return new ClientVersioningManagerImpl(db, clientHelper,
contactGroupFactory, clock); identityManager, contactGroupFactory, clock);
} }
@Test @Test
@@ -117,8 +123,10 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
new BdfEntry(MSG_KEY_LOCAL, true)); new BdfEntry(MSG_KEY_LOCAL, true));
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).addGroup(txn, contactGroup); oneOf(db).addGroup(txn, contactGroup);
oneOf(db).setGroupVisibility(txn, contact.getId(), oneOf(db).setGroupVisibility(txn, contact.getId(),
@@ -138,8 +146,10 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testRemovesGroupWhenRemovingContact() throws Exception { public void testRemovesGroupWhenRemovingContact() throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).removeGroup(txn, contactGroup); oneOf(db).removeGroup(txn, contactGroup);
}}); }});
@@ -174,10 +184,12 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
oneOf(db).addLocalMessage(txn, localVersions, new Metadata(), oneOf(db).addLocalMessage(txn, localVersions, new Metadata(),
false); false);
// Inform contacts that client versions have changed // Inform contacts that client versions have changed
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(singletonList(contact))); will(returnValue(singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
// Find the latest local and remote updates (no remote update) // Find the latest local and remote updates (no remote update)
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
@@ -261,10 +273,12 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(), oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(),
false); false);
// Inform contacts that client versions have changed // Inform contacts that client versions have changed
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(singletonList(contact))); will(returnValue(singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
// Find the latest local and remote updates (no remote update) // Find the latest local and remote updates (no remote update)
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
@@ -357,10 +371,12 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(), oneOf(db).addLocalMessage(txn, newLocalVersions, new Metadata(),
false); false);
// Inform contacts that client versions have changed // Inform contacts that client versions have changed
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(singletonList(contact))); will(returnValue(singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
// Find the latest local and remote updates // Find the latest local and remote updates
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
@@ -970,8 +986,10 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).getContact(txn, contact.getId()); oneOf(db).getContact(txn, contact.getId());
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).containsGroup(txn, contactGroup.getId()); oneOf(db).containsGroup(txn, contactGroup.getId());
will(returnValue(exists)); will(returnValue(exists));

View File

@@ -153,8 +153,8 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl
long timestamp = clock.currentTimeMillis(); long timestamp = clock.currentTimeMillis();
List<InvitationContext> contexts = new ArrayList<>(); List<InvitationContext> contexts = new ArrayList<>();
for (Contact c : contacts) { for (Contact c : contacts) {
byte[] signature = groupInvitationFactory.signInvitation(c, g, byte[] signature = groupInvitationFactory.signInvitation(
timestamp, localAuthor.getPrivateKey()); localAuthor, c, g, timestamp);
contexts.add(new InvitationContext(c.getId(), timestamp, contexts.add(new InvitationContext(c.getId(), timestamp,
signature)); signature));
} }

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@@ -39,7 +40,7 @@ public interface ConversationManager {
@NotNullByDefault @NotNullByDefault
interface ConversationClient { interface ConversationClient {
Group getContactGroup(Contact c); Group getContactGroup(Contact c, AuthorId local);
Collection<ConversationMessageHeader> getMessageHeaders(Transaction txn, Collection<ConversationMessageHeader> getMessageHeaders(Transaction txn,
ContactId contactId) throws DbException; ContactId contactId) throws DbException;

View File

@@ -4,6 +4,7 @@ import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.crypto.CryptoExecutor; import org.briarproject.bramble.api.crypto.CryptoExecutor;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.AuthorId; 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.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@@ -20,8 +21,8 @@ public interface GroupInvitationFactory {
* included in the member's join message. * included in the member's join message.
*/ */
@CryptoExecutor @CryptoExecutor
byte[] signInvitation(Contact c, GroupId privateGroupId, long timestamp, byte[] signInvitation(LocalAuthor creator, Contact member,
byte[] privateKey); GroupId privateGroupId, long timestamp);
/** /**
* Returns a token to be signed by the creator when inviting a member to * Returns a token to be signed by the creator when inviting a member to

View File

@@ -1,6 +1,5 @@
package org.briarproject.briar.api.test; package org.briarproject.briar.api.test;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.IoExecutor;
@@ -24,9 +23,4 @@ public interface TestDataCreator {
@IoExecutor @IoExecutor
Contact addContact(String name) throws DbException; Contact addContact(String name) throws DbException;
@IoExecutor
void addPrivateMessage(Contact contact, String text, long time,
boolean local) throws DbException, FormatException;
} }

View File

@@ -8,6 +8,8 @@ import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
@@ -23,12 +25,14 @@ public abstract class ConversationClientImpl extends BdfIncomingMessageHook
implements ConversationClient { implements ConversationClient {
protected final MessageTracker messageTracker; protected final MessageTracker messageTracker;
protected final IdentityManager identityManager;
protected ConversationClientImpl(DatabaseComponent db, protected ConversationClientImpl(DatabaseComponent db,
ClientHelper clientHelper, MetadataParser metadataParser, ClientHelper clientHelper, MetadataParser metadataParser,
MessageTracker messageTracker) { MessageTracker messageTracker, IdentityManager identityManager) {
super(db, clientHelper, metadataParser); super(db, clientHelper, metadataParser);
this.messageTracker = messageTracker; this.messageTracker = messageTracker;
this.identityManager = identityManager;
} }
/** /**
@@ -40,11 +44,16 @@ public abstract class ConversationClientImpl extends BdfIncomingMessageHook
messageTracker.initializeGroupCount(txn, g); messageTracker.initializeGroupCount(txn, g);
} }
protected AuthorId getLocalAuthorId(Transaction txn) throws DbException {
return identityManager.getLocalAuthor(txn).getId();
}
@Override @Override
public GroupCount getGroupCount(Transaction txn, ContactId contactId) public GroupCount getGroupCount(Transaction txn, ContactId contactId)
throws DbException { throws DbException {
Contact contact = db.getContact(txn, contactId); Contact contact = db.getContact(txn, contactId);
GroupId groupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId groupId = getContactGroup(contact, local).getId();
return messageTracker.getGroupCount(txn, groupId); return messageTracker.getGroupCount(txn, groupId);
} }

View File

@@ -148,8 +148,7 @@ abstract class AbstractProtocolEngine<S extends Session>
void broadcastIntroductionResponseReceivedEvent(Transaction txn, Session s, void broadcastIntroductionResponseReceivedEvent(Transaction txn, Session s,
AuthorId sender, Author otherAuthor, AbstractIntroductionMessage m, AuthorId sender, Author otherAuthor, AbstractIntroductionMessage m,
boolean canSucceed) throws DbException { boolean canSucceed) throws DbException {
AuthorId localAuthorId = identityManager.getLocalAuthor(txn).getId(); Contact c = contactManager.getContact(txn, sender);
Contact c = contactManager.getContact(txn, sender, localAuthorId);
AuthorInfo otherAuthorInfo = AuthorInfo otherAuthorInfo =
contactManager.getAuthorInfo(txn, otherAuthor.getId()); contactManager.getAuthorInfo(txn, otherAuthor.getId());
IntroductionResponse response = IntroductionResponse response =

View File

@@ -249,9 +249,7 @@ class IntroduceeProtocolEngine
.trackMessage(txn, m.getGroupId(), m.getTimestamp(), false); .trackMessage(txn, m.getGroupId(), m.getTimestamp(), false);
// Broadcast IntroductionRequestReceivedEvent // Broadcast IntroductionRequestReceivedEvent
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn); Contact c = contactManager.getContact(txn, s.getIntroducer().getId());
Contact c = contactManager.getContact(txn, s.getIntroducer().getId(),
localAuthor.getId());
AuthorInfo authorInfo = AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, m.getAuthor().getId()); contactManager.getAuthorInfo(txn, m.getAuthor().getId());
IntroductionRequest request = new IntroductionRequest(m.getMessageId(), IntroductionRequest request = new IntroductionRequest(m.getMessageId(),
@@ -432,14 +430,13 @@ class IntroduceeProtocolEngine
Map<TransportId, TransportKeySetId> keys = null; Map<TransportId, TransportKeySetId> keys = null;
try { try {
contactManager.addContact(txn, s.getRemote().author, contactManager.addContact(txn, s.getRemote().author, false);
localAuthor.getId(), false);
// Only add transport properties and keys when the contact was added // Only add transport properties and keys when the contact was added
// This will be changed once we have a way to reset state for peers // This will be changed once we have a way to reset state for peers
// that were contacts already at some point in the past. // that were contacts already at some point in the past.
Contact c = contactManager.getContact(txn, Contact c = contactManager.getContact(txn,
s.getRemote().author.getId(), localAuthor.getId()); s.getRemote().author.getId());
// add the keys to the new contact // add the keys to the new contact
//noinspection ConstantConditions //noinspection ConstantConditions

View File

@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.AuthorInfo; import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Client;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
@@ -79,7 +78,6 @@ class IntroductionManagerImpl extends ConversationClientImpl
private final IntroducerProtocolEngine introducerEngine; private final IntroducerProtocolEngine introducerEngine;
private final IntroduceeProtocolEngine introduceeEngine; private final IntroduceeProtocolEngine introduceeEngine;
private final IntroductionCrypto crypto; private final IntroductionCrypto crypto;
private final IdentityManager identityManager;
private final Group localGroup; private final Group localGroup;
@@ -90,6 +88,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MetadataParser metadataParser,
MessageTracker messageTracker, MessageTracker messageTracker,
IdentityManager identityManager,
ContactGroupFactory contactGroupFactory, ContactGroupFactory contactGroupFactory,
ContactManager contactManager, ContactManager contactManager,
MessageParser messageParser, MessageParser messageParser,
@@ -97,9 +96,9 @@ class IntroductionManagerImpl extends ConversationClientImpl
SessionParser sessionParser, SessionParser sessionParser,
IntroducerProtocolEngine introducerEngine, IntroducerProtocolEngine introducerEngine,
IntroduceeProtocolEngine introduceeEngine, IntroduceeProtocolEngine introduceeEngine,
IntroductionCrypto crypto, IntroductionCrypto crypto) {
IdentityManager identityManager) { super(db, clientHelper, metadataParser, messageTracker,
super(db, clientHelper, metadataParser, messageTracker); identityManager);
this.clientVersioningManager = clientVersioningManager; this.clientVersioningManager = clientVersioningManager;
this.contactGroupFactory = contactGroupFactory; this.contactGroupFactory = contactGroupFactory;
this.contactManager = contactManager; this.contactManager = contactManager;
@@ -109,7 +108,6 @@ class IntroductionManagerImpl extends ConversationClientImpl
this.introducerEngine = introducerEngine; this.introducerEngine = introducerEngine;
this.introduceeEngine = introduceeEngine; this.introduceeEngine = introduceeEngine;
this.crypto = crypto; this.crypto = crypto;
this.identityManager = identityManager;
this.localGroup = this.localGroup =
contactGroupFactory.createLocalGroup(CLIENT_ID, MAJOR_VERSION); contactGroupFactory.createLocalGroup(CLIENT_ID, MAJOR_VERSION);
} }
@@ -126,7 +124,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
@Override @Override
public void addingContact(Transaction txn, Contact c) throws DbException { public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group to share with the contact // Create a group to share with the contact
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.addGroup(txn, g); db.addGroup(txn, g);
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
@@ -148,21 +146,21 @@ class IntroductionManagerImpl extends ConversationClientImpl
abortOrRemoveSessionWithIntroducee(txn, c); abortOrRemoveSessionWithIntroducee(txn, c);
// Remove the contact group (all messages will be removed with it) // Remove the contact group (all messages will be removed with it)
db.removeGroup(txn, getContactGroup(c)); db.removeGroup(txn, getContactGroup(c, getLocalAuthorId(txn)));
} }
@Override @Override
public void onClientVisibilityChanging(Transaction txn, Contact c, public void onClientVisibilityChanging(Transaction txn, Contact c,
Visibility v) throws DbException { Visibility v) throws DbException {
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.setGroupVisibility(txn, c.getId(), g.getId(), v); db.setGroupVisibility(txn, c.getId(), g.getId(), v);
} }
@Override @Override
public Group getContactGroup(Contact c) { public Group getContactGroup(Contact c, AuthorId local) {
return contactGroupFactory return contactGroupFactory
.createContactGroup(CLIENT_ID, MAJOR_VERSION, c); .createContactGroup(CLIENT_ID, MAJOR_VERSION, c, local);
} }
@Override @Override
@@ -328,17 +326,18 @@ class IntroductionManagerImpl extends ConversationClientImpl
try { try {
// Look up the session, if there is one // Look up the session, if there is one
Author introducer = identityManager.getLocalAuthor(txn); Author introducer = identityManager.getLocalAuthor(txn);
SessionId sessionId = SessionId sessionId = crypto.getSessionId(introducer,
crypto.getSessionId(introducer, c1.getAuthor(), c1.getAuthor(), c2.getAuthor());
c2.getAuthor());
StoredSession ss = getSession(txn, sessionId); StoredSession ss = getSession(txn, sessionId);
// Create or parse the session // Create or parse the session
IntroducerSession session; IntroducerSession session;
MessageId storageId; MessageId storageId;
if (ss == null) { if (ss == null) {
// This is the first request - create a new session // This is the first request - create a new session
GroupId groupId1 = getContactGroup(c1).getId(); GroupId groupId1 =
GroupId groupId2 = getContactGroup(c2).getId(); getContactGroup(c1, introducer.getId()).getId();
GroupId groupId2 =
getContactGroup(c2, introducer.getId()).getId();
boolean alice = crypto.isAlice(c1.getAuthor().getId(), boolean alice = crypto.isAlice(c1.getAuthor().getId(),
c2.getAuthor().getId()); c2.getAuthor().getId());
// use fixed deterministic roles for the introducees // use fixed deterministic roles for the introducees
@@ -382,7 +381,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
} }
// Parse the session // Parse the session
Contact contact = db.getContact(txn, contactId); Contact contact = db.getContact(txn, contactId);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
IntroduceeSession session = sessionParser IntroduceeSession session = sessionParser
.parseIntroduceeSession(contactGroupId, ss.bdfSession); .parseIntroduceeSession(contactGroupId, ss.bdfSession);
// Handle the join or leave action // Handle the join or leave action
@@ -408,7 +408,8 @@ class IntroductionManagerImpl extends ConversationClientImpl
Transaction txn, ContactId c) throws DbException { Transaction txn, ContactId c) throws DbException {
try { try {
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
Map<MessageId, BdfDictionary> results = clientHelper Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, contactGroupId, query); .getMessageMetadataAsDictionary(txn, contactGroupId, query);
@@ -521,13 +522,11 @@ class IntroductionManagerImpl extends ConversationClientImpl
BdfDictionary query = sessionEncoder.getIntroducerSessionsQuery(); BdfDictionary query = sessionEncoder.getIntroducerSessionsQuery();
Map<MessageId, BdfDictionary> sessions; Map<MessageId, BdfDictionary> sessions;
try { try {
sessions = clientHelper sessions = clientHelper.getMessageMetadataAsDictionary(txn,
.getMessageMetadataAsDictionary(txn, localGroup.getId(), localGroup.getId(), query);
query);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(); throw new DbException();
} }
LocalAuthor localAuthor = identityManager.getLocalAuthor(txn);
for (Entry<MessageId, BdfDictionary> session : sessions.entrySet()) { for (Entry<MessageId, BdfDictionary> session : sessions.entrySet()) {
IntroducerSession s; IntroducerSession s;
try { try {
@@ -537,18 +536,18 @@ class IntroductionManagerImpl extends ConversationClientImpl
} }
if (s.getIntroduceeA().author.equals(c.getAuthor())) { if (s.getIntroduceeA().author.equals(c.getAuthor())) {
abortOrRemoveSessionWithIntroducee(txn, s, session.getKey(), abortOrRemoveSessionWithIntroducee(txn, s, session.getKey(),
s.getIntroduceeB(), localAuthor); s.getIntroduceeB());
} else if (s.getIntroduceeB().author.equals(c.getAuthor())) { } else if (s.getIntroduceeB().author.equals(c.getAuthor())) {
abortOrRemoveSessionWithIntroducee(txn, s, session.getKey(), abortOrRemoveSessionWithIntroducee(txn, s, session.getKey(),
s.getIntroduceeA(), localAuthor); s.getIntroduceeA());
} }
} }
} }
private void abortOrRemoveSessionWithIntroducee(Transaction txn, private void abortOrRemoveSessionWithIntroducee(Transaction txn,
IntroducerSession s, MessageId storageId, Introducee i, IntroducerSession s, MessageId storageId, Introducee i)
LocalAuthor localAuthor) throws DbException { throws DbException {
if (db.containsContact(txn, i.author.getId(), localAuthor.getId())) { if (db.containsContact(txn, i.author.getId())) {
IntroducerSession session = IntroducerSession session =
introducerEngine.onIntroduceeRemoved(txn, i, s); introducerEngine.onIntroduceeRemoved(txn, i, s);
storeSession(txn, storageId, session); storeSession(txn, storageId, session);

View File

@@ -12,6 +12,8 @@ import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Client;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
@@ -59,8 +61,10 @@ class MessagingManagerImpl extends ConversationClientImpl
MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper, MessagingManagerImpl(DatabaseComponent db, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MessageTracker messageTracker, MetadataParser metadataParser, MessageTracker messageTracker,
IdentityManager identityManager,
ContactGroupFactory contactGroupFactory) { ContactGroupFactory contactGroupFactory) {
super(db, clientHelper, metadataParser, messageTracker); super(db, clientHelper, metadataParser, messageTracker,
identityManager);
this.clientVersioningManager = clientVersioningManager; this.clientVersioningManager = clientVersioningManager;
this.contactGroupFactory = contactGroupFactory; this.contactGroupFactory = contactGroupFactory;
} }
@@ -79,7 +83,7 @@ class MessagingManagerImpl extends ConversationClientImpl
@Override @Override
public void addingContact(Transaction txn, Contact c) throws DbException { public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group to share with the contact // Create a group to share with the contact
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.addGroup(txn, g); db.addGroup(txn, g);
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
@@ -98,21 +102,21 @@ class MessagingManagerImpl extends ConversationClientImpl
} }
@Override @Override
public Group getContactGroup(Contact c) { public Group getContactGroup(Contact c, AuthorId local) {
return contactGroupFactory.createContactGroup(CLIENT_ID, return contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, c); MAJOR_VERSION, c, local);
} }
@Override @Override
public void removingContact(Transaction txn, Contact c) throws DbException { public void removingContact(Transaction txn, Contact c) throws DbException {
db.removeGroup(txn, getContactGroup(c)); db.removeGroup(txn, getContactGroup(c, getLocalAuthorId(txn)));
} }
@Override @Override
public void onClientVisibilityChanging(Transaction txn, Contact c, public void onClientVisibilityChanging(Transaction txn, Contact c,
Visibility v) throws DbException { Visibility v) throws DbException {
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.setGroupVisibility(txn, c.getId(), g.getId(), v); db.setGroupVisibility(txn, c.getId(), g.getId(), v);
} }
@@ -188,15 +192,14 @@ class MessagingManagerImpl extends ConversationClientImpl
@Override @Override
public GroupId getConversationId(ContactId c) throws DbException { public GroupId getConversationId(ContactId c) throws DbException {
Contact contact; return db.transactionWithResult(true, txn -> getConversationId(txn, c));
Transaction txn = db.startTransaction(true);
try {
contact = db.getContact(txn, c);
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
} }
return getContactGroup(contact).getId();
private GroupId getConversationId(Transaction txn, ContactId c)
throws DbException {
Contact contact = db.getContact(txn, c);
AuthorId local = getLocalAuthorId(txn);
return getContactGroup(contact, local).getId();
} }
@Override @Override
@@ -206,7 +209,7 @@ class MessagingManagerImpl extends ConversationClientImpl
Collection<MessageStatus> statuses; Collection<MessageStatus> statuses;
GroupId g; GroupId g;
try { try {
g = getContactGroup(db.getContact(txn, c)).getId(); g = getConversationId(txn, c);
metadata = clientHelper.getMessageMetadataAsDictionary(txn, g); metadata = clientHelper.getMessageMetadataAsDictionary(txn, g);
statuses = db.getMessageStatus(txn, c, g); statuses = db.getMessageStatus(txn, c, g);
} catch (FormatException e) { } catch (FormatException e) {

View File

@@ -17,8 +17,6 @@ import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.AuthorInfo; import org.briarproject.bramble.api.identity.AuthorInfo;
import org.briarproject.bramble.api.identity.AuthorInfo.Status; import org.briarproject.bramble.api.identity.AuthorInfo.Status;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@@ -83,7 +81,6 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
private final PrivateGroupFactory privateGroupFactory; private final PrivateGroupFactory privateGroupFactory;
private final ContactManager contactManager; private final ContactManager contactManager;
private final IdentityManager identityManager;
private final MessageTracker messageTracker; private final MessageTracker messageTracker;
private final List<PrivateGroupHook> hooks; private final List<PrivateGroupHook> hooks;
@@ -91,12 +88,10 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
PrivateGroupManagerImpl(ClientHelper clientHelper, PrivateGroupManagerImpl(ClientHelper clientHelper,
MetadataParser metadataParser, DatabaseComponent db, MetadataParser metadataParser, DatabaseComponent db,
PrivateGroupFactory privateGroupFactory, PrivateGroupFactory privateGroupFactory,
ContactManager contactManager, IdentityManager identityManager, ContactManager contactManager, MessageTracker messageTracker) {
MessageTracker messageTracker) {
super(db, clientHelper, metadataParser); super(db, clientHelper, metadataParser);
this.privateGroupFactory = privateGroupFactory; this.privateGroupFactory = privateGroupFactory;
this.contactManager = contactManager; this.contactManager = contactManager;
this.identityManager = identityManager;
this.messageTracker = messageTracker; this.messageTracker = messageTracker;
hooks = new CopyOnWriteArrayList<>(); hooks = new CopyOnWriteArrayList<>();
} }
@@ -398,18 +393,17 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
try { try {
Collection<GroupMember> members = new ArrayList<>(); Collection<GroupMember> members = new ArrayList<>();
Map<Author, Visibility> authors = getMembers(txn, g); Map<Author, Visibility> authors = getMembers(txn, g);
LocalAuthor la = identityManager.getLocalAuthor(txn);
PrivateGroup privateGroup = getPrivateGroup(txn, g); PrivateGroup privateGroup = getPrivateGroup(txn, g);
for (Entry<Author, Visibility> m : authors.entrySet()) { for (Entry<Author, Visibility> m : authors.entrySet()) {
Author a = m.getKey(); Author a = m.getKey();
AuthorInfo authorInfo = contactManager.getAuthorInfo(txn, a.getId()); AuthorInfo authorInfo =
contactManager.getAuthorInfo(txn, a.getId());
Status status = authorInfo.getStatus(); Status status = authorInfo.getStatus();
Visibility v = m.getValue(); Visibility v = m.getValue();
ContactId c = null; ContactId c = null;
if (v != INVISIBLE && if (v != INVISIBLE &&
(status == VERIFIED || status == UNVERIFIED)) { (status == VERIFIED || status == UNVERIFIED)) {
c = contactManager.getContact(txn, a.getId(), la.getId()) c = contactManager.getContact(txn, a.getId()).getId();
.getId();
} }
boolean isCreator = privateGroup.getCreator().equals(a); boolean isCreator = privateGroup.getCreator().equals(a);
members.add(new GroupMember(a, authorInfo, isCreator, c, v)); members.add(new GroupMember(a, authorInfo, isCreator, c, v));
@@ -483,8 +477,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
if (!foundMember) throw new ProtocolStateException(); if (!foundMember) throw new ProtocolStateException();
if (changed) { if (changed) {
clientHelper.mergeGroupMetadata(txn, g, meta); clientHelper.mergeGroupMetadata(txn, g, meta);
LocalAuthor la = identityManager.getLocalAuthor(txn); ContactId c = contactManager.getContact(txn, a).getId();
ContactId c = contactManager.getContact(txn, a, la.getId()).getId();
Event e = new ContactRelationshipRevealedEvent(g, a, c, v); Event e = new ContactRelationshipRevealedEvent(g, a, c, v);
txn.attach(e); txn.attach(e);
} }

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.client.ContactGroupFactory;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.data.BdfList;
import org.briarproject.bramble.api.identity.AuthorId; 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.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
@@ -34,14 +35,15 @@ class GroupInvitationFactoryImpl implements GroupInvitationFactory {
} }
@Override @Override
public byte[] signInvitation(Contact c, GroupId privateGroupId, public byte[] signInvitation(LocalAuthor creator, Contact member,
long timestamp, byte[] privateKey) { GroupId privateGroupId, long timestamp) {
AuthorId creatorId = c.getLocalAuthorId(); AuthorId creatorId = creator.getId();
AuthorId memberId = c.getAuthor().getId(); AuthorId memberId = member.getAuthor().getId();
BdfList token = createInviteToken(creatorId, memberId, privateGroupId, BdfList token = createInviteToken(creatorId, memberId, privateGroupId,
timestamp); timestamp);
try { try {
return clientHelper.sign(SIGNING_LABEL_INVITE, token, privateKey); return clientHelper.sign(SIGNING_LABEL_INVITE, token,
creator.getPrivateKey());
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} catch (FormatException e) { } catch (FormatException e) {

View File

@@ -14,6 +14,8 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Client;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
@@ -81,13 +83,15 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
ClientHelper clientHelper, ClientHelper clientHelper,
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MessageTracker messageTracker, MetadataParser metadataParser, MessageTracker messageTracker,
IdentityManager identityManager,
ContactGroupFactory contactGroupFactory, ContactGroupFactory contactGroupFactory,
PrivateGroupFactory privateGroupFactory, PrivateGroupFactory privateGroupFactory,
PrivateGroupManager privateGroupManager, PrivateGroupManager privateGroupManager,
MessageParser messageParser, SessionParser sessionParser, MessageParser messageParser, SessionParser sessionParser,
SessionEncoder sessionEncoder, SessionEncoder sessionEncoder,
ProtocolEngineFactory engineFactory) { ProtocolEngineFactory engineFactory) {
super(db, clientHelper, metadataParser, messageTracker); super(db, clientHelper, metadataParser, messageTracker,
identityManager);
this.clientVersioningManager = clientVersioningManager; this.clientVersioningManager = clientVersioningManager;
this.contactGroupFactory = contactGroupFactory; this.contactGroupFactory = contactGroupFactory;
this.privateGroupFactory = privateGroupFactory; this.privateGroupFactory = privateGroupFactory;
@@ -114,7 +118,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Override @Override
public void addingContact(Transaction txn, Contact c) throws DbException { public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group to share with the contact // Create a group to share with the contact
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.addGroup(txn, g); db.addGroup(txn, g);
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
c.getId(), CLIENT_ID, MAJOR_VERSION); c.getId(), CLIENT_ID, MAJOR_VERSION);
@@ -138,13 +142,13 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Override @Override
public void removingContact(Transaction txn, Contact c) throws DbException { public void removingContact(Transaction txn, Contact c) throws DbException {
// Remove the contact group (all messages will be removed with it) // Remove the contact group (all messages will be removed with it)
db.removeGroup(txn, getContactGroup(c)); db.removeGroup(txn, getContactGroup(c, getLocalAuthorId(txn)));
} }
@Override @Override
public Group getContactGroup(Contact c) { public Group getContactGroup(Contact c, AuthorId local) {
return contactGroupFactory.createContactGroup(CLIENT_ID, return contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, c); MAJOR_VERSION, c, local);
} }
@Override @Override
@@ -267,7 +271,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
try { try {
// Look up the session, if there is one // Look up the session, if there is one
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
// Create or parse the session // Create or parse the session
CreatorSession session; CreatorSession session;
@@ -308,7 +313,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
try { try {
// Look up the session // Look up the session
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
if (ss == null) throw new IllegalArgumentException(); if (ss == null) throw new IllegalArgumentException();
// Parse the session // Parse the session
@@ -333,7 +339,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
try { try {
// Look up the session // Look up the session
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
StoredSession ss = getSession(txn, contactGroupId, getSessionId(g)); StoredSession ss = getSession(txn, contactGroupId, getSessionId(g));
if (ss == null) throw new IllegalArgumentException(); if (ss == null) throw new IllegalArgumentException();
// Parse the session // Parse the session
@@ -368,11 +375,12 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
} }
@Override @Override
public Collection<ConversationMessageHeader> getMessageHeaders(Transaction txn, public Collection<ConversationMessageHeader> getMessageHeaders(
ContactId c) throws DbException { Transaction txn, ContactId c) throws DbException {
try { try {
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
Map<MessageId, BdfDictionary> results = clientHelper Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, contactGroupId, query); .getMessageMetadataAsDictionary(txn, contactGroupId, query);
@@ -436,8 +444,9 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
Transaction txn = db.startTransaction(true); Transaction txn = db.startTransaction(true);
try { try {
// Look up the available invite messages for each contact // Look up the available invite messages for each contact
AuthorId local = getLocalAuthorId(txn);
for (Contact c : db.getContacts(txn)) { for (Contact c : db.getContacts(txn)) {
GroupId contactGroupId = getContactGroup(c).getId(); GroupId contactGroupId = getContactGroup(c, local).getId();
Map<MessageId, BdfDictionary> results = Map<MessageId, BdfDictionary> results =
clientHelper.getMessageMetadataAsDictionary(txn, clientHelper.getMessageMetadataAsDictionary(txn,
contactGroupId, query); contactGroupId, query);
@@ -456,10 +465,11 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
@Override @Override
public boolean isInvitationAllowed(Contact c, GroupId privateGroupId) public boolean isInvitationAllowed(Contact c, GroupId privateGroupId)
throws DbException { throws DbException {
GroupId contactGroupId = getContactGroup(c).getId();
SessionId sessionId = getSessionId(privateGroupId); SessionId sessionId = getSessionId(privateGroupId);
Transaction txn = db.startTransaction(true); Transaction txn = db.startTransaction(true);
try { try {
AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(c, local).getId();
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
c.getId(), PrivateGroupManager.CLIENT_ID, c.getId(), PrivateGroupManager.CLIENT_ID,
PrivateGroupManager.MAJOR_VERSION); PrivateGroupManager.MAJOR_VERSION);
@@ -492,15 +502,17 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
public void addingMember(Transaction txn, GroupId privateGroupId, Author a) public void addingMember(Transaction txn, GroupId privateGroupId, Author a)
throws DbException { throws DbException {
// If the member is a contact, handle the add member action // If the member is a contact, handle the add member action
for (Contact c : db.getContactsByAuthorId(txn, a.getId())) if (db.containsContact(txn, a.getId())) {
addingMember(txn, privateGroupId, c); addingMember(txn, privateGroupId, db.getContact(txn, a.getId()));
}
} }
private void addingMember(Transaction txn, GroupId privateGroupId, private void addingMember(Transaction txn, GroupId privateGroupId,
Contact c) throws DbException { Contact c) throws DbException {
try { try {
// Look up the session for the contact, if there is one // Look up the session for the contact, if there is one
GroupId contactGroupId = getContactGroup(c).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(c, local).getId();
SessionId sessionId = getSessionId(privateGroupId); SessionId sessionId = getSessionId(privateGroupId);
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
// Create or parse the session // Create or parse the session
@@ -533,9 +545,10 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
SessionId sessionId = getSessionId(privateGroupId); SessionId sessionId = getSessionId(privateGroupId);
// If we have any sessions in progress, tell the contacts we're leaving // If we have any sessions in progress, tell the contacts we're leaving
try { try {
AuthorId local = getLocalAuthorId(txn);
for (Contact c : db.getContacts(txn)) { for (Contact c : db.getContacts(txn)) {
// Look up the session for the contact, if there is one // Look up the session for the contact, if there is one
GroupId contactGroupId = getContactGroup(c).getId(); GroupId contactGroupId = getContactGroup(c, local).getId();
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
if (ss == null) continue; // No session for this contact if (ss == null) continue; // No session for this contact
// Handle the action // Handle the action
@@ -574,7 +587,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
public void onClientVisibilityChanging(Transaction txn, Contact c, public void onClientVisibilityChanging(Transaction txn, Contact c,
Visibility v) throws DbException { Visibility v) throws DbException {
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.setGroupVisibility(txn, c.getId(), g.getId(), v); db.setGroupVisibility(txn, c.getId(), g.getId(), v);
} }
@@ -603,7 +616,8 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
private Map<GroupId, Visibility> getPreferredVisibilities(Transaction txn, private Map<GroupId, Visibility> getPreferredVisibilities(Transaction txn,
Contact c) throws DbException, FormatException { Contact c) throws DbException, FormatException {
GroupId contactGroupId = getContactGroup(c).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(c, local).getId();
BdfDictionary query = sessionParser.getAllSessionsQuery(); BdfDictionary query = sessionParser.getAllSessionsQuery();
Map<MessageId, BdfDictionary> results = clientHelper Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, contactGroupId, query); .getMessageMetadataAsDictionary(txn, contactGroupId, query);

View File

@@ -28,7 +28,6 @@ import javax.inject.Inject;
class BlogSharingManagerImpl extends SharingManagerImpl<Blog> class BlogSharingManagerImpl extends SharingManagerImpl<Blog>
implements BlogSharingManager, RemoveBlogHook { implements BlogSharingManager, RemoveBlogHook {
private final IdentityManager identityManager;
private final BlogManager blogManager; private final BlogManager blogManager;
@Inject @Inject
@@ -43,8 +42,8 @@ class BlogSharingManagerImpl extends SharingManagerImpl<Blog>
IdentityManager identityManager, BlogManager blogManager) { IdentityManager identityManager, BlogManager blogManager) {
super(db, clientHelper, clientVersioningManager, metadataParser, super(db, clientHelper, clientVersioningManager, metadataParser,
messageParser, sessionEncoder, sessionParser, messageTracker, messageParser, sessionEncoder, sessionParser, messageTracker,
contactGroupFactory, engine, invitationFactory); identityManager, contactGroupFactory, engine,
this.identityManager = identityManager; invitationFactory);
this.blogManager = blogManager; this.blogManager = blogManager;
} }
@@ -80,8 +79,8 @@ class BlogSharingManagerImpl extends SharingManagerImpl<Blog>
// Pre-share both blogs, if they have not been shared already // Pre-share both blogs, if they have not been shared already
try { try {
preShareGroup(txn, c, ourBlog.getGroup()); preShareGroup(txn, c, ourBlog.getGroup(), localAuthor.getId());
preShareGroup(txn, c, theirBlog.getGroup()); preShareGroup(txn, c, theirBlog.getGroup(), localAuthor.getId());
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} }

View File

@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.data.MetadataParser;
import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.ClientId;
import org.briarproject.bramble.api.versioning.ClientVersioningManager; import org.briarproject.bramble.api.versioning.ClientVersioningManager;
@@ -27,13 +28,14 @@ class ForumSharingManagerImpl extends SharingManagerImpl<Forum>
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MessageParser<Forum> messageParser, MetadataParser metadataParser, MessageParser<Forum> messageParser,
SessionEncoder sessionEncoder, SessionParser sessionParser, SessionEncoder sessionEncoder, SessionParser sessionParser,
MessageTracker messageTracker, MessageTracker messageTracker, IdentityManager identityManager,
ContactGroupFactory contactGroupFactory, ContactGroupFactory contactGroupFactory,
ProtocolEngine<Forum> engine, ProtocolEngine<Forum> engine,
InvitationFactory<Forum, ForumInvitationResponse> invitationFactory) { InvitationFactory<Forum, ForumInvitationResponse> invitationFactory) {
super(db, clientHelper, clientVersioningManager, metadataParser, super(db, clientHelper, clientVersioningManager, metadataParser,
messageParser, sessionEncoder, sessionParser, messageTracker, messageParser, sessionEncoder, sessionParser, messageTracker,
contactGroupFactory, engine, invitationFactory); identityManager, contactGroupFactory, engine,
invitationFactory);
} }
@Override @Override

View File

@@ -13,6 +13,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Client; import org.briarproject.bramble.api.sync.Client;
import org.briarproject.bramble.api.sync.ClientId; import org.briarproject.bramble.api.sync.ClientId;
@@ -70,10 +72,11 @@ abstract class SharingManagerImpl<S extends Shareable>
ClientVersioningManager clientVersioningManager, ClientVersioningManager clientVersioningManager,
MetadataParser metadataParser, MessageParser<S> messageParser, MetadataParser metadataParser, MessageParser<S> messageParser,
SessionEncoder sessionEncoder, SessionParser sessionParser, SessionEncoder sessionEncoder, SessionParser sessionParser,
MessageTracker messageTracker, MessageTracker messageTracker, IdentityManager identityManager,
ContactGroupFactory contactGroupFactory, ProtocolEngine<S> engine, ContactGroupFactory contactGroupFactory, ProtocolEngine<S> engine,
InvitationFactory<S, ?> invitationFactory) { InvitationFactory<S, ?> invitationFactory) {
super(db, clientHelper, metadataParser, messageTracker); super(db, clientHelper, metadataParser, messageTracker,
identityManager);
this.clientVersioningManager = clientVersioningManager; this.clientVersioningManager = clientVersioningManager;
this.messageParser = messageParser; this.messageParser = messageParser;
this.sessionEncoder = sessionEncoder; this.sessionEncoder = sessionEncoder;
@@ -105,7 +108,7 @@ abstract class SharingManagerImpl<S extends Shareable>
@Override @Override
public void addingContact(Transaction txn, Contact c) throws DbException { public void addingContact(Transaction txn, Contact c) throws DbException {
// Create a group to share with the contact // Create a group to share with the contact
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.addGroup(txn, g); db.addGroup(txn, g);
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
c.getId(), getClientId(), getMajorVersion()); c.getId(), getClientId(), getMajorVersion());
@@ -123,13 +126,13 @@ abstract class SharingManagerImpl<S extends Shareable>
@Override @Override
public void removingContact(Transaction txn, Contact c) throws DbException { public void removingContact(Transaction txn, Contact c) throws DbException {
// Remove the contact group (all messages will be removed with it) // Remove the contact group (all messages will be removed with it)
db.removeGroup(txn, getContactGroup(c)); db.removeGroup(txn, getContactGroup(c, getLocalAuthorId(txn)));
} }
@Override @Override
public Group getContactGroup(Contact c) { public Group getContactGroup(Contact c, AuthorId local) {
return contactGroupFactory.createContactGroup(getClientId(), return contactGroupFactory.createContactGroup(getClientId(),
getMajorVersion(), c); getMajorVersion(), c, local);
} }
@Override @Override
@@ -160,10 +163,10 @@ abstract class SharingManagerImpl<S extends Shareable>
* and the Contact c in state SHARING. * and the Contact c in state SHARING.
* If a session already exists, this does nothing. * If a session already exists, this does nothing.
*/ */
void preShareGroup(Transaction txn, Contact c, Group g) void preShareGroup(Transaction txn, Contact c, Group g, AuthorId local)
throws DbException, FormatException { throws DbException, FormatException {
// Return if a session already exists with the contact // Return if a session already exists with the contact
GroupId contactGroupId = getContactGroup(c).getId(); GroupId contactGroupId = getContactGroup(c, local).getId();
StoredSession existingSession = getSession(txn, contactGroupId, StoredSession existingSession = getSession(txn, contactGroupId,
getSessionId(g.getId())); getSessionId(g.getId()));
if (existingSession != null) return; if (existingSession != null) return;
@@ -257,11 +260,13 @@ abstract class SharingManagerImpl<S extends Shareable>
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
Contact contact = db.getContact(txn, contactId); Contact contact = db.getContact(txn, contactId);
if (!canBeShared(txn, shareableId, contact)) if (!canBeShared(txn, shareableId, contact)) {
// we might have received an invitation in the meantime // we might have received an invitation in the meantime
return; return;
}
// Look up the session, if there is one // Look up the session, if there is one
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
// Create or parse the session // Create or parse the session
Session session; Session session;
@@ -301,7 +306,8 @@ abstract class SharingManagerImpl<S extends Shareable>
try { try {
// Look up the session // Look up the session
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
StoredSession ss = getSession(txn, contactGroupId, id); StoredSession ss = getSession(txn, contactGroupId, id);
if (ss == null) throw new IllegalArgumentException(); if (ss == null) throw new IllegalArgumentException();
// Parse the session // Parse the session
@@ -325,7 +331,8 @@ abstract class SharingManagerImpl<S extends Shareable>
Transaction txn, ContactId c) throws DbException { Transaction txn, ContactId c) throws DbException {
try { try {
Contact contact = db.getContact(txn, c); Contact contact = db.getContact(txn, c);
GroupId contactGroupId = getContactGroup(contact).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(contact, local).getId();
BdfDictionary query = messageParser.getMessagesVisibleInUiQuery(); BdfDictionary query = messageParser.getMessagesVisibleInUiQuery();
Map<MessageId, BdfDictionary> results = clientHelper Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, contactGroupId, query); .getMessageMetadataAsDictionary(txn, contactGroupId, query);
@@ -385,8 +392,9 @@ abstract class SharingManagerImpl<S extends Shareable>
Transaction txn = db.startTransaction(true); Transaction txn = db.startTransaction(true);
try { try {
// get invitations from each contact // get invitations from each contact
AuthorId local = getLocalAuthorId(txn);
for (Contact c : db.getContacts(txn)) { for (Contact c : db.getContacts(txn)) {
GroupId contactGroupId = getContactGroup(c).getId(); GroupId contactGroupId = getContactGroup(c, local).getId();
Map<MessageId, BdfDictionary> results = Map<MessageId, BdfDictionary> results =
clientHelper.getMessageMetadataAsDictionary(txn, clientHelper.getMessageMetadataAsDictionary(txn,
contactGroupId, query); contactGroupId, query);
@@ -456,7 +464,8 @@ abstract class SharingManagerImpl<S extends Shareable>
Visibility client = clientVersioningManager.getClientVisibility(txn, Visibility client = clientVersioningManager.getClientVisibility(txn,
c.getId(), getShareableClientId(), getShareableMajorVersion()); c.getId(), getShareableClientId(), getShareableMajorVersion());
if (client != SHARED) return false; if (client != SHARED) return false;
GroupId contactGroupId = getContactGroup(c).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(c, local).getId();
SessionId sessionId = getSessionId(g); SessionId sessionId = getSessionId(g);
try { try {
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
@@ -475,9 +484,10 @@ abstract class SharingManagerImpl<S extends Shareable>
SessionId sessionId = getSessionId(shareable.getId()); SessionId sessionId = getSessionId(shareable.getId());
// If we have any sessions in progress, tell the contacts we're leaving // If we have any sessions in progress, tell the contacts we're leaving
try { try {
AuthorId local = getLocalAuthorId(txn);
for (Contact c : db.getContacts(txn)) { for (Contact c : db.getContacts(txn)) {
// Look up the session for the contact, if there is one // Look up the session for the contact, if there is one
GroupId contactGroupId = getContactGroup(c).getId(); GroupId contactGroupId = getContactGroup(c, local).getId();
StoredSession ss = getSession(txn, contactGroupId, sessionId); StoredSession ss = getSession(txn, contactGroupId, sessionId);
if (ss == null) continue; // No session for this contact if (ss == null) continue; // No session for this contact
// Let the engine perform a LEAVE action // Let the engine perform a LEAVE action
@@ -496,7 +506,7 @@ abstract class SharingManagerImpl<S extends Shareable>
public void onClientVisibilityChanging(Transaction txn, Contact c, public void onClientVisibilityChanging(Transaction txn, Contact c,
Visibility v) throws DbException { Visibility v) throws DbException {
// Apply the client's visibility to the contact group // Apply the client's visibility to the contact group
Group g = getContactGroup(c); Group g = getContactGroup(c, getLocalAuthorId(txn));
db.setGroupVisibility(txn, c.getId(), g.getId(), v); db.setGroupVisibility(txn, c.getId(), g.getId(), v);
} }
@@ -525,7 +535,8 @@ abstract class SharingManagerImpl<S extends Shareable>
private Map<GroupId, Visibility> getPreferredVisibilities(Transaction txn, private Map<GroupId, Visibility> getPreferredVisibilities(Transaction txn,
Contact c) throws DbException, FormatException { Contact c) throws DbException, FormatException {
GroupId contactGroupId = getContactGroup(c).getId(); AuthorId local = getLocalAuthorId(txn);
GroupId contactGroupId = getContactGroup(c, local).getId();
BdfDictionary query = sessionParser.getAllSessionsQuery(); BdfDictionary query = sessionParser.getAllSessionsQuery();
Map<MessageId, BdfDictionary> results = clientHelper Map<MessageId, BdfDictionary> results = clientHelper
.getMessageMetadataAsDictionary(txn, contactGroupId, query); .getMessageMetadataAsDictionary(txn, contactGroupId, query);

View File

@@ -13,7 +13,6 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.AuthorFactory; import org.briarproject.bramble.api.identity.AuthorFactory;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.identity.IdentityManager; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor; import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.lifecycle.IoExecutor;
@@ -148,17 +147,15 @@ public class TestDataCreatorImpl implements TestDataCreator {
private List<Contact> createContacts(int numContacts) throws DbException { private List<Contact> createContacts(int numContacts) throws DbException {
List<Contact> contacts = new ArrayList<>(numContacts); List<Contact> contacts = new ArrayList<>(numContacts);
LocalAuthor localAuthor = identityManager.getLocalAuthor();
for (int i = 0; i < numContacts; i++) { for (int i = 0; i < numContacts; i++) {
LocalAuthor author = getRandomAuthor(); LocalAuthor author = getRandomAuthor();
Contact contact = addContact(localAuthor.getId(), author); Contact contact = addContact(author);
contacts.add(contact); contacts.add(contact);
} }
return contacts; return contacts;
} }
private Contact addContact(AuthorId localAuthorId, LocalAuthor author) private Contact addContact(LocalAuthor author) throws DbException {
throws DbException {
// prepare to add contact // prepare to add contact
SecretKey secretKey = getSecretKey(); SecretKey secretKey = getSecretKey();
@@ -172,9 +169,8 @@ public class TestDataCreatorImpl implements TestDataCreator {
Contact contact; Contact contact;
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
ContactId contactId = contactManager ContactId contactId = contactManager.addContact(txn, author,
.addContact(txn, author, localAuthorId, secretKey, secretKey, timestamp, true, verified, true);
timestamp, true, verified, true);
if (random.nextBoolean()) { if (random.nextBoolean()) {
contactManager contactManager
.setContactAlias(txn, contactId, getRandomAuthorName()); .setContactAlias(txn, contactId, getRandomAuthorName());
@@ -196,8 +192,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
@Override @Override
public Contact addContact(String name) throws DbException { public Contact addContact(String name) throws DbException {
LocalAuthor localAuthor = identityManager.getLocalAuthor(); return addContact(getAuthor(name));
return addContact(localAuthor.getId(), getAuthor(name));
} }
private LocalAuthor getAuthor(String name) { private LocalAuthor getAuthor(String name) {
@@ -301,8 +296,10 @@ public class TestDataCreatorImpl implements TestDataCreator {
private void createPrivateMessages(List<Contact> contacts, private void createPrivateMessages(List<Contact> contacts,
int numPrivateMsgs) throws DbException { int numPrivateMsgs) throws DbException {
LocalAuthor localAuthor = identityManager.getLocalAuthor();
for (Contact contact : contacts) { for (Contact contact : contacts) {
Group group = messagingManager.getContactGroup(contact); Group group = messagingManager.getContactGroup(contact,
localAuthor.getId());
for (int i = 0; i < numPrivateMsgs; i++) { for (int i = 0; i < numPrivateMsgs; i++) {
try { try {
createRandomPrivateMessage(group.getId(), i); createRandomPrivateMessage(group.getId(), i);
@@ -345,13 +342,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
} }
} }
@Override
public void addPrivateMessage(Contact contact, String text, long time,
boolean local) throws DbException, FormatException {
Group group = messagingManager.getContactGroup(contact);
createPrivateMessage(group.getId(), text, time, local);
}
private void createBlogPosts(List<Contact> contacts, int numBlogPosts) private void createBlogPosts(List<Contact> contacts, int numBlogPosts)
throws DbException { throws DbException {
for (int i = 0; i < numBlogPosts; i++) { for (int i = 0; i < numBlogPosts; i++) {

View File

@@ -130,8 +130,7 @@ public class BlogManagerImplTest extends BriarTestCase {
@Test @Test
public void testRemovingContact() throws DbException { public void testRemovingContact() throws DbException {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
Contact contact = getContact(blog2.getAuthor(), Contact contact = getContact(blog2.getAuthor(), true);
blog1.getAuthor().getId(), true);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(blogFactory).createBlog(blog2.getAuthor()); oneOf(blogFactory).createBlog(blog2.getAuthor());
@@ -150,8 +149,7 @@ public class BlogManagerImplTest extends BriarTestCase {
@Test @Test
public void testRemovingContactAfterRemovingBlog() throws DbException { public void testRemovingContactAfterRemovingBlog() throws DbException {
Transaction txn = new Transaction(null, false); Transaction txn = new Transaction(null, false);
Contact contact = getContact(blog2.getAuthor(), Contact contact = getContact(blog2.getAuthor(), true);
blog1.getAuthor().getId(), true);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(blogFactory).createBlog(blog2.getAuthor()); oneOf(blogFactory).createBlog(blog2.getAuthor());

View File

@@ -14,6 +14,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
@@ -134,8 +135,10 @@ public class IntroductionIntegrationTest
.makeIntroduction(introducee1, introducee2, "Hi!", time); .makeIntroduction(introducee1, introducee2, "Hi!", time);
// check that messages are tracked properly // check that messages are tracked properly
Group g1 = introductionManager0.getContactGroup(introducee1); Group g1 = introductionManager0.getContactGroup(introducee1,
Group g2 = introductionManager0.getContactGroup(introducee2); author0.getId());
Group g2 = introductionManager0.getContactGroup(introducee2,
author0.getId());
assertGroupCount(messageTracker0, g1.getId(), 1, 0); assertGroupCount(messageTracker0, g1.getId(), 1, 0);
assertGroupCount(messageTracker0, g2.getId(), 1, 0); assertGroupCount(messageTracker0, g2.getId(), 1, 0);
@@ -228,10 +231,8 @@ public class IntroductionIntegrationTest
assertTrue(listener1.succeeded); assertTrue(listener1.succeeded);
assertTrue(listener2.succeeded); assertTrue(listener2.succeeded);
assertTrue(contactManager1 assertTrue(contactManager1.contactExists(author2.getId()));
.contactExists(author2.getId(), author1.getId())); assertTrue(contactManager2.contactExists(author1.getId()));
assertTrue(contactManager2
.contactExists(author1.getId(), author2.getId()));
// make sure that introduced contacts are not verified // make sure that introduced contacts are not verified
for (Contact c : contactManager1.getContacts()) { for (Contact c : contactManager1.getContacts()) {
@@ -318,13 +319,13 @@ public class IntroductionIntegrationTest
assertFalse(listener1.succeeded); assertFalse(listener1.succeeded);
assertFalse(listener2.succeeded); assertFalse(listener2.succeeded);
assertFalse(contactManager1 assertFalse(contactManager1.contactExists(author2.getId()));
.contactExists(author2.getId(), author1.getId())); assertFalse(contactManager2.contactExists(author1.getId()));
assertFalse(contactManager2
.contactExists(author1.getId(), author2.getId()));
Group g1 = introductionManager0.getContactGroup(introducee1); Group g1 = introductionManager0.getContactGroup(introducee1,
Group g2 = introductionManager0.getContactGroup(introducee2); author0.getId());
Group g2 = introductionManager0.getContactGroup(introducee2,
author0.getId());
Collection<ConversationMessageHeader> messages = Collection<ConversationMessageHeader> messages =
db0.transactionWithResult(true, txn -> introductionManager0 db0.transactionWithResult(true, txn -> introductionManager0
.getMessageHeaders(txn, contactId1From0)); .getMessageHeaders(txn, contactId1From0));
@@ -387,10 +388,8 @@ public class IntroductionIntegrationTest
listener1.getResponse().getIntroducedAuthor().getName()); listener1.getResponse().getIntroducedAuthor().getName());
assertFalse(listener1.getResponse().canSucceed()); assertFalse(listener1.getResponse().canSucceed());
assertFalse(contactManager1 assertFalse(contactManager1.contactExists(author2.getId()));
.contactExists(author2.getId(), author1.getId())); assertFalse(contactManager2.contactExists(author1.getId()));
assertFalse(contactManager2
.contactExists(author1.getId(), author2.getId()));
Collection<ConversationMessageHeader> messages = Collection<ConversationMessageHeader> messages =
db0.transactionWithResult(true, txn -> introductionManager0 db0.transactionWithResult(true, txn -> introductionManager0
@@ -499,10 +498,8 @@ public class IntroductionIntegrationTest
sync1To0(2, true); sync1To0(2, true);
sync0To2(2, true); sync0To2(2, true);
assertTrue(contactManager1 assertTrue(contactManager1.contactExists(author2.getId()));
.contactExists(author2.getId(), author1.getId())); assertTrue(contactManager2.contactExists(author1.getId()));
assertTrue(contactManager2
.contactExists(author1.getId(), author2.getId()));
assertDefaultUiMessages(); assertDefaultUiMessages();
assertFalse(listener0.aborted); assertFalse(listener0.aborted);
@@ -593,8 +590,10 @@ public class IntroductionIntegrationTest
introduceeSession = getIntroduceeSession(c1); introduceeSession = getIntroduceeSession(c1);
assertEquals(IntroduceeState.START, introduceeSession.getState()); assertEquals(IntroduceeState.START, introduceeSession.getState());
Group g1 = introductionManager0.getContactGroup(introducee1); Group g1 = introductionManager0.getContactGroup(introducee1,
Group g2 = introductionManager0.getContactGroup(introducee2); author0.getId());
Group g2 = introductionManager0.getContactGroup(introducee2,
author0.getId());
assertEquals(2, db0.transactionWithResult(true, txn -> assertEquals(2, db0.transactionWithResult(true, txn ->
introductionManager0.getMessageHeaders(txn, contactId1From0)) introductionManager0.getMessageHeaders(txn, contactId1From0))
.size()); .size());
@@ -787,8 +786,8 @@ public class IntroductionIntegrationTest
sync0To1(1, true); sync0To1(1, true);
// save ACCEPT from introducee1 // save ACCEPT from introducee1
AcceptMessage m = (AcceptMessage) getMessageFor(c1.getClientHelper(), AcceptMessage m = (AcceptMessage) getMessageFor(introductionManager1,
contact0From1, ACCEPT); c1.getClientHelper(), contact0From1, author1.getId(), ACCEPT);
// sync ACCEPT back to introducer // sync ACCEPT back to introducer
sync1To0(1, true); sync1To0(1, true);
@@ -824,8 +823,8 @@ public class IntroductionIntegrationTest
sync0To1(1, true); sync0To1(1, true);
// save ACCEPT from introducee1 // save ACCEPT from introducee1
AcceptMessage m = (AcceptMessage) getMessageFor(c1.getClientHelper(), AcceptMessage m = (AcceptMessage) getMessageFor(introductionManager1,
contact0From1, ACCEPT); c1.getClientHelper(), contact0From1, author1.getId(), ACCEPT);
// sync ACCEPT back to introducer // sync ACCEPT back to introducer
sync1To0(1, true); sync1To0(1, true);
@@ -859,8 +858,8 @@ public class IntroductionIntegrationTest
sync0To1(1, true); sync0To1(1, true);
// save DECLINE from introducee1 // save DECLINE from introducee1
DeclineMessage m = (DeclineMessage) getMessageFor(c1.getClientHelper(), DeclineMessage m = (DeclineMessage) getMessageFor(introductionManager1,
contact0From1, DECLINE); c1.getClientHelper(), contact0From1, author1.getId(), DECLINE);
// sync DECLINE back to introducer // sync DECLINE back to introducer
sync1To0(1, true); sync1To0(1, true);
@@ -903,8 +902,8 @@ public class IntroductionIntegrationTest
sync0To2(1, true); sync0To2(1, true);
// save AUTH from introducee1 // save AUTH from introducee1
AuthMessage m = (AuthMessage) getMessageFor(c1.getClientHelper(), AuthMessage m = (AuthMessage) getMessageFor(introductionManager1,
contact0From1, AUTH); c1.getClientHelper(), contact0From1, author1.getId(), AUTH);
// sync first AUTH message // sync first AUTH message
sync1To0(1, true); sync1To0(1, true);
@@ -1006,12 +1005,10 @@ public class IntroductionIntegrationTest
// 0 and 1 remove and re-add each other // 0 and 1 remove and re-add each other
contactManager0.removeContact(contactId1From0); contactManager0.removeContact(contactId1From0);
contactManager1.removeContact(contactId0From1); contactManager1.removeContact(contactId0From1);
contactId1From0 = contactManager0 contactId1From0 = contactManager0.addContact(author1, getSecretKey(),
.addContact(author1, author0.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contact1From0 = contactManager0.getContact(contactId1From0); contact1From0 = contactManager0.getContact(contactId1From0);
contactId0From1 = contactManager1 contactId0From1 = contactManager1.addContact(author0, getSecretKey(),
.addContact(author0, author1.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contact0From1 = contactManager1.getContact(contactId0From1); contact0From1 = contactManager1.getContact(contactId0From1);
@@ -1060,9 +1057,9 @@ public class IntroductionIntegrationTest
eventWaiter.await(TIMEOUT, 1); eventWaiter.await(TIMEOUT, 1);
// get response to be forwarded // get response to be forwarded
AcceptMessage message = AcceptMessage message = (AcceptMessage) getMessageFor(
(AcceptMessage) getMessageFor(c0.getClientHelper(), introductionManager0, c0.getClientHelper(), contact2From0,
contact2From0, ACCEPT); author0.getId(), ACCEPT);
// allow visitor to modify response // allow visitor to modify response
AcceptMessage m = visitor.visit(message); AcceptMessage m = visitor.visit(message);
@@ -1345,10 +1342,10 @@ public class IntroductionIntegrationTest
} }
} }
private AbstractIntroductionMessage getMessageFor(ClientHelper ch, private AbstractIntroductionMessage getMessageFor(IntroductionManager im,
Contact contact, MessageType type) ClientHelper ch, Contact contact, AuthorId local, MessageType type)
throws FormatException, DbException { throws FormatException, DbException {
Group g = introductionManager0.getContactGroup(contact); Group g = im.getContactGroup(contact, local);
BdfDictionary query = BdfDictionary.of( BdfDictionary query = BdfDictionary.of(
new BdfEntry(MSG_KEY_MESSAGE_TYPE, type.getValue()) new BdfEntry(MSG_KEY_MESSAGE_TYPE, type.getValue())
); );
@@ -1400,8 +1397,8 @@ public class IntroductionIntegrationTest
.getMessageMetadataAsDictionary(getLocalGroup().getId()); .getMessageMetadataAsDictionary(getLocalGroup().getId());
assertEquals(1, dicts.size()); assertEquals(1, dicts.size());
BdfDictionary d = dicts.values().iterator().next(); BdfDictionary d = dicts.values().iterator().next();
Group introducerGroup = Group introducerGroup = introductionManager2
introductionManager2.getContactGroup(contact0From2); .getContactGroup(contact0From2, author2.getId());
return c.getSessionParser() return c.getSessionParser()
.parseIntroduceeSession(introducerGroup.getId(), d); .parseIntroduceeSession(introducerGroup.getId(), d);
} }

View File

@@ -110,8 +110,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
lifecycleManager.waitForStartup(); lifecycleManager.waitForStartup();
// Add the other user as a contact // Add the other user as a contact
ContactManager contactManager = device.getContactManager(); ContactManager contactManager = device.getContactManager();
return contactManager.addContact(remote, local.getId(), rootKey, return contactManager.addContact(remote, rootKey, timestamp, alice,
timestamp, alice, true, true); true, true);
} }
private void sendMessage(SimplexMessagingIntegrationTestComponent device, private void sendMessage(SimplexMessagingIntegrationTestComponent device,

View File

@@ -29,6 +29,7 @@ import static org.briarproject.briar.api.privategroup.Visibility.INVISIBLE;
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT; import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_CONTACT;
import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US; import static org.briarproject.briar.api.privategroup.Visibility.REVEALED_BY_US;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/** /**
@@ -164,7 +165,7 @@ public class PrivateGroupIntegrationTest
getGroupMember(groupManager2, author1.getId()).getVisibility()); getGroupMember(groupManager2, author1.getId()).getVisibility());
// 1 reveals the contact relationship to 2 // 1 reveals the contact relationship to 2
assertTrue(contactId2From1 != null); assertNotNull(contactId2From1);
groupInvitationManager1.revealRelationship(contactId2From1, groupId0); groupInvitationManager1.revealRelationship(contactId2From1, groupId0);
sync1To2(1, true); sync1To2(1, true);
sync2To1(1, true); sync2To1(1, true);
@@ -213,8 +214,7 @@ public class PrivateGroupIntegrationTest
@Nullable String text) throws DbException { @Nullable String text) throws DbException {
Contact contact = contactManager0.getContact(c); Contact contact = contactManager0.getContact(c);
byte[] signature = groupInvitationFactory byte[] signature = groupInvitationFactory
.signInvitation(contact, groupId0, timestamp, .signInvitation(author0, contact, groupId0, timestamp);
author0.getPrivateKey());
groupInvitationManager0 groupInvitationManager0
.sendInvitation(groupId0, c, text, timestamp, signature); .sendInvitation(groupId0, c, text, timestamp, signature);
} }

View File

@@ -253,8 +253,7 @@ public class PrivateGroupManagerIntegrationTest
long inviteTime = joinTime; long inviteTime = joinTime;
Contact c1 = contactManager0.getContact(contactId1From0); Contact c1 = contactManager0.getContact(contactId1From0);
byte[] creatorSignature = groupInvitationFactory byte[] creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime, .signInvitation(author0, c1, privateGroup0.getId(), inviteTime);
author0.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1, .createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature); inviteTime, creatorSignature);
@@ -306,8 +305,7 @@ public class PrivateGroupManagerIntegrationTest
// signature uses joiner's key, not creator's key // signature uses joiner's key, not creator's key
Contact c1 = contactManager0.getContact(contactId1From0); Contact c1 = contactManager0.getContact(contactId1From0);
creatorSignature = groupInvitationFactory creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime, .signInvitation(author1, c1, privateGroup0.getId(), inviteTime);
author1.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1, .createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature); inviteTime, creatorSignature);
@@ -400,8 +398,7 @@ public class PrivateGroupManagerIntegrationTest
long inviteTime = joinTime - 1; long inviteTime = joinTime - 1;
Contact c2 = contactManager0.getContact(contactId2From0); Contact c2 = contactManager0.getContact(contactId2From0);
byte[] creatorSignature = groupInvitationFactory byte[] creatorSignature = groupInvitationFactory
.signInvitation(c2, privateGroup0.getId(), inviteTime, .signInvitation(author0, c2, privateGroup0.getId(), inviteTime);
author0.getPrivateKey());
GroupMessage joinMsg2 = groupMessageFactory GroupMessage joinMsg2 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author2, .createJoinMessage(privateGroup0.getId(), joinTime, author2,
inviteTime, creatorSignature); inviteTime, creatorSignature);
@@ -522,8 +519,7 @@ public class PrivateGroupManagerIntegrationTest
long inviteTime = joinTime - 1; long inviteTime = joinTime - 1;
Contact c1 = contactManager0.getContact(contactId1From0); Contact c1 = contactManager0.getContact(contactId1From0);
byte[] creatorSignature = groupInvitationFactory byte[] creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime, .signInvitation(author0, c1, privateGroup0.getId(), inviteTime);
author0.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1, .createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature); inviteTime, creatorSignature);

View File

@@ -176,9 +176,9 @@ public class GroupInvitationIntegrationTest
groupInvitationManager1 groupInvitationManager1
.respondToInvitation(contactId0From1, privateGroup0, true); .respondToInvitation(contactId0From1, privateGroup0, true);
messages = db1.transactionWithResult(true, messages = db1.transactionWithResult(true, txn ->
txn -> groupInvitationManager1 groupInvitationManager1.getMessageHeaders(txn,
.getMessageHeaders(txn, contactId0From1)); contactId0From1));
assertEquals(2, messages.size()); assertEquals(2, messages.size());
boolean foundResponse = false; boolean foundResponse = false;
for (ConversationMessageHeader m : messages) { for (ConversationMessageHeader m : messages) {
@@ -199,9 +199,9 @@ public class GroupInvitationIntegrationTest
sync1To0(1, true); sync1To0(1, true);
messages = db1.transactionWithResult(true, txn -> messages = db0.transactionWithResult(true, txn ->
groupInvitationManager0 groupInvitationManager0.getMessageHeaders(txn,
.getMessageHeaders(txn, contactId1From0)); contactId1From0));
assertEquals(2, messages.size()); assertEquals(2, messages.size());
foundResponse = false; foundResponse = false;
for (ConversationMessageHeader m : messages) { for (ConversationMessageHeader m : messages) {
@@ -228,13 +228,15 @@ public class GroupInvitationIntegrationTest
sendInvitation(timestamp, null); sendInvitation(timestamp, null);
// 0 has one read outgoing message // 0 has one read outgoing message
Group g1 = groupInvitationManager0.getContactGroup(contact1From0); Group g1 = groupInvitationManager0.getContactGroup(contact1From0,
author0.getId());
assertGroupCount(messageTracker0, g1.getId(), 1, 0, timestamp); assertGroupCount(messageTracker0, g1.getId(), 1, 0, timestamp);
sync0To1(1, true); sync0To1(1, true);
// 1 has one unread message // 1 has one unread message
Group g0 = groupInvitationManager1.getContactGroup(contact0From1); Group g0 = groupInvitationManager1.getContactGroup(contact0From1,
author1.getId());
assertGroupCount(messageTracker1, g0.getId(), 1, 1, timestamp); assertGroupCount(messageTracker1, g0.getId(), 1, 1, timestamp);
ConversationMessageHeader m = db1.transactionWithResult(true, txn -> ConversationMessageHeader m = db1.transactionWithResult(true, txn ->
groupInvitationManager1.getMessageHeaders(txn, contactId0From1) groupInvitationManager1.getMessageHeaders(txn, contactId0From1)
@@ -460,8 +462,8 @@ public class GroupInvitationIntegrationTest
private void sendInvitation(long timestamp, @Nullable String text) throws private void sendInvitation(long timestamp, @Nullable String text) throws
DbException { DbException {
byte[] signature = groupInvitationFactory.signInvitation(contact1From0, byte[] signature = groupInvitationFactory.signInvitation(author0,
privateGroup0.getId(), timestamp, author0.getPrivateKey()); contact1From0, privateGroup0.getId(), timestamp);
groupInvitationManager0 groupInvitationManager0
.sendInvitation(privateGroup0.getId(), contactId1From0, text, .sendInvitation(privateGroup0.getId(), contactId1From0, text,
timestamp, signature); timestamp, signature);

View File

@@ -14,7 +14,8 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Metadata; import org.briarproject.bramble.api.db.Metadata;
import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.db.Transaction;
import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.identity.Author;
import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.bramble.api.identity.IdentityManager;
import org.briarproject.bramble.api.identity.LocalAuthor;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
@@ -49,6 +50,7 @@ import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
import static org.briarproject.bramble.test.TestUtils.getAuthor; import static org.briarproject.bramble.test.TestUtils.getAuthor;
import static org.briarproject.bramble.test.TestUtils.getContact; import static org.briarproject.bramble.test.TestUtils.getContact;
import static org.briarproject.bramble.test.TestUtils.getGroup; 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.getMessage;
import static org.briarproject.bramble.test.TestUtils.getRandomBytes; import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
import static org.briarproject.bramble.test.TestUtils.getRandomId; import static org.briarproject.bramble.test.TestUtils.getRandomId;
@@ -70,6 +72,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
private final DatabaseComponent db = context.mock(DatabaseComponent.class); private final DatabaseComponent db = context.mock(DatabaseComponent.class);
private final ClientHelper clientHelper = context.mock(ClientHelper.class); private final ClientHelper clientHelper = context.mock(ClientHelper.class);
private final IdentityManager identityManager =
context.mock(IdentityManager.class);
private final ClientVersioningManager clientVersioningManager = private final ClientVersioningManager clientVersioningManager =
context.mock(ClientVersioningManager.class); context.mock(ClientVersioningManager.class);
private final ContactGroupFactory contactGroupFactory = private final ContactGroupFactory contactGroupFactory =
@@ -99,8 +103,8 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
private final Transaction txn = new Transaction(null, false); private final Transaction txn = new Transaction(null, false);
private final Author author = getAuthor(); private final Author author = getAuthor();
private final Contact contact = getContact(author, private final Contact contact = getContact(author, true);
new AuthorId(getRandomId()), true); private final LocalAuthor localAuthor = getLocalAuthor();
private final ContactId contactId = contact.getId(); private final ContactId contactId = contact.getId();
private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group localGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION); private final Group contactGroup = getGroup(CLIENT_ID, MAJOR_VERSION);
@@ -143,9 +147,9 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
MessageTracker messageTracker = context.mock(MessageTracker.class); MessageTracker messageTracker = context.mock(MessageTracker.class);
groupInvitationManager = new GroupInvitationManagerImpl(db, groupInvitationManager = new GroupInvitationManagerImpl(db,
clientHelper, clientVersioningManager, metadataParser, clientHelper, clientVersioningManager, metadataParser,
messageTracker, contactGroupFactory, privateGroupFactory, messageTracker, identityManager, contactGroupFactory,
privateGroupManager, messageParser, sessionParser, privateGroupFactory, privateGroupManager, messageParser,
sessionEncoder, engineFactory); sessionParser, sessionEncoder, engineFactory);
} }
@Test @Test
@@ -181,8 +185,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
.of(new BdfEntry(GROUP_KEY_CONTACT_ID, c.getId().getInt())); .of(new BdfEntry(GROUP_KEY_CONTACT_ID, c.getId().getInt()));
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, c); MAJOR_VERSION, c, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).addGroup(txn, contactGroup); oneOf(db).addGroup(txn, contactGroup);
oneOf(clientVersioningManager).getClientVisibility(txn, contactId, oneOf(clientVersioningManager).getClientVisibility(txn, contactId,
@@ -204,8 +210,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
private void expectAddingMember(GroupId g, Contact c) throws Exception { private void expectAddingMember(GroupId g, Contact c) throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, c); MAJOR_VERSION, c, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
}}); }});
expectGetSession(noResults, new SessionId(g.getBytes()), expectGetSession(noResults, new SessionId(g.getBytes()),
@@ -260,8 +268,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
@Test @Test
public void testRemovingContact() throws Exception { public void testRemovingContact() throws Exception {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).removeGroup(txn, contactGroup); oneOf(db).removeGroup(txn, contactGroup);
}}); }});
@@ -475,8 +485,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
}}); }});
expectCreateStorageId(); expectCreateStorageId();
@@ -507,8 +519,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(sessionParser) oneOf(sessionParser)
.parseCreatorSession(contactGroup.getId(), bdfSession); .parseCreatorSession(contactGroup.getId(), bdfSession);
@@ -536,8 +550,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
}}); }});
@@ -588,8 +604,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(sessionParser) oneOf(sessionParser)
.parseInviteeSession(contactGroup.getId(), bdfSession); .parseInviteeSession(contactGroup.getId(), bdfSession);
@@ -610,8 +628,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(sessionParser) oneOf(sessionParser)
.parsePeerSession(contactGroup.getId(), bdfSession); .parsePeerSession(contactGroup.getId(), bdfSession);
@@ -635,8 +655,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(txn)); will(returnValue(txn));
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).endTransaction(txn); oneOf(db).endTransaction(txn);
}}); }});
@@ -672,8 +694,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).getContact(txn, contactId); oneOf(db).getContact(txn, contactId);
will(returnValue(contact)); will(returnValue(contact));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(messageParser).getMessagesVisibleInUiQuery(); oneOf(messageParser).getMessagesVisibleInUiQuery();
will(returnValue(query)); will(returnValue(query));
@@ -744,10 +768,12 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
will(returnValue(query)); will(returnValue(query));
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(Collections.singletonList(contact))); will(returnValue(Collections.singletonList(contact)));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
contactGroup.getId(), query); contactGroup.getId(), query);
@@ -814,8 +840,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
throws Exception { throws Exception {
expectGetSession(oneResult, sessionId, contactGroup.getId()); expectGetSession(oneResult, sessionId, contactGroup.getId());
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).startTransaction(true); oneOf(db).startTransaction(true);
will(returnValue(txn)); will(returnValue(txn));
@@ -837,8 +865,10 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
public void testAddingMember() throws Exception { public void testAddingMember() throws Exception {
expectAddingMember(privateGroup.getId(), contact); expectAddingMember(privateGroup.getId(), contact);
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(db).getContactsByAuthorId(txn, author.getId()); oneOf(db).containsContact(txn, author.getId());
will(returnValue(Collections.singletonList(contact))); will(returnValue(true));
oneOf(db).getContact(txn, author.getId());
will(returnValue(contact));
}}); }});
groupInvitationManager.addingMember(txn, privateGroup.getId(), author); groupInvitationManager.addingMember(txn, privateGroup.getId(), author);
} }
@@ -866,16 +896,18 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
sessionId, contactGroup3.getId()); sessionId, contactGroup3.getId());
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(contacts)); will(returnValue(contacts));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact2); MAJOR_VERSION, contact2, localAuthor.getId());
will(returnValue(contactGroup2)); will(returnValue(contactGroup2));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact3); MAJOR_VERSION, contact3, localAuthor.getId());
will(returnValue(contactGroup3)); will(returnValue(contactGroup3));
// session 1 // session 1
oneOf(sessionParser).getRole(bdfSession); oneOf(sessionParser).getRole(bdfSession);

View File

@@ -330,8 +330,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
privateGroup.getSalt(), privateGroup.getSalt(),
getRandomString(MAX_GROUP_INVITATION_TEXT_LENGTH), getRandomString(MAX_GROUP_INVITATION_TEXT_LENGTH),
signature); signature);
Contact notCreatorContact = getContact(contactId, getAuthor(), Contact notCreatorContact = getContact(contactId, getAuthor(), true);
localAuthor.getId(), true);
expectGetContactId(); expectGetContactId();
context.checking(new Expectations() {{ context.checking(new Expectations() {{

View File

@@ -126,7 +126,7 @@ public class BlogSharingIntegrationTest
// get sharing group and assert group message count // get sharing group and assert group message count
GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID, GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact1From0).getId(); MAJOR_VERSION, contact1From0, author0.getId()).getId();
assertGroupCount(messageTracker0, g, 1, 0); assertGroupCount(messageTracker0, g, 1, 0);
// check that request message state is correct // check that request message state is correct
@@ -217,7 +217,7 @@ public class BlogSharingIntegrationTest
// get sharing group and assert group message count // get sharing group and assert group message count
GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID, GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact1From0).getId(); MAJOR_VERSION, contact1From0, author0.getId()).getId();
assertGroupCount(messageTracker0, g, 1, 0); assertGroupCount(messageTracker0, g, 1, 0);
// sync first request message // sync first request message

View File

@@ -62,8 +62,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
private final LocalAuthor localAuthor = getLocalAuthor(); private final LocalAuthor localAuthor = getLocalAuthor();
private final Author author = getAuthor(); private final Author author = getAuthor();
private final Contact contact = private final Contact contact = getContact(author, true);
getContact(author, localAuthor.getId(), true);
private final ContactId contactId = contact.getId(); private final ContactId contactId = contact.getId();
private final Collection<Contact> contacts = private final Collection<Contact> contacts =
Collections.singletonList(contact); Collections.singletonList(contact);
@@ -123,8 +122,10 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
// Create the contact group and share it with the contact // Create the contact group and share it with the contact
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(db).addGroup(txn, contactGroup); oneOf(db).addGroup(txn, contactGroup);
oneOf(clientVersioningManager).getClientVisibility(txn, contactId, oneOf(clientVersioningManager).getClientVisibility(txn, contactId,
@@ -202,7 +203,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
Message message = getMessage(contactGroup.getId()); Message message = getMessage(contactGroup.getId());
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(sessionParser) oneOf(sessionParser)
.getSessionQuery(new SessionId(blog.getId().getBytes())); .getSessionQuery(new SessionId(blog.getId().getBytes()));
@@ -237,10 +238,12 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
Session session = new Session(contactGroup.getId(), blog.getId()); Session session = new Session(contactGroup.getId(), blog.getId());
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(identityManager).getLocalAuthor(txn);
will(returnValue(localAuthor));
oneOf(db).getContacts(txn); oneOf(db).getContacts(txn);
will(returnValue(contacts)); will(returnValue(contacts));
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID, oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact); MAJOR_VERSION, contact, localAuthor.getId());
will(returnValue(contactGroup)); will(returnValue(contactGroup));
oneOf(sessionParser) oneOf(sessionParser)
.getSessionQuery(new SessionId(blog.getId().getBytes())); .getSessionQuery(new SessionId(blog.getId().getBytes()));

View File

@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.Group; import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.TestDatabaseModule; import org.briarproject.bramble.test.TestDatabaseModule;
@@ -416,7 +417,7 @@ public class ForumSharingIntegrationTest
// response and invitation got tracked // response and invitation got tracked
Group group = contactGroupFactory.createContactGroup(CLIENT_ID, Group group = contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact0From1); MAJOR_VERSION, contact0From1, author1.getId());
assertEquals(2, c1.getMessageTracker().getGroupCount(group.getId()) assertEquals(2, c1.getMessageTracker().getGroupCount(group.getId())
.getMsgCount()); .getMsgCount());
@@ -448,7 +449,7 @@ public class ForumSharingIntegrationTest
// assert that the invitation arrived // assert that the invitation arrived
Group group = contactGroupFactory.createContactGroup(CLIENT_ID, Group group = contactGroupFactory.createContactGroup(CLIENT_ID,
MAJOR_VERSION, contact0From1); MAJOR_VERSION, contact0From1, author1.getId());
assertEquals(1, c1.getMessageTracker().getGroupCount(group.getId()) assertEquals(1, c1.getMessageTracker().getGroupCount(group.getId())
.getMsgCount()); .getMsgCount());
@@ -777,8 +778,9 @@ public class ForumSharingIntegrationTest
.contains(contact0From1)); .contains(contact0From1));
// send an accept message for the same forum // send an accept message for the same forum
Message m = messageEncoder.encodeAcceptMessage( GroupId contactGroupId = forumSharingManager0.getContactGroup(
forumSharingManager0.getContactGroup(contact1From0).getId(), contact1From0, author0.getId()).getId();
Message m = messageEncoder.encodeAcceptMessage(contactGroupId,
forum0.getId(), clock.currentTimeMillis(), invitationId); forum0.getId(), clock.currentTimeMillis(), invitationId);
c0.getClientHelper().addLocalMessage(m, new BdfDictionary(), true); c0.getClientHelper().addLocalMessage(m, new BdfDictionary(), true);

View File

@@ -283,20 +283,16 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
} }
protected void addDefaultContacts() throws Exception { protected void addDefaultContacts() throws Exception {
contactId1From0 = contactManager0 contactId1From0 = contactManager0.addContact(author1, getSecretKey(),
.addContact(author1, author0.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contact1From0 = contactManager0.getContact(contactId1From0); contact1From0 = contactManager0.getContact(contactId1From0);
contactId0From1 = contactManager1 contactId0From1 = contactManager1.addContact(author0, getSecretKey(),
.addContact(author0, author1.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contact0From1 = contactManager1.getContact(contactId0From1); contact0From1 = contactManager1.getContact(contactId0From1);
contactId2From0 = contactManager0 contactId2From0 = contactManager0.addContact(author2, getSecretKey(),
.addContact(author2, author0.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contact2From0 = contactManager0.getContact(contactId2From0); contact2From0 = contactManager0.getContact(contactId2From0);
contactId0From2 = contactManager2 contactId0From2 = contactManager2.addContact(author0, getSecretKey(),
.addContact(author0, author2.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contact0From2 = contactManager2.getContact(contactId0From2); contact0From2 = contactManager2.getContact(contactId0From2);
@@ -315,11 +311,9 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
protected void addContacts1And2(boolean haveTransportProperties) protected void addContacts1And2(boolean haveTransportProperties)
throws Exception { throws Exception {
contactId2From1 = contactManager1 contactId2From1 = contactManager1.addContact(author2, getSecretKey(),
.addContact(author2, author1.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
contactId1From2 = contactManager2 contactId1From2 = contactManager2.addContact(author1, getSecretKey(),
.addContact(author1, author2.getId(), getSecretKey(),
clock.currentTimeMillis(), true, true, true); clock.currentTimeMillis(), true, true, true);
// Sync initial client versioning updates // Sync initial client versioning updates

View File

@@ -11,6 +11,7 @@ import org.briarproject.bramble.api.db.DatabaseExecutor
import org.briarproject.bramble.api.db.NoSuchContactException import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.bramble.api.event.Event import org.briarproject.bramble.api.event.Event
import org.briarproject.bramble.api.event.EventListener import org.briarproject.bramble.api.event.EventListener
import org.briarproject.bramble.api.identity.IdentityManager
import org.briarproject.bramble.api.system.Clock import org.briarproject.bramble.api.system.Clock
import org.briarproject.bramble.util.StringUtils.utf8IsTooLong import org.briarproject.bramble.util.StringUtils.utf8IsTooLong
import org.briarproject.briar.api.blog.BlogInvitationRequest import org.briarproject.briar.api.blog.BlogInvitationRequest
@@ -46,6 +47,7 @@ internal class MessagingControllerImpl
@Inject @Inject
constructor( constructor(
private val messagingManager: MessagingManager, private val messagingManager: MessagingManager,
private val identityManager: IdentityManager,
private val conversationManager: ConversationManager, private val conversationManager: ConversationManager,
private val privateMessageFactory: PrivateMessageFactory, private val privateMessageFactory: PrivateMessageFactory,
private val contactManager: ContactManager, private val contactManager: ContactManager,
@@ -71,7 +73,7 @@ constructor(
if (utf8IsTooLong(message, MAX_PRIVATE_MESSAGE_TEXT_LENGTH)) if (utf8IsTooLong(message, MAX_PRIVATE_MESSAGE_TEXT_LENGTH))
throw BadRequestResponse("Message text is too long") throw BadRequestResponse("Message text is too long")
val group = messagingManager.getContactGroup(contact) val group = messagingManager.getContactGroup(contact, identityManager.localAuthor.id)
val now = clock.currentTimeMillis() val now = clock.currentTimeMillis()
val m = privateMessageFactory.createPrivateMessage(group.id, now, message, emptyList()) val m = privateMessageFactory.createPrivateMessage(group.id, now, message, emptyList())

View File

@@ -35,7 +35,7 @@ abstract class ControllerTest {
protected val group: Group = getGroup(getClientId(), 0) protected val group: Group = getGroup(getClientId(), 0)
protected val author: Author = getAuthor() protected val author: Author = getAuthor()
protected val localAuthor: LocalAuthor = getLocalAuthor() protected val localAuthor: LocalAuthor = getLocalAuthor()
protected val contact: Contact = getContact(author, localAuthor.id, true) protected val contact: Contact = getContact(author, true)
protected val message: Message = getMessage(group.id) protected val message: Message = getMessage(group.id)
protected val text: String = getRandomString(5) protected val text: String = getRandomString(5)
protected val timestamp = 42L protected val timestamp = 42L

View File

@@ -40,6 +40,7 @@ internal class MessagingControllerImplTest : ControllerTest() {
private val controller = MessagingControllerImpl( private val controller = MessagingControllerImpl(
messagingManager, messagingManager,
identityManager,
conversationManager, conversationManager,
privateMessageFactory, privateMessageFactory,
contactManager, contactManager,
@@ -114,7 +115,8 @@ internal class MessagingControllerImplTest : ControllerTest() {
expectGetContact() expectGetContact()
every { ctx.body() } returns """{"text": "$text"}""" every { ctx.body() } returns """{"text": "$text"}"""
every { messagingManager.getContactGroup(contact) } returns group every { identityManager.localAuthor } returns localAuthor
every { messagingManager.getContactGroup(contact, localAuthor.id) } returns group
every { clock.currentTimeMillis() } returns timestamp every { clock.currentTimeMillis() } returns timestamp
every { every {
privateMessageFactory.createPrivateMessage( privateMessageFactory.createPrivateMessage(