Identity manager hooks. #209

This commit is contained in:
akwizgran
2016-01-20 12:03:15 +00:00
parent 82cf12040f
commit c4692a7007
16 changed files with 258 additions and 53 deletions

View File

@@ -61,7 +61,6 @@ public class Contact {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof Contact) return id.equals(((Contact) o).id); return o instanceof Contact && id.equals(((Contact) o).id);
return false;
} }
} }

View File

@@ -23,7 +23,6 @@ public class ContactId {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof ContactId) return id == ((ContactId) o).id; return o instanceof ContactId && id == ((ContactId) o).id;
return false;
} }
} }

View File

@@ -152,6 +152,9 @@ public interface DatabaseComponent {
/** Returns all contacts. */ /** Returns all contacts. */
Collection<Contact> getContacts() throws DbException; Collection<Contact> getContacts() throws DbException;
/** Returns all contacts associated with the given local pseudonym. */
Collection<ContactId> getContacts(AuthorId a) throws DbException;
/** Returns the group with the given ID, if the user subscribes to it. */ /** Returns the group with the given ID, if the user subscribes to it. */
Group getGroup(GroupId g) throws DbException; Group getGroup(GroupId g) throws DbException;
@@ -300,6 +303,10 @@ public interface DatabaseComponent {
/** Sets the status of the given contact. */ /** Sets the status of the given contact. */
void setContactStatus(ContactId c, Contact.Status s) throws DbException; void setContactStatus(ContactId c, Contact.Status s) throws DbException;
/** Sets the status of the given local pseudonym. */
void setLocalAuthorStatus(AuthorId a, LocalAuthor.Status s)
throws DbException;
/** Marks the given message as valid or invalid. */ /** Marks the given message as valid or invalid. */
void setMessageValidity(Message m, ClientId c, boolean valid) void setMessageValidity(Message m, ClientId c, boolean valid)
throws DbException; throws DbException;

View File

@@ -6,6 +6,12 @@ import java.util.Collection;
public interface IdentityManager { public interface IdentityManager {
/** Registers a hook to be called whenever a local pseudonym is added. */
void registerIdentityAddedHook(IdentityAddedHook hook);
/** Registers a hook to be called whenever a local pseudonym is removed. */
void registerIdentityRemovedHook(IdentityRemovedHook hook);
/** Stores a local pseudonym. */ /** Stores a local pseudonym. */
void addLocalAuthor(LocalAuthor a) throws DbException; void addLocalAuthor(LocalAuthor a) throws DbException;
@@ -17,4 +23,12 @@ public interface IdentityManager {
/** Removes a local pseudonym and all associated state. */ /** Removes a local pseudonym and all associated state. */
void removeLocalAuthor(AuthorId a) throws DbException; void removeLocalAuthor(AuthorId a) throws DbException;
interface IdentityAddedHook {
void identityAdded(AuthorId a);
}
interface IdentityRemovedHook {
void identityRemoved(AuthorId a);
}
} }

View File

@@ -3,14 +3,36 @@ package org.briarproject.api.identity;
/** A pseudonym for the local user. */ /** A pseudonym for the local user. */
public class LocalAuthor extends Author { public class LocalAuthor extends Author {
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 byte[] privateKey; private final byte[] privateKey;
private final long created; private final long created;
private final Status status;
public LocalAuthor(AuthorId id, String name, byte[] publicKey, public LocalAuthor(AuthorId id, String name, byte[] publicKey,
byte[] privateKey, long created) { byte[] privateKey, long created, Status status) {
super(id, name, publicKey); super(id, name, publicKey);
this.privateKey = privateKey; this.privateKey = privateKey;
this.created = created; this.created = created;
this.status = status;
} }
/** Returns the private key used to generate the pseudonym's signatures. */ /** Returns the private key used to generate the pseudonym's signatures. */
@@ -18,7 +40,16 @@ public class LocalAuthor extends Author {
return privateKey; return privateKey;
} }
/**
* Returns the time the pseudonym was created, in milliseconds since the
* Unix epoch.
*/
public long getTimeCreated() { public long getTimeCreated() {
return created; return created;
} }
/** Returns the status of the pseudonym. */
public Status getStatus() {
return status;
}
} }

View File

@@ -13,6 +13,7 @@ import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager.IdentityRemovedHook;
import org.briarproject.api.lifecycle.Service; import org.briarproject.api.lifecycle.Service;
import java.util.ArrayList; import java.util.ArrayList;
@@ -27,7 +28,8 @@ 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.ADDING;
import static org.briarproject.api.contact.Contact.Status.REMOVING; import static org.briarproject.api.contact.Contact.Status.REMOVING;
class ContactManagerImpl implements ContactManager, Service { class ContactManagerImpl implements ContactManager, Service,
IdentityRemovedHook {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(ContactManagerImpl.class.getName()); Logger.getLogger(ContactManagerImpl.class.getName());
@@ -118,4 +120,14 @@ class ContactManagerImpl implements ContactManager, Service {
db.removeContact(c); db.removeContact(c);
eventBus.broadcast(new ContactRemovedEvent(c)); eventBus.broadcast(new ContactRemovedEvent(c));
} }
@Override
public void identityRemoved(AuthorId a) {
// Remove any contacts of the local pseudonym that's being removed
try {
for (ContactId c : db.getContacts(a)) removeContact(c);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
} }

View File

@@ -4,6 +4,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import javax.inject.Singleton; import javax.inject.Singleton;
@@ -15,8 +16,10 @@ public class ContactModule extends AbstractModule {
@Provides @Singleton @Provides @Singleton
ContactManager getContactManager(LifecycleManager lifecycleManager, ContactManager getContactManager(LifecycleManager lifecycleManager,
IdentityManager identityManager,
ContactManagerImpl contactManager) { ContactManagerImpl contactManager) {
lifecycleManager.register(contactManager); lifecycleManager.register(contactManager);
identityManager.registerIdentityRemovedHook(contactManager);
return contactManager; return contactManager;
} }
} }

View File

@@ -334,7 +334,7 @@ interface Database<T> {
* Locking: read * Locking: read
*/ */
Collection<MessageStatus> getMessageStatus(T txn, ContactId c, GroupId g) Collection<MessageStatus> getMessageStatus(T txn, ContactId c, GroupId g)
throws DbException; throws DbException;
/** /**
* Returns the status of the given message with respect to the given * Returns the status of the given message with respect to the given
@@ -343,7 +343,7 @@ interface Database<T> {
* Locking: read * Locking: read
*/ */
MessageStatus getMessageStatus(T txn, ContactId c, MessageId m) MessageStatus getMessageStatus(T txn, ContactId c, MessageId m)
throws DbException; throws DbException;
/** /**
* Returns the IDs of some messages received from the given contact that * Returns the IDs of some messages received from the given contact that
@@ -388,7 +388,7 @@ interface Database<T> {
* Locking: read. * Locking: read.
*/ */
Collection<MessageId> getMessagesToValidate(T txn, ClientId c) Collection<MessageId> getMessagesToValidate(T txn, ClientId c)
throws DbException; throws DbException;
/** /**
* Returns the message with the given ID, in serialised form. * Returns the message with the given ID, in serialised form.
@@ -639,6 +639,14 @@ interface Database<T> {
void setContactStatus(T txn, ContactId c, Contact.Status s) void setContactStatus(T txn, ContactId c, Contact.Status s)
throws DbException; throws DbException;
/**
* Sets the status of the given local pseudonym.
* <p>
* Locking: write.
*/
void setLocalAuthorStatus(T txn, AuthorId a, LocalAuthor.Status s)
throws DbException;
/** /**
* Marks the given message as valid or invalid. * Marks the given message as valid or invalid.
* <p> * <p>

View File

@@ -16,10 +16,7 @@ import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.db.NoSuchMessageException; import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException; import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException; import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalAuthorAddedEvent;
import org.briarproject.api.event.LocalAuthorRemovedEvent;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent; import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.LocalTransportsUpdatedEvent; import org.briarproject.api.event.LocalTransportsUpdatedEvent;
import org.briarproject.api.event.MessageAddedEvent; import org.briarproject.api.event.MessageAddedEvent;
@@ -218,7 +215,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
} }
eventBus.broadcast(new LocalAuthorAddedEvent(a.getId()));
} }
public void addLocalMessage(Message m, ClientId c, Metadata meta) public void addLocalMessage(Message m, ClientId c, Metadata meta)
@@ -572,6 +568,25 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
} }
public Collection<ContactId> getContacts(AuthorId a) throws DbException {
lock.readLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsLocalAuthor(txn, a))
throw new NoSuchLocalAuthorException();
Collection<ContactId> contacts = db.getContacts(txn, a);
db.commitTransaction(txn);
return contacts;
} catch (DbException e) {
db.abortTransaction(txn);
throw e;
}
} finally {
lock.readLock().unlock();
}
}
public Group getGroup(GroupId g) throws DbException { public Group getGroup(GroupId g) throws DbException {
lock.readLock().lock(); lock.readLock().lock();
try { try {
@@ -1242,14 +1257,12 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
public void removeLocalAuthor(AuthorId a) throws DbException { public void removeLocalAuthor(AuthorId a) throws DbException {
Collection<ContactId> affected;
lock.writeLock().lock(); lock.writeLock().lock();
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
if (!db.containsLocalAuthor(txn, a)) if (!db.containsLocalAuthor(txn, a))
throw new NoSuchLocalAuthorException(); throw new NoSuchLocalAuthorException();
affected = db.getContacts(txn, a);
db.removeLocalAuthor(txn, a); db.removeLocalAuthor(txn, a);
db.commitTransaction(txn); db.commitTransaction(txn);
} catch (DbException e) { } catch (DbException e) {
@@ -1259,9 +1272,6 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
} }
for (ContactId c : affected)
eventBus.broadcast(new ContactRemovedEvent(c));
eventBus.broadcast(new LocalAuthorRemovedEvent(a));
} }
public void removeTransport(TransportId t) throws DbException { public void removeTransport(TransportId t) throws DbException {
@@ -1302,6 +1312,25 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} }
} }
public void setLocalAuthorStatus(AuthorId a, LocalAuthor.Status s)
throws DbException {
lock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsLocalAuthor(txn, a))
throw new NoSuchLocalAuthorException();
db.setLocalAuthorStatus(txn, a, 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) public void setMessageValidity(Message m, ClientId c, boolean valid)
throws DbException { throws DbException {
lock.writeLock().lock(); lock.writeLock().lock();

View File

@@ -64,8 +64,8 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
*/ */
abstract class JdbcDatabase implements Database<Connection> { abstract class JdbcDatabase implements Database<Connection> {
private static final int SCHEMA_VERSION = 15; private static final int SCHEMA_VERSION = 16;
private static final int MIN_SCHEMA_VERSION = 15; private static final int MIN_SCHEMA_VERSION = 16;
private static final String CREATE_SETTINGS = private static final String CREATE_SETTINGS =
"CREATE TABLE settings" "CREATE TABLE settings"
@@ -81,6 +81,7 @@ abstract class JdbcDatabase implements Database<Connection> {
+ " publicKey BINARY NOT NULL," + " publicKey BINARY NOT NULL,"
+ " privateKey BINARY NOT NULL," + " privateKey BINARY NOT NULL,"
+ " created BIGINT NOT NULL," + " created BIGINT NOT NULL,"
+ " status INT NOT NULL,"
+ " PRIMARY KEY (authorId))"; + " PRIMARY KEY (authorId))";
private static final String CREATE_CONTACTS = private static final String CREATE_CONTACTS =
@@ -719,15 +720,16 @@ abstract class JdbcDatabase implements Database<Connection> {
throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
String sql = "INSERT INTO localAuthors" String sql = "INSERT INTO localAuthors (authorId, name, publicKey,"
+ " (authorId, name, publicKey, privateKey, created)" + " privateKey, created, status)"
+ " VALUES (?, ?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setBytes(1, a.getId().getBytes()); ps.setBytes(1, a.getId().getBytes());
ps.setString(2, a.getName()); ps.setString(2, a.getName());
ps.setBytes(3, a.getPublicKey()); ps.setBytes(3, a.getPublicKey());
ps.setBytes(4, a.getPrivateKey()); ps.setBytes(4, a.getPrivateKey());
ps.setLong(5, a.getTimeCreated()); ps.setLong(5, a.getTimeCreated());
ps.setInt(6, a.getStatus().getValue());
int affected = ps.executeUpdate(); int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException(); if (affected != 1) throw new DbStateException();
ps.close(); ps.close();
@@ -1345,7 +1347,7 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT name, publicKey, privateKey, created" String sql = "SELECT name, publicKey, privateKey, created, status"
+ " FROM localAuthors" + " FROM localAuthors"
+ " WHERE authorId = ?"; + " WHERE authorId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
@@ -1356,8 +1358,10 @@ abstract class JdbcDatabase implements Database<Connection> {
byte[] publicKey = rs.getBytes(2); byte[] publicKey = rs.getBytes(2);
byte[] privateKey = rs.getBytes(3); byte[] privateKey = rs.getBytes(3);
long created = rs.getLong(4); long created = rs.getLong(4);
LocalAuthor.Status status = LocalAuthor.Status.fromValue(
rs.getInt(5));
LocalAuthor localAuthor = new LocalAuthor(a, name, publicKey, LocalAuthor localAuthor = new LocalAuthor(a, name, publicKey,
privateKey, created); privateKey, created, status);
if (rs.next()) throw new DbStateException(); if (rs.next()) throw new DbStateException();
rs.close(); rs.close();
ps.close(); ps.close();
@@ -1374,7 +1378,8 @@ abstract class JdbcDatabase implements Database<Connection> {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT authorId, name, publicKey, privateKey, created" String sql = "SELECT authorId, name, publicKey, privateKey,"
+ " created, status"
+ " FROM localAuthors"; + " FROM localAuthors";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
rs = ps.executeQuery(); rs = ps.executeQuery();
@@ -1385,8 +1390,10 @@ abstract class JdbcDatabase implements Database<Connection> {
byte[] publicKey = rs.getBytes(3); byte[] publicKey = rs.getBytes(3);
byte[] privateKey = rs.getBytes(4); byte[] privateKey = rs.getBytes(4);
long created = rs.getLong(5); long created = rs.getLong(5);
LocalAuthor.Status status = LocalAuthor.Status.fromValue(
rs.getInt(6));
authors.add(new LocalAuthor(authorId, name, publicKey, authors.add(new LocalAuthor(authorId, name, publicKey,
privateKey, created)); privateKey, created, status));
} }
rs.close(); rs.close();
ps.close(); ps.close();
@@ -2398,7 +2405,8 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
public void mergeSettings(Connection txn, Settings s, String namespace) throws DbException { public void mergeSettings(Connection txn, Settings s, String namespace)
throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
// Update any settings that already exist // Update any settings that already exist
@@ -2712,6 +2720,24 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
public void setLocalAuthorStatus(Connection txn, AuthorId a,
LocalAuthor.Status s) throws DbException {
PreparedStatement ps = null;
try {
String sql = "UPDATE localAuthors SET status = ?"
+ " WHERE authorId = ?";
ps = txn.prepareStatement(sql);
ps.setInt(1, s.getValue());
ps.setBytes(2, a.getBytes());
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) public void setMessageValidity(Connection txn, MessageId m, boolean valid)
throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;

View File

@@ -4,38 +4,114 @@ import com.google.inject.Inject;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalAuthorAddedEvent;
import org.briarproject.api.event.LocalAuthorRemovedEvent;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.Service;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
class IdentityManagerImpl implements IdentityManager { import static java.util.logging.Level.WARNING;
import static org.briarproject.api.identity.LocalAuthor.Status.ACTIVE;
import static org.briarproject.api.identity.LocalAuthor.Status.ADDING;
import static org.briarproject.api.identity.LocalAuthor.Status.REMOVING;
class IdentityManagerImpl implements IdentityManager, Service {
private static final Logger LOG =
Logger.getLogger(IdentityManagerImpl.class.getName());
private final DatabaseComponent db; private final DatabaseComponent db;
private final EventBus eventBus;
private final List<IdentityAddedHook> addHooks;
private final List<IdentityRemovedHook> removeHooks;
@Inject @Inject
IdentityManagerImpl(DatabaseComponent db) { IdentityManagerImpl(DatabaseComponent db, EventBus eventBus) {
this.db = db; this.db = db;
this.eventBus = eventBus;
addHooks = new CopyOnWriteArrayList<IdentityAddedHook>();
removeHooks = new CopyOnWriteArrayList<IdentityRemovedHook>();
}
@Override
public boolean start() {
// Finish adding/removing any partly added/removed pseudonyms
try {
for (LocalAuthor a : db.getLocalAuthors()) {
if (a.getStatus().equals(ADDING)) {
for (IdentityAddedHook hook : addHooks)
hook.identityAdded(a.getId());
db.setLocalAuthorStatus(a.getId(), ACTIVE);
eventBus.broadcast(new LocalAuthorAddedEvent(a.getId()));
} else if (a.getStatus().equals(REMOVING)) {
for (IdentityRemovedHook hook : removeHooks)
hook.identityRemoved(a.getId());
db.removeLocalAuthor(a.getId());
eventBus.broadcast(new LocalAuthorRemovedEvent(a.getId()));
}
}
return true;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return false;
}
}
@Override
public boolean stop() {
return false;
}
@Override
public void registerIdentityAddedHook(IdentityAddedHook hook) {
addHooks.add(hook);
}
@Override
public void registerIdentityRemovedHook(IdentityRemovedHook hook) {
removeHooks.add(hook);
} }
@Override @Override
public void addLocalAuthor(LocalAuthor a) throws DbException { public void addLocalAuthor(LocalAuthor a) throws DbException {
db.addLocalAuthor(a); db.addLocalAuthor(a);
for (IdentityAddedHook hook : addHooks) hook.identityAdded(a.getId());
db.setLocalAuthorStatus(a.getId(), ACTIVE);
eventBus.broadcast(new LocalAuthorAddedEvent(a.getId()));
} }
@Override @Override
public LocalAuthor getLocalAuthor(AuthorId a) throws DbException { public LocalAuthor getLocalAuthor(AuthorId a) throws DbException {
return db.getLocalAuthor(a); LocalAuthor author = db.getLocalAuthor(a);
if (author.getStatus().equals(ACTIVE)) return author;
throw new NoSuchLocalAuthorException();
} }
@Override @Override
public Collection<LocalAuthor> getLocalAuthors() throws DbException { public Collection<LocalAuthor> getLocalAuthors() throws DbException {
return db.getLocalAuthors(); Collection<LocalAuthor> authors = db.getLocalAuthors();
// Filter out any pseudonyms that are being added or removed
List<LocalAuthor> active = new ArrayList<LocalAuthor>(authors.size());
for (LocalAuthor a : authors)
if (a.getStatus().equals(ACTIVE)) active.add(a);
return Collections.unmodifiableList(active);
} }
@Override @Override
public void removeLocalAuthor(AuthorId a) throws DbException { public void removeLocalAuthor(AuthorId a) throws DbException {
db.setLocalAuthorStatus(a, REMOVING);
for (IdentityRemovedHook hook : removeHooks) hook.identityRemoved(a);
db.removeLocalAuthor(a); db.removeLocalAuthor(a);
eventBus.broadcast(new LocalAuthorRemovedEvent(a));
} }
} }

View File

@@ -14,6 +14,8 @@ import java.io.IOException;
import javax.inject.Inject; import javax.inject.Inject;
import static org.briarproject.api.identity.LocalAuthor.Status.ADDING;
class AuthorFactoryImpl implements AuthorFactory { class AuthorFactoryImpl implements AuthorFactory {
private final CryptoComponent crypto; private final CryptoComponent crypto;
@@ -35,7 +37,7 @@ class AuthorFactoryImpl implements AuthorFactory {
public LocalAuthor createLocalAuthor(String name, byte[] publicKey, public LocalAuthor createLocalAuthor(String name, byte[] publicKey,
byte[] privateKey) { byte[] privateKey) {
return new LocalAuthor(getId(name, publicKey), name, publicKey, return new LocalAuthor(getId(name, publicKey), name, publicKey,
privateKey, clock.currentTimeMillis()); privateKey, clock.currentTimeMillis(), ADDING);
} }
private AuthorId getId(String name, byte[] publicKey) { private AuthorId getId(String name, byte[] publicKey) {

View File

@@ -2,7 +2,6 @@ package org.briarproject.db;
import org.briarproject.BriarTestCase; import org.briarproject.BriarTestCase;
import org.briarproject.TestUtils; import org.briarproject.TestUtils;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties; import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
@@ -17,8 +16,6 @@ import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException; import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException; import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalAuthorAddedEvent;
import org.briarproject.api.event.LocalAuthorRemovedEvent;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent; import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.LocalTransportsUpdatedEvent; import org.briarproject.api.event.LocalTransportsUpdatedEvent;
import org.briarproject.api.event.MessageAddedEvent; import org.briarproject.api.event.MessageAddedEvent;
@@ -57,7 +54,6 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; 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.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH; import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES; import static org.briarproject.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
@@ -97,11 +93,12 @@ public class DatabaseComponentImplTest extends BriarTestCase {
authorId = new AuthorId(TestUtils.getRandomId()); authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]); author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId()); localAuthorId = new AuthorId(TestUtils.getRandomId());
long timestamp = System.currentTimeMillis();
localAuthor = new LocalAuthor(localAuthorId, "Bob", localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp,
LocalAuthor.Status.ACTIVE);
messageId = new MessageId(TestUtils.getRandomId()); messageId = new MessageId(TestUtils.getRandomId());
messageId1 = new MessageId(TestUtils.getRandomId()); messageId1 = new MessageId(TestUtils.getRandomId());
long timestamp = System.currentTimeMillis();
size = 1234; size = 1234;
raw = new byte[size]; raw = new byte[size];
message = new Message(messageId, groupId, timestamp, raw); message = new Message(messageId, groupId, timestamp, raw);
@@ -112,7 +109,8 @@ public class DatabaseComponentImplTest extends BriarTestCase {
"bar", "baz")); "bar", "baz"));
maxLatency = Integer.MAX_VALUE; maxLatency = Integer.MAX_VALUE;
contactId = new ContactId(234); contactId = new ContactId(234);
contact = new Contact(contactId, author, localAuthorId, ACTIVE); contact = new Contact(contactId, author, localAuthorId,
Contact.Status.ACTIVE);
} }
private <T> DatabaseComponent createDatabaseComponent(Database<T> database, private <T> DatabaseComponent createDatabaseComponent(Database<T> database,
@@ -141,7 +139,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).containsLocalAuthor(txn, localAuthorId); oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(false)); will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor); oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
// addContact() // addContact()
oneOf(database).containsContact(txn, authorId); oneOf(database).containsContact(txn, authorId);
will(returnValue(false)); will(returnValue(false));
@@ -184,10 +181,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
// removeLocalAuthor() // removeLocalAuthor()
oneOf(database).containsLocalAuthor(txn, localAuthorId); oneOf(database).containsLocalAuthor(txn, localAuthorId);
will(returnValue(true)); will(returnValue(true));
oneOf(database).getContacts(txn, localAuthorId);
will(returnValue(Collections.emptyList()));
oneOf(database).removeLocalAuthor(txn, localAuthorId); oneOf(database).removeLocalAuthor(txn, localAuthorId);
oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class)));
// close() // close()
oneOf(shutdown).removeShutdownHook(shutdownHandle); oneOf(shutdown).removeShutdownHook(shutdownHandle);
oneOf(database).close(); oneOf(database).close();
@@ -657,7 +651,6 @@ public class DatabaseComponentImplTest extends BriarTestCase {
will(returnValue(false)); will(returnValue(false));
oneOf(database).addLocalAuthor(txn, localAuthor); oneOf(database).addLocalAuthor(txn, localAuthor);
oneOf(database).commitTransaction(txn); oneOf(database).commitTransaction(txn);
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
// addContact() // addContact()
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));

View File

@@ -3,6 +3,7 @@ package org.briarproject.db;
import org.briarproject.BriarTestCase; import org.briarproject.BriarTestCase;
import org.briarproject.TestDatabaseConfig; import org.briarproject.TestDatabaseConfig;
import org.briarproject.TestUtils; import org.briarproject.TestUtils;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties; import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
@@ -21,7 +22,6 @@ import org.briarproject.api.sync.MessageStatus;
import org.briarproject.api.transport.IncomingKeys; import org.briarproject.api.transport.IncomingKeys;
import org.briarproject.api.transport.OutgoingKeys; import org.briarproject.api.transport.OutgoingKeys;
import org.briarproject.api.transport.TransportKeys; import org.briarproject.api.transport.TransportKeys;
import org.briarproject.api.Settings;
import org.briarproject.system.SystemClock; import org.briarproject.system.SystemClock;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
@@ -80,10 +80,11 @@ public class H2DatabaseTest extends BriarTestCase {
AuthorId authorId = new AuthorId(TestUtils.getRandomId()); AuthorId authorId = new AuthorId(TestUtils.getRandomId());
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]); author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
localAuthorId = new AuthorId(TestUtils.getRandomId()); localAuthorId = new AuthorId(TestUtils.getRandomId());
localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], 1234);
messageId = new MessageId(TestUtils.getRandomId());
timestamp = System.currentTimeMillis(); timestamp = System.currentTimeMillis();
localAuthor = new LocalAuthor(localAuthorId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp,
LocalAuthor.Status.ACTIVE);
messageId = new MessageId(TestUtils.getRandomId());
size = 1234; size = 1234;
raw = new byte[size]; raw = new byte[size];
random.nextBytes(raw); random.nextBytes(raw);
@@ -94,7 +95,7 @@ public class H2DatabaseTest extends BriarTestCase {
@Before @Before
public void setUp() { public void setUp() {
testDir.mkdirs(); assertTrue(testDir.mkdirs());
} }
@Test @Test

View File

@@ -41,6 +41,7 @@ import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule; import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule; import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule; import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.messaging.MessagingModule; import org.briarproject.messaging.MessagingModule;
import org.junit.Test; import org.junit.Test;
@@ -64,6 +65,8 @@ import static org.junit.Assert.assertTrue;
public class ConstantsTest extends BriarTestCase { public class ConstantsTest extends BriarTestCase {
// TODO: Break this up into tests that are relevant for each package
private final CryptoComponent crypto; private final CryptoComponent crypto;
private final GroupFactory groupFactory; private final GroupFactory groupFactory;
private final AuthorFactory authorFactory; private final AuthorFactory authorFactory;
@@ -76,7 +79,7 @@ public class ConstantsTest extends BriarTestCase {
new TestLifecycleModule(), new TestSystemModule(), new TestLifecycleModule(), new TestSystemModule(),
new ContactModule(), new CryptoModule(), new DatabaseModule(), new ContactModule(), new CryptoModule(), new DatabaseModule(),
new DataModule(), new EventModule(), new ForumModule(), new DataModule(), new EventModule(), new ForumModule(),
new MessagingModule(), new SyncModule()); new IdentityModule(), new MessagingModule(), new SyncModule());
crypto = i.getInstance(CryptoComponent.class); crypto = i.getInstance(CryptoComponent.class);
groupFactory = i.getInstance(GroupFactory.class); groupFactory = i.getInstance(GroupFactory.class);
authorFactory = i.getInstance(AuthorFactory.class); authorFactory = i.getInstance(AuthorFactory.class);

View File

@@ -123,7 +123,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
db.addTransport(transportId, MAX_LATENCY); db.addTransport(transportId, MAX_LATENCY);
// Add an identity for Alice // Add an identity for Alice
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice", LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], timestamp); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp,
LocalAuthor.Status.ADDING);
identityManager.addLocalAuthor(aliceAuthor); identityManager.addLocalAuthor(aliceAuthor);
// Add Bob as a contact // Add Bob as a contact
Author bobAuthor = new Author(bobId, "Bob", Author bobAuthor = new Author(bobId, "Bob",
@@ -188,7 +189,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
db.addTransport(transportId, MAX_LATENCY); db.addTransport(transportId, MAX_LATENCY);
// Add an identity for Bob // Add an identity for Bob
LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob", LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[100], timestamp); new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp,
LocalAuthor.Status.ADDING);
identityManager.addLocalAuthor(bobAuthor); identityManager.addLocalAuthor(bobAuthor);
// Add Alice as a contact // Add Alice as a contact
Author aliceAuthor = new Author(aliceId, "Alice", Author aliceAuthor = new Author(aliceId, "Alice",