mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-21 07:09:56 +01:00
Merge branch '1538-create-handshake-key-pair' into 'master'
Generate and store handshake key pair at startup if necessary Closes #1538 See merge request briar/briar!1082
This commit is contained in:
@@ -33,7 +33,8 @@ public abstract class BdfIncomingMessageHook implements IncomingMessageHook {
|
|||||||
/**
|
/**
|
||||||
* Called once for each incoming message that passes validation.
|
* Called once for each incoming message that passes validation.
|
||||||
*
|
*
|
||||||
* @return whether or not this message should be shared
|
* @param txn A read-write transaction
|
||||||
|
* @return Whether or not this message should be shared
|
||||||
* @throws DbException Should only be used for real database errors.
|
* @throws DbException Should only be used for real database errors.
|
||||||
* If this is thrown, delivery will be attempted again at next startup,
|
* If this is thrown, delivery will be attempted again at next startup,
|
||||||
* whereas if a FormatException is thrown, the message will be permanently
|
* whereas if a FormatException is thrown, the message will be permanently
|
||||||
|
|||||||
@@ -159,8 +159,20 @@ public interface ContactManager {
|
|||||||
|
|
||||||
interface ContactHook {
|
interface ContactHook {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a contact is being added.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param c The contact that is being added
|
||||||
|
*/
|
||||||
void addingContact(Transaction txn, Contact c) throws DbException;
|
void addingContact(Transaction txn, Contact c) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a contact is being removed
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param c The contact that is being removed
|
||||||
|
*/
|
||||||
void removingContact(Transaction txn, Contact c) throws DbException;
|
void removingContact(Transaction txn, Contact c) throws DbException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import org.briarproject.bramble.api.contact.PendingContactId;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
@@ -128,9 +128,9 @@ public interface DatabaseComponent {
|
|||||||
HandshakeKeys k) throws DbException;
|
HandshakeKeys k) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a local pseudonym.
|
* Stores an identity.
|
||||||
*/
|
*/
|
||||||
void addLocalAuthor(Transaction txn, LocalAuthor a) throws DbException;
|
void addIdentity(Transaction txn, Identity i) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a local message.
|
* Stores a local message.
|
||||||
@@ -174,12 +174,12 @@ public interface DatabaseComponent {
|
|||||||
boolean containsGroup(Transaction txn, GroupId g) throws DbException;
|
boolean containsGroup(Transaction txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the database contains the given local author.
|
* Returns true if the database contains an identity for the given
|
||||||
|
* pseudonym.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
boolean containsLocalAuthor(Transaction txn, AuthorId local)
|
boolean containsIdentity(Transaction txn, AuthorId a) throws DbException;
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the database contains the given pending contact.
|
* Returns true if the database contains the given pending contact.
|
||||||
@@ -317,18 +317,18 @@ public interface DatabaseComponent {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the local pseudonym with the given ID.
|
* Returns the identity for the local pseudonym with the given ID.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
LocalAuthor getLocalAuthor(Transaction txn, AuthorId a) throws DbException;
|
Identity getIdentity(Transaction txn, AuthorId a) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all local pseudonyms.
|
* Returns the identities for all local pseudonyms.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
Collection<LocalAuthor> getLocalAuthors(Transaction txn) throws DbException;
|
Collection<Identity> getIdentities(Transaction txn) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message with the given ID.
|
* Returns the message with the given ID.
|
||||||
@@ -559,9 +559,9 @@ public interface DatabaseComponent {
|
|||||||
HandshakeKeySetId k) throws DbException;
|
HandshakeKeySetId k) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a local pseudonym (and all associated state) from the database.
|
* Removes an identity (and all associated state) from the database.
|
||||||
*/
|
*/
|
||||||
void removeLocalAuthor(Transaction txn, AuthorId a) throws DbException;
|
void removeIdentity(Transaction txn, AuthorId a) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a message (and all associated state) from the database.
|
* Removes a message (and all associated state) from the database.
|
||||||
@@ -619,6 +619,12 @@ public interface DatabaseComponent {
|
|||||||
void addMessageDependencies(Transaction txn, Message dependent,
|
void addMessageDependencies(Transaction txn, Message dependent,
|
||||||
Collection<MessageId> dependencies) throws DbException;
|
Collection<MessageId> dependencies) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the handshake key pair for the identity with the given ID.
|
||||||
|
*/
|
||||||
|
void setHandshakeKeyPair(Transaction txn, AuthorId local, byte[] publicKey,
|
||||||
|
byte[] privateKey) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the reordering window for the given transport key set in the given
|
* Sets the reordering window for the given transport key set in the given
|
||||||
* time period.
|
* time period.
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.briarproject.bramble.api.db;
|
package org.briarproject.bramble.api.db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when a database operation is attempted for a pseudonym that is not in
|
* Thrown when a database operation is attempted for an identity that is not in
|
||||||
* the database. This exception may occur due to concurrent updates and does
|
* the database. This exception may occur due to concurrent updates and does
|
||||||
* not indicate a database error.
|
* not indicate a database error.
|
||||||
*/
|
*/
|
||||||
public class NoSuchLocalAuthorException extends DbException {
|
public class NoSuchIdentityException extends DbException {
|
||||||
}
|
}
|
||||||
@@ -18,14 +18,7 @@ public interface AuthorFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a local author with the current format version and the given
|
* Creates a local author with the current format version and the given
|
||||||
* name and keys.
|
* name.
|
||||||
*/
|
*/
|
||||||
LocalAuthor createLocalAuthor(String name, byte[] publicKey,
|
LocalAuthor createLocalAuthor(String name);
|
||||||
byte[] privateKey);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a local author with the given format version, name and keys.
|
|
||||||
*/
|
|
||||||
LocalAuthor createLocalAuthor(int formatVersion, String name,
|
|
||||||
byte[] publicKey, byte[] privateKey);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package org.briarproject.bramble.api.identity;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@NotNullByDefault
|
||||||
|
public class Identity {
|
||||||
|
|
||||||
|
private final LocalAuthor localAuthor;
|
||||||
|
@Nullable
|
||||||
|
private final byte[] handshakePublicKey, handshakePrivateKey;
|
||||||
|
private final long created;
|
||||||
|
|
||||||
|
public Identity(LocalAuthor localAuthor,
|
||||||
|
@Nullable byte[] handshakePublicKey,
|
||||||
|
@Nullable byte[] handshakePrivateKey, long created) {
|
||||||
|
if (handshakePublicKey != null) {
|
||||||
|
int keyLength = handshakePublicKey.length;
|
||||||
|
if (keyLength == 0 || keyLength > MAX_AGREEMENT_PUBLIC_KEY_BYTES)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
this.localAuthor = localAuthor;
|
||||||
|
this.handshakePublicKey = handshakePublicKey;
|
||||||
|
this.handshakePrivateKey = handshakePrivateKey;
|
||||||
|
this.created = created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID of the user's pseudonym.
|
||||||
|
*/
|
||||||
|
public AuthorId getId() {
|
||||||
|
return localAuthor.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user's pseudonym.
|
||||||
|
*/
|
||||||
|
public LocalAuthor getLocalAuthor() {
|
||||||
|
return localAuthor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the identity has a handshake key pair.
|
||||||
|
*/
|
||||||
|
public boolean hasHandshakeKeyPair() {
|
||||||
|
return handshakePublicKey != null && handshakePrivateKey != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the public key used for handshaking, or null if no key exists.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public byte[] getHandshakePublicKey() {
|
||||||
|
return handshakePublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the private key used for handshaking, or null if no key exists.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public byte[] getHandshakePrivateKey() {
|
||||||
|
return handshakePrivateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time the identity was created, in milliseconds since the
|
||||||
|
* Unix epoch.
|
||||||
|
*/
|
||||||
|
public long getTimeCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return localAuthor.getId().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o instanceof Identity) {
|
||||||
|
Identity i = (Identity) o;
|
||||||
|
return created == i.created &&
|
||||||
|
localAuthor.equals(i.localAuthor) &&
|
||||||
|
Arrays.equals(handshakePublicKey, i.handshakePublicKey) &&
|
||||||
|
Arrays.equals(handshakePrivateKey, i.handshakePrivateKey);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +1,29 @@
|
|||||||
package org.briarproject.bramble.api.identity;
|
package org.briarproject.bramble.api.identity;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
||||||
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface IdentityManager {
|
public interface IdentityManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a local identity with the given name.
|
* Creates an identity with the given name. The identity includes a
|
||||||
|
* handshake key pair.
|
||||||
*/
|
*/
|
||||||
@CryptoExecutor
|
@CryptoExecutor
|
||||||
LocalAuthor createLocalAuthor(String name);
|
Identity createIdentity(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the given local identity with the manager. The identity is
|
* Registers the given identity with the manager. This method should be
|
||||||
* not stored until {@link #storeLocalAuthor()} is called.
|
* called before {@link LifecycleManager#startServices(SecretKey)}. The
|
||||||
|
* identity is stored when {@link LifecycleManager#startServices(SecretKey)}
|
||||||
|
* is called. The identity must include a handshake key pair.
|
||||||
*/
|
*/
|
||||||
void registerLocalAuthor(LocalAuthor a);
|
void registerIdentity(Identity i);
|
||||||
|
|
||||||
/**
|
|
||||||
* Stores the local identity registered with
|
|
||||||
* {@link #registerLocalAuthor(LocalAuthor)}, if any.
|
|
||||||
*/
|
|
||||||
void storeLocalAuthor() throws DbException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cached local identity or loads it from the database.
|
* Returns the cached local identity or loads it from the database.
|
||||||
@@ -33,7 +32,18 @@ public interface IdentityManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cached local identity or loads it from the database.
|
* Returns the cached local identity or loads it from the database.
|
||||||
|
* <p/>
|
||||||
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
LocalAuthor getLocalAuthor(Transaction txn) throws DbException;
|
LocalAuthor getLocalAuthor(Transaction txn) throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cached handshake keys or loads them from the database.
|
||||||
|
* <p/>
|
||||||
|
* Read-only.
|
||||||
|
*
|
||||||
|
* @return A two-element array containing the public key in the first
|
||||||
|
* element and the private key in the second
|
||||||
|
*/
|
||||||
|
byte[][] getHandshakeKeys(Transaction txn) throws DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,8 @@ package org.briarproject.bramble.api.identity;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pseudonym for the local user.
|
* A pseudonym for the local user.
|
||||||
*/
|
*/
|
||||||
@@ -15,31 +12,11 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K
|
|||||||
public class LocalAuthor extends Author {
|
public class LocalAuthor extends Author {
|
||||||
|
|
||||||
private final byte[] privateKey;
|
private final byte[] privateKey;
|
||||||
@Nullable
|
|
||||||
private final byte[] handshakePublicKey, handshakePrivateKey;
|
|
||||||
private final long created;
|
|
||||||
|
|
||||||
public LocalAuthor(AuthorId id, int formatVersion, String name,
|
public LocalAuthor(AuthorId id, int formatVersion, String name,
|
||||||
byte[] publicKey, byte[] privateKey, long created) {
|
byte[] publicKey, byte[] privateKey) {
|
||||||
super(id, formatVersion, name, publicKey);
|
super(id, formatVersion, name, publicKey);
|
||||||
this.privateKey = privateKey;
|
this.privateKey = privateKey;
|
||||||
this.created = created;
|
|
||||||
handshakePublicKey = null;
|
|
||||||
handshakePrivateKey = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalAuthor(AuthorId id, int formatVersion, String name,
|
|
||||||
byte[] publicKey, byte[] privateKey, byte[] handshakePublicKey,
|
|
||||||
byte[] handshakePrivateKey, long created) {
|
|
||||||
super(id, formatVersion, name, publicKey);
|
|
||||||
if (handshakePublicKey.length == 0 ||
|
|
||||||
handshakePublicKey.length > MAX_PUBLIC_KEY_LENGTH) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
this.privateKey = privateKey;
|
|
||||||
this.handshakePublicKey = handshakePublicKey;
|
|
||||||
this.handshakePrivateKey = handshakePrivateKey;
|
|
||||||
this.created = created;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,28 +25,4 @@ public class LocalAuthor extends Author {
|
|||||||
public byte[] getPrivateKey() {
|
public byte[] getPrivateKey() {
|
||||||
return privateKey;
|
return privateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the public key used for handshaking, or null if no key exists.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public byte[] getHandshakePublicKey() {
|
|
||||||
return handshakePublicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the private key used for handshaking, or null if no key exists.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public byte[] getHandshakePrivateKey() {
|
|
||||||
return handshakePrivateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the time the pseudonym was created, in milliseconds since the
|
|
||||||
* Unix epoch.
|
|
||||||
*/
|
|
||||||
public long getTimeCreated() {
|
|
||||||
return created;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event that is broadcast when a local pseudonym is added.
|
* An event that is broadcast when an identity is added.
|
||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class LocalAuthorAddedEvent extends Event {
|
public class IdentityAddedEvent extends Event {
|
||||||
|
|
||||||
private final AuthorId authorId;
|
private final AuthorId authorId;
|
||||||
|
|
||||||
public LocalAuthorAddedEvent(AuthorId authorId) {
|
public IdentityAddedEvent(AuthorId authorId) {
|
||||||
this.authorId = authorId;
|
this.authorId = authorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7,15 +7,15 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event that is broadcast when a local pseudonym is removed.
|
* An event that is broadcast when an identity is removed.
|
||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class LocalAuthorRemovedEvent extends Event {
|
public class IdentityRemovedEvent extends Event {
|
||||||
|
|
||||||
private final AuthorId authorId;
|
private final AuthorId authorId;
|
||||||
|
|
||||||
public LocalAuthorRemovedEvent(AuthorId authorId) {
|
public IdentityRemovedEvent(AuthorId authorId) {
|
||||||
this.authorId = authorId;
|
this.authorId = authorId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,16 +2,16 @@ package org.briarproject.bramble.api.lifecycle;
|
|||||||
|
|
||||||
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.Transaction;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the lifecycle of the app, starting {@link Client Clients}, starting
|
* Manages the lifecycle of the app: opening and closing the
|
||||||
* and stopping {@link Service Services}, shutting down
|
* {@link DatabaseComponent} starting and stopping {@link Service Services},
|
||||||
* {@link ExecutorService ExecutorServices}, and opening and closing the
|
* and shutting down {@link ExecutorService ExecutorServices}.
|
||||||
* {@link DatabaseComponent}.
|
|
||||||
*/
|
*/
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface LifecycleManager {
|
public interface LifecycleManager {
|
||||||
@@ -42,18 +42,19 @@ public interface LifecycleManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a hook to be called after the database is opened and before
|
||||||
|
* {@link Service services} are started. This method should be called
|
||||||
|
* before {@link #startServices(SecretKey)}.
|
||||||
|
*/
|
||||||
|
void registerOpenDatabaseHook(OpenDatabaseHook hook);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a {@link Service} to be started and stopped. This method
|
* Registers a {@link Service} to be started and stopped. This method
|
||||||
* should be called before {@link #startServices(SecretKey)}.
|
* should be called before {@link #startServices(SecretKey)}.
|
||||||
*/
|
*/
|
||||||
void registerService(Service s);
|
void registerService(Service s);
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a {@link Client} to be started. This method should be called
|
|
||||||
* before {@link #startServices(SecretKey)}.
|
|
||||||
*/
|
|
||||||
void registerClient(Client c);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an {@link ExecutorService} to be shut down. This method
|
* Registers an {@link ExecutorService} to be shut down. This method
|
||||||
* should be called before {@link #startServices(SecretKey)}.
|
* should be called before {@link #startServices(SecretKey)}.
|
||||||
@@ -62,7 +63,7 @@ public interface LifecycleManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the {@link DatabaseComponent} using the given key and starts any
|
* Opens the {@link DatabaseComponent} using the given key and starts any
|
||||||
* registered {@link Client Clients} and {@link Service Services}.
|
* registered {@link Service Services}.
|
||||||
*/
|
*/
|
||||||
StartResult startServices(SecretKey dbKey);
|
StartResult startServices(SecretKey dbKey);
|
||||||
|
|
||||||
@@ -80,8 +81,7 @@ public interface LifecycleManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for the {@link DatabaseComponent} to be opened and all registered
|
* Waits for the {@link DatabaseComponent} to be opened and all registered
|
||||||
* {@link Client Clients} and {@link Service Services} to start before
|
* {@link Service Services} to start before returning.
|
||||||
* returning.
|
|
||||||
*/
|
*/
|
||||||
void waitForStartup() throws InterruptedException;
|
void waitForStartup() throws InterruptedException;
|
||||||
|
|
||||||
@@ -97,4 +97,13 @@ public interface LifecycleManager {
|
|||||||
*/
|
*/
|
||||||
LifecycleState getLifecycleState();
|
LifecycleState getLifecycleState();
|
||||||
|
|
||||||
|
interface OpenDatabaseHook {
|
||||||
|
/**
|
||||||
|
* Called when the database is being opened, before
|
||||||
|
* {@link #waitForDatabase()} returns.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
*/
|
||||||
|
void onDatabaseOpened(Transaction txn) throws DbException;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package org.briarproject.bramble.api.sync;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
public interface Client {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called at startup to create any local state needed by the client.
|
|
||||||
*/
|
|
||||||
void createLocalState(Transaction txn) throws DbException;
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,8 @@ public interface IncomingMessageHook {
|
|||||||
/**
|
/**
|
||||||
* Called once for each incoming message that passes validation.
|
* Called once for each incoming message that passes validation.
|
||||||
*
|
*
|
||||||
* @return whether or not this message should be shared
|
* @param txn A read-write transaction
|
||||||
|
* @return Whether or not this message should be shared
|
||||||
* @throws DbException Should only be used for real database errors.
|
* @throws DbException Should only be used for real database errors.
|
||||||
* If this is thrown, delivery will be attempted again at next startup,
|
* If this is thrown, delivery will be attempted again at next startup,
|
||||||
* whereas if an InvalidMessageException is thrown,
|
* whereas if an InvalidMessageException is thrown,
|
||||||
|
|||||||
@@ -46,7 +46,14 @@ public interface ClientVersioningManager {
|
|||||||
ClientId clientId, int majorVersion) throws DbException;
|
ClientId clientId, int majorVersion) throws DbException;
|
||||||
|
|
||||||
interface ClientVersioningHook {
|
interface ClientVersioningHook {
|
||||||
|
/**
|
||||||
|
* Called when the visibility of a client with respect to a contact is
|
||||||
|
* changing.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param c The contact affected by the visibility change
|
||||||
|
* @param v The new visibility of the client
|
||||||
|
*/
|
||||||
void onClientVisibilityChanging(Transaction txn, Contact c,
|
void onClientVisibilityChanging(Transaction txn, Contact c,
|
||||||
Visibility v) throws DbException;
|
Visibility v) throws DbException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.contact.PendingContactId;
|
|||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
@@ -30,6 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||||
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
||||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||||
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.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
@@ -99,25 +101,26 @@ public class TestUtils {
|
|||||||
return new SecretKey(getRandomBytes(SecretKey.LENGTH));
|
return new SecretKey(getRandomBytes(SecretKey.LENGTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LocalAuthor getLocalAuthor() {
|
public static Identity getIdentity() {
|
||||||
return getLocalAuthor(1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH));
|
LocalAuthor localAuthor = getLocalAuthor();
|
||||||
}
|
byte[] handshakePub = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||||
|
byte[] handshakePriv = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||||
public static LocalAuthor getLocalAuthor(int nameLength) {
|
return new Identity(localAuthor, handshakePub, handshakePriv,
|
||||||
AuthorId id = new AuthorId(getRandomId());
|
|
||||||
String name = getRandomString(nameLength);
|
|
||||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
|
||||||
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
|
||||||
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey,
|
|
||||||
timestamp);
|
timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Author getAuthor() {
|
public static LocalAuthor getLocalAuthor() {
|
||||||
return getAuthor(1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH));
|
AuthorId id = new AuthorId(getRandomId());
|
||||||
|
int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH);
|
||||||
|
String name = getRandomString(nameLength);
|
||||||
|
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||||
|
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||||
|
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Author getAuthor(int nameLength) {
|
public static Author getAuthor() {
|
||||||
AuthorId id = new AuthorId(getRandomId());
|
AuthorId id = new AuthorId(getRandomId());
|
||||||
|
int nameLength = 1 + random.nextInt(MAX_AUTHOR_NAME_LENGTH);
|
||||||
String name = getRandomString(nameLength);
|
String name = getRandomString(nameLength);
|
||||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||||
return new Author(id, FORMAT_VERSION, name, publicKey);
|
return new Author(id, FORMAT_VERSION, name, publicKey);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import org.briarproject.bramble.api.account.AccountManager;
|
|||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
@@ -161,8 +161,8 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
synchronized (stateChangeLock) {
|
synchronized (stateChangeLock) {
|
||||||
if (hasDatabaseKey())
|
if (hasDatabaseKey())
|
||||||
throw new AssertionError("Already have a database key");
|
throw new AssertionError("Already have a database key");
|
||||||
LocalAuthor localAuthor = identityManager.createLocalAuthor(name);
|
Identity identity = identityManager.createIdentity(name);
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.registerIdentity(identity);
|
||||||
SecretKey key = crypto.generateSecretKey();
|
SecretKey key = crypto.generateSecretKey();
|
||||||
if (!encryptAndStoreDatabaseKey(key, password)) return false;
|
if (!encryptAndStoreDatabaseKey(key, password)) return false;
|
||||||
databaseKey = key;
|
databaseKey = key;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.briarproject.bramble.api.db.Metadata;
|
|||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
@@ -120,9 +120,9 @@ interface Database<T> {
|
|||||||
HandshakeKeys k) throws DbException;
|
HandshakeKeys k) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a local pseudonym.
|
* Stores an identity.
|
||||||
*/
|
*/
|
||||||
void addLocalAuthor(T txn, LocalAuthor a) throws DbException;
|
void addIdentity(T txn, Identity i) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores a message.
|
* Stores a message.
|
||||||
@@ -187,11 +187,12 @@ interface Database<T> {
|
|||||||
boolean containsGroup(T txn, GroupId g) throws DbException;
|
boolean containsGroup(T txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the database contains the given local pseudonym.
|
* Returns true if the database contains an identity for the given
|
||||||
|
* pseudonym.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
boolean containsLocalAuthor(T txn, AuthorId a) throws DbException;
|
boolean containsIdentity(T txn, AuthorId a) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the database contains the given message.
|
* Returns true if the database contains the given message.
|
||||||
@@ -323,18 +324,18 @@ interface Database<T> {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the local pseudonym with the given ID.
|
* Returns the identity for local pseudonym with the given ID.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
LocalAuthor getLocalAuthor(T txn, AuthorId a) throws DbException;
|
Identity getIdentity(T txn, AuthorId a) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all local pseudonyms.
|
* Returns the identities for all local pseudonyms.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Read-only.
|
* Read-only.
|
||||||
*/
|
*/
|
||||||
Collection<LocalAuthor> getLocalAuthors(T txn) throws DbException;
|
Collection<Identity> getIdentities(T txn) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message with the given ID.
|
* Returns the message with the given ID.
|
||||||
@@ -629,9 +630,9 @@ interface Database<T> {
|
|||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a local pseudonym (and all associated state) from the database.
|
* Removes an identity (and all associated state) from the database.
|
||||||
*/
|
*/
|
||||||
void removeLocalAuthor(T txn, AuthorId a) throws DbException;
|
void removeIdentity(T txn, AuthorId a) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a message (and all associated state) from the database.
|
* Removes a message (and all associated state) from the database.
|
||||||
@@ -685,6 +686,12 @@ interface Database<T> {
|
|||||||
void setGroupVisibility(T txn, ContactId c, GroupId g, boolean shared)
|
void setGroupVisibility(T txn, ContactId c, GroupId g, boolean shared)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the handshake key pair for the identity with the given ID.
|
||||||
|
*/
|
||||||
|
void setHandshakeKeyPair(T txn, AuthorId local, byte[] publicKey,
|
||||||
|
byte[] privateKey) throws DbException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the given message as shared.
|
* Marks the given message as shared.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.briarproject.bramble.api.db.Metadata;
|
|||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchLocalAuthorException;
|
import org.briarproject.bramble.api.db.NoSuchIdentityException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchPendingContactException;
|
import org.briarproject.bramble.api.db.NoSuchPendingContactException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchTransportException;
|
import org.briarproject.bramble.api.db.NoSuchTransportException;
|
||||||
@@ -32,9 +32,9 @@ import org.briarproject.bramble.api.event.EventBus;
|
|||||||
import org.briarproject.bramble.api.event.EventExecutor;
|
import org.briarproject.bramble.api.event.EventExecutor;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent;
|
import org.briarproject.bramble.api.identity.event.IdentityAddedEvent;
|
||||||
import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent;
|
import org.briarproject.bramble.api.identity.event.IdentityRemovedEvent;
|
||||||
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
@@ -237,9 +237,9 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
throws DbException {
|
throws DbException {
|
||||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, local))
|
if (!db.containsIdentity(txn, local))
|
||||||
throw new NoSuchLocalAuthorException();
|
throw new NoSuchIdentityException();
|
||||||
if (db.containsLocalAuthor(txn, remote.getId()))
|
if (db.containsIdentity(txn, remote.getId()))
|
||||||
throw new ContactExistsException();
|
throw new ContactExistsException();
|
||||||
if (db.containsContact(txn, remote.getId(), local))
|
if (db.containsContact(txn, remote.getId(), local))
|
||||||
throw new ContactExistsException();
|
throw new ContactExistsException();
|
||||||
@@ -283,13 +283,13 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLocalAuthor(Transaction transaction, LocalAuthor a)
|
public void addIdentity(Transaction transaction, Identity i)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, a.getId())) {
|
if (!db.containsIdentity(txn, i.getId())) {
|
||||||
db.addLocalAuthor(txn, a);
|
db.addIdentity(txn, i);
|
||||||
transaction.attach(new LocalAuthorAddedEvent(a.getId()));
|
transaction.attach(new IdentityAddedEvent(i.getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,8 +345,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
public boolean containsContact(Transaction transaction, AuthorId remote,
|
public boolean containsContact(Transaction transaction, AuthorId remote,
|
||||||
AuthorId local) throws DbException {
|
AuthorId local) throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, local))
|
if (!db.containsIdentity(txn, local))
|
||||||
throw new NoSuchLocalAuthorException();
|
throw new NoSuchIdentityException();
|
||||||
return db.containsContact(txn, remote, local);
|
return db.containsContact(txn, remote, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,10 +358,10 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsLocalAuthor(Transaction transaction, AuthorId local)
|
public boolean containsIdentity(Transaction transaction, AuthorId a)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
return db.containsLocalAuthor(txn, local);
|
return db.containsIdentity(txn, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -505,8 +505,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
public Collection<ContactId> getContacts(Transaction transaction,
|
public Collection<ContactId> getContacts(Transaction transaction,
|
||||||
AuthorId a) throws DbException {
|
AuthorId a) throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, a))
|
if (!db.containsIdentity(txn, a))
|
||||||
throw new NoSuchLocalAuthorException();
|
throw new NoSuchIdentityException();
|
||||||
return db.getContacts(txn, a);
|
return db.getContacts(txn, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,19 +554,19 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalAuthor getLocalAuthor(Transaction transaction, AuthorId a)
|
public Identity getIdentity(Transaction transaction, AuthorId a)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, a))
|
if (!db.containsIdentity(txn, a))
|
||||||
throw new NoSuchLocalAuthorException();
|
throw new NoSuchIdentityException();
|
||||||
return db.getLocalAuthor(txn, a);
|
return db.getIdentity(txn, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<LocalAuthor> getLocalAuthors(Transaction transaction)
|
public Collection<Identity> getIdentities(Transaction transaction)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
return db.getLocalAuthors(txn);
|
return db.getIdentities(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -905,14 +905,14 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeLocalAuthor(Transaction transaction, AuthorId a)
|
public void removeIdentity(Transaction transaction, AuthorId a)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
T txn = unbox(transaction);
|
T txn = unbox(transaction);
|
||||||
if (!db.containsLocalAuthor(txn, a))
|
if (!db.containsIdentity(txn, a))
|
||||||
throw new NoSuchLocalAuthorException();
|
throw new NoSuchIdentityException();
|
||||||
db.removeLocalAuthor(txn, a);
|
db.removeIdentity(txn, a);
|
||||||
transaction.attach(new LocalAuthorRemovedEvent(a));
|
transaction.attach(new IdentityRemovedEvent(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1035,6 +1035,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHandshakeKeyPair(Transaction transaction, AuthorId local,
|
||||||
|
byte[] publicKey, byte[] privateKey) throws DbException {
|
||||||
|
if (transaction.isReadOnly()) throw new IllegalArgumentException();
|
||||||
|
T txn = unbox(transaction);
|
||||||
|
if (!db.containsIdentity(txn, local))
|
||||||
|
throw new NoSuchIdentityException();
|
||||||
|
db.setHandshakeKeyPair(txn, local, publicKey, privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setReorderingWindow(Transaction transaction,
|
public void setReorderingWindow(Transaction transaction,
|
||||||
TransportKeySetId k, TransportId t, long timePeriod, long base,
|
TransportKeySetId k, TransportId t, long timePeriod, long base,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.db.Metadata;
|
|||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
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.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
@@ -874,8 +875,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addLocalAuthor(Connection txn, LocalAuthor a)
|
public void addIdentity(Connection txn, Identity i) throws DbException {
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
String sql = "INSERT INTO localAuthors"
|
String sql = "INSERT INTO localAuthors"
|
||||||
@@ -883,16 +883,17 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
+ " handshakePublicKey, handshakePrivateKey, created)"
|
+ " handshakePublicKey, handshakePrivateKey, created)"
|
||||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, a.getId().getBytes());
|
LocalAuthor local = i.getLocalAuthor();
|
||||||
ps.setInt(2, a.getFormatVersion());
|
ps.setBytes(1, local.getId().getBytes());
|
||||||
ps.setString(3, a.getName());
|
ps.setInt(2, local.getFormatVersion());
|
||||||
ps.setBytes(4, a.getPublicKey());
|
ps.setString(3, local.getName());
|
||||||
ps.setBytes(5, a.getPrivateKey());
|
ps.setBytes(4, local.getPublicKey());
|
||||||
if (a.getHandshakePublicKey() == null) ps.setNull(6, BINARY);
|
ps.setBytes(5, local.getPrivateKey());
|
||||||
else ps.setBytes(6, a.getHandshakePublicKey());
|
if (i.getHandshakePublicKey() == null) ps.setNull(6, BINARY);
|
||||||
if (a.getHandshakePrivateKey() == null) ps.setNull(7, BINARY);
|
else ps.setBytes(6, i.getHandshakePublicKey());
|
||||||
else ps.setBytes(7, a.getHandshakePrivateKey());
|
if (i.getHandshakePrivateKey() == null) ps.setNull(7, BINARY);
|
||||||
ps.setLong(8, a.getTimeCreated());
|
else ps.setBytes(7, i.getHandshakePrivateKey());
|
||||||
|
ps.setLong(8, i.getTimeCreated());
|
||||||
int affected = ps.executeUpdate();
|
int affected = ps.executeUpdate();
|
||||||
if (affected != 1) throw new DbStateException();
|
if (affected != 1) throw new DbStateException();
|
||||||
ps.close();
|
ps.close();
|
||||||
@@ -1248,7 +1249,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsLocalAuthor(Connection txn, AuthorId a)
|
public boolean containsIdentity(Connection txn, AuthorId a)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
@@ -1660,41 +1661,6 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public LocalAuthor getLocalAuthor(Connection txn, AuthorId a)
|
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
|
||||||
ResultSet rs = null;
|
|
||||||
try {
|
|
||||||
String sql = "SELECT formatVersion, name, publicKey, privateKey,"
|
|
||||||
+ " handshakePublicKey, handshakePrivateKey, created"
|
|
||||||
+ " FROM localAuthors"
|
|
||||||
+ " WHERE authorId = ?";
|
|
||||||
ps = txn.prepareStatement(sql);
|
|
||||||
ps.setBytes(1, a.getBytes());
|
|
||||||
rs = ps.executeQuery();
|
|
||||||
if (!rs.next()) throw new DbStateException();
|
|
||||||
int formatVersion = rs.getInt(1);
|
|
||||||
String name = rs.getString(2);
|
|
||||||
byte[] publicKey = rs.getBytes(3);
|
|
||||||
byte[] privateKey = rs.getBytes(4);
|
|
||||||
byte[] handshakePublicKey = rs.getBytes(5);
|
|
||||||
byte[] handshakePrivateKey = rs.getBytes(6);
|
|
||||||
long created = rs.getLong(7);
|
|
||||||
LocalAuthor localAuthor = new LocalAuthor(a, formatVersion, name,
|
|
||||||
publicKey, privateKey, handshakePublicKey,
|
|
||||||
handshakePrivateKey, created);
|
|
||||||
if (rs.next()) throw new DbStateException();
|
|
||||||
rs.close();
|
|
||||||
ps.close();
|
|
||||||
return localAuthor;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
tryToClose(rs, LOG, WARNING);
|
|
||||||
tryToClose(ps, LOG, WARNING);
|
|
||||||
throw new DbException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<HandshakeKeySet> getHandshakeKeys(Connection txn,
|
public Collection<HandshakeKeySet> getHandshakeKeys(Connection txn,
|
||||||
TransportId t) throws DbException {
|
TransportId t) throws DbException {
|
||||||
@@ -1776,30 +1742,69 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<LocalAuthor> getLocalAuthors(Connection txn)
|
public Identity getIdentity(Connection txn, AuthorId a) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try {
|
||||||
|
String sql = "SELECT formatVersion, name, publicKey, privateKey,"
|
||||||
|
+ " handshakePublicKey, handshakePrivateKey, created"
|
||||||
|
+ " FROM localAuthors"
|
||||||
|
+ " WHERE authorId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, a.getBytes());
|
||||||
|
rs = ps.executeQuery();
|
||||||
|
if (!rs.next()) throw new DbStateException();
|
||||||
|
int formatVersion = rs.getInt(1);
|
||||||
|
String name = rs.getString(2);
|
||||||
|
byte[] publicKey = rs.getBytes(3);
|
||||||
|
byte[] privateKey = rs.getBytes(4);
|
||||||
|
byte[] handshakePublicKey = rs.getBytes(5);
|
||||||
|
byte[] handshakePrivateKey = rs.getBytes(6);
|
||||||
|
long created = rs.getLong(7);
|
||||||
|
if (rs.next()) throw new DbStateException();
|
||||||
|
rs.close();
|
||||||
|
ps.close();
|
||||||
|
LocalAuthor local = new LocalAuthor(a, formatVersion, name,
|
||||||
|
publicKey, privateKey);
|
||||||
|
return new Identity(local, handshakePublicKey, handshakePrivateKey,
|
||||||
|
created);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
tryToClose(rs, LOG, WARNING);
|
||||||
|
tryToClose(ps, LOG, WARNING);
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Identity> getIdentities(Connection txn)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT authorId, formatVersion, name, publicKey,"
|
String sql = "SELECT authorId, formatVersion, name, publicKey,"
|
||||||
+ " privateKey, created"
|
+ " privateKey, handshakePublicKey, handshakePrivateKey,"
|
||||||
|
+ " created"
|
||||||
+ " FROM localAuthors";
|
+ " FROM localAuthors";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
rs = ps.executeQuery();
|
rs = ps.executeQuery();
|
||||||
List<LocalAuthor> authors = new ArrayList<>();
|
List<Identity> identities = new ArrayList<>();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
AuthorId authorId = new AuthorId(rs.getBytes(1));
|
AuthorId authorId = new AuthorId(rs.getBytes(1));
|
||||||
int formatVersion = rs.getInt(2);
|
int formatVersion = rs.getInt(2);
|
||||||
String name = rs.getString(3);
|
String name = rs.getString(3);
|
||||||
byte[] publicKey = rs.getBytes(4);
|
byte[] publicKey = rs.getBytes(4);
|
||||||
byte[] privateKey = rs.getBytes(5);
|
byte[] privateKey = rs.getBytes(5);
|
||||||
long created = rs.getLong(6);
|
byte[] handshakePublicKey = rs.getBytes(6);
|
||||||
authors.add(new LocalAuthor(authorId, formatVersion, name,
|
byte[] handshakePrivateKey = rs.getBytes(7);
|
||||||
publicKey, privateKey, created));
|
long created = rs.getLong(8);
|
||||||
|
LocalAuthor local = new LocalAuthor(authorId, formatVersion,
|
||||||
|
name, publicKey, privateKey);
|
||||||
|
identities.add(new Identity(local, handshakePublicKey,
|
||||||
|
handshakePrivateKey, created));
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
return authors;
|
return identities;
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
tryToClose(rs, LOG, WARNING);
|
tryToClose(rs, LOG, WARNING);
|
||||||
tryToClose(ps, LOG, WARNING);
|
tryToClose(ps, LOG, WARNING);
|
||||||
@@ -2958,8 +2963,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeLocalAuthor(Connection txn, AuthorId a)
|
public void removeIdentity(Connection txn, AuthorId a) throws DbException {
|
||||||
throws DbException {
|
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
String sql = "DELETE FROM localAuthors WHERE authorId = ?";
|
String sql = "DELETE FROM localAuthors WHERE authorId = ?";
|
||||||
@@ -3176,6 +3180,27 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setHandshakeKeyPair(Connection txn, AuthorId local,
|
||||||
|
byte[] publicKey, byte[] privateKey) throws DbException {
|
||||||
|
PreparedStatement ps = null;
|
||||||
|
try {
|
||||||
|
String sql = "UPDATE localAuthors"
|
||||||
|
+ " SET handshakePublicKey = ?, handshakePrivateKey = ?"
|
||||||
|
+ " WHERE authorId = ?";
|
||||||
|
ps = txn.prepareStatement(sql);
|
||||||
|
ps.setBytes(1, publicKey);
|
||||||
|
ps.setBytes(2, privateKey);
|
||||||
|
ps.setBytes(3, local.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 setMessageShared(Connection txn, MessageId m)
|
public void setMessageShared(Connection txn, MessageId m)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package org.briarproject.bramble.identity;
|
package org.briarproject.bramble.identity;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.bramble.api.crypto.KeyPair;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
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.system.Clock;
|
|
||||||
import org.briarproject.bramble.util.ByteUtils;
|
import org.briarproject.bramble.util.ByteUtils;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
@@ -22,12 +22,10 @@ import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
|||||||
class AuthorFactoryImpl implements AuthorFactory {
|
class AuthorFactoryImpl implements AuthorFactory {
|
||||||
|
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
private final Clock clock;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AuthorFactoryImpl(CryptoComponent crypto, Clock clock) {
|
AuthorFactoryImpl(CryptoComponent crypto) {
|
||||||
this.crypto = crypto;
|
this.crypto = crypto;
|
||||||
this.clock = clock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -43,17 +41,12 @@ class AuthorFactoryImpl implements AuthorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalAuthor createLocalAuthor(String name, byte[] publicKey,
|
public LocalAuthor createLocalAuthor(String name) {
|
||||||
byte[] privateKey) {
|
KeyPair signatureKeyPair = crypto.generateSignatureKeyPair();
|
||||||
return createLocalAuthor(FORMAT_VERSION, name, publicKey, privateKey);
|
byte[] publicKey = signatureKeyPair.getPublic().getEncoded();
|
||||||
}
|
byte[] privateKey = signatureKeyPair.getPrivate().getEncoded();
|
||||||
|
AuthorId id = getId(FORMAT_VERSION, name, publicKey);
|
||||||
@Override
|
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey);
|
||||||
public LocalAuthor createLocalAuthor(int formatVersion, String name,
|
|
||||||
byte[] publicKey, byte[] privateKey) {
|
|
||||||
AuthorId id = getId(formatVersion, name, publicKey);
|
|
||||||
return new LocalAuthor(id, formatVersion, name, publicKey, privateKey,
|
|
||||||
clock.currentTimeMillis());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AuthorId getId(int formatVersion, String name, byte[] publicKey) {
|
private AuthorId getId(int formatVersion, String name, byte[] publicKey) {
|
||||||
|
|||||||
@@ -6,97 +6,164 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
import static org.briarproject.bramble.util.LogUtils.now;
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class IdentityManagerImpl implements IdentityManager {
|
class IdentityManagerImpl implements IdentityManager, OpenDatabaseHook {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(IdentityManagerImpl.class.getName());
|
getLogger(IdentityManagerImpl.class.getName());
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
private final AuthorFactory authorFactory;
|
private final AuthorFactory authorFactory;
|
||||||
|
private final Clock clock;
|
||||||
|
|
||||||
// The local author is immutable so we can cache it
|
/**
|
||||||
|
* The user's identity, or null if no identity has been registered or
|
||||||
|
* loaded. If non-null, this identity always has handshake keys.
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private volatile LocalAuthor cachedAuthor;
|
private volatile Identity cachedIdentity = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if {@code cachedIdentity} was registered via
|
||||||
|
* {@link #registerIdentity(Identity)} and should be stored when
|
||||||
|
* {@link #onDatabaseOpened(Transaction)} is called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private volatile boolean shouldStoreIdentity = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the handshake keys in {@code cachedIdentity} were generated
|
||||||
|
* when the identity was loaded and should be stored when
|
||||||
|
* {@link #onDatabaseOpened(Transaction)} is called.
|
||||||
|
*/
|
||||||
|
private volatile boolean shouldStoreKeys = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
IdentityManagerImpl(DatabaseComponent db, CryptoComponent crypto,
|
IdentityManagerImpl(DatabaseComponent db, CryptoComponent crypto,
|
||||||
AuthorFactory authorFactory) {
|
AuthorFactory authorFactory, Clock clock) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.crypto = crypto;
|
this.crypto = crypto;
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalAuthor createLocalAuthor(String name) {
|
public Identity createIdentity(String name) {
|
||||||
long start = now();
|
long start = now();
|
||||||
KeyPair keyPair = crypto.generateSignatureKeyPair();
|
LocalAuthor localAuthor = authorFactory.createLocalAuthor(name);
|
||||||
byte[] publicKey = keyPair.getPublic().getEncoded();
|
KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair();
|
||||||
byte[] privateKey = keyPair.getPrivate().getEncoded();
|
byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded();
|
||||||
LocalAuthor localAuthor = authorFactory.createLocalAuthor(name,
|
byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded();
|
||||||
publicKey, privateKey);
|
logDuration(LOG, "Creating identity", start);
|
||||||
logDuration(LOG, "Creating local author", start);
|
return new Identity(localAuthor, handshakePub, handshakePriv,
|
||||||
return localAuthor;
|
clock.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerLocalAuthor(LocalAuthor a) {
|
public void registerIdentity(Identity i) {
|
||||||
cachedAuthor = a;
|
if (!i.hasHandshakeKeyPair()) throw new IllegalArgumentException();
|
||||||
LOG.info("Local author registered");
|
cachedIdentity = i;
|
||||||
|
shouldStoreIdentity = true;
|
||||||
|
LOG.info("Identity registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeLocalAuthor() throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
LocalAuthor cached = cachedAuthor;
|
Identity cached = getCachedIdentity(txn);
|
||||||
if (cached == null) {
|
if (shouldStoreIdentity) {
|
||||||
LOG.info("No local author to store");
|
// The identity was registered at startup - store it
|
||||||
return;
|
db.addIdentity(txn, cached);
|
||||||
|
LOG.info("Identity stored");
|
||||||
|
} else if (shouldStoreKeys) {
|
||||||
|
// Handshake keys were generated when loading the identity -
|
||||||
|
// store them
|
||||||
|
byte[] handshakePub =
|
||||||
|
requireNonNull(cached.getHandshakePublicKey());
|
||||||
|
byte[] handshakePriv =
|
||||||
|
requireNonNull(cached.getHandshakePrivateKey());
|
||||||
|
db.setHandshakeKeyPair(txn, cached.getId(), handshakePub,
|
||||||
|
handshakePriv);
|
||||||
|
LOG.info("Handshake key pair stored");
|
||||||
}
|
}
|
||||||
db.transaction(false, txn -> db.addLocalAuthor(txn, cached));
|
|
||||||
LOG.info("Local author stored");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalAuthor getLocalAuthor() throws DbException {
|
public LocalAuthor getLocalAuthor() throws DbException {
|
||||||
if (cachedAuthor == null) {
|
Identity cached = cachedIdentity;
|
||||||
cachedAuthor =
|
if (cached == null)
|
||||||
db.transactionWithResult(true, this::loadLocalAuthor);
|
cached = db.transactionWithResult(true, this::getCachedIdentity);
|
||||||
LOG.info("Local author loaded");
|
return cached.getLocalAuthor();
|
||||||
}
|
|
||||||
LocalAuthor cached = cachedAuthor;
|
|
||||||
if (cached == null) throw new AssertionError();
|
|
||||||
return cached;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocalAuthor getLocalAuthor(Transaction txn) throws DbException {
|
public LocalAuthor getLocalAuthor(Transaction txn) throws DbException {
|
||||||
if (cachedAuthor == null) {
|
return getCachedIdentity(txn).getLocalAuthor();
|
||||||
cachedAuthor = loadLocalAuthor(txn);
|
}
|
||||||
LOG.info("Local author loaded");
|
|
||||||
}
|
@Override
|
||||||
LocalAuthor cached = cachedAuthor;
|
public byte[][] getHandshakeKeys(Transaction txn) throws DbException {
|
||||||
if (cached == null) throw new AssertionError();
|
Identity cached = getCachedIdentity(txn);
|
||||||
|
return new byte[][] {
|
||||||
|
cached.getHandshakePublicKey(),
|
||||||
|
cached.getHandshakePrivateKey()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the identity if necessary and returns it. If
|
||||||
|
* {@code cachedIdentity} was not already set by calling
|
||||||
|
* {@link #registerIdentity(Identity)}, this method sets it. If
|
||||||
|
* {@code cachedIdentity} was already set, either by calling
|
||||||
|
* {@link #registerIdentity(Identity)} or by a previous call to this
|
||||||
|
* method, then this method returns the cached identity without hitting
|
||||||
|
* the database.
|
||||||
|
*/
|
||||||
|
private Identity getCachedIdentity(Transaction txn) throws DbException {
|
||||||
|
Identity cached = cachedIdentity;
|
||||||
|
if (cached == null)
|
||||||
|
cachedIdentity = cached = loadIdentityWithKeyPair(txn);
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalAuthor loadLocalAuthor(Transaction txn) throws DbException {
|
/**
|
||||||
return db.getLocalAuthors(txn).iterator().next();
|
* Loads and returns the identity, generating a handshake key pair if
|
||||||
|
* necessary and setting {@code shouldStoreKeys} if a handshake key pair
|
||||||
|
* was generated.
|
||||||
|
*/
|
||||||
|
private Identity loadIdentityWithKeyPair(Transaction txn)
|
||||||
|
throws DbException {
|
||||||
|
Collection<Identity> identities = db.getIdentities(txn);
|
||||||
|
if (identities.size() != 1) throw new DbException();
|
||||||
|
Identity i = identities.iterator().next();
|
||||||
|
LOG.info("Identity loaded");
|
||||||
|
if (i.hasHandshakeKeyPair()) return i;
|
||||||
|
KeyPair handshakeKeyPair = crypto.generateAgreementKeyPair();
|
||||||
|
byte[] handshakePub = handshakeKeyPair.getPublic().getEncoded();
|
||||||
|
byte[] handshakePriv = handshakeKeyPair.getPrivate().getEncoded();
|
||||||
|
LOG.info("Handshake key pair generated");
|
||||||
|
shouldStoreKeys = true;
|
||||||
|
return new Identity(i.getLocalAuthor(), handshakePub, handshakePriv,
|
||||||
|
i.getTimeCreated());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.bramble.identity;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -24,8 +25,9 @@ public class IdentityModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
IdentityManager provideIdentityManager(
|
IdentityManager provideIdentityManager(LifecycleManager lifecycleManager,
|
||||||
IdentityManagerImpl identityManager) {
|
IdentityManagerImpl identityManager) {
|
||||||
|
lifecycleManager.registerOpenDatabaseHook(identityManager);
|
||||||
return identityManager;
|
return identityManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,13 +7,11 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.MigrationListener;
|
import org.briarproject.bramble.api.db.MigrationListener;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.lifecycle.Service;
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
import org.briarproject.bramble.api.lifecycle.ServiceException;
|
import org.briarproject.bramble.api.lifecycle.ServiceException;
|
||||||
import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent;
|
import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@@ -28,6 +26,7 @@ import javax.inject.Inject;
|
|||||||
import static java.util.logging.Level.FINE;
|
import static java.util.logging.Level.FINE;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.COMPACTING_DATABASE;
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.MIGRATING_DATABASE;
|
||||||
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
|
||||||
@@ -49,14 +48,13 @@ import static org.briarproject.bramble.util.LogUtils.now;
|
|||||||
class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(LifecycleManagerImpl.class.getName());
|
getLogger(LifecycleManagerImpl.class.getName());
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final List<Service> services;
|
private final List<Service> services;
|
||||||
private final List<Client> clients;
|
private final List<OpenDatabaseHook> openDatabaseHooks;
|
||||||
private final List<ExecutorService> executors;
|
private final List<ExecutorService> executors;
|
||||||
private final IdentityManager identityManager;
|
|
||||||
private final Semaphore startStopSemaphore = new Semaphore(1);
|
private final Semaphore startStopSemaphore = new Semaphore(1);
|
||||||
private final CountDownLatch dbLatch = new CountDownLatch(1);
|
private final CountDownLatch dbLatch = new CountDownLatch(1);
|
||||||
private final CountDownLatch startupLatch = new CountDownLatch(1);
|
private final CountDownLatch startupLatch = new CountDownLatch(1);
|
||||||
@@ -65,13 +63,11 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
|||||||
private volatile LifecycleState state = STARTING;
|
private volatile LifecycleState state = STARTING;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
LifecycleManagerImpl(DatabaseComponent db, EventBus eventBus,
|
LifecycleManagerImpl(DatabaseComponent db, EventBus eventBus) {
|
||||||
IdentityManager identityManager) {
|
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.identityManager = identityManager;
|
|
||||||
services = new CopyOnWriteArrayList<>();
|
services = new CopyOnWriteArrayList<>();
|
||||||
clients = new CopyOnWriteArrayList<>();
|
openDatabaseHooks = new CopyOnWriteArrayList<>();
|
||||||
executors = new CopyOnWriteArrayList<>();
|
executors = new CopyOnWriteArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,10 +79,12 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerClient(Client c) {
|
public void registerOpenDatabaseHook(OpenDatabaseHook hook) {
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Registering client " + c.getClass().getSimpleName());
|
LOG.info("Registering open database hook "
|
||||||
clients.add(c);
|
+ hook.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
openDatabaseHooks.add(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -102,28 +100,28 @@ class LifecycleManagerImpl implements LifecycleManager, MigrationListener {
|
|||||||
return ALREADY_RUNNING;
|
return ALREADY_RUNNING;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
LOG.info("Starting services");
|
LOG.info("Opening database");
|
||||||
long start = now();
|
long start = now();
|
||||||
|
|
||||||
boolean reopened = db.open(dbKey, this);
|
boolean reopened = db.open(dbKey, this);
|
||||||
if (reopened) logDuration(LOG, "Reopening database", start);
|
if (reopened) logDuration(LOG, "Reopening database", start);
|
||||||
else logDuration(LOG, "Creating database", start);
|
else logDuration(LOG, "Creating database", start);
|
||||||
identityManager.storeLocalAuthor();
|
|
||||||
|
|
||||||
|
db.transaction(false, txn -> {
|
||||||
|
for (OpenDatabaseHook hook : openDatabaseHooks) {
|
||||||
|
long start1 = now();
|
||||||
|
hook.onDatabaseOpened(txn);
|
||||||
|
if (LOG.isLoggable(FINE)) {
|
||||||
|
logDuration(LOG, "Calling open database hook "
|
||||||
|
+ hook.getClass().getSimpleName(), start1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LOG.info("Starting services");
|
||||||
state = STARTING_SERVICES;
|
state = STARTING_SERVICES;
|
||||||
dbLatch.countDown();
|
dbLatch.countDown();
|
||||||
eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES));
|
eventBus.broadcast(new LifecycleEvent(STARTING_SERVICES));
|
||||||
|
|
||||||
db.transaction(false, txn -> {
|
|
||||||
for (Client c : clients) {
|
|
||||||
long start1 = now();
|
|
||||||
c.createLocalState(txn);
|
|
||||||
if (LOG.isLoggable(FINE)) {
|
|
||||||
logDuration(LOG, "Starting client "
|
|
||||||
+ c.getClass().getSimpleName(), start1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
for (Service s : services) {
|
for (Service s : services) {
|
||||||
start = now();
|
start = now();
|
||||||
s.startService();
|
s.startService();
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class PropertiesModule {
|
|||||||
ValidationManager validationManager, ContactManager contactManager,
|
ValidationManager validationManager, ContactManager contactManager,
|
||||||
ClientVersioningManager clientVersioningManager,
|
ClientVersioningManager clientVersioningManager,
|
||||||
TransportPropertyManagerImpl transportPropertyManager) {
|
TransportPropertyManagerImpl transportPropertyManager) {
|
||||||
lifecycleManager.registerClient(transportPropertyManager);
|
lifecycleManager.registerOpenDatabaseHook(transportPropertyManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
transportPropertyManager);
|
transportPropertyManager);
|
||||||
contactManager.registerContactHook(transportPropertyManager);
|
contactManager.registerContactHook(transportPropertyManager);
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||||
import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
import org.briarproject.bramble.api.properties.TransportPropertyManager;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -40,7 +40,8 @@ import javax.inject.Inject;
|
|||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
class TransportPropertyManagerImpl implements TransportPropertyManager,
|
||||||
Client, ContactHook, ClientVersioningHook, IncomingMessageHook {
|
OpenDatabaseHook, ContactHook, ClientVersioningHook,
|
||||||
|
IncomingMessageHook {
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
@@ -67,7 +68,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
if (db.containsGroup(txn, localGroup.getId())) return;
|
if (db.containsGroup(txn, localGroup.getId())) return;
|
||||||
db.addGroup(txn, localGroup);
|
db.addGroup(txn, localGroup);
|
||||||
// Set things up for any pre-existing contacts
|
// Set things up for any pre-existing contacts
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.lifecycle.Service;
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
import org.briarproject.bramble.api.lifecycle.ServiceException;
|
import org.briarproject.bramble.api.lifecycle.ServiceException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.ClientId;
|
import org.briarproject.bramble.api.sync.ClientId;
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
@@ -53,8 +53,8 @@ import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_
|
|||||||
import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_KEY_UPDATE_VERSION;
|
import static org.briarproject.bramble.versioning.ClientVersioningConstants.MSG_KEY_UPDATE_VERSION;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
class ClientVersioningManagerImpl implements ClientVersioningManager,
|
||||||
Service, ContactHook, IncomingMessageHook {
|
Service, OpenDatabaseHook, ContactHook, IncomingMessageHook {
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
@@ -124,7 +124,7 @@ class ClientVersioningManagerImpl implements ClientVersioningManager, Client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
if (db.containsGroup(txn, localGroup.getId())) return;
|
if (db.containsGroup(txn, localGroup.getId())) return;
|
||||||
db.addGroup(txn, localGroup);
|
db.addGroup(txn, localGroup);
|
||||||
// Set things up for any pre-existing contacts
|
// Set things up for any pre-existing contacts
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class VersioningModule {
|
|||||||
ClientVersioningManagerImpl clientVersioningManager,
|
ClientVersioningManagerImpl clientVersioningManager,
|
||||||
LifecycleManager lifecycleManager, ContactManager contactManager,
|
LifecycleManager lifecycleManager, ContactManager contactManager,
|
||||||
ValidationManager validationManager) {
|
ValidationManager validationManager) {
|
||||||
lifecycleManager.registerClient(clientVersioningManager);
|
lifecycleManager.registerOpenDatabaseHook(clientVersioningManager);
|
||||||
lifecycleManager.registerService(clientVersioningManager);
|
lifecycleManager.registerService(clientVersioningManager);
|
||||||
contactManager.registerContactHook(clientVersioningManager);
|
contactManager.registerContactHook(clientVersioningManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.account;
|
|||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
@@ -24,7 +25,7 @@ import static junit.framework.Assert.assertFalse;
|
|||||||
import static junit.framework.Assert.assertNull;
|
import static junit.framework.Assert.assertNull;
|
||||||
import static junit.framework.Assert.assertTrue;
|
import static junit.framework.Assert.assertTrue;
|
||||||
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||||
@@ -47,7 +48,8 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final String encryptedKeyHex = toHexString(encryptedKey);
|
private final String encryptedKeyHex = toHexString(encryptedKey);
|
||||||
private final byte[] newEncryptedKey = getRandomBytes(123);
|
private final byte[] newEncryptedKey = getRandomBytes(123);
|
||||||
private final String newEncryptedKeyHex = toHexString(newEncryptedKey);
|
private final String newEncryptedKeyHex = toHexString(newEncryptedKey);
|
||||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
private final Identity identity = getIdentity();
|
||||||
|
private final LocalAuthor localAuthor = identity.getLocalAuthor();
|
||||||
private final String authorName = localAuthor.getName();
|
private final String authorName = localAuthor.getName();
|
||||||
private final String password = getRandomString(10);
|
private final String password = getRandomString(10);
|
||||||
private final String newPassword = getRandomString(10);
|
private final String newPassword = getRandomString(10);
|
||||||
@@ -251,9 +253,9 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateAccountStoresDbKey() throws Exception {
|
public void testCreateAccountStoresDbKey() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(identityManager).createLocalAuthor(authorName);
|
oneOf(identityManager).createIdentity(authorName);
|
||||||
will(returnValue(localAuthor));
|
will(returnValue(identity));
|
||||||
oneOf(identityManager).registerLocalAuthor(localAuthor);
|
oneOf(identityManager).registerIdentity(identity);
|
||||||
oneOf(crypto).generateSecretKey();
|
oneOf(crypto).generateSecretKey();
|
||||||
will(returnValue(key));
|
will(returnValue(key));
|
||||||
oneOf(crypto).encryptWithPassword(key.getBytes(), password);
|
oneOf(crypto).encryptWithPassword(key.getBytes(), password);
|
||||||
|
|||||||
@@ -11,16 +11,17 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
import org.briarproject.bramble.api.db.NoSuchContactException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
import org.briarproject.bramble.api.db.NoSuchGroupException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchLocalAuthorException;
|
import org.briarproject.bramble.api.db.NoSuchIdentityException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
import org.briarproject.bramble.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchPendingContactException;
|
import org.briarproject.bramble.api.db.NoSuchPendingContactException;
|
||||||
import org.briarproject.bramble.api.db.NoSuchTransportException;
|
import org.briarproject.bramble.api.db.NoSuchTransportException;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent;
|
import org.briarproject.bramble.api.identity.event.IdentityAddedEvent;
|
||||||
import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent;
|
import org.briarproject.bramble.api.identity.event.IdentityRemovedEvent;
|
||||||
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
@@ -65,6 +66,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.INVISIBLE;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||||
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
import static org.briarproject.bramble.api.sync.Group.Visibility.VISIBLE;
|
||||||
@@ -77,8 +79,9 @@ import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
|||||||
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getContact;
|
import static org.briarproject.bramble.test.TestUtils.getContact;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getTransportId;
|
import static org.briarproject.bramble.test.TestUtils.getTransportId;
|
||||||
@@ -104,6 +107,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
private final GroupId groupId;
|
private final GroupId groupId;
|
||||||
private final Group group;
|
private final Group group;
|
||||||
private final Author author;
|
private final Author author;
|
||||||
|
private final Identity identity;
|
||||||
private final LocalAuthor localAuthor;
|
private final LocalAuthor localAuthor;
|
||||||
private final String alias;
|
private final String alias;
|
||||||
private final Message message, message1;
|
private final Message message, message1;
|
||||||
@@ -122,7 +126,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
group = getGroup(clientId, majorVersion);
|
group = getGroup(clientId, majorVersion);
|
||||||
groupId = group.getId();
|
groupId = group.getId();
|
||||||
author = getAuthor();
|
author = getAuthor();
|
||||||
localAuthor = getLocalAuthor();
|
identity = getIdentity();
|
||||||
|
localAuthor = identity.getLocalAuthor();
|
||||||
message = getMessage(groupId);
|
message = getMessage(groupId);
|
||||||
message1 = getMessage(groupId);
|
message1 = getMessage(groupId);
|
||||||
messageId = message.getId();
|
messageId = message.getId();
|
||||||
@@ -157,15 +162,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
// startTransaction()
|
// startTransaction()
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
// registerLocalAuthor()
|
// addIdentity()
|
||||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
oneOf(database).containsIdentity(txn, localAuthor.getId());
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).addLocalAuthor(txn, localAuthor);
|
oneOf(database).addIdentity(txn, identity);
|
||||||
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(IdentityAddedEvent.class)));
|
||||||
// addContact()
|
// addContact()
|
||||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
oneOf(database).containsIdentity(txn, localAuthor.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
oneOf(database).containsIdentity(txn, author.getId());
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
oneOf(database).containsContact(txn, author.getId(),
|
oneOf(database).containsContact(txn, author.getId(),
|
||||||
localAuthor.getId());
|
localAuthor.getId());
|
||||||
@@ -201,11 +206,11 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).removeContact(txn, contactId);
|
oneOf(database).removeContact(txn, contactId);
|
||||||
oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class)));
|
||||||
// removeLocalAuthor()
|
// removeIdentity()
|
||||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
oneOf(database).containsIdentity(txn, localAuthor.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).removeLocalAuthor(txn, localAuthor.getId());
|
oneOf(database).removeIdentity(txn, localAuthor.getId());
|
||||||
oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class)));
|
oneOf(eventBus).broadcast(with(any(IdentityRemovedEvent.class)));
|
||||||
// endTransaction()
|
// endTransaction()
|
||||||
oneOf(database).commitTransaction(txn);
|
oneOf(database).commitTransaction(txn);
|
||||||
// close()
|
// close()
|
||||||
@@ -216,7 +221,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
assertFalse(db.open(key, null));
|
assertFalse(db.open(key, null));
|
||||||
db.transaction(false, transaction -> {
|
db.transaction(false, transaction -> {
|
||||||
db.addLocalAuthor(transaction, localAuthor);
|
db.addIdentity(transaction, identity);
|
||||||
assertEquals(contactId, db.addContact(transaction, author,
|
assertEquals(contactId, db.addContact(transaction, author,
|
||||||
localAuthor.getId(), true));
|
localAuthor.getId(), true));
|
||||||
assertEquals(singletonList(contact),
|
assertEquals(singletonList(contact),
|
||||||
@@ -227,7 +232,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
db.getGroups(transaction, clientId, majorVersion));
|
db.getGroups(transaction, clientId, majorVersion));
|
||||||
db.removeGroup(transaction, group);
|
db.removeGroup(transaction, group);
|
||||||
db.removeContact(transaction, contactId);
|
db.removeContact(transaction, contactId);
|
||||||
db.removeLocalAuthor(transaction, localAuthor.getId());
|
db.removeIdentity(transaction, localAuthor.getId());
|
||||||
});
|
});
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
@@ -432,16 +437,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVariousMethodsThrowExceptionIfLocalAuthorIsMissing()
|
public void testVariousMethodsThrowExceptionIfIdentityIsMissing()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// Check whether the pseudonym is in the DB (which it's not)
|
// Check whether the identity is in the DB (which it's not)
|
||||||
exactly(3).of(database).startTransaction();
|
exactly(4).of(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
exactly(3).of(database).containsLocalAuthor(txn,
|
exactly(4).of(database).containsIdentity(txn, localAuthor.getId());
|
||||||
localAuthor.getId());
|
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
exactly(3).of(database).abortTransaction(txn);
|
exactly(4).of(database).abortTransaction(txn);
|
||||||
}});
|
}});
|
||||||
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
DatabaseComponent db = createDatabaseComponent(database, eventBus,
|
||||||
eventExecutor, shutdownManager);
|
eventExecutor, shutdownManager);
|
||||||
@@ -451,23 +455,34 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
db.addContact(transaction, author, localAuthor.getId(),
|
db.addContact(transaction, author, localAuthor.getId(),
|
||||||
true));
|
true));
|
||||||
fail();
|
fail();
|
||||||
} catch (NoSuchLocalAuthorException expected) {
|
} catch (NoSuchIdentityException expected) {
|
||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.transaction(false, transaction ->
|
db.transaction(false, transaction ->
|
||||||
db.getLocalAuthor(transaction, localAuthor.getId()));
|
db.getIdentity(transaction, localAuthor.getId()));
|
||||||
fail();
|
fail();
|
||||||
} catch (NoSuchLocalAuthorException expected) {
|
} catch (NoSuchIdentityException expected) {
|
||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.transaction(false, transaction ->
|
db.transaction(false, transaction ->
|
||||||
db.removeLocalAuthor(transaction, localAuthor.getId()));
|
db.removeIdentity(transaction, localAuthor.getId()));
|
||||||
fail();
|
fail();
|
||||||
} catch (NoSuchLocalAuthorException expected) {
|
} catch (NoSuchIdentityException expected) {
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||||
|
byte[] privateKey = getRandomBytes(123);
|
||||||
|
db.transaction(false, transaction ->
|
||||||
|
db.setHandshakeKeyPair(transaction, localAuthor.getId(),
|
||||||
|
publicKey, privateKey));
|
||||||
|
fail();
|
||||||
|
} catch (NoSuchIdentityException expected) {
|
||||||
// Expected
|
// Expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1403,10 +1418,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
oneOf(database).containsIdentity(txn, localAuthor.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
// Contact is a local identity
|
// Contact is a local identity
|
||||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
oneOf(database).containsIdentity(txn, author.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).abortTransaction(txn);
|
oneOf(database).abortTransaction(txn);
|
||||||
}});
|
}});
|
||||||
@@ -1429,9 +1444,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(database).startTransaction();
|
oneOf(database).startTransaction();
|
||||||
will(returnValue(txn));
|
will(returnValue(txn));
|
||||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
oneOf(database).containsIdentity(txn, localAuthor.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
oneOf(database).containsIdentity(txn, author.getId());
|
||||||
will(returnValue(false));
|
will(returnValue(false));
|
||||||
// Contact already exists for this local identity
|
// Contact already exists for this local identity
|
||||||
oneOf(database).containsContact(txn, author.getId(),
|
oneOf(database).containsContact(txn, author.getId(),
|
||||||
@@ -1454,7 +1469,6 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testMessageDependencies() throws Exception {
|
public void testMessageDependencies() throws Exception {
|
||||||
int shutdownHandle = 12345;
|
int shutdownHandle = 12345;
|
||||||
MessageId messageId2 = new MessageId(getRandomId());
|
MessageId messageId2 = new MessageId(getRandomId());
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.ContactId;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.identity.AuthorId;
|
import org.briarproject.bramble.api.identity.AuthorId;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.sync.ClientId;
|
import org.briarproject.bramble.api.sync.ClientId;
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
@@ -37,7 +38,7 @@ import static org.briarproject.bramble.api.sync.validation.MessageState.DELIVERE
|
|||||||
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
@@ -161,11 +162,11 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testContainsLocalAuthor() throws Exception {
|
public void testContainsIdentity() throws Exception {
|
||||||
String name = "containsLocalAuthor(T, AuthorId)";
|
String name = "containsIdentity(T, AuthorId)";
|
||||||
benchmark(name, db -> {
|
benchmark(name, db -> {
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
db.containsLocalAuthor(txn, localAuthor.getId());
|
db.containsIdentity(txn, localAuthor.getId());
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -295,21 +296,21 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLocalAuthor() throws Exception {
|
public void testGetIdentity() throws Exception {
|
||||||
String name = "getLocalAuthor(T, AuthorId)";
|
String name = "getIdentity(T, AuthorId)";
|
||||||
benchmark(name, db -> {
|
benchmark(name, db -> {
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
db.getLocalAuthor(txn, localAuthor.getId());
|
db.getIdentity(txn, localAuthor.getId());
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLocalAuthors() throws Exception {
|
public void testGetIdentities() throws Exception {
|
||||||
String name = "getLocalAuthors(T)";
|
String name = "getIdentities(T)";
|
||||||
benchmark(name, db -> {
|
benchmark(name, db -> {
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
db.getLocalAuthors(txn);
|
db.getIdentities(txn);
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -531,7 +532,8 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void populateDatabase(Database<Connection> db) throws DbException {
|
void populateDatabase(Database<Connection> db) throws DbException {
|
||||||
localAuthor = getLocalAuthor();
|
Identity identity = getIdentity();
|
||||||
|
localAuthor = identity.getLocalAuthor();
|
||||||
clientIds = new ArrayList<>();
|
clientIds = new ArrayList<>();
|
||||||
contacts = new ArrayList<>();
|
contacts = new ArrayList<>();
|
||||||
groups = new ArrayList<>();
|
groups = new ArrayList<>();
|
||||||
@@ -543,7 +545,7 @@ public abstract class DatabasePerformanceTest extends BrambleTestCase {
|
|||||||
for (int i = 0; i < CLIENTS; i++) clientIds.add(getClientId());
|
for (int i = 0; i < CLIENTS; i++) clientIds.add(getClientId());
|
||||||
|
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
for (int i = 0; i < CONTACTS; i++) {
|
for (int i = 0; i < CONTACTS; i++) {
|
||||||
ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(),
|
ContactId c = db.addContact(txn, getAuthor(), localAuthor.getId(),
|
||||||
random.nextBoolean());
|
random.nextBoolean());
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.db.DbException;
|
|||||||
import org.briarproject.bramble.api.db.MessageDeletedException;
|
import org.briarproject.bramble.api.db.MessageDeletedException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
@@ -57,6 +58,7 @@ 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.contact.PendingContactState.FAILED;
|
||||||
|
import static org.briarproject.bramble.api.crypto.CryptoConstants.MAX_AGREEMENT_PUBLIC_KEY_BYTES;
|
||||||
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;
|
||||||
@@ -73,9 +75,10 @@ import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
|||||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
import static org.briarproject.bramble.test.TestUtils.getClientId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
import static org.briarproject.bramble.test.TestUtils.getGroup;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
import static org.briarproject.bramble.test.TestUtils.getMessage;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getPendingContact;
|
import static org.briarproject.bramble.test.TestUtils.getPendingContact;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||||
@@ -103,6 +106,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
private final int majorVersion;
|
private final int majorVersion;
|
||||||
private final Group group;
|
private final Group group;
|
||||||
private final Author author;
|
private final Author author;
|
||||||
|
private final Identity identity;
|
||||||
private final LocalAuthor localAuthor;
|
private final LocalAuthor localAuthor;
|
||||||
private final Message message;
|
private final Message message;
|
||||||
private final MessageId messageId;
|
private final MessageId messageId;
|
||||||
@@ -119,7 +123,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
group = getGroup(clientId, majorVersion);
|
group = getGroup(clientId, majorVersion);
|
||||||
groupId = group.getId();
|
groupId = group.getId();
|
||||||
author = getAuthor();
|
author = getAuthor();
|
||||||
localAuthor = getLocalAuthor();
|
identity = getIdentity();
|
||||||
|
localAuthor = identity.getLocalAuthor();
|
||||||
message = getMessage(groupId);
|
message = getMessage(groupId);
|
||||||
messageId = message.getId();
|
messageId = message.getId();
|
||||||
transportId = getTransportId();
|
transportId = getTransportId();
|
||||||
@@ -145,7 +150,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
assertFalse(db.containsContact(txn, contactId));
|
assertFalse(db.containsContact(txn, contactId));
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
assertTrue(db.containsContact(txn, contactId));
|
assertTrue(db.containsContact(txn, contactId));
|
||||||
@@ -208,7 +213,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -239,7 +244,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared but unvalidated message
|
// Add a contact, a shared group and a shared but unvalidated message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -284,7 +289,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, an invisible group and a shared message
|
// Add a contact, an invisible group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -335,7 +340,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and an unshared message
|
// Add a contact, a shared group and an unshared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -366,7 +371,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -393,7 +398,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact and a visible group
|
// Add a contact and a visible group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -434,7 +439,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -566,7 +571,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact and a shared group
|
// Add a contact and a shared group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -586,7 +591,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact
|
// Add a contact
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
|
|
||||||
@@ -604,7 +609,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, an invisible group and a message
|
// Add a contact, an invisible group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -623,7 +628,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact and a group
|
// Add a contact and a group
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -675,7 +680,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(emptyList(), db.getTransportKeys(txn, transportId));
|
assertEquals(emptyList(), db.getTransportKeys(txn, transportId));
|
||||||
|
|
||||||
// Add the contact, the transport and the transport keys
|
// Add the contact, the transport and the transport keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
@@ -776,7 +781,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
assertEquals(emptyList(), db.getHandshakeKeys(txn, transportId));
|
assertEquals(emptyList(), db.getHandshakeKeys(txn, transportId));
|
||||||
|
|
||||||
// Add the contact, the transport and the handshake keys
|
// Add the contact, the transport and the handshake keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
@@ -929,7 +934,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add the contact, transport and transport keys
|
// Add the contact, transport and transport keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
@@ -973,7 +978,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add the contact, transport and handshake keys
|
// Add the contact, transport and handshake keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
@@ -1020,7 +1025,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add the contact, transport and transport keys
|
// Add the contact, transport and transport keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
@@ -1067,7 +1072,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add the contact, transport and handshake keys
|
// Add the contact, transport and handshake keys
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addTransport(txn, transportId, 123);
|
db.addTransport(txn, transportId, 123);
|
||||||
@@ -1109,14 +1114,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a local author - no contacts should be associated
|
// Add an identity for a local author - no contacts should be
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
// associated
|
||||||
|
db.addIdentity(txn, identity);
|
||||||
|
|
||||||
// Add a contact associated with the local author
|
// Add a contact associated with the local author
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
|
|
||||||
// Ensure contact is returned from database by Author ID
|
// Ensure contact is returned from database by author ID
|
||||||
Collection<Contact> contacts =
|
Collection<Contact> contacts =
|
||||||
db.getContactsByAuthorId(txn, author.getId());
|
db.getContactsByAuthorId(txn, author.getId());
|
||||||
assertEquals(1, contacts.size());
|
assertEquals(1, contacts.size());
|
||||||
@@ -1136,8 +1142,9 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a local author - no contacts should be associated
|
// Add an identity for a local author - no contacts should be
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
// associated
|
||||||
|
db.addIdentity(txn, identity);
|
||||||
Collection<ContactId> contacts =
|
Collection<ContactId> contacts =
|
||||||
db.getContacts(txn, localAuthor.getId());
|
db.getContacts(txn, localAuthor.getId());
|
||||||
assertEquals(emptyList(), contacts);
|
assertEquals(emptyList(), contacts);
|
||||||
@@ -1148,8 +1155,8 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
contacts = db.getContacts(txn, localAuthor.getId());
|
contacts = db.getContacts(txn, localAuthor.getId());
|
||||||
assertEquals(singletonList(contactId), contacts);
|
assertEquals(singletonList(contactId), contacts);
|
||||||
|
|
||||||
// Remove the local author - the contact should be removed
|
// Remove the identity - the contact should be removed
|
||||||
db.removeLocalAuthor(txn, localAuthor.getId());
|
db.removeIdentity(txn, localAuthor.getId());
|
||||||
contacts = db.getContacts(txn, localAuthor.getId());
|
contacts = db.getContacts(txn, localAuthor.getId());
|
||||||
assertEquals(emptyList(), contacts);
|
assertEquals(emptyList(), contacts);
|
||||||
assertFalse(db.containsContact(txn, contactId));
|
assertFalse(db.containsContact(txn, contactId));
|
||||||
@@ -1164,7 +1171,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact - initially there should be no offered messages
|
// Add a contact - initially there should be no offered messages
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
assertEquals(0, db.countOfferedMessages(txn, contactId));
|
assertEquals(0, db.countOfferedMessages(txn, contactId));
|
||||||
@@ -1748,7 +1755,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -1850,14 +1857,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testDifferentLocalAuthorsCanHaveTheSameContact()
|
public void testDifferentLocalAuthorsCanHaveTheSameContact()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
LocalAuthor localAuthor1 = getLocalAuthor();
|
Identity identity1 = getIdentity();
|
||||||
|
LocalAuthor localAuthor1 = identity1.getLocalAuthor();
|
||||||
|
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add two local authors
|
// Add identities for two local authors
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
db.addLocalAuthor(txn, localAuthor1);
|
db.addIdentity(txn, identity1);
|
||||||
|
|
||||||
// Add the same contact for each local author
|
// Add the same contact for each local author
|
||||||
ContactId contactId =
|
ContactId contactId =
|
||||||
@@ -1881,7 +1889,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -1935,7 +1943,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact
|
// Add a contact
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
|
|
||||||
@@ -1992,7 +2000,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a group and a message
|
// Add a contact, a group and a message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -2076,7 +2084,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -2121,7 +2129,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
Connection txn = db.startTransaction();
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
// Add a contact, a shared group and a shared message
|
// Add a contact, a shared group and a shared message
|
||||||
db.addLocalAuthor(txn, localAuthor);
|
db.addIdentity(txn, identity);
|
||||||
assertEquals(contactId,
|
assertEquals(contactId,
|
||||||
db.addContact(txn, author, localAuthor.getId(), true));
|
db.addContact(txn, author, localAuthor.getId(), true));
|
||||||
db.addGroup(txn, group);
|
db.addGroup(txn, group);
|
||||||
@@ -2237,6 +2245,30 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetHandshakeKeyPair() throws Exception {
|
||||||
|
Identity withoutKeys =
|
||||||
|
new Identity(localAuthor, null, null, identity.getTimeCreated());
|
||||||
|
assertFalse(withoutKeys.hasHandshakeKeyPair());
|
||||||
|
byte[] publicKey = getRandomBytes(MAX_AGREEMENT_PUBLIC_KEY_BYTES);
|
||||||
|
byte[] privateKey = getRandomBytes(123);
|
||||||
|
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
|
db.addIdentity(txn, withoutKeys);
|
||||||
|
Identity retrieved = db.getIdentity(txn, localAuthor.getId());
|
||||||
|
assertFalse(retrieved.hasHandshakeKeyPair());
|
||||||
|
db.setHandshakeKeyPair(txn, localAuthor.getId(), publicKey, privateKey);
|
||||||
|
retrieved = db.getIdentity(txn, localAuthor.getId());
|
||||||
|
assertTrue(retrieved.hasHandshakeKeyPair());
|
||||||
|
assertArrayEquals(publicKey, retrieved.getHandshakePublicKey());
|
||||||
|
assertArrayEquals(privateKey, retrieved.getHandshakePrivateKey());
|
||||||
|
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
private Database<Connection> open(boolean resume) throws Exception {
|
private Database<Connection> open(boolean resume) throws Exception {
|
||||||
return open(resume, new TestMessageFactory(), new SystemClock());
|
return open(resume, new TestMessageFactory(), new SystemClock());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,18 +8,17 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.briarproject.bramble.test.DbExpectations;
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.util.Collection;
|
import static java.util.Collections.singletonList;
|
||||||
import java.util.Collections;
|
import static org.briarproject.bramble.test.TestUtils.getIdentity;
|
||||||
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class IdentityManagerImplTest extends BrambleMockTestCase {
|
public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||||
@@ -28,67 +27,100 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
|||||||
private final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
private final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||||
private final AuthorFactory authorFactory =
|
private final AuthorFactory authorFactory =
|
||||||
context.mock(AuthorFactory.class);
|
context.mock(AuthorFactory.class);
|
||||||
private final PublicKey publicKey = context.mock(PublicKey.class);
|
private final Clock clock = context.mock(Clock.class);
|
||||||
private final PrivateKey privateKey = context.mock(PrivateKey.class);
|
private final PublicKey handshakePublicKey = context.mock(PublicKey.class);
|
||||||
|
private final PrivateKey handshakePrivateKey =
|
||||||
|
context.mock(PrivateKey.class);
|
||||||
|
|
||||||
private final Transaction txn = new Transaction(null, false);
|
private final Transaction txn = new Transaction(null, false);
|
||||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
private final Identity identityWithKeys = getIdentity();
|
||||||
private final Collection<LocalAuthor> localAuthors =
|
private final LocalAuthor localAuthor = identityWithKeys.getLocalAuthor();
|
||||||
Collections.singletonList(localAuthor);
|
private final Identity identityWithoutKeys = new Identity(localAuthor,
|
||||||
private final String authorName = localAuthor.getName();
|
null, null, identityWithKeys.getTimeCreated());
|
||||||
private final KeyPair keyPair = new KeyPair(publicKey, privateKey);
|
private final KeyPair handshakeKeyPair =
|
||||||
private final byte[] publicKeyBytes = localAuthor.getPublicKey();
|
new KeyPair(handshakePublicKey, handshakePrivateKey);
|
||||||
private final byte[] privateKeyBytes = localAuthor.getPrivateKey();
|
private final byte[] handshakePublicKeyBytes =
|
||||||
private IdentityManager identityManager;
|
identityWithKeys.getHandshakePublicKey();
|
||||||
|
private final byte[] handshakePrivateKeyBytes =
|
||||||
|
identityWithKeys.getHandshakePrivateKey();
|
||||||
|
|
||||||
|
private IdentityManagerImpl identityManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
identityManager = new IdentityManagerImpl(db, crypto, authorFactory);
|
identityManager =
|
||||||
|
new IdentityManagerImpl(db, crypto, authorFactory, clock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLocalAuthor() {
|
public void testOpenDatabaseIdentityRegistered() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(crypto).generateSignatureKeyPair();
|
oneOf(db).addIdentity(txn, identityWithKeys);
|
||||||
will(returnValue(keyPair));
|
|
||||||
oneOf(publicKey).getEncoded();
|
|
||||||
will(returnValue(publicKeyBytes));
|
|
||||||
oneOf(privateKey).getEncoded();
|
|
||||||
will(returnValue(privateKeyBytes));
|
|
||||||
oneOf(authorFactory).createLocalAuthor(authorName,
|
|
||||||
publicKeyBytes, privateKeyBytes);
|
|
||||||
will(returnValue(localAuthor));
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(localAuthor,
|
identityManager.registerIdentity(identityWithKeys);
|
||||||
identityManager.createLocalAuthor(authorName));
|
identityManager.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterAndStoreLocalAuthor() throws Exception {
|
public void testOpenDatabaseHandshakeKeysGenerated() throws Exception {
|
||||||
context.checking(new DbExpectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
oneOf(db).getIdentities(txn);
|
||||||
oneOf(db).addLocalAuthor(txn, localAuthor);
|
will(returnValue(singletonList(identityWithoutKeys)));
|
||||||
|
oneOf(crypto).generateAgreementKeyPair();
|
||||||
|
will(returnValue(handshakeKeyPair));
|
||||||
|
oneOf(handshakePublicKey).getEncoded();
|
||||||
|
will(returnValue(handshakePublicKeyBytes));
|
||||||
|
oneOf(handshakePrivateKey).getEncoded();
|
||||||
|
will(returnValue(handshakePrivateKeyBytes));
|
||||||
|
oneOf(db).setHandshakeKeyPair(txn, localAuthor.getId(),
|
||||||
|
handshakePublicKeyBytes, handshakePrivateKeyBytes);
|
||||||
}});
|
}});
|
||||||
|
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.onDatabaseOpened(txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpenDatabaseNoHandshakeKeysGenerated() throws Exception {
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(db).getIdentities(txn);
|
||||||
|
will(returnValue(singletonList(identityWithKeys)));
|
||||||
|
}});
|
||||||
|
|
||||||
|
identityManager.onDatabaseOpened(txn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetLocalAuthorIdentityRegistered() throws DbException {
|
||||||
|
identityManager.registerIdentity(identityWithKeys);
|
||||||
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
||||||
identityManager.storeLocalAuthor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetLocalAuthor() throws Exception {
|
public void testGetLocalAuthorHandshakeKeysGenerated() throws Exception {
|
||||||
context.checking(new DbExpectations() {{
|
context.checking(new DbExpectations() {{
|
||||||
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
oneOf(db).getLocalAuthors(txn);
|
oneOf(db).getIdentities(txn);
|
||||||
will(returnValue(localAuthors));
|
will(returnValue(singletonList(identityWithoutKeys)));
|
||||||
|
oneOf(crypto).generateAgreementKeyPair();
|
||||||
|
will(returnValue(handshakeKeyPair));
|
||||||
|
oneOf(handshakePublicKey).getEncoded();
|
||||||
|
will(returnValue(handshakePublicKeyBytes));
|
||||||
|
oneOf(handshakePrivateKey).getEncoded();
|
||||||
|
will(returnValue(handshakePrivateKeyBytes));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetCachedLocalAuthor() throws DbException {
|
public void testGetLocalAuthorNoHandshakeKeysGenerated() throws Exception {
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
context.checking(new DbExpectations() {{
|
||||||
|
oneOf(db).transactionWithResult(with(true), withDbCallable(txn));
|
||||||
|
oneOf(db).getIdentities(txn);
|
||||||
|
will(returnValue(singletonList(identityWithKeys)));
|
||||||
|
}});
|
||||||
|
|
||||||
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
assertEquals(localAuthor, identityManager.getLocalAuthor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package org.briarproject.bramble.lifecycle;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent;
|
||||||
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class LifecycleManagerImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
|
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||||
|
private final EventBus eventBus = context.mock(EventBus.class);
|
||||||
|
|
||||||
|
private final SecretKey dbKey = getSecretKey();
|
||||||
|
|
||||||
|
private LifecycleManagerImpl lifecycleManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
lifecycleManager = new LifecycleManagerImpl(db, eventBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOpenDatabaseHooksAreCalledAtStartup() throws Exception {
|
||||||
|
Transaction txn = new Transaction(null, false);
|
||||||
|
AtomicBoolean called = new AtomicBoolean(false);
|
||||||
|
OpenDatabaseHook hook = transaction -> called.set(true);
|
||||||
|
|
||||||
|
context.checking(new DbExpectations() {{
|
||||||
|
oneOf(db).open(dbKey, lifecycleManager);
|
||||||
|
will(returnValue(false));
|
||||||
|
oneOf(db).transaction(with(false), withDbRunnable(txn));
|
||||||
|
allowing(eventBus).broadcast(with(any(LifecycleEvent.class)));
|
||||||
|
}});
|
||||||
|
|
||||||
|
lifecycleManager.registerOpenDatabaseHook(hook);
|
||||||
|
|
||||||
|
assertEquals(SUCCESS, lifecycleManager.startServices(dbKey));
|
||||||
|
assertTrue(called.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -115,7 +115,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
1, true, true);
|
1, true, true);
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
t.createLocalState(txn);
|
t.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -129,7 +129,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
TransportPropertyManagerImpl t = createInstance();
|
TransportPropertyManagerImpl t = createInstance();
|
||||||
t.createLocalState(txn);
|
t.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
|||||||
import org.briarproject.bramble.api.lifecycle.Service;
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@@ -32,7 +31,7 @@ public class TestLifecycleModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerClient(Client c) {
|
public void registerOpenDatabaseHook(OpenDatabaseHook hook) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
|||||||
expectAddingContact();
|
expectAddingContact();
|
||||||
|
|
||||||
ClientVersioningManagerImpl c = createInstance();
|
ClientVersioningManagerImpl c = createInstance();
|
||||||
c.createLocalState(txn);
|
c.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -95,7 +95,7 @@ public class ClientVersioningManagerImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
ClientVersioningManagerImpl c = createInstance();
|
ClientVersioningManagerImpl c = createInstance();
|
||||||
c.createLocalState(txn);
|
c.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ public class AppModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
RecentEmoji provideRecentEmoji(LifecycleManager lifecycleManager,
|
RecentEmoji provideRecentEmoji(LifecycleManager lifecycleManager,
|
||||||
RecentEmojiImpl recentEmoji) {
|
RecentEmojiImpl recentEmoji) {
|
||||||
lifecycleManager.registerClient(recentEmoji);
|
lifecycleManager.registerOpenDatabaseHook(recentEmoji);
|
||||||
return recentEmoji;
|
return recentEmoji;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import com.vanniktech.emoji.emoji.Emoji;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.settings.Settings;
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
import org.briarproject.bramble.api.settings.SettingsManager;
|
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_
|
|||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
class RecentEmojiImpl implements RecentEmoji, Client {
|
class RecentEmojiImpl implements RecentEmoji, OpenDatabaseHook {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(RecentEmojiImpl.class.getName());
|
Logger.getLogger(RecentEmojiImpl.class.getName());
|
||||||
@@ -72,7 +72,7 @@ class RecentEmojiImpl implements RecentEmoji, Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
Settings settings =
|
Settings settings =
|
||||||
settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
settingsManager.getSettings(txn, SETTINGS_NAMESPACE);
|
||||||
String serialized = settings.get(EMOJI_LRU_PREFERENCE);
|
String serialized = settings.get(EMOJI_LRU_PREFERENCE);
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ public interface BlogManager {
|
|||||||
void registerRemoveBlogHook(RemoveBlogHook hook);
|
void registerRemoveBlogHook(RemoveBlogHook hook);
|
||||||
|
|
||||||
interface RemoveBlogHook {
|
interface RemoveBlogHook {
|
||||||
|
/**
|
||||||
|
* Called when a blog is being removed.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param b The blog that is being removed
|
||||||
|
*/
|
||||||
void removingBlog(Transaction txn, Blog b) throws DbException;
|
void removingBlog(Transaction txn, Blog b) throws DbException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,12 @@ public interface ForumManager {
|
|||||||
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
void setReadFlag(GroupId g, MessageId m, boolean read) throws DbException;
|
||||||
|
|
||||||
interface RemoveForumHook {
|
interface RemoveForumHook {
|
||||||
|
/**
|
||||||
|
* Called when a forum is being removed.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param f The forum that is being removed
|
||||||
|
*/
|
||||||
void removingForum(Transaction txn, Forum f) throws DbException;
|
void removingForum(Transaction txn, Forum f) throws DbException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,9 +140,22 @@ public interface PrivateGroupManager {
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
interface PrivateGroupHook {
|
interface PrivateGroupHook {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a member is being added to a private group.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param g The ID of the private group
|
||||||
|
* @param a The member that is being added
|
||||||
|
*/
|
||||||
void addingMember(Transaction txn, GroupId g, Author a)
|
void addingMember(Transaction txn, GroupId g, Author a)
|
||||||
throws DbException;
|
throws DbException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a private group is being removed.
|
||||||
|
*
|
||||||
|
* @param txn A read-write transaction
|
||||||
|
* @param g The ID of the private group that is being removed
|
||||||
|
*/
|
||||||
void removingGroup(Transaction txn, GroupId g) throws DbException;
|
void removingGroup(Transaction txn, GroupId g) throws DbException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ import org.briarproject.bramble.api.identity.AuthorId;
|
|||||||
import org.briarproject.bramble.api.identity.AuthorInfo;
|
import org.briarproject.bramble.api.identity.AuthorInfo;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
import org.briarproject.bramble.api.sync.Message;
|
||||||
@@ -68,7 +68,7 @@ import static org.briarproject.briar.api.blog.MessageType.WRAPPED_POST;
|
|||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||||
ContactHook, Client {
|
OpenDatabaseHook, ContactHook {
|
||||||
|
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
@@ -90,7 +90,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
// Create our personal blog if necessary
|
// Create our personal blog if necessary
|
||||||
LocalAuthor a = identityManager.getLocalAuthor(txn);
|
LocalAuthor a = identityManager.getLocalAuthor(txn);
|
||||||
Blog b = blogFactory.createBlog(a);
|
Blog b = blogFactory.createBlog(a);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class BlogModule {
|
|||||||
BlogManager provideBlogManager(BlogManagerImpl blogManager,
|
BlogManager provideBlogManager(BlogManagerImpl blogManager,
|
||||||
LifecycleManager lifecycleManager, ContactManager contactManager,
|
LifecycleManager lifecycleManager, ContactManager contactManager,
|
||||||
ValidationManager validationManager) {
|
ValidationManager validationManager) {
|
||||||
lifecycleManager.registerClient(blogManager);
|
lifecycleManager.registerOpenDatabaseHook(blogManager);
|
||||||
contactManager.registerContactHook(blogManager);
|
contactManager.registerContactHook(blogManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
blogManager);
|
blogManager);
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import com.rometools.rome.feed.synd.SyndFeed;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.client.ClientHelper;
|
import org.briarproject.bramble.api.client.ClientHelper;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.data.BdfEntry;
|
import org.briarproject.bramble.api.data.BdfEntry;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
@@ -32,17 +30,14 @@ import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL;
|
|||||||
|
|
||||||
class FeedFactoryImpl implements FeedFactory {
|
class FeedFactoryImpl implements FeedFactory {
|
||||||
|
|
||||||
private final CryptoComponent cryptoComponent;
|
|
||||||
private final AuthorFactory authorFactory;
|
private final AuthorFactory authorFactory;
|
||||||
private final BlogFactory blogFactory;
|
private final BlogFactory blogFactory;
|
||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FeedFactoryImpl(CryptoComponent cryptoComponent,
|
FeedFactoryImpl(AuthorFactory authorFactory, BlogFactory blogFactory,
|
||||||
AuthorFactory authorFactory, BlogFactory blogFactory,
|
|
||||||
ClientHelper clientHelper, Clock clock) {
|
ClientHelper clientHelper, Clock clock) {
|
||||||
this.cryptoComponent = cryptoComponent;
|
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
this.blogFactory = blogFactory;
|
this.blogFactory = blogFactory;
|
||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
@@ -55,10 +50,7 @@ class FeedFactoryImpl implements FeedFactory {
|
|||||||
if (title == null) title = "RSS";
|
if (title == null) title = "RSS";
|
||||||
else title = StringUtils.truncateUtf8(title, MAX_AUTHOR_NAME_LENGTH);
|
else title = StringUtils.truncateUtf8(title, MAX_AUTHOR_NAME_LENGTH);
|
||||||
|
|
||||||
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
|
LocalAuthor localAuthor = authorFactory.createLocalAuthor(title);
|
||||||
LocalAuthor localAuthor = authorFactory.createLocalAuthor(title,
|
|
||||||
keyPair.getPublic().getEncoded(),
|
|
||||||
keyPair.getPrivate().getEncoded());
|
|
||||||
Blog blog = blogFactory.createFeedBlog(localAuthor);
|
Blog blog = blogFactory.createFeedBlog(localAuthor);
|
||||||
long added = clock.currentTimeMillis();
|
long added = clock.currentTimeMillis();
|
||||||
|
|
||||||
@@ -80,7 +72,7 @@ class FeedFactoryImpl implements FeedFactory {
|
|||||||
BdfList authorList = d.getList(KEY_FEED_AUTHOR);
|
BdfList authorList = d.getList(KEY_FEED_AUTHOR);
|
||||||
byte[] privateKey = d.getRaw(KEY_FEED_PRIVATE_KEY);
|
byte[] privateKey = d.getRaw(KEY_FEED_PRIVATE_KEY);
|
||||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||||
LocalAuthor localAuthor = authorFactory.createLocalAuthor(
|
LocalAuthor localAuthor = new LocalAuthor(author.getId(),
|
||||||
author.getFormatVersion(), author.getName(),
|
author.getFormatVersion(), author.getName(),
|
||||||
author.getPublicKey(), privateKey);
|
author.getPublicKey(), privateKey);
|
||||||
Blog blog = blogFactory.createFeedBlog(localAuthor);
|
Blog blog = blogFactory.createFeedBlog(localAuthor);
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ import org.briarproject.bramble.api.event.Event;
|
|||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TorConstants;
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
import org.briarproject.bramble.api.plugin.TransportId;
|
||||||
import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent;
|
import org.briarproject.bramble.api.plugin.event.TransportEnabledEvent;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
@@ -32,6 +32,7 @@ import org.briarproject.bramble.api.system.Scheduler;
|
|||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.briarproject.briar.api.blog.Blog;
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
import org.briarproject.briar.api.blog.BlogManager;
|
import org.briarproject.briar.api.blog.BlogManager;
|
||||||
|
import org.briarproject.briar.api.blog.BlogManager.RemoveBlogHook;
|
||||||
import org.briarproject.briar.api.blog.BlogPost;
|
import org.briarproject.briar.api.blog.BlogPost;
|
||||||
import org.briarproject.briar.api.blog.BlogPostFactory;
|
import org.briarproject.briar.api.blog.BlogPostFactory;
|
||||||
import org.briarproject.briar.api.feed.Feed;
|
import org.briarproject.briar.api.feed.Feed;
|
||||||
@@ -75,8 +76,8 @@ import static org.briarproject.briar.util.HtmlUtils.clean;
|
|||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class FeedManagerImpl implements FeedManager, Client, EventListener,
|
class FeedManagerImpl implements FeedManager, EventListener, OpenDatabaseHook,
|
||||||
BlogManager.RemoveBlogHook {
|
RemoveBlogHook {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(FeedManagerImpl.class.getName());
|
Logger.getLogger(FeedManagerImpl.class.getName());
|
||||||
@@ -136,7 +137,7 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
Group g = getLocalGroup();
|
Group g = getLocalGroup();
|
||||||
// Return if we've already set the local group up
|
// Return if we've already set the local group up
|
||||||
if (db.containsGroup(txn, g.getId())) return;
|
if (db.containsGroup(txn, g.getId())) return;
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ public class FeedModule {
|
|||||||
FeedManager provideFeedManager(FeedManagerImpl feedManager,
|
FeedManager provideFeedManager(FeedManagerImpl feedManager,
|
||||||
LifecycleManager lifecycleManager, EventBus eventBus,
|
LifecycleManager lifecycleManager, EventBus eventBus,
|
||||||
BlogManager blogManager) {
|
BlogManager blogManager) {
|
||||||
|
lifecycleManager.registerOpenDatabaseHook(feedManager);
|
||||||
lifecycleManager.registerClient(feedManager);
|
|
||||||
eventBus.addListener(feedManager);
|
eventBus.addListener(feedManager);
|
||||||
blogManager.registerRemoveBlogHook(feedManager);
|
blogManager.registerRemoveBlogHook(feedManager);
|
||||||
return feedManager;
|
return feedManager;
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import org.briarproject.bramble.api.identity.AuthorId;
|
|||||||
import org.briarproject.bramble.api.identity.AuthorInfo;
|
import org.briarproject.bramble.api.identity.AuthorInfo;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -67,7 +67,7 @@ import static org.briarproject.briar.introduction.MessageType.REQUEST;
|
|||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class IntroductionManagerImpl extends ConversationClientImpl
|
class IntroductionManagerImpl extends ConversationClientImpl
|
||||||
implements IntroductionManager, Client, ContactHook,
|
implements IntroductionManager, OpenDatabaseHook, ContactHook,
|
||||||
ClientVersioningHook {
|
ClientVersioningHook {
|
||||||
|
|
||||||
private final ClientVersioningManager clientVersioningManager;
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
@@ -115,7 +115,7 @@ class IntroductionManagerImpl extends ConversationClientImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
// Create a local group to store protocol sessions
|
// Create a local group to store protocol sessions
|
||||||
if (db.containsGroup(txn, localGroup.getId())) return;
|
if (db.containsGroup(txn, localGroup.getId())) return;
|
||||||
db.addGroup(txn, localGroup);
|
db.addGroup(txn, localGroup);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class IntroductionModule {
|
|||||||
ConversationManager conversationManager,
|
ConversationManager conversationManager,
|
||||||
ClientVersioningManager clientVersioningManager,
|
ClientVersioningManager clientVersioningManager,
|
||||||
IntroductionManagerImpl introductionManager) {
|
IntroductionManagerImpl introductionManager) {
|
||||||
lifecycleManager.registerClient(introductionManager);
|
lifecycleManager.registerOpenDatabaseHook(introductionManager);
|
||||||
contactManager.registerContactHook(introductionManager);
|
contactManager.registerContactHook(introductionManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID,
|
validationManager.registerIncomingMessageHook(CLIENT_ID,
|
||||||
MAJOR_VERSION, introductionManager);
|
MAJOR_VERSION, introductionManager);
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import org.briarproject.bramble.api.data.MetadataParser;
|
|||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -50,7 +50,8 @@ import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ
|
|||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class MessagingManagerImpl extends ConversationClientImpl
|
class MessagingManagerImpl extends ConversationClientImpl
|
||||||
implements MessagingManager, Client, ContactHook, ClientVersioningHook {
|
implements MessagingManager, OpenDatabaseHook, ContactHook,
|
||||||
|
ClientVersioningHook {
|
||||||
|
|
||||||
private final ClientVersioningManager clientVersioningManager;
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
private final ContactGroupFactory contactGroupFactory;
|
private final ContactGroupFactory contactGroupFactory;
|
||||||
@@ -66,7 +67,7 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
// Create a local group to indicate that we've set this client up
|
// Create a local group to indicate that we've set this client up
|
||||||
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
|
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION);
|
MAJOR_VERSION);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class MessagingModule {
|
|||||||
ConversationManager conversationManager,
|
ConversationManager conversationManager,
|
||||||
ClientVersioningManager clientVersioningManager,
|
ClientVersioningManager clientVersioningManager,
|
||||||
MessagingManagerImpl messagingManager) {
|
MessagingManagerImpl messagingManager) {
|
||||||
lifecycleManager.registerClient(messagingManager);
|
lifecycleManager.registerOpenDatabaseHook(messagingManager);
|
||||||
contactManager.registerContactHook(messagingManager);
|
contactManager.registerContactHook(messagingManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
messagingManager);
|
messagingManager);
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import org.briarproject.bramble.api.db.DbException;
|
|||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -62,7 +62,7 @@ import static org.briarproject.briar.privategroup.invitation.Role.PEER;
|
|||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class GroupInvitationManagerImpl extends ConversationClientImpl
|
class GroupInvitationManagerImpl extends ConversationClientImpl
|
||||||
implements GroupInvitationManager, Client, ContactHook,
|
implements GroupInvitationManager, OpenDatabaseHook, ContactHook,
|
||||||
PrivateGroupHook, ClientVersioningHook {
|
PrivateGroupHook, ClientVersioningHook {
|
||||||
|
|
||||||
private final ClientVersioningManager clientVersioningManager;
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
@@ -101,7 +101,7 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
// Create a local group to indicate that we've set this client up
|
// Create a local group to indicate that we've set this client up
|
||||||
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
|
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION);
|
MAJOR_VERSION);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class GroupInvitationModule {
|
|||||||
PrivateGroupManager privateGroupManager,
|
PrivateGroupManager privateGroupManager,
|
||||||
ConversationManager conversationManager,
|
ConversationManager conversationManager,
|
||||||
ClientVersioningManager clientVersioningManager) {
|
ClientVersioningManager clientVersioningManager) {
|
||||||
lifecycleManager.registerClient(groupInvitationManager);
|
lifecycleManager.registerOpenDatabaseHook(groupInvitationManager);
|
||||||
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
validationManager.registerIncomingMessageHook(CLIENT_ID, MAJOR_VERSION,
|
||||||
groupInvitationManager);
|
groupInvitationManager);
|
||||||
contactManager.registerContactHook(groupInvitationManager);
|
contactManager.registerContactHook(groupInvitationManager);
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Metadata;
|
import org.briarproject.bramble.api.db.Metadata;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.Client;
|
|
||||||
import org.briarproject.bramble.api.sync.ClientId;
|
import org.briarproject.bramble.api.sync.ClientId;
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
import org.briarproject.bramble.api.sync.Group;
|
||||||
import org.briarproject.bramble.api.sync.Group.Visibility;
|
import org.briarproject.bramble.api.sync.Group.Visibility;
|
||||||
@@ -55,7 +55,7 @@ import static org.briarproject.briar.sharing.State.SHARING;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
abstract class SharingManagerImpl<S extends Shareable>
|
abstract class SharingManagerImpl<S extends Shareable>
|
||||||
extends ConversationClientImpl
|
extends ConversationClientImpl
|
||||||
implements SharingManager<S>, Client, ContactHook,
|
implements SharingManager<S>, OpenDatabaseHook, ContactHook,
|
||||||
ClientVersioningHook {
|
ClientVersioningHook {
|
||||||
|
|
||||||
private final ClientVersioningManager clientVersioningManager;
|
private final ClientVersioningManager clientVersioningManager;
|
||||||
@@ -92,7 +92,7 @@ abstract class SharingManagerImpl<S extends Shareable>
|
|||||||
protected abstract int getShareableMajorVersion();
|
protected abstract int getShareableMajorVersion();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createLocalState(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
// Create a local group to indicate that we've set this client up
|
// Create a local group to indicate that we've set this client up
|
||||||
Group localGroup = contactGroupFactory.createLocalGroup(getClientId(),
|
Group localGroup = contactGroupFactory.createLocalGroup(getClientId(),
|
||||||
getMajorVersion());
|
getMajorVersion());
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class SharingModule {
|
|||||||
ConversationManager conversationManager, BlogManager blogManager,
|
ConversationManager conversationManager, BlogManager blogManager,
|
||||||
ClientVersioningManager clientVersioningManager,
|
ClientVersioningManager clientVersioningManager,
|
||||||
BlogSharingManagerImpl blogSharingManager) {
|
BlogSharingManagerImpl blogSharingManager) {
|
||||||
lifecycleManager.registerClient(blogSharingManager);
|
lifecycleManager.registerOpenDatabaseHook(blogSharingManager);
|
||||||
contactManager.registerContactHook(blogSharingManager);
|
contactManager.registerContactHook(blogSharingManager);
|
||||||
validationManager.registerIncomingMessageHook(
|
validationManager.registerIncomingMessageHook(
|
||||||
BlogSharingManager.CLIENT_ID, BlogSharingManager.MAJOR_VERSION,
|
BlogSharingManager.CLIENT_ID, BlogSharingManager.MAJOR_VERSION,
|
||||||
@@ -135,7 +135,7 @@ public class SharingModule {
|
|||||||
ConversationManager conversationManager, ForumManager forumManager,
|
ConversationManager conversationManager, ForumManager forumManager,
|
||||||
ClientVersioningManager clientVersioningManager,
|
ClientVersioningManager clientVersioningManager,
|
||||||
ForumSharingManagerImpl forumSharingManager) {
|
ForumSharingManagerImpl forumSharingManager) {
|
||||||
lifecycleManager.registerClient(forumSharingManager);
|
lifecycleManager.registerOpenDatabaseHook(forumSharingManager);
|
||||||
contactManager.registerContactHook(forumSharingManager);
|
contactManager.registerContactHook(forumSharingManager);
|
||||||
validationManager.registerIncomingMessageHook(
|
validationManager.registerIncomingMessageHook(
|
||||||
ForumSharingManager.CLIENT_ID,
|
ForumSharingManager.CLIENT_ID,
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
|||||||
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.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
@@ -74,7 +72,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
private final ClientHelper clientHelper;
|
private final ClientHelper clientHelper;
|
||||||
private final MessageTracker messageTracker;
|
private final MessageTracker messageTracker;
|
||||||
private final BlogPostFactory blogPostFactory;
|
private final BlogPostFactory blogPostFactory;
|
||||||
private final CryptoComponent cryptoComponent;
|
|
||||||
|
|
||||||
private final DatabaseComponent db;
|
private final DatabaseComponent db;
|
||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
@@ -94,9 +91,8 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
TestDataCreatorImpl(AuthorFactory authorFactory, Clock clock,
|
TestDataCreatorImpl(AuthorFactory authorFactory, Clock clock,
|
||||||
PrivateMessageFactory privateMessageFactory,
|
PrivateMessageFactory privateMessageFactory,
|
||||||
ClientHelper clientHelper, MessageTracker messageTracker,
|
ClientHelper clientHelper, MessageTracker messageTracker,
|
||||||
BlogPostFactory blogPostFactory, CryptoComponent cryptoComponent,
|
BlogPostFactory blogPostFactory, DatabaseComponent db,
|
||||||
DatabaseComponent db, IdentityManager identityManager,
|
IdentityManager identityManager, ContactManager contactManager,
|
||||||
ContactManager contactManager,
|
|
||||||
TransportPropertyManager transportPropertyManager,
|
TransportPropertyManager transportPropertyManager,
|
||||||
MessagingManager messagingManager, BlogManager blogManager,
|
MessagingManager messagingManager, BlogManager blogManager,
|
||||||
ForumManager forumManager, @IoExecutor Executor ioExecutor) {
|
ForumManager forumManager, @IoExecutor Executor ioExecutor) {
|
||||||
@@ -106,7 +102,6 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
this.clientHelper = clientHelper;
|
this.clientHelper = clientHelper;
|
||||||
this.messageTracker = messageTracker;
|
this.messageTracker = messageTracker;
|
||||||
this.blogPostFactory = blogPostFactory;
|
this.blogPostFactory = blogPostFactory;
|
||||||
this.cryptoComponent = cryptoComponent;
|
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.identityManager = identityManager;
|
this.identityManager = identityManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
@@ -150,14 +145,14 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
List<Contact> contacts = new ArrayList<>(numContacts);
|
List<Contact> contacts = new ArrayList<>(numContacts);
|
||||||
LocalAuthor localAuthor = identityManager.getLocalAuthor();
|
LocalAuthor localAuthor = identityManager.getLocalAuthor();
|
||||||
for (int i = 0; i < numContacts; i++) {
|
for (int i = 0; i < numContacts; i++) {
|
||||||
LocalAuthor author = getRandomAuthor();
|
LocalAuthor remote = getRandomAuthor();
|
||||||
Contact contact = addContact(localAuthor.getId(), author);
|
Contact contact = addContact(localAuthor.getId(), remote);
|
||||||
contacts.add(contact);
|
contacts.add(contact);
|
||||||
}
|
}
|
||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Contact addContact(AuthorId localAuthorId, LocalAuthor author)
|
private Contact addContact(AuthorId localAuthorId, LocalAuthor remote)
|
||||||
throws DbException {
|
throws DbException {
|
||||||
|
|
||||||
// prepare to add contact
|
// prepare to add contact
|
||||||
@@ -173,7 +168,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
ContactId contactId = contactManager
|
ContactId contactId = contactManager
|
||||||
.addContact(txn, author, localAuthorId, secretKey,
|
.addContact(txn, remote, localAuthorId, secretKey,
|
||||||
timestamp, true, verified, true);
|
timestamp, true, verified, true);
|
||||||
if (random.nextBoolean()) {
|
if (random.nextBoolean()) {
|
||||||
contactManager
|
contactManager
|
||||||
@@ -187,24 +182,18 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Added contact " + author.getName());
|
LOG.info("Added contact " + remote.getName());
|
||||||
LOG.info("with transport properties: " + props.toString());
|
LOG.info("with transport properties: " + props.toString());
|
||||||
}
|
}
|
||||||
localAuthors.put(contact, author);
|
localAuthors.put(contact, remote);
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Contact addContact(String name) throws DbException {
|
public Contact addContact(String name) throws DbException {
|
||||||
LocalAuthor localAuthor = identityManager.getLocalAuthor();
|
LocalAuthor localAuthor = identityManager.getLocalAuthor();
|
||||||
return addContact(localAuthor.getId(), getAuthor(name));
|
LocalAuthor remote = authorFactory.createLocalAuthor(name);
|
||||||
}
|
return addContact(localAuthor.getId(), remote);
|
||||||
|
|
||||||
private LocalAuthor getAuthor(String name) {
|
|
||||||
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
|
|
||||||
byte[] publicKey = keyPair.getPublic().getEncoded();
|
|
||||||
byte[] privateKey = keyPair.getPrivate().getEncoded();
|
|
||||||
return authorFactory.createLocalAuthor(name, publicKey, privateKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRandomAuthorName() {
|
private String getRandomAuthorName() {
|
||||||
@@ -213,7 +202,7 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private LocalAuthor getRandomAuthor() {
|
private LocalAuthor getRandomAuthor() {
|
||||||
return getAuthor(getRandomAuthorName());
|
return authorFactory.createLocalAuthor(getRandomAuthorName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecretKey getSecretKey() {
|
private SecretKey getSecretKey() {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLocalState() throws DbException {
|
public void testOpenDatabaseHook() throws DbException {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
@@ -123,7 +123,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
|||||||
oneOf(db).addGroup(txn, blog1.getGroup());
|
oneOf(db).addGroup(txn, blog1.getGroup());
|
||||||
}});
|
}});
|
||||||
|
|
||||||
blogManager.createLocalState(txn);
|
blogManager.onDatabaseOpened(txn);
|
||||||
context.assertIsSatisfied();
|
context.assertIsSatisfied();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ import java.util.Iterator;
|
|||||||
|
|
||||||
import static junit.framework.Assert.assertNotNull;
|
import static junit.framework.Assert.assertNotNull;
|
||||||
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.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.NONE;
|
import static org.briarproject.bramble.api.identity.AuthorInfo.Status.NONE;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.briarproject.briar.api.blog.MessageType.COMMENT;
|
import static org.briarproject.briar.api.blog.MessageType.COMMENT;
|
||||||
import static org.briarproject.briar.api.blog.MessageType.POST;
|
import static org.briarproject.briar.api.blog.MessageType.POST;
|
||||||
@@ -50,10 +48,8 @@ public class BlogManagerIntegrationTest
|
|||||||
|
|
||||||
author0 = identityManager0.getLocalAuthor();
|
author0 = identityManager0.getLocalAuthor();
|
||||||
author1 = identityManager1.getLocalAuthor();
|
author1 = identityManager1.getLocalAuthor();
|
||||||
rssAuthor = c0.getAuthorFactory().createLocalAuthor(
|
String rssTitle = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||||
getRandomString(MAX_AUTHOR_NAME_LENGTH),
|
rssAuthor = c0.getAuthorFactory().createLocalAuthor(rssTitle);
|
||||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
|
||||||
getRandomBytes(123));
|
|
||||||
|
|
||||||
blogManager0 = c0.getBlogManager();
|
blogManager0 = c0.getBlogManager();
|
||||||
blogManager1 = c1.getBlogManager();
|
blogManager1 = c1.getBlogManager();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package org.briarproject.briar.feed;
|
package org.briarproject.briar.feed;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.contact.ContactModule;
|
import org.briarproject.bramble.contact.ContactModule;
|
||||||
import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
import org.briarproject.bramble.crypto.CryptoExecutorModule;
|
||||||
@@ -51,8 +51,8 @@ public class FeedManagerIntegrationTest extends BriarTestCase {
|
|||||||
injectEagerSingletons(component);
|
injectEagerSingletons(component);
|
||||||
|
|
||||||
IdentityManager identityManager = component.getIdentityManager();
|
IdentityManager identityManager = component.getIdentityManager();
|
||||||
LocalAuthor localAuthor = identityManager.createLocalAuthor("feedTest");
|
Identity identity = identityManager.createIdentity("feedTest");
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.registerIdentity(identity);
|
||||||
|
|
||||||
lifecycleManager = component.getLifecycleManager();
|
lifecycleManager = component.getLifecycleManager();
|
||||||
lifecycleManager.startServices(getSecretKey());
|
lifecycleManager.startServices(getSecretKey());
|
||||||
|
|||||||
@@ -58,10 +58,8 @@ public class IntroductionCryptoIntegrationTest extends BrambleTestCase {
|
|||||||
crypto = new IntroductionCryptoImpl(cryptoComponent, clientHelper);
|
crypto = new IntroductionCryptoImpl(cryptoComponent, clientHelper);
|
||||||
|
|
||||||
introducer = getRealAuthor(authorFactory);
|
introducer = getRealAuthor(authorFactory);
|
||||||
LocalAuthor introducee1 =
|
LocalAuthor introducee1 = getRealLocalAuthor(authorFactory);
|
||||||
getRealLocalAuthor(cryptoComponent, authorFactory);
|
LocalAuthor introducee2 = getRealLocalAuthor(authorFactory);
|
||||||
LocalAuthor introducee2 =
|
|
||||||
getRealLocalAuthor(cryptoComponent, authorFactory);
|
|
||||||
boolean isAlice =
|
boolean isAlice =
|
||||||
crypto.isAlice(introducee1.getId(), introducee2.getId());
|
crypto.isAlice(introducee1.getId(), introducee2.getId());
|
||||||
alice = isAlice ? introducee1 : introducee2;
|
alice = isAlice ? introducee1 : introducee2;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.briarproject.briar.messaging;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.UniqueId;
|
import org.briarproject.bramble.api.UniqueId;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.PrivateKey;
|
|
||||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -70,12 +69,8 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testForumPostFitsIntoRecord() throws Exception {
|
public void testForumPostFitsIntoRecord() throws Exception {
|
||||||
// Create a maximum-length author
|
// Create a maximum-length author
|
||||||
int formatVersion = Integer.MAX_VALUE;
|
|
||||||
String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||||
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
|
LocalAuthor author = authorFactory.createLocalAuthor(authorName);
|
||||||
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
|
|
||||||
LocalAuthor author = authorFactory.createLocalAuthor(formatVersion,
|
|
||||||
authorName, authorPublic, privateKey.getEncoded());
|
|
||||||
// Create a maximum-length forum post
|
// Create a maximum-length forum post
|
||||||
GroupId groupId = new GroupId(getRandomId());
|
GroupId groupId = new GroupId(getRandomId());
|
||||||
long timestamp = Long.MAX_VALUE;
|
long timestamp = Long.MAX_VALUE;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import org.briarproject.bramble.api.crypto.SecretKey;
|
|||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
@@ -75,13 +75,14 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testWriteAndRead() throws Exception {
|
public void testWriteAndRead() throws Exception {
|
||||||
// Create the identities
|
// Create the identities
|
||||||
LocalAuthor aliceAuthor =
|
Identity aliceIdentity =
|
||||||
alice.getIdentityManager().createLocalAuthor("Alice");
|
alice.getIdentityManager().createIdentity("Alice");
|
||||||
LocalAuthor bobAuthor =
|
Identity bobIdentity = bob.getIdentityManager().createIdentity("Bob");
|
||||||
bob.getIdentityManager().createLocalAuthor("Bob");
|
|
||||||
// Set up the devices and get the contact IDs
|
// Set up the devices and get the contact IDs
|
||||||
ContactId bobId = setUp(alice, aliceAuthor, bobAuthor, true);
|
ContactId bobId = setUp(alice, aliceIdentity,
|
||||||
ContactId aliceId = setUp(bob, bobAuthor, aliceAuthor, false);
|
bobIdentity.getLocalAuthor(), true);
|
||||||
|
ContactId aliceId = setUp(bob, bobIdentity,
|
||||||
|
aliceIdentity.getLocalAuthor(), false);
|
||||||
// Add a private message listener
|
// Add a private message listener
|
||||||
PrivateMessageListener listener = new PrivateMessageListener();
|
PrivateMessageListener listener = new PrivateMessageListener();
|
||||||
bob.getEventBus().addListener(listener);
|
bob.getEventBus().addListener(listener);
|
||||||
@@ -100,10 +101,10 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ContactId setUp(SimplexMessagingIntegrationTestComponent device,
|
private ContactId setUp(SimplexMessagingIntegrationTestComponent device,
|
||||||
LocalAuthor local, Author remote, boolean alice) throws Exception {
|
Identity local, Author remote, boolean alice) throws Exception {
|
||||||
// Add an identity for the user
|
// Add an identity for the user
|
||||||
IdentityManager identityManager = device.getIdentityManager();
|
IdentityManager identityManager = device.getIdentityManager();
|
||||||
identityManager.registerLocalAuthor(local);
|
identityManager.registerIdentity(local);
|
||||||
// Start the lifecycle manager
|
// Start the lifecycle manager
|
||||||
LifecycleManager lifecycleManager = device.getLifecycleManager();
|
LifecycleManager lifecycleManager = device.getLifecycleManager();
|
||||||
lifecycleManager.startServices(getSecretKey());
|
lifecycleManager.startServices(getSecretKey());
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLocalStateFirstTime() throws Exception {
|
public void testDatabaseOpenHookFirstTime() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION);
|
MAJOR_VERSION);
|
||||||
@@ -161,11 +161,11 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(Collections.singletonList(contact)));
|
will(returnValue(Collections.singletonList(contact)));
|
||||||
}});
|
}});
|
||||||
expectAddingContact(contact);
|
expectAddingContact(contact);
|
||||||
groupInvitationManager.createLocalState(txn);
|
groupInvitationManager.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLocalStateSubsequentTime() throws Exception {
|
public void testOpenDatabaseHookSubsequentTime() throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID,
|
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION);
|
MAJOR_VERSION);
|
||||||
@@ -173,7 +173,7 @@ public class GroupInvitationManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(db).containsGroup(txn, localGroup.getId());
|
oneOf(db).containsGroup(txn, localGroup.getId());
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
}});
|
}});
|
||||||
groupInvitationManager.createLocalState(txn);
|
groupInvitationManager.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectAddingContact(Contact c) throws Exception {
|
private void expectAddingContact(Contact c) throws Exception {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLocalStateFirstTimeWithExistingContact()
|
public void testOpenDatabaseHookFirstTimeWithExistingContact()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
|||||||
// Set things up for the contact
|
// Set things up for the contact
|
||||||
expectAddingContact(txn);
|
expectAddingContact(txn);
|
||||||
|
|
||||||
blogSharingManager.createLocalState(txn);
|
blogSharingManager.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectAddingContact(Transaction txn) throws Exception {
|
private void expectAddingContact(Transaction txn) throws Exception {
|
||||||
@@ -149,7 +149,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateLocalStateSubsequentTime() throws Exception {
|
public void testOpenDatabaseHookSubsequentTime() throws Exception {
|
||||||
Transaction txn = new Transaction(null, false);
|
Transaction txn = new Transaction(null, false);
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
@@ -161,7 +161,7 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
|||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
blogSharingManager.createLocalState(txn);
|
blogSharingManager.onDatabaseOpened(txn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
|||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventListener;
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
|
import org.briarproject.bramble.api.identity.Identity;
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
@@ -274,12 +275,15 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createAndRegisterIdentities() {
|
private void createAndRegisterIdentities() {
|
||||||
author0 = identityManager0.createLocalAuthor(AUTHOR0);
|
Identity identity0 = identityManager0.createIdentity(AUTHOR0);
|
||||||
identityManager0.registerLocalAuthor(author0);
|
identityManager0.registerIdentity(identity0);
|
||||||
author1 = identityManager1.createLocalAuthor(AUTHOR1);
|
author0 = identity0.getLocalAuthor();
|
||||||
identityManager1.registerLocalAuthor(author1);
|
Identity identity1 = identityManager0.createIdentity(AUTHOR1);
|
||||||
author2 = identityManager2.createLocalAuthor(AUTHOR2);
|
identityManager1.registerIdentity(identity1);
|
||||||
identityManager2.registerLocalAuthor(author2);
|
author1 = identity1.getLocalAuthor();
|
||||||
|
Identity identity2 = identityManager0.createIdentity(AUTHOR2);
|
||||||
|
identityManager2.registerIdentity(identity2);
|
||||||
|
author2 = identity2.getLocalAuthor();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addDefaultContacts() throws Exception {
|
protected void addDefaultContacts() throws Exception {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package org.briarproject.briar.test;
|
package org.briarproject.briar.test;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.KeyPair;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||||
@@ -10,8 +8,7 @@ import org.briarproject.bramble.api.sync.GroupId;
|
|||||||
import org.briarproject.briar.api.client.MessageTracker;
|
import org.briarproject.briar.api.client.MessageTracker;
|
||||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
@@ -27,23 +24,20 @@ public class BriarTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void assertGroupCount(MessageTracker tracker, GroupId g,
|
public static void assertGroupCount(MessageTracker tracker, GroupId g,
|
||||||
long msgCount, long unreadCount) throws DbException {
|
long msgCount, long unreadCount) throws DbException {
|
||||||
GroupCount c1 = tracker.getGroupCount(g);
|
GroupCount c1 = tracker.getGroupCount(g);
|
||||||
assertEquals(msgCount, c1.getMsgCount());
|
assertEquals(msgCount, c1.getMsgCount());
|
||||||
assertEquals(unreadCount, c1.getUnreadCount());
|
assertEquals(unreadCount, c1.getUnreadCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Author getRealAuthor(AuthorFactory authorFactory) {
|
public static Author getRealAuthor(AuthorFactory authorFactory) {
|
||||||
return authorFactory.createAuthor(getRandomString(5),
|
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
return authorFactory.createLocalAuthor(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LocalAuthor getRealLocalAuthor(
|
public static LocalAuthor getRealLocalAuthor(AuthorFactory authorFactory) {
|
||||||
CryptoComponent cryptoComponent, AuthorFactory authorFactory) {
|
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||||
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
|
return authorFactory.createLocalAuthor(name);
|
||||||
return authorFactory.createLocalAuthor(getRandomString(5),
|
|
||||||
keyPair.getPublic().getEncoded(),
|
|
||||||
keyPair.getPrivate().getEncoded());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user