mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Merge branch '1567-remove-pending-contact-state-from-db' into 'master'
Remove pending contact state from DB See merge request briar/briar!1102
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
package org.briarproject.bramble.api.contact;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.Pair;
|
||||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
import org.briarproject.bramble.api.UnsupportedVersionException;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
@@ -76,9 +77,11 @@ public interface ContactManager {
|
|||||||
throws DbException, FormatException;
|
throws DbException, FormatException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of {@link PendingContact}s.
|
* Returns a list of {@link PendingContact PendingContacts} and their
|
||||||
|
* {@link PendingContactState states}.
|
||||||
*/
|
*/
|
||||||
Collection<PendingContact> getPendingContacts() throws DbException;
|
Collection<Pair<PendingContact, PendingContactState>> getPendingContacts()
|
||||||
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a {@link PendingContact}.
|
* Removes a {@link PendingContact}.
|
||||||
|
|||||||
@@ -12,15 +12,13 @@ public class PendingContact {
|
|||||||
private final PendingContactId id;
|
private final PendingContactId id;
|
||||||
private final PublicKey publicKey;
|
private final PublicKey publicKey;
|
||||||
private final String alias;
|
private final String alias;
|
||||||
private final PendingContactState state;
|
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
|
|
||||||
public PendingContact(PendingContactId id, PublicKey publicKey,
|
public PendingContact(PendingContactId id, PublicKey publicKey,
|
||||||
String alias, PendingContactState state, long timestamp) {
|
String alias, long timestamp) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
this.state = state;
|
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,10 +34,6 @@ public class PendingContact {
|
|||||||
return alias;
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PendingContactState getState() {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
public long getTimestamp() {
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,9 @@
|
|||||||
package org.briarproject.bramble.api.contact;
|
package org.briarproject.bramble.api.contact;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
public enum PendingContactState {
|
public enum PendingContactState {
|
||||||
|
|
||||||
WAITING_FOR_CONNECTION(0),
|
WAITING_FOR_CONNECTION,
|
||||||
CONNECTED(1),
|
CONNECTED,
|
||||||
ADDING_CONTACT(2),
|
ADDING_CONTACT,
|
||||||
FAILED(3);
|
FAILED
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
PendingContactState(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PendingContactState fromValue(int value) {
|
|
||||||
for (PendingContactState s : values()) if (s.value == value) return s;
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.briarproject.bramble.api.contact.event;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event that is broadcast when a pending contact is added.
|
||||||
|
*/
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class PendingContactAddedEvent extends Event {
|
||||||
|
|
||||||
|
private final PendingContact pendingContact;
|
||||||
|
|
||||||
|
public PendingContactAddedEvent(PendingContact pendingContact) {
|
||||||
|
this.pendingContact = pendingContact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PendingContact getPendingContact() {
|
||||||
|
return pendingContact;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
|||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
|
||||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||||
@@ -181,10 +180,7 @@ public class TestUtils {
|
|||||||
PendingContactId id = new PendingContactId(getRandomId());
|
PendingContactId id = new PendingContactId(getRandomId());
|
||||||
PublicKey publicKey = getAgreementPublicKey();
|
PublicKey publicKey = getAgreementPublicKey();
|
||||||
String alias = getRandomString(nameLength);
|
String alias = getRandomString(nameLength);
|
||||||
int stateIndex =
|
return new PendingContact(id, publicKey, alias, timestamp);
|
||||||
random.nextInt(PendingContactState.values().length - 1);
|
|
||||||
PendingContactState state = PendingContactState.values()[stateIndex];
|
|
||||||
return new PendingContact(id, publicKey, alias, state, timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ContactId getContactId() {
|
public static ContactId getContactId() {
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package org.briarproject.bramble.contact;
|
package org.briarproject.bramble.contact;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.Pair;
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
@@ -19,6 +21,7 @@ import org.briarproject.bramble.api.identity.LocalAuthor;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.transport.KeyManager;
|
import org.briarproject.bramble.api.transport.KeyManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@@ -28,6 +31,7 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32_LINK_BYTES;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32_LINK_BYTES;
|
||||||
|
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.OURSELVES;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.UNKNOWN;
|
||||||
@@ -111,8 +115,16 @@ class ContactManagerImpl implements ContactManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PendingContact> getPendingContacts() throws DbException {
|
public Collection<Pair<PendingContact, PendingContactState>> getPendingContacts()
|
||||||
return db.transactionWithResult(true, db::getPendingContacts);
|
throws DbException {
|
||||||
|
Collection<PendingContact> pendingContacts =
|
||||||
|
db.transactionWithResult(true, db::getPendingContacts);
|
||||||
|
List<Pair<PendingContact, PendingContactState>> pairs =
|
||||||
|
new ArrayList<>(pendingContacts.size());
|
||||||
|
for (PendingContact p : pendingContacts) {
|
||||||
|
pairs.add(new Pair<>(p, WAITING_FOR_CONNECTION)); // TODO
|
||||||
|
}
|
||||||
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT
|
|||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
|
||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX;
|
||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
|
||||||
|
|
||||||
class PendingContactFactoryImpl implements PendingContactFactory {
|
class PendingContactFactoryImpl implements PendingContactFactory {
|
||||||
|
|
||||||
@@ -39,8 +38,7 @@ class PendingContactFactoryImpl implements PendingContactFactory {
|
|||||||
PublicKey publicKey = parseHandshakeLink(link);
|
PublicKey publicKey = parseHandshakeLink(link);
|
||||||
PendingContactId id = getPendingContactId(publicKey);
|
PendingContactId id = getPendingContactId(publicKey);
|
||||||
long timestamp = clock.currentTimeMillis();
|
long timestamp = clock.currentTimeMillis();
|
||||||
return new PendingContact(id, publicKey, alias, WAITING_FOR_CONNECTION,
|
return new PendingContact(id, publicKey, alias, timestamp);
|
||||||
timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PublicKey parseHandshakeLink(String link) throws FormatException {
|
private PublicKey parseHandshakeLink(String link) throws FormatException {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
|||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
|
||||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
@@ -674,12 +673,6 @@ interface Database<T> {
|
|||||||
void setMessageState(T txn, MessageId m, MessageState state)
|
void setMessageState(T txn, MessageId m, MessageState state)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the state of the given pending contact.
|
|
||||||
*/
|
|
||||||
void setPendingContactState(T txn, PendingContactId p,
|
|
||||||
PendingContactState state) throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the reordering window for the given transport keys in the given
|
* Sets the reordering window for the given transport keys in the given
|
||||||
* time period.
|
* time period.
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import org.briarproject.bramble.api.contact.PendingContactId;
|
|||||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent;
|
import org.briarproject.bramble.api.contact.event.ContactVerifiedEvent;
|
||||||
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
|
||||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||||
import org.briarproject.bramble.api.crypto.PublicKey;
|
import org.briarproject.bramble.api.crypto.PublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
@@ -295,8 +295,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
if (db.containsPendingContact(txn, p.getId()))
|
if (db.containsPendingContact(txn, p.getId()))
|
||||||
throw new PendingContactExistsException();
|
throw new PendingContactExistsException();
|
||||||
db.addPendingContact(txn, p);
|
db.addPendingContact(txn, p);
|
||||||
transaction.attach(new PendingContactStateChangedEvent(p.getId(),
|
transaction.attach(new PendingContactAddedEvent(p));
|
||||||
p.getState()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
|||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState;
|
|
||||||
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
import org.briarproject.bramble.api.crypto.AgreementPrivateKey;
|
||||||
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
import org.briarproject.bramble.api.crypto.AgreementPublicKey;
|
||||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
import org.briarproject.bramble.api.crypto.PrivateKey;
|
||||||
@@ -98,7 +97,7 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
abstract class JdbcDatabase implements Database<Connection> {
|
abstract class JdbcDatabase implements Database<Connection> {
|
||||||
|
|
||||||
// Package access for testing
|
// Package access for testing
|
||||||
static final int CODE_SCHEMA_VERSION = 44;
|
static final int CODE_SCHEMA_VERSION = 45;
|
||||||
|
|
||||||
// Time period offsets for incoming transport keys
|
// Time period offsets for incoming transport keys
|
||||||
private static final int OFFSET_PREV = -1;
|
private static final int OFFSET_PREV = -1;
|
||||||
@@ -264,7 +263,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " (pendingContactId _HASH NOT NULL,"
|
+ " (pendingContactId _HASH NOT NULL,"
|
||||||
+ " publicKey _BINARY NOT NULL,"
|
+ " publicKey _BINARY NOT NULL,"
|
||||||
+ " alias _STRING NOT NULL,"
|
+ " alias _STRING NOT NULL,"
|
||||||
+ " state INT NOT NULL,"
|
|
||||||
+ " timestamp BIGINT NOT NULL,"
|
+ " timestamp BIGINT NOT NULL,"
|
||||||
+ " PRIMARY KEY (pendingContactId))";
|
+ " PRIMARY KEY (pendingContactId))";
|
||||||
|
|
||||||
@@ -457,7 +455,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
new Migration40_41(dbTypes),
|
new Migration40_41(dbTypes),
|
||||||
new Migration41_42(dbTypes),
|
new Migration41_42(dbTypes),
|
||||||
new Migration42_43(dbTypes),
|
new Migration42_43(dbTypes),
|
||||||
new Migration43_44(dbTypes)
|
new Migration43_44(dbTypes),
|
||||||
|
new Migration44_45()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,14 +932,13 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
String sql = "INSERT INTO pendingContacts (pendingContactId,"
|
String sql = "INSERT INTO pendingContacts (pendingContactId,"
|
||||||
+ " publicKey, alias, state, timestamp)"
|
+ " publicKey, alias, timestamp)"
|
||||||
+ " VALUES (?, ?, ?, ?, ?)";
|
+ " VALUES (?, ?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, p.getId().getBytes());
|
ps.setBytes(1, p.getId().getBytes());
|
||||||
ps.setBytes(2, p.getPublicKey().getEncoded());
|
ps.setBytes(2, p.getPublicKey().getEncoded());
|
||||||
ps.setString(3, p.getAlias());
|
ps.setString(3, p.getAlias());
|
||||||
ps.setInt(4, p.getState().getValue());
|
ps.setLong(4, p.getTimestamp());
|
||||||
ps.setLong(5, p.getTimestamp());
|
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -2213,8 +2211,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
Statement s = null;
|
Statement s = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT pendingContactId, publicKey, alias, state,"
|
String sql = "SELECT pendingContactId, publicKey, alias, timestamp"
|
||||||
+ " timestamp"
|
|
||||||
+ " FROM pendingContacts";
|
+ " FROM pendingContacts";
|
||||||
s = txn.createStatement();
|
s = txn.createStatement();
|
||||||
rs = s.executeQuery(sql);
|
rs = s.executeQuery(sql);
|
||||||
@@ -2223,11 +2220,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PendingContactId id = new PendingContactId(rs.getBytes(1));
|
PendingContactId id = new PendingContactId(rs.getBytes(1));
|
||||||
PublicKey publicKey = new AgreementPublicKey(rs.getBytes(2));
|
PublicKey publicKey = new AgreementPublicKey(rs.getBytes(2));
|
||||||
String alias = rs.getString(3);
|
String alias = rs.getString(3);
|
||||||
PendingContactState state =
|
long timestamp = rs.getLong(4);
|
||||||
PendingContactState.fromValue(rs.getInt(4));
|
|
||||||
long timestamp = rs.getLong(5);
|
|
||||||
pendingContacts.add(new PendingContact(id, publicKey, alias,
|
pendingContacts.add(new PendingContact(id, publicKey, alias,
|
||||||
state, timestamp));
|
timestamp));
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
s.close();
|
s.close();
|
||||||
@@ -3077,25 +3072,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPendingContactState(Connection txn, PendingContactId p,
|
|
||||||
PendingContactState state) throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
try {
|
|
||||||
String sql = "UPDATE pendingContacts SET state = ?"
|
|
||||||
+ " WHERE pendingContactId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setInt(1, state.getValue());
|
|
||||||
ps.setBytes(2, p.getBytes());
|
|
||||||
int affected = ps.executeUpdate();
|
|
||||||
if (affected < 0 || affected > 1) throw new DbStateException();
|
|
||||||
ps.close();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
tryToClose(ps, LOG, WARNING);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setReorderingWindow(Connection txn, KeySetId k,
|
public void setReorderingWindow(Connection txn, KeySetId k,
|
||||||
TransportId t, long timePeriod, long base, byte[] bitmap)
|
TransportId t, long timePeriod, long base, byte[] bitmap)
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package org.briarproject.bramble.db;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.db.JdbcUtils.tryToClose;
|
||||||
|
|
||||||
|
class Migration44_45 implements Migration<Connection> {
|
||||||
|
|
||||||
|
private static final Logger LOG = getLogger(Migration44_45.class.getName());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStartVersion() {
|
||||||
|
return 44;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEndVersion() {
|
||||||
|
return 45;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void migrate(Connection txn) throws DbException {
|
||||||
|
Statement s = null;
|
||||||
|
try {
|
||||||
|
s = txn.createStatement();
|
||||||
|
s.execute("ALTER TABLE pendingContacts DROP COLUMN state");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(s, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.BASE32
|
|||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT_VERSION;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.FORMAT_VERSION;
|
||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.ID_LABEL;
|
||||||
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
|
import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.RAW_LINK_BYTES;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
import static org.briarproject.bramble.test.TestUtils.getAgreementPublicKey;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
@@ -108,7 +107,6 @@ public class PendingContactFactoryImplTest extends BrambleMockTestCase {
|
|||||||
assertArrayEquals(publicKey.getEncoded(),
|
assertArrayEquals(publicKey.getEncoded(),
|
||||||
p.getPublicKey().getEncoded());
|
p.getPublicKey().getEncoded());
|
||||||
assertEquals(alias, p.getAlias());
|
assertEquals(alias, p.getAlias());
|
||||||
assertEquals(WAITING_FOR_CONNECTION, p.getState());
|
|
||||||
assertEquals(timestamp, p.getTimestamp());
|
assertEquals(timestamp, p.getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ import static java.util.Collections.emptyMap;
|
|||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
|
||||||
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
|
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||||
@@ -2211,16 +2210,6 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
PendingContact retrieved = pendingContacts.iterator().next();
|
PendingContact retrieved = pendingContacts.iterator().next();
|
||||||
assertEquals(pendingContact.getId(), retrieved.getId());
|
assertEquals(pendingContact.getId(), retrieved.getId());
|
||||||
assertEquals(pendingContact.getAlias(), retrieved.getAlias());
|
assertEquals(pendingContact.getAlias(), retrieved.getAlias());
|
||||||
assertEquals(pendingContact.getState(), retrieved.getState());
|
|
||||||
assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp());
|
|
||||||
|
|
||||||
db.setPendingContactState(txn, pendingContact.getId(), FAILED);
|
|
||||||
pendingContacts = db.getPendingContacts(txn);
|
|
||||||
assertEquals(1, pendingContacts.size());
|
|
||||||
retrieved = pendingContacts.iterator().next();
|
|
||||||
assertEquals(pendingContact.getId(), retrieved.getId());
|
|
||||||
assertEquals(pendingContact.getAlias(), retrieved.getAlias());
|
|
||||||
assertEquals(FAILED, retrieved.getState());
|
|
||||||
assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp());
|
assertEquals(pendingContact.getTimestamp(), retrieved.getTimestamp());
|
||||||
|
|
||||||
db.removePendingContact(txn, pendingContact.getId());
|
db.removePendingContact(txn, pendingContact.getId());
|
||||||
@@ -2232,8 +2221,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetHandshakeKeyPair() throws Exception {
|
public void testSetHandshakeKeyPair() throws Exception {
|
||||||
Identity withoutKeys =
|
Identity withoutKeys = new Identity(localAuthor, null, null,
|
||||||
new Identity(localAuthor, null, null, identity.getTimeCreated());
|
identity.getTimeCreated());
|
||||||
assertFalse(withoutKeys.hasHandshakeKeyPair());
|
assertFalse(withoutKeys.hasHandshakeKeyPair());
|
||||||
PublicKey publicKey = getAgreementPublicKey();
|
PublicKey publicKey = getAgreementPublicKey();
|
||||||
PrivateKey privateKey = getAgreementPrivateKey();
|
PrivateKey privateKey = getAgreementPrivateKey();
|
||||||
|
|||||||
@@ -18,10 +18,9 @@ import org.briarproject.bramble.api.contact.Contact;
|
|||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
|
|
||||||
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
|
||||||
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
@@ -65,7 +64,6 @@ import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAn
|
|||||||
import static android.support.v4.view.ViewCompat.getTransitionName;
|
import static android.support.v4.view.ViewCompat.getTransitionName;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
@@ -293,15 +291,8 @@ public class ContactListFragment extends BaseFragment implements EventListener,
|
|||||||
(ConversationMessageReceivedEvent) e;
|
(ConversationMessageReceivedEvent) e;
|
||||||
ConversationMessageHeader h = p.getMessageHeader();
|
ConversationMessageHeader h = p.getMessageHeader();
|
||||||
updateItem(p.getContactId(), h);
|
updateItem(p.getContactId(), h);
|
||||||
} else if (e instanceof PendingContactStateChangedEvent) {
|
} else if (e instanceof PendingContactAddedEvent ||
|
||||||
PendingContactStateChangedEvent pe =
|
e instanceof PendingContactRemovedEvent) {
|
||||||
(PendingContactStateChangedEvent) e;
|
|
||||||
// only re-check pending contacts for initial state
|
|
||||||
if (pe.getPendingContactState() == WAITING_FOR_CONNECTION) {
|
|
||||||
checkForPendingContacts();
|
|
||||||
}
|
|
||||||
} else if (e instanceof PendingContactRemovedEvent ||
|
|
||||||
e instanceof ContactAddedRemotelyEvent) {
|
|
||||||
checkForPendingContacts();
|
checkForPendingContacts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import android.app.Application;
|
|||||||
import android.arch.lifecycle.AndroidViewModel;
|
import android.arch.lifecycle.AndroidViewModel;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.MutableLiveData;
|
import android.arch.lifecycle.MutableLiveData;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
@@ -45,7 +44,7 @@ public class AddContactViewModel extends AndroidViewModel {
|
|||||||
private String remoteHandshakeLink;
|
private String remoteHandshakeLink;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AddContactViewModel(@NonNull Application application,
|
AddContactViewModel(Application application,
|
||||||
ContactManager contactManager,
|
ContactManager contactManager,
|
||||||
@DatabaseExecutor Executor dbExecutor) {
|
@DatabaseExecutor Executor dbExecutor) {
|
||||||
super(application);
|
super(application);
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.briarproject.briar.android.contact.add.remote;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
class PendingContactItem {
|
||||||
|
|
||||||
|
private final PendingContact pendingContact;
|
||||||
|
private final PendingContactState state;
|
||||||
|
|
||||||
|
PendingContactItem(PendingContact pendingContact,
|
||||||
|
PendingContactState state) {
|
||||||
|
this.pendingContact = pendingContact;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingContact getPendingContact() {
|
||||||
|
return pendingContact;
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingContactState getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,8 @@ public class PendingContactListActivity extends BriarActivity
|
|||||||
viewModel.getPendingContacts()
|
viewModel.getPendingContacts()
|
||||||
.observe(this, this::onPendingContactsChanged);
|
.observe(this, this::onPendingContactsChanged);
|
||||||
|
|
||||||
adapter = new PendingContactListAdapter(this, this, PendingContact.class);
|
adapter = new PendingContactListAdapter(this, this,
|
||||||
|
PendingContactItem.class);
|
||||||
list = findViewById(R.id.list);
|
list = findViewById(R.id.list);
|
||||||
list.setEmptyText(R.string.no_pending_contacts);
|
list.setEmptyText(R.string.no_pending_contacts);
|
||||||
list.setLayoutManager(new LinearLayoutManager(this));
|
list.setLayoutManager(new LinearLayoutManager(this));
|
||||||
@@ -75,13 +76,11 @@ public class PendingContactListActivity extends BriarActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
case android.R.id.home:
|
onBackPressed();
|
||||||
onBackPressed();
|
return true;
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -89,8 +88,9 @@ public class PendingContactListActivity extends BriarActivity
|
|||||||
viewModel.removePendingContact(pendingContact.getId());
|
viewModel.removePendingContact(pendingContact.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onPendingContactsChanged(Collection<PendingContact> contacts) {
|
private void onPendingContactsChanged(
|
||||||
if (contacts.isEmpty()) {
|
Collection<PendingContactItem> items) {
|
||||||
|
if (items.isEmpty()) {
|
||||||
if (adapter.isEmpty()) {
|
if (adapter.isEmpty()) {
|
||||||
list.showData(); // hides progress bar, shows empty text
|
list.showData(); // hides progress bar, shows empty text
|
||||||
} else {
|
} else {
|
||||||
@@ -98,7 +98,7 @@ public class PendingContactListActivity extends BriarActivity
|
|||||||
supportFinishAfterTransition();
|
supportFinishAfterTransition();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
adapter.setItems(contacts);
|
adapter.setItems(items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import org.briarproject.briar.android.util.BriarAdapter;
|
|||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class PendingContactListAdapter extends
|
class PendingContactListAdapter extends
|
||||||
BriarAdapter<PendingContact, PendingContactViewHolder> {
|
BriarAdapter<PendingContactItem, PendingContactViewHolder> {
|
||||||
|
|
||||||
private final PendingContactListener listener;
|
private final PendingContactListener listener;
|
||||||
|
|
||||||
PendingContactListAdapter(Context ctx, PendingContactListener listener,
|
PendingContactListAdapter(Context ctx, PendingContactListener listener,
|
||||||
Class<PendingContact> c) {
|
Class<PendingContactItem> c) {
|
||||||
super(ctx, c);
|
super(ctx, c);
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
@@ -37,23 +37,29 @@ class PendingContactListAdapter extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(PendingContact item1, PendingContact item2) {
|
public int compare(PendingContactItem item1, PendingContactItem item2) {
|
||||||
return (int) (item1.getTimestamp() - item2.getTimestamp());
|
long timestamp1 = item1.getPendingContact().getTimestamp();
|
||||||
|
long timestamp2 = item2.getPendingContact().getTimestamp();
|
||||||
|
return Long.compare(timestamp1, timestamp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areContentsTheSame(PendingContact item1,
|
public boolean areContentsTheSame(PendingContactItem item1,
|
||||||
PendingContact item2) {
|
PendingContactItem item2) {
|
||||||
return item1.getId().equals(item2.getId()) &&
|
PendingContact p1 = item1.getPendingContact();
|
||||||
item1.getAlias().equals(item2.getAlias()) &&
|
PendingContact p2 = item2.getPendingContact();
|
||||||
item1.getTimestamp() == item2.getTimestamp() &&
|
return p1.getId().equals(p2.getId()) &&
|
||||||
|
p1.getAlias().equals(p2.getAlias()) &&
|
||||||
|
p1.getTimestamp() == p2.getTimestamp() &&
|
||||||
item1.getState() == item2.getState();
|
item1.getState() == item2.getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean areItemsTheSame(PendingContact item1,
|
public boolean areItemsTheSame(PendingContactItem item1,
|
||||||
PendingContact item2) {
|
PendingContactItem item2) {
|
||||||
return item1.getId().equals(item2.getId());
|
PendingContact p1 = item1.getPendingContact();
|
||||||
|
PendingContact p2 = item2.getPendingContact();
|
||||||
|
return p1.getId().equals(p2.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import android.arch.lifecycle.AndroidViewModel;
|
|||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.MutableLiveData;
|
import android.arch.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.Pair;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
import org.briarproject.bramble.api.contact.ContactManager;
|
||||||
import org.briarproject.bramble.api.contact.PendingContact;
|
import org.briarproject.bramble.api.contact.PendingContact;
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
|
import org.briarproject.bramble.api.contact.PendingContactState;
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent;
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
@@ -18,7 +19,9 @@ import org.briarproject.bramble.api.event.EventBus;
|
|||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -40,11 +43,11 @@ public class PendingContactListViewModel extends AndroidViewModel
|
|||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
|
||||||
private final MutableLiveData<Collection<PendingContact>> pendingContacts =
|
private final MutableLiveData<Collection<PendingContactItem>>
|
||||||
new MutableLiveData<>();
|
pendingContacts = new MutableLiveData<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PendingContactListViewModel(Application application,
|
PendingContactListViewModel(Application application,
|
||||||
@DatabaseExecutor Executor dbExecutor,
|
@DatabaseExecutor Executor dbExecutor,
|
||||||
ContactManager contactManager, EventBus eventBus) {
|
ContactManager contactManager, EventBus eventBus) {
|
||||||
super(application);
|
super(application);
|
||||||
@@ -63,8 +66,7 @@ public class PendingContactListViewModel extends AndroidViewModel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof ContactAddedRemotelyEvent ||
|
if (e instanceof PendingContactStateChangedEvent ||
|
||||||
e instanceof PendingContactStateChangedEvent ||
|
|
||||||
e instanceof PendingContactRemovedEvent) {
|
e instanceof PendingContactRemovedEvent) {
|
||||||
loadPendingContacts();
|
loadPendingContacts();
|
||||||
}
|
}
|
||||||
@@ -73,14 +75,21 @@ public class PendingContactListViewModel extends AndroidViewModel
|
|||||||
private void loadPendingContacts() {
|
private void loadPendingContacts() {
|
||||||
dbExecutor.execute(() -> {
|
dbExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
pendingContacts.postValue(contactManager.getPendingContacts());
|
Collection<Pair<PendingContact, PendingContactState>> pairs =
|
||||||
|
contactManager.getPendingContacts();
|
||||||
|
List<PendingContactItem> items = new ArrayList<>(pairs.size());
|
||||||
|
for (Pair<PendingContact, PendingContactState> p : pairs) {
|
||||||
|
items.add(new PendingContactItem(p.getFirst(),
|
||||||
|
p.getSecond()));
|
||||||
|
}
|
||||||
|
pendingContacts.setValue(items);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveData<Collection<PendingContact>> getPendingContacts() {
|
LiveData<Collection<PendingContactItem>> getPendingContacts() {
|
||||||
return pendingContacts;
|
return pendingContacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,13 +35,14 @@ class PendingContactViewHolder extends ViewHolder {
|
|||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(PendingContact item) {
|
public void bind(PendingContactItem item) {
|
||||||
avatar.setText(item.getAlias());
|
PendingContact p = item.getPendingContact();
|
||||||
avatar.setBackgroundBytes(item.getId().getBytes());
|
avatar.setText(p.getAlias());
|
||||||
name.setText(item.getAlias());
|
avatar.setBackgroundBytes(p.getId().getBytes());
|
||||||
time.setText(formatDate(time.getContext(), item.getTimestamp()));
|
name.setText(p.getAlias());
|
||||||
|
time.setText(formatDate(time.getContext(), p.getTimestamp()));
|
||||||
removeButton.setOnClickListener(v -> {
|
removeButton.setOnClickListener(v -> {
|
||||||
listener.onFailedPendingContactRemoved(item);
|
listener.onFailedPendingContactRemoved(p);
|
||||||
removeButton.setEnabled(false);
|
removeButton.setEnabled(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -107,11 +107,27 @@ Until it is completed, a pending contact is returned as JSON:
|
|||||||
{
|
{
|
||||||
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||||
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
||||||
"state": "adding_contact",
|
|
||||||
"timestamp": 1557838312175
|
"timestamp": 1557838312175
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It is possible to get a list of all pending contacts:
|
||||||
|
|
||||||
|
`GET /v1/contacts/add/pending`
|
||||||
|
|
||||||
|
This will return a JSON array of pending contacts and their states:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"pendingContact": {
|
||||||
|
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||||
|
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
||||||
|
"timestamp": 1557838312175
|
||||||
|
},
|
||||||
|
"state": "adding_contact"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
The state can be one of these values:
|
The state can be one of these values:
|
||||||
|
|
||||||
* `waiting_for_connection`
|
* `waiting_for_connection`
|
||||||
@@ -119,21 +135,16 @@ The state can be one of these values:
|
|||||||
* `adding_contact`
|
* `adding_contact`
|
||||||
* `failed`
|
* `failed`
|
||||||
|
|
||||||
If you want to get informed about state changes,
|
If you want to be informed about state changes,
|
||||||
you can use the Websocket API (below) to listen for events.
|
you can use the Websocket API (below) to listen for events.
|
||||||
|
|
||||||
The following events are relevant here:
|
The following events are relevant here:
|
||||||
|
|
||||||
|
* `PendingContactAddedEvent`
|
||||||
* `PendingContactStateChangedEvent`
|
* `PendingContactStateChangedEvent`
|
||||||
* `PendingContactRemovedEvent`
|
* `PendingContactRemovedEvent`
|
||||||
* `ContactAddedRemotelyEvent` (when the pending contact becomes an actual contact)
|
* `ContactAddedRemotelyEvent` (when the pending contact becomes an actual contact)
|
||||||
|
|
||||||
It is possible to get a list of all pending contacts:
|
|
||||||
|
|
||||||
`GET /v1/contacts/add/pending`
|
|
||||||
|
|
||||||
This will return a JSON array of pending contacts formatted as shown above.
|
|
||||||
|
|
||||||
To remove a pending contact and abort the process of adding it:
|
To remove a pending contact and abort the process of adding it:
|
||||||
|
|
||||||
`DELETE /v1/contacts/add/pending`
|
`DELETE /v1/contacts/add/pending`
|
||||||
@@ -302,6 +313,22 @@ it will send a JSON object representing the new contact to connected websocket c
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### A pending contact was added
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"pendingContact": {
|
||||||
|
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
|
||||||
|
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
|
||||||
|
"timestamp": 1557838312175
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "PendingContactAddedEvent",
|
||||||
|
"type": "event"
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
### A pending contact changed its state
|
### A pending contact changed its state
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.contact.ContactManager
|
|||||||
import org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX
|
import org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId
|
import org.briarproject.bramble.api.contact.PendingContactId
|
||||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
|
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
|
||||||
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||||
@@ -28,6 +29,7 @@ import javax.inject.Singleton
|
|||||||
|
|
||||||
internal const val EVENT_CONTACT_ADDED_REMOTELY = "ContactAddedRemotelyEvent"
|
internal const val EVENT_CONTACT_ADDED_REMOTELY = "ContactAddedRemotelyEvent"
|
||||||
internal const val EVENT_PENDING_CONTACT_STATE_CHANGED = "PendingContactStateChangedEvent"
|
internal const val EVENT_PENDING_CONTACT_STATE_CHANGED = "PendingContactStateChangedEvent"
|
||||||
|
internal const val EVENT_PENDING_CONTACT_ADDED = "PendingContactAddedEvent"
|
||||||
internal const val EVENT_PENDING_CONTACT_REMOVED = "PendingContactRemovedEvent"
|
internal const val EVENT_PENDING_CONTACT_REMOVED = "PendingContactRemovedEvent"
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -47,6 +49,9 @@ constructor(
|
|||||||
is PendingContactStateChangedEvent -> {
|
is PendingContactStateChangedEvent -> {
|
||||||
webSocket.sendEvent(EVENT_PENDING_CONTACT_STATE_CHANGED, e.output())
|
webSocket.sendEvent(EVENT_PENDING_CONTACT_STATE_CHANGED, e.output())
|
||||||
}
|
}
|
||||||
|
is PendingContactAddedEvent -> {
|
||||||
|
webSocket.sendEvent(EVENT_PENDING_CONTACT_ADDED, e.output())
|
||||||
|
}
|
||||||
is PendingContactRemovedEvent -> {
|
is PendingContactRemovedEvent -> {
|
||||||
webSocket.sendEvent(EVENT_PENDING_CONTACT_REMOVED, e.output())
|
webSocket.sendEvent(EVENT_PENDING_CONTACT_REMOVED, e.output())
|
||||||
}
|
}
|
||||||
@@ -78,8 +83,8 @@ constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun listPendingContacts(ctx: Context): Context {
|
override fun listPendingContacts(ctx: Context): Context {
|
||||||
val pendingContacts = contactManager.pendingContacts.map { pendingContact ->
|
val pendingContacts = contactManager.pendingContacts.map { pair ->
|
||||||
pendingContact.output()
|
JsonDict("pendingContact" to pair.first.output(), "state" to pair.second.output())
|
||||||
}
|
}
|
||||||
return ctx.json(pendingContacts)
|
return ctx.json(pendingContacts)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.briar.headless.contact
|
|||||||
import org.briarproject.bramble.api.contact.PendingContact
|
import org.briarproject.bramble.api.contact.PendingContact
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState
|
import org.briarproject.bramble.api.contact.PendingContactState
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState.*
|
import org.briarproject.bramble.api.contact.PendingContactState.*
|
||||||
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||||
import org.briarproject.briar.headless.json.JsonDict
|
import org.briarproject.briar.headless.json.JsonDict
|
||||||
@@ -10,7 +11,6 @@ import org.briarproject.briar.headless.json.JsonDict
|
|||||||
internal fun PendingContact.output() = JsonDict(
|
internal fun PendingContact.output() = JsonDict(
|
||||||
"pendingContactId" to id.bytes,
|
"pendingContactId" to id.bytes,
|
||||||
"alias" to alias,
|
"alias" to alias,
|
||||||
"state" to state.output(),
|
|
||||||
"timestamp" to timestamp
|
"timestamp" to timestamp
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,6 +22,10 @@ internal fun PendingContactState.output() = when(this) {
|
|||||||
else -> throw AssertionError()
|
else -> throw AssertionError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun PendingContactAddedEvent.output() = JsonDict(
|
||||||
|
"pendingContact" to pendingContact.output()
|
||||||
|
)
|
||||||
|
|
||||||
internal fun PendingContactStateChangedEvent.output() = JsonDict(
|
internal fun PendingContactStateChangedEvent.output() = JsonDict(
|
||||||
"pendingContactId" to id.bytes,
|
"pendingContactId" to id.bytes,
|
||||||
"state" to pendingContactState.output()
|
"state" to pendingContactState.output()
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test
|
|||||||
class ContactControllerIntegrationTest: IntegrationTest() {
|
class ContactControllerIntegrationTest: IntegrationTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `list of contacts need authentication token`() {
|
fun `returning list of contacts needs authentication token`() {
|
||||||
val response = getWithWrongToken("$url/contacts")
|
val response = getWithWrongToken("$url/contacts")
|
||||||
assertEquals(401, response.statusCode)
|
assertEquals(401, response.statusCode)
|
||||||
}
|
}
|
||||||
@@ -72,11 +72,10 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
|||||||
assertEquals(200, response.statusCode)
|
assertEquals(200, response.statusCode)
|
||||||
assertEquals(1, response.jsonArray.length())
|
assertEquals(1, response.jsonArray.length())
|
||||||
val jsonObject = response.jsonArray.getJSONObject(0)
|
val jsonObject = response.jsonArray.getJSONObject(0)
|
||||||
assertEquals(alias, jsonObject.getString("alias"))
|
assertEquals(alias, jsonObject.getJSONObject("pendingContact").getString("alias"))
|
||||||
assertEquals("waiting_for_connection", jsonObject.getString("state"))
|
|
||||||
|
|
||||||
// remove pending contact again
|
// remove pending contact again
|
||||||
val idString = jsonObject.getString("pendingContactId")
|
val idString = jsonObject.getJSONObject("pendingContact").getString("pendingContactId")
|
||||||
val deleteJson = """{"pendingContactId": "$idString"}"""
|
val deleteJson = """{"pendingContactId": "$idString"}"""
|
||||||
response = delete("$url/contacts/add/pending", deleteJson)
|
response = delete("$url/contacts/add/pending", deleteJson)
|
||||||
assertEquals(200, response.statusCode)
|
assertEquals(200, response.statusCode)
|
||||||
@@ -94,7 +93,7 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `adding pending contacts needs authentication token`() {
|
fun `adding a pending contact needs authentication token`() {
|
||||||
val response = postWithWrongToken("$url/contacts/add/pending")
|
val response = postWithWrongToken("$url/contacts/add/pending")
|
||||||
assertEquals(401, response.statusCode)
|
assertEquals(401, response.statusCode)
|
||||||
}
|
}
|
||||||
@@ -106,7 +105,7 @@ class ContactControllerIntegrationTest: IntegrationTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `deleting contact need authentication token`() {
|
fun `deleting a contact needs authentication token`() {
|
||||||
val response = deleteWithWrongToken("$url/contacts/1")
|
val response = deleteWithWrongToken("$url/contacts/1")
|
||||||
assertEquals(401, response.statusCode)
|
assertEquals(401, response.statusCode)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ import io.mockk.Runs
|
|||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
import io.mockk.runs
|
import io.mockk.runs
|
||||||
|
import org.briarproject.bramble.api.Pair
|
||||||
import org.briarproject.bramble.api.contact.Contact
|
import org.briarproject.bramble.api.contact.Contact
|
||||||
import org.briarproject.bramble.api.contact.ContactId
|
import org.briarproject.bramble.api.contact.ContactId
|
||||||
import org.briarproject.bramble.api.contact.PendingContactId
|
import org.briarproject.bramble.api.contact.PendingContactId
|
||||||
import org.briarproject.bramble.api.contact.PendingContactState.FAILED
|
import org.briarproject.bramble.api.contact.PendingContactState.FAILED
|
||||||
|
import org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION
|
||||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
|
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
|
||||||
|
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
|
||||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException
|
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||||
@@ -124,8 +127,14 @@ internal class ContactControllerTest : ControllerTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testListPendingContacts() {
|
fun testListPendingContacts() {
|
||||||
every { contactManager.pendingContacts } returns listOf(pendingContact)
|
every { contactManager.pendingContacts } returns listOf(
|
||||||
every { ctx.json(listOf(pendingContact.output())) } returns ctx
|
Pair(pendingContact, WAITING_FOR_CONNECTION)
|
||||||
|
)
|
||||||
|
val dict = JsonDict(
|
||||||
|
"pendingContact" to pendingContact.output(),
|
||||||
|
"state" to WAITING_FOR_CONNECTION.output()
|
||||||
|
)
|
||||||
|
every { ctx.json(listOf(dict)) } returns ctx
|
||||||
controller.listPendingContacts(ctx)
|
controller.listPendingContacts(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +234,20 @@ internal class ContactControllerTest : ControllerTest() {
|
|||||||
controller.eventOccurred(event)
|
controller.eventOccurred(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testPendingContactAddedEvent() {
|
||||||
|
val event = PendingContactAddedEvent(pendingContact)
|
||||||
|
|
||||||
|
every {
|
||||||
|
webSocketController.sendEvent(
|
||||||
|
EVENT_PENDING_CONTACT_ADDED,
|
||||||
|
event.output()
|
||||||
|
)
|
||||||
|
} just runs
|
||||||
|
|
||||||
|
controller.eventOccurred(event)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPendingContactRemovedEvent() {
|
fun testPendingContactRemovedEvent() {
|
||||||
val event = PendingContactRemovedEvent(pendingContact.id)
|
val event = PendingContactRemovedEvent(pendingContact.id)
|
||||||
@@ -284,13 +307,27 @@ internal class ContactControllerTest : ControllerTest() {
|
|||||||
{
|
{
|
||||||
"pendingContactId": ${toJson(pendingContact.id.bytes)},
|
"pendingContactId": ${toJson(pendingContact.id.bytes)},
|
||||||
"alias": "${pendingContact.alias}",
|
"alias": "${pendingContact.alias}",
|
||||||
"state": "${pendingContact.state.name.toLowerCase()}",
|
|
||||||
"timestamp": ${pendingContact.timestamp}
|
"timestamp": ${pendingContact.timestamp}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
assertJsonEquals(json, pendingContact.output())
|
assertJsonEquals(json, pendingContact.output())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testOutputPendingContactAddedEvent() {
|
||||||
|
val event = PendingContactAddedEvent(pendingContact)
|
||||||
|
val json = """
|
||||||
|
{
|
||||||
|
"pendingContact": {
|
||||||
|
"pendingContactId": ${toJson(pendingContact.id.bytes)},
|
||||||
|
"alias": "${pendingContact.alias}",
|
||||||
|
"timestamp": ${pendingContact.timestamp}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
assertJsonEquals(json, event.output())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testOutputPendingContactStateChangedEvent() {
|
fun testOutputPendingContactStateChangedEvent() {
|
||||||
val event = PendingContactStateChangedEvent(pendingContact.id, FAILED)
|
val event = PendingContactStateChangedEvent(pendingContact.id, FAILED)
|
||||||
|
|||||||
Reference in New Issue
Block a user