mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Contact manager hooks. #209
This commit is contained in:
@@ -1,23 +1,24 @@
|
||||
package org.briarproject.android;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
import android.app.Application;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import org.briarproject.api.android.AndroidExecutor;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.android.ReferenceManager;
|
||||
import org.briarproject.api.crypto.SecretKey;
|
||||
import org.briarproject.api.db.DatabaseConfig;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.ui.UiCallback;
|
||||
|
||||
import android.app.Application;
|
||||
import java.io.File;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
public class AndroidModule extends AbstractModule {
|
||||
|
||||
@@ -81,9 +82,10 @@ public class AndroidModule extends AbstractModule {
|
||||
|
||||
@Provides @Singleton
|
||||
AndroidNotificationManager getAndroidNotificationManager(
|
||||
LifecycleManager lifecycleManager,
|
||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||
AndroidNotificationManagerImpl notificationManager) {
|
||||
lifecycleManager.register(notificationManager);
|
||||
eventBus.addListener(notificationManager);
|
||||
return notificationManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.event.MessageValidatedEvent;
|
||||
import org.briarproject.api.event.SettingsUpdatedEvent;
|
||||
@@ -61,7 +60,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final Executor dbExecutor;
|
||||
private final EventBus eventBus;
|
||||
private final MessagingManager messagingManager;
|
||||
private final ForumManager forumManager;
|
||||
private final AndroidExecutor androidExecutor;
|
||||
@@ -80,12 +78,11 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
@Inject
|
||||
public AndroidNotificationManagerImpl(DatabaseComponent db,
|
||||
@DatabaseExecutor Executor dbExecutor, EventBus eventBus,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
MessagingManager messagingManager, ForumManager forumManager,
|
||||
AndroidExecutor androidExecutor, Application app) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.eventBus = eventBus;
|
||||
this.messagingManager = messagingManager;
|
||||
this.forumManager = forumManager;
|
||||
this.androidExecutor = androidExecutor;
|
||||
@@ -94,7 +91,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
eventBus.addListener(this);
|
||||
loadSettings();
|
||||
return true;
|
||||
}
|
||||
@@ -114,7 +110,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
eventBus.removeListener(this);
|
||||
clearNotifications();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,37 @@ import org.briarproject.api.identity.AuthorId;
|
||||
|
||||
public class Contact {
|
||||
|
||||
public enum Status {
|
||||
|
||||
ADDING(0), ACTIVE(1), REMOVING(2);
|
||||
|
||||
private final int value;
|
||||
|
||||
Status(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Status fromValue(int value) {
|
||||
for (Status s : values()) if (s.value == value) return s;
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
private final ContactId id;
|
||||
private final Author author;
|
||||
private final AuthorId localAuthorId;
|
||||
private final Status status;
|
||||
|
||||
public Contact(ContactId id, Author author, AuthorId localAuthorId) {
|
||||
public Contact(ContactId id, Author author, AuthorId localAuthorId,
|
||||
Status status) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.localAuthorId = localAuthorId;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public ContactId getId() {
|
||||
@@ -27,6 +50,10 @@ public class Contact {
|
||||
return localAuthorId;
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
|
||||
@@ -8,6 +8,12 @@ import java.util.Collection;
|
||||
|
||||
public interface ContactManager {
|
||||
|
||||
/** Registers a hook to be called whenever a contact is added. */
|
||||
void registerContactAddedHook(ContactAddedHook hook);
|
||||
|
||||
/** Registers a hook to be called whenever a contact is removed. */
|
||||
void registerContactRemovedHook(ContactRemovedHook hook);
|
||||
|
||||
/**
|
||||
* Stores a contact associated with the given local and remote pseudonyms,
|
||||
* and returns an ID for the contact.
|
||||
@@ -22,4 +28,12 @@ public interface ContactManager {
|
||||
|
||||
/** Removes a contact and all associated state. */
|
||||
void removeContact(ContactId c) throws DbException;
|
||||
|
||||
interface ContactAddedHook {
|
||||
void contactAdded(ContactId c);
|
||||
}
|
||||
|
||||
interface ContactRemovedHook {
|
||||
void contactRemoved(ContactId c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,6 +297,9 @@ public interface DatabaseComponent {
|
||||
*/
|
||||
void removeTransport(TransportId t) throws DbException;
|
||||
|
||||
/** Sets the status of the given contact. */
|
||||
void setContactStatus(ContactId c, Contact.Status s) throws DbException;
|
||||
|
||||
/** Marks the given message as valid or invalid. */
|
||||
void setMessageValidity(Message m, ClientId c, boolean valid)
|
||||
throws DbException;
|
||||
|
||||
@@ -13,12 +13,6 @@ public interface MessagingManager {
|
||||
/** Returns the unique ID of the messaging client. */
|
||||
ClientId getClientId();
|
||||
|
||||
/**
|
||||
* Informs the messaging manager that a new contact has been added.
|
||||
* Creates a private conversation with the contact.
|
||||
*/
|
||||
void addContact(ContactId c) throws DbException;
|
||||
|
||||
/** Stores a local private message. */
|
||||
void addLocalMessage(PrivateMessage m) throws DbException;
|
||||
|
||||
|
||||
@@ -6,6 +6,26 @@ package org.briarproject.api.sync;
|
||||
*/
|
||||
public interface ValidationManager {
|
||||
|
||||
enum Status {
|
||||
|
||||
UNKNOWN(0), INVALID(1), VALID(2);
|
||||
|
||||
private final int value;
|
||||
|
||||
Status(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Status fromValue(int value) {
|
||||
for (Status s : values()) if (s.value == value) return s;
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets the message validator for the given client. */
|
||||
void setMessageValidator(ClientId c, MessageValidator v);
|
||||
}
|
||||
|
||||
@@ -7,38 +7,115 @@ import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.NoSuchContactException;
|
||||
import org.briarproject.api.event.ContactAddedEvent;
|
||||
import org.briarproject.api.event.ContactRemovedEvent;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class ContactManagerImpl implements ContactManager {
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.contact.Contact.Status.ACTIVE;
|
||||
import static org.briarproject.api.contact.Contact.Status.ADDING;
|
||||
import static org.briarproject.api.contact.Contact.Status.REMOVING;
|
||||
|
||||
class ContactManagerImpl implements ContactManager, Service {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ContactManagerImpl.class.getName());
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final EventBus eventBus;
|
||||
private final List<ContactAddedHook> addHooks;
|
||||
private final List<ContactRemovedHook> removeHooks;
|
||||
|
||||
@Inject
|
||||
ContactManagerImpl(DatabaseComponent db) {
|
||||
ContactManagerImpl(DatabaseComponent db, EventBus eventBus) {
|
||||
this.db = db;
|
||||
this.eventBus = eventBus;
|
||||
addHooks = new CopyOnWriteArrayList<ContactAddedHook>();
|
||||
removeHooks = new CopyOnWriteArrayList<ContactRemovedHook>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
// Finish adding/removing any partly added/removed contacts
|
||||
try {
|
||||
for (Contact c : db.getContacts()) {
|
||||
if (c.getStatus().equals(ADDING)) {
|
||||
for (ContactAddedHook hook : addHooks)
|
||||
hook.contactAdded(c.getId());
|
||||
db.setContactStatus(c.getId(), ACTIVE);
|
||||
eventBus.broadcast(new ContactAddedEvent(c.getId()));
|
||||
} else if (c.getStatus().equals(REMOVING)) {
|
||||
for (ContactRemovedHook hook : removeHooks)
|
||||
hook.contactRemoved(c.getId());
|
||||
db.removeContact(c.getId());
|
||||
eventBus.broadcast(new ContactRemovedEvent(c.getId()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerContactAddedHook(ContactAddedHook hook) {
|
||||
addHooks.add(hook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerContactRemovedHook(ContactRemovedHook hook) {
|
||||
removeHooks.add(hook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactId addContact(Author remote, AuthorId local)
|
||||
throws DbException {
|
||||
return db.addContact(remote, local);
|
||||
ContactId c = db.addContact(remote, local);
|
||||
for (ContactAddedHook hook : addHooks) hook.contactAdded(c);
|
||||
db.setContactStatus(c, ACTIVE);
|
||||
eventBus.broadcast(new ContactAddedEvent(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Contact getContact(ContactId c) throws DbException {
|
||||
return db.getContact(c);
|
||||
Contact contact = db.getContact(c);
|
||||
if (contact.getStatus().equals(ACTIVE)) return contact;
|
||||
throw new NoSuchContactException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Contact> getContacts() throws DbException {
|
||||
return db.getContacts();
|
||||
Collection<Contact> contacts = db.getContacts();
|
||||
// Filter out any contacts that are being added or removed
|
||||
List<Contact> active = new ArrayList<Contact>(contacts.size());
|
||||
for (Contact c : contacts)
|
||||
if (c.getStatus().equals(ACTIVE)) active.add(c);
|
||||
return Collections.unmodifiableList(active);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeContact(ContactId c) throws DbException {
|
||||
db.setContactStatus(c, REMOVING);
|
||||
for (ContactRemovedHook hook : removeHooks) hook.contactRemoved(c);
|
||||
db.removeContact(c);
|
||||
eventBus.broadcast(new ContactRemovedEvent(c));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
package org.briarproject.contact;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
public class ContactModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ContactManager.class).to(ContactManagerImpl.class);
|
||||
protected void configure() {}
|
||||
|
||||
@Provides @Singleton
|
||||
ContactManager getContactManager(LifecycleManager lifecycleManager,
|
||||
ContactManagerImpl contactManager) {
|
||||
lifecycleManager.register(contactManager);
|
||||
return contactManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,7 +631,19 @@ interface Database<T> {
|
||||
*/
|
||||
void resetExpiryTime(T txn, ContactId c, MessageId m) throws DbException;
|
||||
|
||||
/** Marks the given message as valid or invalid. */
|
||||
/**
|
||||
* Sets the status of the given contact.
|
||||
* <p>
|
||||
* Locking: write.
|
||||
*/
|
||||
void setContactStatus(T txn, ContactId c, Contact.Status s)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Marks the given message as valid or invalid.
|
||||
* <p>
|
||||
* Locking: write.
|
||||
*/
|
||||
void setMessageValidity(T txn, MessageId m, boolean valid)
|
||||
throws DbException;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.briarproject.api.db.NoSuchLocalAuthorException;
|
||||
import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.db.NoSuchSubscriptionException;
|
||||
import org.briarproject.api.db.NoSuchTransportException;
|
||||
import org.briarproject.api.event.ContactAddedEvent;
|
||||
import org.briarproject.api.event.ContactRemovedEvent;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.LocalAuthorAddedEvent;
|
||||
@@ -147,7 +146,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
|
||||
public ContactId addContact(Author remote, AuthorId local)
|
||||
throws DbException {
|
||||
ContactId c;
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
T txn = db.startTransaction();
|
||||
@@ -156,8 +154,9 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
throw new ContactExistsException();
|
||||
if (!db.containsLocalAuthor(txn, local))
|
||||
throw new NoSuchLocalAuthorException();
|
||||
c = db.addContact(txn, remote, local);
|
||||
ContactId c = db.addContact(txn, remote, local);
|
||||
db.commitTransaction(txn);
|
||||
return c;
|
||||
} catch (DbException e) {
|
||||
db.abortTransaction(txn);
|
||||
throw e;
|
||||
@@ -165,8 +164,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
eventBus.broadcast(new ContactAddedEvent(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
public void addContactGroup(ContactId c, Group g) throws DbException {
|
||||
@@ -1219,7 +1216,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
eventBus.broadcast(new ContactRemovedEvent(c));
|
||||
}
|
||||
|
||||
public void removeGroup(Group g) throws DbException {
|
||||
@@ -1287,6 +1283,25 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
||||
eventBus.broadcast(new TransportRemovedEvent(t));
|
||||
}
|
||||
|
||||
public void setContactStatus(ContactId c, Contact.Status s)
|
||||
throws DbException {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
T txn = db.startTransaction();
|
||||
try {
|
||||
if (!db.containsContact(txn, c))
|
||||
throw new NoSuchContactException();
|
||||
db.setContactStatus(txn, c, s);
|
||||
db.commitTransaction(txn);
|
||||
} catch (DbException e) {
|
||||
db.abortTransaction(txn);
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMessageValidity(Message m, ClientId c, boolean valid)
|
||||
throws DbException {
|
||||
lock.writeLock().lock();
|
||||
|
||||
@@ -50,8 +50,12 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.contact.Contact.Status.ADDING;
|
||||
import static org.briarproject.api.db.Metadata.REMOVE;
|
||||
import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
|
||||
import static org.briarproject.api.sync.ValidationManager.Status.INVALID;
|
||||
import static org.briarproject.api.sync.ValidationManager.Status.UNKNOWN;
|
||||
import static org.briarproject.api.sync.ValidationManager.Status.VALID;
|
||||
import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
|
||||
|
||||
/**
|
||||
@@ -60,12 +64,8 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
|
||||
*/
|
||||
abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
private static final int SCHEMA_VERSION = 14;
|
||||
private static final int MIN_SCHEMA_VERSION = 14;
|
||||
|
||||
private static final int VALIDATION_UNKNOWN = 0;
|
||||
private static final int VALIDATION_INVALID = 1;
|
||||
private static final int VALIDATION_VALID = 2;
|
||||
private static final int SCHEMA_VERSION = 15;
|
||||
private static final int MIN_SCHEMA_VERSION = 15;
|
||||
|
||||
private static final String CREATE_SETTINGS =
|
||||
"CREATE TABLE settings"
|
||||
@@ -90,6 +90,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " name VARCHAR NOT NULL,"
|
||||
+ " publicKey BINARY NOT NULL,"
|
||||
+ " localAuthorId HASH NOT NULL,"
|
||||
+ " status INT NOT NULL,"
|
||||
+ " PRIMARY KEY (contactId),"
|
||||
+ " UNIQUE (authorId),"
|
||||
+ " FOREIGN KEY (localAuthorId)"
|
||||
@@ -533,13 +534,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
try {
|
||||
// Create a contact row
|
||||
String sql = "INSERT INTO contacts"
|
||||
+ " (authorId, name, publicKey, localAuthorId)"
|
||||
+ " VALUES (?, ?, ?, ?)";
|
||||
+ " (authorId, name, publicKey, localAuthorId, status)"
|
||||
+ " VALUES (?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, remote.getId().getBytes());
|
||||
ps.setString(2, remote.getName());
|
||||
ps.setBytes(3, remote.getPublicKey());
|
||||
ps.setBytes(4, local.getBytes());
|
||||
ps.setInt(5, ADDING.getValue());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected != 1) throw new DbStateException();
|
||||
ps.close();
|
||||
@@ -747,7 +749,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.setBytes(2, m.getGroupId().getBytes());
|
||||
ps.setLong(3, m.getTimestamp());
|
||||
ps.setBoolean(4, local);
|
||||
ps.setInt(5, local ? VALIDATION_VALID : VALIDATION_UNKNOWN);
|
||||
ps.setInt(5, local ? VALID.getValue() : UNKNOWN.getValue());
|
||||
byte[] raw = m.getRaw();
|
||||
ps.setInt(6, raw.length);
|
||||
ps.setBytes(7, raw);
|
||||
@@ -1192,7 +1194,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT authorId, name, publicKey, localAuthorId"
|
||||
String sql = "SELECT authorId, name, publicKey, localAuthorId,"
|
||||
+ " status"
|
||||
+ " FROM contacts"
|
||||
+ " WHERE contactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
@@ -1203,10 +1206,11 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
String name = rs.getString(2);
|
||||
byte[] publicKey = rs.getBytes(3);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
|
||||
Contact.Status status = Contact.Status.fromValue(rs.getInt(5));
|
||||
rs.close();
|
||||
ps.close();
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
return new Contact(c, author, localAuthorId);
|
||||
return new Contact(c, author, localAuthorId, status);
|
||||
} catch (SQLException e) {
|
||||
tryToClose(rs);
|
||||
tryToClose(ps);
|
||||
@@ -1240,7 +1244,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT contactId, authorId, name, publicKey,"
|
||||
+ " localAuthorId"
|
||||
+ " localAuthorId, status"
|
||||
+ " FROM contacts";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
@@ -1252,7 +1256,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
||||
contacts.add(new Contact(contactId, author, localAuthorId));
|
||||
Contact.Status status = Contact.Status.fromValue(rs.getInt(6));
|
||||
contacts.add(new Contact(contactId, author, localAuthorId,
|
||||
status));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1612,7 +1618,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " ORDER BY timestamp DESC LIMIT ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setInt(2, VALIDATION_VALID);
|
||||
ps.setInt(2, VALID.getValue());
|
||||
ps.setLong(3, now);
|
||||
ps.setInt(4, maxMessages);
|
||||
rs = ps.executeQuery();
|
||||
@@ -1674,7 +1680,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " ORDER BY timestamp DESC";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setInt(2, VALIDATION_VALID);
|
||||
ps.setInt(2, VALID.getValue());
|
||||
ps.setLong(3, now);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
@@ -1704,7 +1710,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " JOIN groups AS g ON m.groupId = g.groupId"
|
||||
+ " WHERE valid = ? AND clientId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, VALIDATION_UNKNOWN);
|
||||
ps.setInt(1, UNKNOWN.getValue());
|
||||
ps.setBytes(2, c.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
@@ -1799,7 +1805,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
+ " ORDER BY timestamp DESC";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
ps.setInt(2, VALIDATION_VALID);
|
||||
ps.setInt(2, VALID.getValue());
|
||||
ps.setLong(3, now);
|
||||
rs = ps.executeQuery();
|
||||
List<MessageId> ids = new ArrayList<MessageId>();
|
||||
@@ -1846,7 +1852,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT c.contactId, authorId, c.name, publicKey,"
|
||||
+ " localAuthorId"
|
||||
+ " localAuthorId, status"
|
||||
+ " FROM contacts AS c"
|
||||
+ " JOIN contactGroups AS cg"
|
||||
+ " ON c.contactId = cg.contactId"
|
||||
@@ -1862,7 +1868,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
||||
contacts.add(new Contact(contactId, author, localAuthorId));
|
||||
Contact.Status status = Contact.Status.fromValue(rs.getInt(6));
|
||||
contacts.add(new Contact(contactId, author, localAuthorId,
|
||||
status));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -2687,13 +2695,30 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setContactStatus(Connection txn, ContactId c, Contact.Status s)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE contacts SET status = ? WHERE contactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, s.getValue());
|
||||
ps.setInt(2, c.getInt());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
||||
ps.close();
|
||||
} catch (SQLException e) {
|
||||
tryToClose(ps);
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMessageValidity(Connection txn, MessageId m, boolean valid)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "UPDATE messages SET valid = ? WHERE messageId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, valid ? VALIDATION_VALID : VALIDATION_INVALID);
|
||||
ps.setInt(1, valid ? VALID.getValue() : INVALID.getValue());
|
||||
ps.setBytes(2, m.getBytes());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected < 0) throw new DbStateException();
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.briarproject.api.data.ObjectReader;
|
||||
import org.briarproject.api.forum.ForumManager;
|
||||
import org.briarproject.api.forum.ForumPostFactory;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.system.Clock;
|
||||
|
||||
@@ -26,16 +25,17 @@ public class ForumModule extends AbstractModule {
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
ForumPostValidator getValidator(LifecycleManager lifecycleManager,
|
||||
CryptoComponent crypto, ValidationManager validationManager,
|
||||
ForumPostValidator getValidator(ValidationManager validationManager,
|
||||
ForumManager forumManager, CryptoComponent crypto,
|
||||
BdfReaderFactory bdfReaderFactory,
|
||||
BdfWriterFactory bdfWriterFactory,
|
||||
ObjectReader<Author> authorReader, MetadataEncoder metadataEncoder,
|
||||
Clock clock) {
|
||||
ForumPostValidator validator = new ForumPostValidator(crypto,
|
||||
validationManager, bdfReaderFactory, bdfWriterFactory,
|
||||
authorReader, metadataEncoder, clock);
|
||||
lifecycleManager.register(validator);
|
||||
bdfReaderFactory, bdfWriterFactory, authorReader,
|
||||
metadataEncoder, clock);
|
||||
validationManager.setMessageValidator(forumManager.getClientId(),
|
||||
validator);
|
||||
return validator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@ import org.briarproject.api.data.MetadataEncoder;
|
||||
import org.briarproject.api.data.ObjectReader;
|
||||
import org.briarproject.api.db.Metadata;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.briarproject.api.sync.MessageValidator;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.system.Clock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -35,15 +33,13 @@ import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENG
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||
import static org.briarproject.forum.ForumManagerImpl.CLIENT_ID;
|
||||
|
||||
class ForumPostValidator implements MessageValidator, Service {
|
||||
class ForumPostValidator implements MessageValidator {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ForumPostValidator.class.getName());
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final ValidationManager validationManager;
|
||||
private final BdfReaderFactory bdfReaderFactory;
|
||||
private final BdfWriterFactory bdfWriterFactory;
|
||||
private final ObjectReader<Author> authorReader;
|
||||
@@ -53,13 +49,11 @@ class ForumPostValidator implements MessageValidator, Service {
|
||||
|
||||
@Inject
|
||||
ForumPostValidator(CryptoComponent crypto,
|
||||
ValidationManager validationManager,
|
||||
BdfReaderFactory bdfReaderFactory,
|
||||
BdfWriterFactory bdfWriterFactory,
|
||||
ObjectReader<Author> authorReader,
|
||||
MetadataEncoder metadataEncoder, Clock clock) {
|
||||
this.crypto = crypto;
|
||||
this.validationManager = validationManager;
|
||||
this.bdfReaderFactory = bdfReaderFactory;
|
||||
this.bdfWriterFactory = bdfWriterFactory;
|
||||
this.authorReader = authorReader;
|
||||
@@ -68,17 +62,6 @@ class ForumPostValidator implements MessageValidator, Service {
|
||||
keyParser = crypto.getSignatureKeyParser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
validationManager.setMessageValidator(CLIENT_ID, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metadata validateMessage(Message m) {
|
||||
// Reject the message if it's too far in the future
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorFactory;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.messaging.MessagingManager;
|
||||
import org.briarproject.api.plugins.ConnectionManager;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||
@@ -48,7 +47,7 @@ class AliceConnector extends Connector {
|
||||
StreamWriterFactory streamWriterFactory,
|
||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
||||
KeyManager keyManager, ConnectionManager connectionManager,
|
||||
ContactManager contactManager, MessagingManager messagingManager,
|
||||
ContactManager contactManager,
|
||||
TransportPropertyManager transportPropertyManager, Clock clock,
|
||||
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
|
||||
LocalAuthor localAuthor,
|
||||
@@ -57,9 +56,8 @@ class AliceConnector extends Connector {
|
||||
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
|
||||
streamWriterFactory, authorFactory, groupFactory,
|
||||
keyManager, connectionManager, contactManager,
|
||||
messagingManager, transportPropertyManager, clock,
|
||||
reuseConnection, group, plugin, localAuthor, localProps,
|
||||
random);
|
||||
transportPropertyManager, clock, reuseConnection, group,
|
||||
plugin, localAuthor, localProps, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorFactory;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.messaging.MessagingManager;
|
||||
import org.briarproject.api.plugins.ConnectionManager;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||
@@ -48,7 +47,7 @@ class BobConnector extends Connector {
|
||||
StreamWriterFactory streamWriterFactory,
|
||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
||||
KeyManager keyManager, ConnectionManager connectionManager,
|
||||
ContactManager contactManager, MessagingManager messagingManager,
|
||||
ContactManager contactManager,
|
||||
TransportPropertyManager transportPropertyManager, Clock clock,
|
||||
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
|
||||
LocalAuthor localAuthor,
|
||||
@@ -57,9 +56,8 @@ class BobConnector extends Connector {
|
||||
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
|
||||
streamWriterFactory, authorFactory, groupFactory,
|
||||
keyManager, connectionManager, contactManager,
|
||||
messagingManager, transportPropertyManager, clock,
|
||||
reuseConnection, group, plugin, localAuthor, localProps,
|
||||
random);
|
||||
transportPropertyManager, clock, reuseConnection, group,
|
||||
plugin, localAuthor, localProps, random);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorFactory;
|
||||
import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.messaging.MessagingManager;
|
||||
import org.briarproject.api.plugins.ConnectionManager;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||
@@ -65,7 +64,6 @@ abstract class Connector extends Thread {
|
||||
protected final KeyManager keyManager;
|
||||
protected final ConnectionManager connectionManager;
|
||||
protected final ContactManager contactManager;
|
||||
protected final MessagingManager messagingManager;
|
||||
protected final TransportPropertyManager transportPropertyManager;
|
||||
protected final Clock clock;
|
||||
protected final boolean reuseConnection;
|
||||
@@ -89,7 +87,7 @@ abstract class Connector extends Thread {
|
||||
StreamWriterFactory streamWriterFactory,
|
||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
||||
KeyManager keyManager, ConnectionManager connectionManager,
|
||||
ContactManager contactManager, MessagingManager messagingManager,
|
||||
ContactManager contactManager,
|
||||
TransportPropertyManager transportPropertyManager, Clock clock,
|
||||
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
|
||||
LocalAuthor localAuthor,
|
||||
@@ -106,7 +104,6 @@ abstract class Connector extends Thread {
|
||||
this.keyManager = keyManager;
|
||||
this.connectionManager = connectionManager;
|
||||
this.contactManager = contactManager;
|
||||
this.messagingManager = messagingManager;
|
||||
this.transportPropertyManager = transportPropertyManager;
|
||||
this.clock = clock;
|
||||
this.reuseConnection = reuseConnection;
|
||||
@@ -287,8 +284,6 @@ abstract class Connector extends Thread {
|
||||
// Derive transport keys for each transport shared with the contact
|
||||
keyManager.addContact(contactId, remoteProps.keySet(), master,
|
||||
timestamp, alice);
|
||||
// Create a private messaging conversation
|
||||
messagingManager.addContact(contactId);
|
||||
}
|
||||
|
||||
protected void tryToClose(DuplexTransportConnection conn,
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.briarproject.api.identity.LocalAuthor;
|
||||
import org.briarproject.api.invitation.InvitationListener;
|
||||
import org.briarproject.api.invitation.InvitationState;
|
||||
import org.briarproject.api.invitation.InvitationTask;
|
||||
import org.briarproject.api.messaging.MessagingManager;
|
||||
import org.briarproject.api.plugins.ConnectionManager;
|
||||
import org.briarproject.api.plugins.PluginManager;
|
||||
import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
||||
@@ -58,7 +57,6 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
private final ConnectionManager connectionManager;
|
||||
private final IdentityManager identityManager;
|
||||
private final ContactManager contactManager;
|
||||
private final MessagingManager messagingManager;
|
||||
private final TransportPropertyManager transportPropertyManager;
|
||||
private final Clock clock;
|
||||
private final PluginManager pluginManager;
|
||||
@@ -85,7 +83,6 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
||||
KeyManager keyManager, ConnectionManager connectionManager,
|
||||
IdentityManager identityManager, ContactManager contactManager,
|
||||
MessagingManager messagingManager,
|
||||
TransportPropertyManager transportPropertyManager, Clock clock,
|
||||
PluginManager pluginManager, AuthorId localAuthorId,
|
||||
int localInvitationCode, int remoteInvitationCode,
|
||||
@@ -102,7 +99,6 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
this.connectionManager = connectionManager;
|
||||
this.identityManager = identityManager;
|
||||
this.contactManager = contactManager;
|
||||
this.messagingManager = messagingManager;
|
||||
this.transportPropertyManager = transportPropertyManager;
|
||||
this.clock = clock;
|
||||
this.pluginManager = pluginManager;
|
||||
@@ -201,8 +197,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory,
|
||||
streamReaderFactory, streamWriterFactory, authorFactory,
|
||||
groupFactory, keyManager, connectionManager, contactManager,
|
||||
messagingManager, transportPropertyManager, clock,
|
||||
reuseConnection, this, plugin, localAuthor, localProps, random);
|
||||
transportPropertyManager, clock, reuseConnection, this, plugin,
|
||||
localAuthor, localProps, random);
|
||||
}
|
||||
|
||||
private Connector createBobConnector(DuplexPlugin plugin,
|
||||
@@ -213,8 +209,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
|
||||
return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory,
|
||||
streamReaderFactory, streamWriterFactory, authorFactory,
|
||||
groupFactory, keyManager, connectionManager, contactManager,
|
||||
messagingManager, transportPropertyManager, clock,
|
||||
reuseConnection, this, plugin, localAuthor, localProps, random);
|
||||
transportPropertyManager, clock, reuseConnection, this, plugin,
|
||||
localAuthor, localProps, random);
|
||||
}
|
||||
|
||||
public void localConfirmationSucceeded() {
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.briarproject.api.identity.AuthorId;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.invitation.InvitationTask;
|
||||
import org.briarproject.api.invitation.InvitationTaskFactory;
|
||||
import org.briarproject.api.messaging.MessagingManager;
|
||||
import org.briarproject.api.plugins.ConnectionManager;
|
||||
import org.briarproject.api.plugins.PluginManager;
|
||||
import org.briarproject.api.property.TransportPropertyManager;
|
||||
@@ -34,7 +33,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
||||
private final ConnectionManager connectionManager;
|
||||
private final IdentityManager identityManager;
|
||||
private final ContactManager contactManager;
|
||||
private final MessagingManager messagingManager;
|
||||
private final TransportPropertyManager transportPropertyManager;
|
||||
private final Clock clock;
|
||||
private final PluginManager pluginManager;
|
||||
@@ -47,7 +45,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
||||
AuthorFactory authorFactory, GroupFactory groupFactory,
|
||||
KeyManager keyManager, ConnectionManager connectionManager,
|
||||
IdentityManager identityManager, ContactManager contactManager,
|
||||
MessagingManager messagingManager,
|
||||
TransportPropertyManager transportPropertyManager,
|
||||
Clock clock, PluginManager pluginManager) {
|
||||
this.crypto = crypto;
|
||||
@@ -61,7 +58,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
||||
this.connectionManager = connectionManager;
|
||||
this.identityManager = identityManager;
|
||||
this.contactManager = contactManager;
|
||||
this.messagingManager = messagingManager;
|
||||
this.transportPropertyManager = transportPropertyManager;
|
||||
this.clock = clock;
|
||||
this.pluginManager = pluginManager;
|
||||
@@ -72,8 +68,7 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
|
||||
return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory,
|
||||
streamReaderFactory, streamWriterFactory, authorFactory,
|
||||
groupFactory, keyManager, connectionManager, identityManager,
|
||||
contactManager, messagingManager, transportPropertyManager,
|
||||
clock, pluginManager, localAuthorId, localCode, remoteCode,
|
||||
reuseConnection);
|
||||
contactManager, transportPropertyManager, clock, pluginManager,
|
||||
localAuthorId, localCode, remoteCode, reuseConnection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.UniqueId;
|
||||
import org.briarproject.api.contact.Contact;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.contact.ContactManager.ContactAddedHook;
|
||||
import org.briarproject.api.contact.ContactManager.ContactRemovedHook;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfReader;
|
||||
import org.briarproject.api.data.BdfReaderFactory;
|
||||
@@ -42,7 +44,8 @@ import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
|
||||
class MessagingManagerImpl implements MessagingManager {
|
||||
class MessagingManagerImpl implements MessagingManager, ContactAddedHook,
|
||||
ContactRemovedHook {
|
||||
|
||||
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
|
||||
"6bcdc006c0910b0f44e40644c3b31f1a"
|
||||
@@ -72,18 +75,17 @@ class MessagingManagerImpl implements MessagingManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientId getClientId() {
|
||||
return CLIENT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addContact(ContactId c) throws DbException {
|
||||
// Create the conversation group
|
||||
Group conversation = createConversationGroup(db.getContact(c));
|
||||
// Subscribe to the group and share it with the contact
|
||||
db.addGroup(conversation);
|
||||
db.addContactGroup(c, conversation);
|
||||
db.setVisibility(conversation.getId(), Collections.singletonList(c));
|
||||
public void contactAdded(ContactId c) {
|
||||
try {
|
||||
// Create the conversation group
|
||||
Group g = createConversationGroup(db.getContact(c));
|
||||
// Subscribe to the group and share it with the contact
|
||||
db.addGroup(g);
|
||||
db.addContactGroup(c, g);
|
||||
db.setVisibility(g.getId(), Collections.singletonList(c));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private Group createConversationGroup(Contact c) {
|
||||
@@ -113,6 +115,20 @@ class MessagingManagerImpl implements MessagingManager {
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contactRemoved(ContactId c) {
|
||||
try {
|
||||
db.removeGroup(createConversationGroup(db.getContact(c)));
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientId getClientId() {
|
||||
return CLIENT_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLocalMessage(PrivateMessage m) throws DbException {
|
||||
BdfDictionary d = new BdfDictionary();
|
||||
@@ -131,7 +147,7 @@ class MessagingManagerImpl implements MessagingManager {
|
||||
|
||||
@Override
|
||||
public ContactId getContactId(GroupId g) throws DbException {
|
||||
// TODO: Make this more efficient
|
||||
// TODO: Use metadata to attach the contact ID to the group
|
||||
for (Contact c : db.getContacts()) {
|
||||
Group conversation = createConversationGroup(c);
|
||||
if (conversation.getId().equals(g)) return c.getId();
|
||||
|
||||
@@ -3,9 +3,9 @@ package org.briarproject.messaging;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.data.BdfReaderFactory;
|
||||
import org.briarproject.api.data.MetadataEncoder;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.messaging.MessagingManager;
|
||||
import org.briarproject.api.messaging.PrivateMessageFactory;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
@@ -17,18 +17,26 @@ public class MessagingModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(MessagingManager.class).to(MessagingManagerImpl.class);
|
||||
bind(PrivateMessageFactory.class).to(PrivateMessageFactoryImpl.class);
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
PrivateMessageValidator getValidator(LifecycleManager lifecycleManager,
|
||||
ValidationManager validationManager,
|
||||
PrivateMessageValidator getValidator(ValidationManager validationManager,
|
||||
MessagingManager messagingManager,
|
||||
BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder,
|
||||
Clock clock) {
|
||||
PrivateMessageValidator validator = new PrivateMessageValidator(
|
||||
validationManager, bdfReaderFactory, metadataEncoder, clock);
|
||||
lifecycleManager.register(validator);
|
||||
bdfReaderFactory, metadataEncoder, clock);
|
||||
validationManager.setMessageValidator(messagingManager.getClientId(),
|
||||
validator);
|
||||
return validator;
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
MessagingManager getMessagingManager(ContactManager contactManager,
|
||||
MessagingManagerImpl messagingManager) {
|
||||
contactManager.registerContactAddedHook(messagingManager);
|
||||
contactManager.registerContactRemovedHook(messagingManager);
|
||||
return messagingManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,11 +7,9 @@ import org.briarproject.api.data.BdfReader;
|
||||
import org.briarproject.api.data.BdfReaderFactory;
|
||||
import org.briarproject.api.data.MetadataEncoder;
|
||||
import org.briarproject.api.db.Metadata;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.briarproject.api.sync.MessageValidator;
|
||||
import org.briarproject.api.sync.ValidationManager;
|
||||
import org.briarproject.api.system.Clock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -24,39 +22,24 @@ import static org.briarproject.api.messaging.MessagingConstants.MAX_CONTENT_TYPE
|
||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||
import static org.briarproject.messaging.MessagingManagerImpl.CLIENT_ID;
|
||||
|
||||
class PrivateMessageValidator implements MessageValidator, Service {
|
||||
class PrivateMessageValidator implements MessageValidator {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(PrivateMessageValidator.class.getName());
|
||||
|
||||
private final ValidationManager validationManager;
|
||||
private final BdfReaderFactory bdfReaderFactory;
|
||||
private final MetadataEncoder metadataEncoder;
|
||||
private final Clock clock;
|
||||
|
||||
@Inject
|
||||
PrivateMessageValidator(ValidationManager validationManager,
|
||||
BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder,
|
||||
Clock clock) {
|
||||
this.validationManager = validationManager;
|
||||
PrivateMessageValidator(BdfReaderFactory bdfReaderFactory,
|
||||
MetadataEncoder metadataEncoder, Clock clock) {
|
||||
this.bdfReaderFactory = bdfReaderFactory;
|
||||
this.metadataEncoder = metadataEncoder;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
validationManager.setMessageValidator(CLIENT_ID, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metadata validateMessage(Message m) {
|
||||
// Reject the message if it's too far in the future
|
||||
|
||||
@@ -4,9 +4,9 @@ import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import org.briarproject.api.data.ObjectReader;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.identity.Author;
|
||||
import org.briarproject.api.identity.AuthorFactory;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.GroupFactory;
|
||||
import org.briarproject.api.sync.MessageFactory;
|
||||
@@ -48,9 +48,9 @@ public class SyncModule extends AbstractModule {
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
ValidationManager getValidationManager(LifecycleManager lifecycleManager,
|
||||
ValidationManager getValidationManager(EventBus eventBus,
|
||||
ValidationManagerImpl validationManager) {
|
||||
lifecycleManager.register(validationManager);
|
||||
eventBus.addListener(validationManager);
|
||||
return validationManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,8 @@ import org.briarproject.api.db.Metadata;
|
||||
import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.db.NoSuchSubscriptionException;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.event.MessageAddedEvent;
|
||||
import org.briarproject.api.lifecycle.Service;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
@@ -31,8 +29,7 @@ import java.util.logging.Logger;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
|
||||
class ValidationManagerImpl implements ValidationManager, Service,
|
||||
EventListener {
|
||||
class ValidationManagerImpl implements ValidationManager, EventListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ValidationManagerImpl.class.getName());
|
||||
@@ -40,32 +37,18 @@ class ValidationManagerImpl implements ValidationManager, Service,
|
||||
private final DatabaseComponent db;
|
||||
private final Executor dbExecutor;
|
||||
private final Executor cryptoExecutor;
|
||||
private final EventBus eventBus;
|
||||
private final Map<ClientId, MessageValidator> validators;
|
||||
|
||||
@Inject
|
||||
ValidationManagerImpl(DatabaseComponent db,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
@CryptoExecutor Executor cryptoExecutor, EventBus eventBus) {
|
||||
@CryptoExecutor Executor cryptoExecutor) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.cryptoExecutor = cryptoExecutor;
|
||||
this.eventBus = eventBus;
|
||||
validators = new ConcurrentHashMap<ClientId, MessageValidator>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
eventBus.addListener(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
eventBus.removeListener(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessageValidator(ClientId c, MessageValidator v) {
|
||||
validators.put(c, v);
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.event.ContactRemovedEvent;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.event.TransportAddedEvent;
|
||||
import org.briarproject.api.event.TransportRemovedEvent;
|
||||
@@ -38,19 +37,17 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
private final DatabaseComponent db;
|
||||
private final CryptoComponent crypto;
|
||||
private final ExecutorService dbExecutor;
|
||||
private final EventBus eventBus;
|
||||
private final Timer timer;
|
||||
private final Clock clock;
|
||||
private final ConcurrentHashMap<TransportId, TransportKeyManager> managers;
|
||||
|
||||
@Inject
|
||||
KeyManagerImpl(DatabaseComponent db, CryptoComponent crypto,
|
||||
@DatabaseExecutor ExecutorService dbExecutor, EventBus eventBus,
|
||||
Timer timer, Clock clock) {
|
||||
@DatabaseExecutor ExecutorService dbExecutor, Timer timer,
|
||||
Clock clock) {
|
||||
this.db = db;
|
||||
this.crypto = crypto;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.eventBus = eventBus;
|
||||
this.timer = timer;
|
||||
this.clock = clock;
|
||||
managers = new ConcurrentHashMap<TransportId, TransportKeyManager>();
|
||||
@@ -58,7 +55,6 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
eventBus.addListener(this);
|
||||
try {
|
||||
Map<TransportId, Integer> latencies = db.getTransportLatencies();
|
||||
for (Entry<TransportId, Integer> e : latencies.entrySet())
|
||||
@@ -72,7 +68,6 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
eventBus.removeListener(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.transport;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.transport.KeyManager;
|
||||
import org.briarproject.api.transport.StreamReaderFactory;
|
||||
@@ -20,8 +21,9 @@ public class TransportModule extends AbstractModule {
|
||||
|
||||
@Provides @Singleton
|
||||
KeyManager getKeyManager(LifecycleManager lifecycleManager,
|
||||
KeyManagerImpl keyManager) {
|
||||
EventBus eventBus, KeyManagerImpl keyManager) {
|
||||
lifecycleManager.register(keyManager);
|
||||
eventBus.addListener(keyManager);
|
||||
return keyManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import org.briarproject.api.db.NoSuchLocalAuthorException;
|
||||
import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.db.NoSuchSubscriptionException;
|
||||
import org.briarproject.api.db.NoSuchTransportException;
|
||||
import org.briarproject.api.event.ContactAddedEvent;
|
||||
import org.briarproject.api.event.ContactRemovedEvent;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
import org.briarproject.api.event.LocalAuthorAddedEvent;
|
||||
import org.briarproject.api.event.LocalAuthorRemovedEvent;
|
||||
@@ -59,6 +57,7 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.briarproject.api.contact.Contact.Status.ACTIVE;
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
||||
@@ -113,7 +112,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
"bar", "baz"));
|
||||
maxLatency = Integer.MAX_VALUE;
|
||||
contactId = new ContactId(234);
|
||||
contact = new Contact(contactId, author, localAuthorId);
|
||||
contact = new Contact(contactId, author, localAuthorId, ACTIVE);
|
||||
}
|
||||
|
||||
private <T> DatabaseComponent createDatabaseComponent(Database<T> database,
|
||||
@@ -150,7 +149,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
will(returnValue(true));
|
||||
oneOf(database).addContact(txn, author, localAuthorId);
|
||||
will(returnValue(contactId));
|
||||
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
||||
// getContacts()
|
||||
oneOf(database).getContacts(txn);
|
||||
will(returnValue(Collections.singletonList(contact)));
|
||||
@@ -183,7 +181,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
oneOf(database).containsContact(txn, contactId);
|
||||
will(returnValue(true));
|
||||
oneOf(database).removeContact(txn, contactId);
|
||||
oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class)));
|
||||
// removeLocalAuthor()
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
will(returnValue(true));
|
||||
@@ -671,7 +668,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
|
||||
oneOf(database).addContact(txn, author, localAuthorId);
|
||||
will(returnValue(contactId));
|
||||
oneOf(database).commitTransaction(txn);
|
||||
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
||||
// Check whether the transport is in the DB (which it's not)
|
||||
exactly(6).of(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.briarproject.api.sync.PacketWriterFactory;
|
||||
import org.briarproject.api.sync.Request;
|
||||
import org.briarproject.api.sync.SubscriptionUpdate;
|
||||
import org.briarproject.api.sync.TransportUpdate;
|
||||
import org.briarproject.contact.ContactModule;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
import org.briarproject.data.DataModule;
|
||||
import org.briarproject.db.DatabaseModule;
|
||||
@@ -73,9 +74,9 @@ public class ConstantsTest extends BriarTestCase {
|
||||
public ConstantsTest() throws Exception {
|
||||
Injector i = Guice.createInjector(new TestDatabaseModule(),
|
||||
new TestLifecycleModule(), new TestSystemModule(),
|
||||
new CryptoModule(), new DatabaseModule(), new DataModule(),
|
||||
new EventModule(), new ForumModule(), new MessagingModule(),
|
||||
new SyncModule());
|
||||
new ContactModule(), new CryptoModule(), new DatabaseModule(),
|
||||
new DataModule(), new EventModule(), new ForumModule(),
|
||||
new MessagingModule(), new SyncModule());
|
||||
crypto = i.getInstance(CryptoComponent.class);
|
||||
groupFactory = i.getInstance(GroupFactory.class);
|
||||
authorFactory = i.getInstance(AuthorFactory.class);
|
||||
|
||||
@@ -129,8 +129,6 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
Author bobAuthor = new Author(bobId, "Bob",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
ContactId contactId = contactManager.addContact(bobAuthor, aliceId);
|
||||
// Create a private conversation
|
||||
messagingManager.addContact(contactId);
|
||||
// Derive and store the transport keys
|
||||
keyManager.addContact(contactId, Collections.singletonList(transportId),
|
||||
master, timestamp, true);
|
||||
@@ -174,14 +172,14 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
IdentityManager identityManager =
|
||||
bob.getInstance(IdentityManager.class);
|
||||
ContactManager contactManager = bob.getInstance(ContactManager.class);
|
||||
MessagingManager messagingManager =
|
||||
bob.getInstance(MessagingManager.class);
|
||||
KeyManager keyManager = bob.getInstance(KeyManager.class);
|
||||
StreamReaderFactory streamReaderFactory =
|
||||
bob.getInstance(StreamReaderFactory.class);
|
||||
PacketReaderFactory packetReaderFactory =
|
||||
bob.getInstance(PacketReaderFactory.class);
|
||||
EventBus eventBus = bob.getInstance(EventBus.class);
|
||||
// Bob needs a MessagingManager even though we're not using it directly
|
||||
bob.getInstance(MessagingManager.class);
|
||||
|
||||
// Start the lifecyle manager
|
||||
lifecycleManager.startServices();
|
||||
@@ -196,8 +194,6 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
Author aliceAuthor = new Author(aliceId, "Alice",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
ContactId contactId = contactManager.addContact(aliceAuthor, bobId);
|
||||
// Create a private conversation
|
||||
messagingManager.addContact(contactId);
|
||||
// Derive and store the transport keys
|
||||
keyManager.addContact(contactId, Collections.singletonList(transportId),
|
||||
master, timestamp, false);
|
||||
|
||||
Reference in New Issue
Block a user