mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Merge branch '617-author-versioning' into 'master'
Use a versioned format for encoding authors See merge request akwizgran/briar!661
This commit is contained in:
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
@@ -93,10 +94,13 @@ public interface ClientHelper {
|
||||
|
||||
BdfList toList(Message m) throws FormatException;
|
||||
|
||||
BdfList toList(Author a);
|
||||
|
||||
byte[] sign(String label, BdfList toSign, byte[] privateKey)
|
||||
throws FormatException, GeneralSecurityException;
|
||||
|
||||
void verifySignature(String label, byte[] sig, byte[] publicKey,
|
||||
BdfList signed) throws FormatException, GeneralSecurityException;
|
||||
|
||||
Author parseAndValidateAuthor(BdfList author) throws FormatException;
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.briarproject.bramble.api.data;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@NotNullByDefault
|
||||
public interface ObjectReader<T> {
|
||||
|
||||
T readObject(BdfReader r) throws IOException;
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package org.briarproject.bramble.api.identity;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
|
||||
/**
|
||||
* A pseudonym for a user.
|
||||
*/
|
||||
@@ -17,20 +19,25 @@ public class Author {
|
||||
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
|
||||
}
|
||||
|
||||
/**
|
||||
* The current version of the author structure.
|
||||
*/
|
||||
public static final int FORMAT_VERSION = 0;
|
||||
|
||||
private final AuthorId id;
|
||||
private final int formatVersion;
|
||||
private final String name;
|
||||
private final byte[] publicKey;
|
||||
|
||||
public Author(AuthorId id, String name, byte[] publicKey) {
|
||||
int length;
|
||||
try {
|
||||
length = name.getBytes("UTF-8").length;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (length == 0 || length > AuthorConstants.MAX_AUTHOR_NAME_LENGTH)
|
||||
public Author(AuthorId id, int formatVersion, String name,
|
||||
byte[] publicKey) {
|
||||
int nameLength = StringUtils.toUtf8(name).length;
|
||||
if (nameLength == 0 || nameLength > MAX_AUTHOR_NAME_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
if (publicKey.length == 0 || publicKey.length > MAX_PUBLIC_KEY_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
this.id = id;
|
||||
this.formatVersion = formatVersion;
|
||||
this.name = name;
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
@@ -42,6 +49,13 @@ public class Author {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the author structure used to create the author.
|
||||
*/
|
||||
public int getFormatVersion() {
|
||||
return formatVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the author's name.
|
||||
*/
|
||||
|
||||
@@ -5,8 +5,27 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
@NotNullByDefault
|
||||
public interface AuthorFactory {
|
||||
|
||||
/**
|
||||
* Creates an author with the current format version and the given name and
|
||||
* public key.
|
||||
*/
|
||||
Author createAuthor(String name, byte[] publicKey);
|
||||
|
||||
/**
|
||||
* Creates an author with the given format version, name and public key.
|
||||
*/
|
||||
Author createAuthor(int formatVersion, String name, byte[] publicKey);
|
||||
|
||||
/**
|
||||
* Creates a local author with the current format version and the given
|
||||
* name and keys.
|
||||
*/
|
||||
LocalAuthor createLocalAuthor(String name, byte[] publicKey,
|
||||
byte[] privateKey);
|
||||
|
||||
/**
|
||||
* Creates a local author with the given format version, name and keys.
|
||||
*/
|
||||
LocalAuthor createLocalAuthor(int formatVersion, String name,
|
||||
byte[] publicKey, byte[] privateKey);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ public class LocalAuthor extends Author {
|
||||
private final byte[] privateKey;
|
||||
private final long created;
|
||||
|
||||
public LocalAuthor(AuthorId id, String name, byte[] publicKey,
|
||||
byte[] privateKey, long created) {
|
||||
super(id, name, publicKey);
|
||||
public LocalAuthor(AuthorId id, int formatVersion, String name,
|
||||
byte[] publicKey, byte[] privateKey, long created) {
|
||||
super(id, formatVersion, name, publicKey);
|
||||
this.privateKey = privateKey;
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
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_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
@@ -67,7 +68,8 @@ public class TestUtils {
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
long created = System.currentTimeMillis();
|
||||
return new LocalAuthor(id, name, publicKey, privateKey, created);
|
||||
return new LocalAuthor(id, FORMAT_VERSION, name, publicKey, privateKey,
|
||||
created);
|
||||
}
|
||||
|
||||
public static Author getAuthor() {
|
||||
@@ -78,7 +80,7 @@ public class TestUtils {
|
||||
AuthorId id = new AuthorId(getRandomId());
|
||||
String name = getRandomString(nameLength);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
return new Author(id, name, publicKey);
|
||||
return new Author(id, FORMAT_VERSION, name, publicKey);
|
||||
}
|
||||
|
||||
public static Group getGroup(ClientId clientId) {
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Metadata;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
@@ -32,7 +34,12 @@ import java.util.Map.Entry;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
@@ -51,12 +58,14 @@ class ClientHelperImpl implements ClientHelper {
|
||||
private final MetadataParser metadataParser;
|
||||
private final MetadataEncoder metadataEncoder;
|
||||
private final CryptoComponent crypto;
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
@Inject
|
||||
ClientHelperImpl(DatabaseComponent db, MessageFactory messageFactory,
|
||||
BdfReaderFactory bdfReaderFactory,
|
||||
BdfWriterFactory bdfWriterFactory, MetadataParser metadataParser,
|
||||
MetadataEncoder metadataEncoder, CryptoComponent crypto) {
|
||||
MetadataEncoder metadataEncoder, CryptoComponent crypto,
|
||||
AuthorFactory authorFactory) {
|
||||
this.db = db;
|
||||
this.messageFactory = messageFactory;
|
||||
this.bdfReaderFactory = bdfReaderFactory;
|
||||
@@ -64,6 +73,7 @@ class ClientHelperImpl implements ClientHelper {
|
||||
this.metadataParser = metadataParser;
|
||||
this.metadataEncoder = metadataEncoder;
|
||||
this.crypto = crypto;
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -341,6 +351,11 @@ class ClientHelperImpl implements ClientHelper {
|
||||
raw.length - MESSAGE_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfList toList(Author a) {
|
||||
return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] sign(String label, BdfList toSign, byte[] privateKey)
|
||||
throws FormatException, GeneralSecurityException {
|
||||
@@ -355,4 +370,16 @@ class ClientHelperImpl implements ClientHelper {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Author parseAndValidateAuthor(BdfList author)
|
||||
throws FormatException {
|
||||
checkSize(author, 3);
|
||||
int formatVersion = author.getLong(0).intValue();
|
||||
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
||||
String name = author.getString(1);
|
||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = author.getRaw(2);
|
||||
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
return authorFactory.createAuthor(formatVersion, name, publicKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,6 @@ package org.briarproject.bramble.client;
|
||||
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.data.MetadataParser;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
@@ -18,19 +10,14 @@ import dagger.Provides;
|
||||
public class ClientModule {
|
||||
|
||||
@Provides
|
||||
ClientHelper provideClientHelper(DatabaseComponent db,
|
||||
MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory,
|
||||
BdfWriterFactory bdfWriterFactory, MetadataParser metadataParser,
|
||||
MetadataEncoder metadataEncoder, CryptoComponent cryptoComponent) {
|
||||
return new ClientHelperImpl(db, messageFactory, bdfReaderFactory,
|
||||
bdfWriterFactory, metadataParser, metadataEncoder,
|
||||
cryptoComponent);
|
||||
ClientHelper provideClientHelper(ClientHelperImpl clientHelper) {
|
||||
return clientHelper;
|
||||
}
|
||||
|
||||
@Provides
|
||||
ContactGroupFactory provideContactGroupFactory(GroupFactory groupFactory,
|
||||
ClientHelper clientHelper) {
|
||||
return new ContactGroupFactoryImpl(groupFactory, clientHelper);
|
||||
ContactGroupFactory provideContactGroupFactory(
|
||||
ContactGroupFactoryImpl contactGroupFactory) {
|
||||
return contactGroupFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
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_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||
@@ -227,6 +228,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
|
||||
// Write the name, public key and signature
|
||||
w.writeListStart();
|
||||
w.writeLong(localAuthor.getFormatVersion());
|
||||
w.writeString(localAuthor.getName());
|
||||
w.writeRaw(localAuthor.getPublicKey());
|
||||
w.writeRaw(sig);
|
||||
@@ -236,11 +238,16 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
|
||||
private Author receivePseudonym(BdfReader r, byte[] nonce)
|
||||
throws GeneralSecurityException, IOException {
|
||||
// Read the name, public key and signature
|
||||
// Read the format version, name, public key and signature
|
||||
r.readListStart();
|
||||
int formatVersion = (int) r.readLong();
|
||||
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
||||
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
|
||||
if (name.isEmpty()) throw new FormatException();
|
||||
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
||||
if (publicKey.length == 0) throw new FormatException();
|
||||
byte[] sig = r.readRaw(MAX_SIGNATURE_LENGTH);
|
||||
if (sig.length == 0) throw new FormatException();
|
||||
r.readListEnd();
|
||||
LOG.info("Received pseudonym");
|
||||
// Verify the signature
|
||||
@@ -249,7 +256,7 @@ class ContactExchangeTaskImpl extends Thread implements ContactExchangeTask {
|
||||
LOG.info("Invalid signature");
|
||||
throw new GeneralSecurityException();
|
||||
}
|
||||
return authorFactory.createAuthor(name, publicKey);
|
||||
return authorFactory.createAuthor(formatVersion, name, publicKey);
|
||||
}
|
||||
|
||||
private void sendTimestamp(BdfWriter w, long timestamp)
|
||||
|
||||
@@ -68,8 +68,8 @@ import static org.briarproject.bramble.db.ExponentialBackoff.calculateExpiry;
|
||||
@NotNullByDefault
|
||||
abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
private static final int SCHEMA_VERSION = 32;
|
||||
private static final int MIN_SCHEMA_VERSION = 32;
|
||||
private static final int SCHEMA_VERSION = 33;
|
||||
private static final int MIN_SCHEMA_VERSION = 33;
|
||||
|
||||
private static final String CREATE_SETTINGS =
|
||||
"CREATE TABLE settings"
|
||||
@@ -81,6 +81,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private static final String CREATE_LOCAL_AUTHORS =
|
||||
"CREATE TABLE localAuthors"
|
||||
+ " (authorId _HASH NOT NULL,"
|
||||
+ " formatVersion INT NOT NULL,"
|
||||
+ " name _STRING NOT NULL,"
|
||||
+ " publicKey _BINARY NOT NULL,"
|
||||
+ " privateKey _BINARY NOT NULL,"
|
||||
@@ -91,6 +92,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
"CREATE TABLE contacts"
|
||||
+ " (contactId _COUNTER,"
|
||||
+ " authorId _HASH NOT NULL,"
|
||||
+ " formatVersion INT NOT NULL,"
|
||||
+ " name _STRING NOT NULL,"
|
||||
+ " publicKey _BINARY NOT NULL,"
|
||||
+ " localAuthorId _HASH NOT NULL,"
|
||||
@@ -513,16 +515,18 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
try {
|
||||
// Create a contact row
|
||||
String sql = "INSERT INTO contacts"
|
||||
+ " (authorId, name, publicKey, localAuthorId,"
|
||||
+ " (authorId, formatVersion, name, publicKey,"
|
||||
+ " localAuthorId,"
|
||||
+ " verified, active)"
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?)";
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, remote.getId().getBytes());
|
||||
ps.setString(2, remote.getName());
|
||||
ps.setBytes(3, remote.getPublicKey());
|
||||
ps.setBytes(4, local.getBytes());
|
||||
ps.setBoolean(5, verified);
|
||||
ps.setBoolean(6, active);
|
||||
ps.setInt(2, remote.getFormatVersion());
|
||||
ps.setString(3, remote.getName());
|
||||
ps.setBytes(4, remote.getPublicKey());
|
||||
ps.setBytes(5, local.getBytes());
|
||||
ps.setBoolean(6, verified);
|
||||
ps.setBoolean(7, active);
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected != 1) throw new DbStateException();
|
||||
ps.close();
|
||||
@@ -590,14 +594,16 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "INSERT INTO localAuthors"
|
||||
+ " (authorId, name, publicKey, privateKey, created)"
|
||||
+ " VALUES (?, ?, ?, ?, ?)";
|
||||
+ " (authorId, formatVersion, name, publicKey,"
|
||||
+ " privateKey, created)"
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, a.getId().getBytes());
|
||||
ps.setString(2, a.getName());
|
||||
ps.setBytes(3, a.getPublicKey());
|
||||
ps.setBytes(4, a.getPrivateKey());
|
||||
ps.setLong(5, a.getTimeCreated());
|
||||
ps.setInt(2, a.getFormatVersion());
|
||||
ps.setString(3, a.getName());
|
||||
ps.setBytes(4, a.getPublicKey());
|
||||
ps.setBytes(5, a.getPrivateKey());
|
||||
ps.setLong(6, a.getTimeCreated());
|
||||
int affected = ps.executeUpdate();
|
||||
if (affected != 1) throw new DbStateException();
|
||||
ps.close();
|
||||
@@ -1013,7 +1019,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT authorId, name, publicKey,"
|
||||
String sql = "SELECT authorId, formatVersion, name, publicKey,"
|
||||
+ " localAuthorId, verified, active"
|
||||
+ " FROM contacts"
|
||||
+ " WHERE contactId = ?";
|
||||
@@ -1022,14 +1028,16 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next()) throw new DbStateException();
|
||||
AuthorId authorId = new AuthorId(rs.getBytes(1));
|
||||
String name = rs.getString(2);
|
||||
byte[] publicKey = rs.getBytes(3);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
|
||||
boolean verified = rs.getBoolean(5);
|
||||
boolean active = rs.getBoolean(6);
|
||||
int formatVersion = rs.getInt(2);
|
||||
String name = rs.getString(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
||||
boolean verified = rs.getBoolean(6);
|
||||
boolean active = rs.getBoolean(7);
|
||||
rs.close();
|
||||
ps.close();
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
Author author =
|
||||
new Author(authorId, formatVersion, name, publicKey);
|
||||
return new Contact(c, author, localAuthorId, verified, active);
|
||||
} catch (SQLException e) {
|
||||
tryToClose(rs);
|
||||
@@ -1044,8 +1052,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT contactId, authorId, name, publicKey,"
|
||||
+ " localAuthorId, verified, active"
|
||||
String sql = "SELECT contactId, authorId, formatVersion, name,"
|
||||
+ " publicKey, localAuthorId, verified, active"
|
||||
+ " FROM contacts";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
@@ -1053,12 +1061,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
while (rs.next()) {
|
||||
ContactId contactId = new ContactId(rs.getInt(1));
|
||||
AuthorId authorId = new AuthorId(rs.getBytes(2));
|
||||
String name = rs.getString(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
||||
boolean verified = rs.getBoolean(6);
|
||||
boolean active = rs.getBoolean(7);
|
||||
int formatVersion = rs.getInt(3);
|
||||
String name = rs.getString(4);
|
||||
byte[] publicKey = rs.getBytes(5);
|
||||
Author author =
|
||||
new Author(authorId, formatVersion, name, publicKey);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(6));
|
||||
boolean verified = rs.getBoolean(7);
|
||||
boolean active = rs.getBoolean(8);
|
||||
contacts.add(new Contact(contactId, author, localAuthorId,
|
||||
verified, active));
|
||||
}
|
||||
@@ -1101,7 +1111,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT contactId, name, publicKey,"
|
||||
String sql = "SELECT contactId, formatVersion, name, publicKey,"
|
||||
+ " localAuthorId, verified, active"
|
||||
+ " FROM contacts"
|
||||
+ " WHERE authorId = ?";
|
||||
@@ -1111,12 +1121,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
List<Contact> contacts = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
ContactId c = new ContactId(rs.getInt(1));
|
||||
String name = rs.getString(2);
|
||||
byte[] publicKey = rs.getBytes(3);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(4));
|
||||
boolean verified = rs.getBoolean(5);
|
||||
boolean active = rs.getBoolean(6);
|
||||
Author author = new Author(remote, name, publicKey);
|
||||
int formatVersion = rs.getInt(2);
|
||||
String name = rs.getString(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
AuthorId localAuthorId = new AuthorId(rs.getBytes(5));
|
||||
boolean verified = rs.getBoolean(6);
|
||||
boolean active = rs.getBoolean(7);
|
||||
Author author =
|
||||
new Author(remote, formatVersion, name, publicKey);
|
||||
contacts.add(new Contact(c, author, localAuthorId, verified,
|
||||
active));
|
||||
}
|
||||
@@ -1235,19 +1247,21 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT name, publicKey, privateKey, created"
|
||||
String sql = "SELECT formatVersion, name, publicKey,"
|
||||
+ " privateKey, created"
|
||||
+ " FROM localAuthors"
|
||||
+ " WHERE authorId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, a.getBytes());
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next()) throw new DbStateException();
|
||||
String name = rs.getString(1);
|
||||
byte[] publicKey = rs.getBytes(2);
|
||||
byte[] privateKey = rs.getBytes(3);
|
||||
long created = rs.getLong(4);
|
||||
LocalAuthor localAuthor = new LocalAuthor(a, name, publicKey,
|
||||
privateKey, created);
|
||||
int formatVersion = rs.getInt(1);
|
||||
String name = rs.getString(2);
|
||||
byte[] publicKey = rs.getBytes(3);
|
||||
byte[] privateKey = rs.getBytes(4);
|
||||
long created = rs.getLong(5);
|
||||
LocalAuthor localAuthor = new LocalAuthor(a, formatVersion, name,
|
||||
publicKey, privateKey, created);
|
||||
if (rs.next()) throw new DbStateException();
|
||||
rs.close();
|
||||
ps.close();
|
||||
@@ -1265,19 +1279,21 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT authorId, name, publicKey, privateKey, created"
|
||||
String sql = "SELECT authorId, formatVersion, name, publicKey,"
|
||||
+ " privateKey, created"
|
||||
+ " FROM localAuthors";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
List<LocalAuthor> authors = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
AuthorId authorId = new AuthorId(rs.getBytes(1));
|
||||
String name = rs.getString(2);
|
||||
byte[] publicKey = rs.getBytes(3);
|
||||
byte[] privateKey = rs.getBytes(4);
|
||||
long created = rs.getLong(5);
|
||||
authors.add(new LocalAuthor(authorId, name, publicKey,
|
||||
privateKey, created));
|
||||
int formatVersion = rs.getInt(2);
|
||||
String name = rs.getString(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
byte[] privateKey = rs.getBytes(5);
|
||||
long created = rs.getLong(6);
|
||||
authors.add(new LocalAuthor(authorId, formatVersion, name,
|
||||
publicKey, privateKey, created));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
|
||||
@@ -1,61 +1,65 @@
|
||||
package org.briarproject.bramble.identity;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.data.BdfWriter;
|
||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import org.briarproject.bramble.util.ByteUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||
import static org.briarproject.bramble.api.identity.AuthorId.LABEL;
|
||||
import static org.briarproject.bramble.util.ByteUtils.INT_32_BYTES;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class AuthorFactoryImpl implements AuthorFactory {
|
||||
|
||||
private final CryptoComponent crypto;
|
||||
private final BdfWriterFactory bdfWriterFactory;
|
||||
private final Clock clock;
|
||||
|
||||
@Inject
|
||||
AuthorFactoryImpl(CryptoComponent crypto, BdfWriterFactory bdfWriterFactory,
|
||||
Clock clock) {
|
||||
AuthorFactoryImpl(CryptoComponent crypto, Clock clock) {
|
||||
this.crypto = crypto;
|
||||
this.bdfWriterFactory = bdfWriterFactory;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Author createAuthor(String name, byte[] publicKey) {
|
||||
return new Author(getId(name, publicKey), name, publicKey);
|
||||
return createAuthor(FORMAT_VERSION, name, publicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Author createAuthor(int formatVersion, String name,
|
||||
byte[] publicKey) {
|
||||
AuthorId id = getId(formatVersion, name, publicKey);
|
||||
return new Author(id, formatVersion, name, publicKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalAuthor createLocalAuthor(String name, byte[] publicKey,
|
||||
byte[] privateKey) {
|
||||
return new LocalAuthor(getId(name, publicKey), name, publicKey,
|
||||
privateKey, clock.currentTimeMillis());
|
||||
return createLocalAuthor(FORMAT_VERSION, name, publicKey, privateKey);
|
||||
}
|
||||
|
||||
private AuthorId getId(String name, byte[] publicKey) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
BdfWriter w = bdfWriterFactory.createWriter(out);
|
||||
try {
|
||||
w.writeListStart();
|
||||
w.writeString(name);
|
||||
w.writeRaw(publicKey);
|
||||
w.writeListEnd();
|
||||
} catch (IOException e) {
|
||||
// Shouldn't happen with ByteArrayOutputStream
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new AuthorId(crypto.hash(AuthorId.LABEL, out.toByteArray()));
|
||||
@Override
|
||||
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) {
|
||||
byte[] formatVersionBytes = new byte[INT_32_BYTES];
|
||||
ByteUtils.writeUint32(formatVersion, formatVersionBytes, 0);
|
||||
return new AuthorId(crypto.hash(LABEL, formatVersionBytes,
|
||||
StringUtils.toUtf8(name), publicKey));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.briarproject.bramble.identity;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.data.BdfReader;
|
||||
import org.briarproject.bramble.api.data.ObjectReader;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class AuthorReader implements ObjectReader<Author> {
|
||||
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
AuthorReader(AuthorFactory authorFactory) {
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Author readObject(BdfReader r) throws IOException {
|
||||
r.readListStart();
|
||||
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
|
||||
if (name.length() == 0) throw new FormatException();
|
||||
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
||||
r.readListEnd();
|
||||
return authorFactory.createAuthor(name, publicKey);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,7 @@
|
||||
package org.briarproject.bramble.identity;
|
||||
|
||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||
import org.briarproject.bramble.api.data.ObjectReader;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@@ -24,19 +18,14 @@ public class IdentityModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
AuthorFactory provideAuthorFactory(CryptoComponent crypto,
|
||||
BdfWriterFactory bdfWriterFactory, Clock clock) {
|
||||
return new AuthorFactoryImpl(crypto, bdfWriterFactory, clock);
|
||||
AuthorFactory provideAuthorFactory(AuthorFactoryImpl authorFactory) {
|
||||
return authorFactory;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
IdentityManager provideIdentityModule(DatabaseComponent db) {
|
||||
return new IdentityManagerImpl(db);
|
||||
}
|
||||
|
||||
@Provides
|
||||
ObjectReader<Author> provideAuthorReader(AuthorFactory authorFactory) {
|
||||
return new AuthorReader(authorFactory);
|
||||
IdentityManager provideIdentityManager(
|
||||
IdentityManagerImpl identityManager) {
|
||||
return identityManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.briarproject.bramble.api.data.MetadataParser;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.Metadata;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
@@ -31,9 +33,14 @@ import java.security.GeneralSecurityException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
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.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
@@ -54,7 +61,8 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
context.mock(MetadataEncoder.class);
|
||||
private final CryptoComponent cryptoComponent =
|
||||
context.mock(CryptoComponent.class);
|
||||
private final ClientHelper clientHelper;
|
||||
private final AuthorFactory authorFactory =
|
||||
context.mock(AuthorFactory.class);
|
||||
|
||||
private final GroupId groupId = new GroupId(getRandomId());
|
||||
private final BdfDictionary dictionary = new BdfDictionary();
|
||||
@@ -66,17 +74,15 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
private final Metadata metadata = new Metadata();
|
||||
private final BdfList list = BdfList.of("Sign this!", getRandomBytes(42));
|
||||
private final String label = StringUtils.getRandomString(5);
|
||||
private final Author author = getAuthor();
|
||||
|
||||
public ClientHelperImplTest() {
|
||||
clientHelper =
|
||||
new ClientHelperImpl(db, messageFactory, bdfReaderFactory,
|
||||
bdfWriterFactory, metadataParser, metadataEncoder,
|
||||
cryptoComponent);
|
||||
}
|
||||
private final ClientHelper clientHelper = new ClientHelperImpl(db,
|
||||
messageFactory, bdfReaderFactory, bdfWriterFactory, metadataParser,
|
||||
metadataEncoder, cryptoComponent, authorFactory);
|
||||
|
||||
@Test
|
||||
public void testAddLocalMessage() throws Exception {
|
||||
boolean shared = true;
|
||||
boolean shared = new Random().nextBoolean();
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -180,8 +186,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
|
||||
assertEquals(map,
|
||||
clientHelper.getMessageMetadataAsDictionary(groupId));
|
||||
assertEquals(map, clientHelper.getMessageMetadataAsDictionary(groupId));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
@@ -318,8 +323,7 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}});
|
||||
|
||||
try {
|
||||
clientHelper
|
||||
.verifySignature(label, rawMessage, publicKey, list);
|
||||
clientHelper.verifySignature(label, rawMessage, publicKey, list);
|
||||
fail();
|
||||
} catch (GeneralSecurityException e) {
|
||||
// expected
|
||||
@@ -327,6 +331,166 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParsesAndEncodesAuthor() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(author.getFormatVersion(),
|
||||
author.getName(), author.getPublicKey());
|
||||
will(returnValue(author));
|
||||
}});
|
||||
|
||||
BdfList authorList = clientHelper.toList(author);
|
||||
assertEquals(author, clientHelper.parseAndValidateAuthor(authorList));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsValidAuthor() throws Exception {
|
||||
BdfList authorList = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(author.getFormatVersion(),
|
||||
author.getName(), author.getPublicKey());
|
||||
will(returnValue(author));
|
||||
}});
|
||||
|
||||
assertEquals(author, clientHelper.parseAndValidateAuthor(authorList));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortAuthor() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongAuthor() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
author.getPublicKey(),
|
||||
"foo"
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithNullFormatVersion() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
null,
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithNonIntegerFormatVersion()
|
||||
throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
"foo",
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithUnknownFormatVersion() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion() + 1,
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithTooShortName() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
"",
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithTooLongName() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1),
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithNullName() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
null,
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithNonStringName() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
getRandomBytes(5),
|
||||
author.getPublicKey()
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithTooShortPublicKey() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
new byte[0]
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithTooLongPublicKey() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1)
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithNullPublicKey() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
null
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsAuthorWithNonRawPublicKey() throws Exception {
|
||||
BdfList invalidAuthor = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
"foo"
|
||||
);
|
||||
clientHelper.parseAndValidateAuthor(invalidAuthor);
|
||||
}
|
||||
|
||||
private byte[] expectToByteArray(BdfList list) throws Exception {
|
||||
BdfWriter bdfWriter = context.mock(BdfWriter.class);
|
||||
|
||||
@@ -352,5 +516,4 @@ public class ClientHelperImplTest extends BrambleTestCase {
|
||||
will(returnValue(eof));
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ import org.junit.Test;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -32,9 +33,7 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
private final KeyManager keyManager = context.mock(KeyManager.class);
|
||||
private final ContactManager contactManager;
|
||||
private final ContactId contactId = new ContactId(42);
|
||||
private final Author remote =
|
||||
new Author(new AuthorId(getRandomId()), "remote",
|
||||
getRandomBytes(42));
|
||||
private final Author remote = getAuthor();
|
||||
private final AuthorId local = new AuthorId(getRandomId());
|
||||
private final boolean verified = false, active = true;
|
||||
private final Contact contact =
|
||||
@@ -47,8 +46,8 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
@Test
|
||||
public void testAddContact() throws Exception {
|
||||
SecretKey master = getSecretKey();
|
||||
long timestamp = 42;
|
||||
boolean alice = true;
|
||||
long timestamp = System.currentTimeMillis();
|
||||
boolean alice = new Random().nextBoolean();
|
||||
Transaction txn = new Transaction(null, false);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
|
||||
@@ -17,7 +17,6 @@ import org.briarproject.bramble.api.db.NoSuchTransportException;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.identity.event.LocalAuthorAddedEvent;
|
||||
import org.briarproject.bramble.api.identity.event.LocalAuthorRemovedEvent;
|
||||
@@ -49,7 +48,6 @@ import org.briarproject.bramble.api.transport.OutgoingKeys;
|
||||
import org.briarproject.bramble.api.transport.TransportKeys;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -59,7 +57,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
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.VISIBLE;
|
||||
@@ -68,6 +65,9 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERE
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.REORDERING_WINDOW_SIZE;
|
||||
import static org.briarproject.bramble.db.DatabaseConstants.MAX_OFFERED_MESSAGES;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -85,9 +85,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
private final ClientId clientId;
|
||||
private final GroupId groupId;
|
||||
private final Group group;
|
||||
private final AuthorId authorId;
|
||||
private final Author author;
|
||||
private final AuthorId localAuthorId;
|
||||
private final LocalAuthor localAuthor;
|
||||
private final MessageId messageId, messageId1;
|
||||
private final int size;
|
||||
@@ -100,18 +98,15 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
private final Contact contact;
|
||||
|
||||
public DatabaseComponentImplTest() {
|
||||
clientId = new ClientId(StringUtils.getRandomString(5));
|
||||
clientId = new ClientId(getRandomString(123));
|
||||
groupId = new GroupId(TestUtils.getRandomId());
|
||||
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
authorId = new AuthorId(TestUtils.getRandomId());
|
||||
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
localAuthorId = new AuthorId(TestUtils.getRandomId());
|
||||
long timestamp = System.currentTimeMillis();
|
||||
localAuthor = new LocalAuthor(localAuthorId, "Bob",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||
author = getAuthor();
|
||||
localAuthor = getLocalAuthor();
|
||||
messageId = new MessageId(TestUtils.getRandomId());
|
||||
messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
long timestamp = System.currentTimeMillis();
|
||||
size = 1234;
|
||||
raw = new byte[size];
|
||||
message = new Message(messageId, groupId, timestamp, raw);
|
||||
@@ -120,7 +115,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
transportId = new TransportId("id");
|
||||
maxLatency = Integer.MAX_VALUE;
|
||||
contactId = new ContactId(234);
|
||||
contact = new Contact(contactId, author, localAuthorId, true, true);
|
||||
contact = new Contact(contactId, author, localAuthor.getId(),
|
||||
true, true);
|
||||
}
|
||||
|
||||
private DatabaseComponent createDatabaseComponent(Database<Object> database,
|
||||
@@ -142,18 +138,20 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
// registerLocalAuthor()
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(database).addLocalAuthor(txn, localAuthor);
|
||||
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
|
||||
// addContact()
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsLocalAuthor(txn, authorId);
|
||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
||||
oneOf(database).containsContact(txn, author.getId(),
|
||||
localAuthor.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(database).addContact(txn, author, localAuthorId, true, true);
|
||||
oneOf(database).addContact(txn, author, localAuthor.getId(),
|
||||
true, true);
|
||||
will(returnValue(contactId));
|
||||
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
||||
oneOf(eventBus).broadcast(with(any(
|
||||
@@ -187,9 +185,9 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
oneOf(database).removeContact(txn, contactId);
|
||||
oneOf(eventBus).broadcast(with(any(ContactRemovedEvent.class)));
|
||||
// removeLocalAuthor()
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(true));
|
||||
oneOf(database).removeLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).removeLocalAuthor(txn, localAuthor.getId());
|
||||
oneOf(eventBus).broadcast(with(any(LocalAuthorRemovedEvent.class)));
|
||||
// endTransaction()
|
||||
oneOf(database).commitTransaction(txn);
|
||||
@@ -203,9 +201,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalAuthor(transaction, localAuthor);
|
||||
assertEquals(contactId,
|
||||
db.addContact(transaction, author, localAuthorId, true,
|
||||
true));
|
||||
assertEquals(contactId, db.addContact(transaction, author,
|
||||
localAuthor.getId(), true, true));
|
||||
assertEquals(Collections.singletonList(contact),
|
||||
db.getContacts(transaction));
|
||||
db.addGroup(transaction, group); // First time - listeners called
|
||||
@@ -214,7 +211,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
db.getGroups(transaction, clientId));
|
||||
db.removeGroup(transaction, group);
|
||||
db.removeContact(transaction, contactId);
|
||||
db.removeLocalAuthor(transaction, localAuthorId);
|
||||
db.removeLocalAuthor(transaction, localAuthor.getId());
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
@@ -487,7 +484,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
// Check whether the pseudonym is in the DB (which it's not)
|
||||
exactly(3).of(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
exactly(3).of(database).containsLocalAuthor(txn, localAuthorId);
|
||||
exactly(3).of(database).containsLocalAuthor(txn,
|
||||
localAuthor.getId());
|
||||
will(returnValue(false));
|
||||
exactly(3).of(database).abortTransaction(txn);
|
||||
}});
|
||||
@@ -496,7 +494,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addContact(transaction, author, localAuthorId, true, true);
|
||||
db.addContact(transaction, author, localAuthor.getId(), true, true);
|
||||
fail();
|
||||
} catch (NoSuchLocalAuthorException expected) {
|
||||
// Expected
|
||||
@@ -506,7 +504,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.getLocalAuthor(transaction, localAuthorId);
|
||||
db.getLocalAuthor(transaction, localAuthor.getId());
|
||||
fail();
|
||||
} catch (NoSuchLocalAuthorException expected) {
|
||||
// Expected
|
||||
@@ -516,7 +514,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
|
||||
transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.removeLocalAuthor(transaction, localAuthorId);
|
||||
db.removeLocalAuthor(transaction, localAuthor.getId());
|
||||
fail();
|
||||
} catch (NoSuchLocalAuthorException expected) {
|
||||
// Expected
|
||||
@@ -759,18 +757,20 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
// registerLocalAuthor()
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(database).addLocalAuthor(txn, localAuthor);
|
||||
oneOf(eventBus).broadcast(with(any(LocalAuthorAddedEvent.class)));
|
||||
// addContact()
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsLocalAuthor(txn, authorId);
|
||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
||||
oneOf(database).containsContact(txn, author.getId(),
|
||||
localAuthor.getId());
|
||||
will(returnValue(false));
|
||||
oneOf(database).addContact(txn, author, localAuthorId, true, true);
|
||||
oneOf(database).addContact(txn, author, localAuthor.getId(),
|
||||
true, true);
|
||||
will(returnValue(contactId));
|
||||
oneOf(eventBus).broadcast(with(any(ContactAddedEvent.class)));
|
||||
oneOf(eventBus).broadcast(with(any(
|
||||
@@ -792,9 +792,8 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addLocalAuthor(transaction, localAuthor);
|
||||
assertEquals(contactId,
|
||||
db.addContact(transaction, author, localAuthorId, true,
|
||||
true));
|
||||
assertEquals(contactId, db.addContact(transaction, author,
|
||||
localAuthor.getId(), true, true));
|
||||
db.commitTransaction(transaction);
|
||||
} finally {
|
||||
db.endTransaction(transaction);
|
||||
@@ -1406,10 +1405,10 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(true));
|
||||
// Contact is a local identity
|
||||
oneOf(database).containsLocalAuthor(txn, authorId);
|
||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
||||
will(returnValue(true));
|
||||
oneOf(database).abortTransaction(txn);
|
||||
}});
|
||||
@@ -1419,7 +1418,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addContact(transaction, author, localAuthorId, true, true);
|
||||
db.addContact(transaction, author, localAuthor.getId(), true, true);
|
||||
fail();
|
||||
} catch (ContactExistsException expected) {
|
||||
// Expected
|
||||
@@ -1433,12 +1432,13 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(database).startTransaction();
|
||||
will(returnValue(txn));
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthorId);
|
||||
oneOf(database).containsLocalAuthor(txn, localAuthor.getId());
|
||||
will(returnValue(true));
|
||||
oneOf(database).containsLocalAuthor(txn, authorId);
|
||||
oneOf(database).containsLocalAuthor(txn, author.getId());
|
||||
will(returnValue(false));
|
||||
// Contact already exists for this local identity
|
||||
oneOf(database).containsContact(txn, authorId, localAuthorId);
|
||||
oneOf(database).containsContact(txn, author.getId(),
|
||||
localAuthor.getId());
|
||||
will(returnValue(true));
|
||||
oneOf(database).abortTransaction(txn);
|
||||
}});
|
||||
@@ -1448,7 +1448,7 @@ public class DatabaseComponentImplTest extends BrambleMockTestCase {
|
||||
|
||||
Transaction transaction = db.startTransaction(false);
|
||||
try {
|
||||
db.addContact(transaction, author, localAuthorId, true, true);
|
||||
db.addContact(transaction, author, localAuthor.getId(), true, true);
|
||||
fail();
|
||||
} catch (ContactExistsException expected) {
|
||||
// Expected
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.db.Metadata;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.settings.Settings;
|
||||
@@ -26,7 +25,6 @@ import org.briarproject.bramble.system.SystemClock;
|
||||
import org.briarproject.bramble.test.BrambleTestCase;
|
||||
import org.briarproject.bramble.test.TestDatabaseConfig;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -46,7 +44,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.briarproject.bramble.api.db.Metadata.REMOVE;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
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.VISIBLE;
|
||||
@@ -56,6 +53,11 @@ import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERE
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.UNKNOWN;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -75,7 +77,6 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
private final ClientId clientId;
|
||||
private final Group group;
|
||||
private final Author author;
|
||||
private final AuthorId localAuthorId;
|
||||
private final LocalAuthor localAuthor;
|
||||
private final MessageId messageId;
|
||||
private final long timestamp;
|
||||
@@ -86,19 +87,16 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
private final ContactId contactId;
|
||||
|
||||
JdbcDatabaseTest() throws Exception {
|
||||
groupId = new GroupId(TestUtils.getRandomId());
|
||||
clientId = new ClientId(StringUtils.getRandomString(5));
|
||||
groupId = new GroupId(getRandomId());
|
||||
clientId = new ClientId(getRandomString(123));
|
||||
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
author = new Author(authorId, "Alice", new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
localAuthorId = new AuthorId(TestUtils.getRandomId());
|
||||
author = getAuthor();
|
||||
localAuthor = getLocalAuthor();
|
||||
messageId = new MessageId(getRandomId());
|
||||
timestamp = System.currentTimeMillis();
|
||||
localAuthor = new LocalAuthor(localAuthorId, "Bob",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||
messageId = new MessageId(TestUtils.getRandomId());
|
||||
size = 1234;
|
||||
raw = TestUtils.getRandomBytes(size);
|
||||
raw = getRandomBytes(size);
|
||||
message = new Message(messageId, groupId, timestamp, raw);
|
||||
transportId = new TransportId("id");
|
||||
contactId = new ContactId(1);
|
||||
@@ -119,7 +117,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
Connection txn = db.startTransaction();
|
||||
assertFalse(db.containsContact(txn, contactId));
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
assertTrue(db.containsContact(txn, contactId));
|
||||
assertFalse(db.containsGroup(txn, groupId));
|
||||
@@ -182,7 +180,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -220,7 +218,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and a shared but unvalidated message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -266,7 +264,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, an invisible group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
@@ -318,7 +316,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and an unshared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -350,7 +348,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -377,13 +375,13 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact and a visible group
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, false);
|
||||
|
||||
// Add some messages to ack
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId1 = new MessageId(getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId, timestamp, raw);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
db.addStatus(txn, contactId, messageId, false, true);
|
||||
@@ -414,7 +412,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -572,7 +570,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact and a shared group
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -592,7 +590,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
|
||||
// The group is not in the database
|
||||
@@ -610,7 +608,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a group and a message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addMessage(txn, message, DELIVERED, true);
|
||||
@@ -630,7 +628,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact and a group
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
|
||||
@@ -680,7 +678,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add the contact, the transport and the transport keys
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addTransport(txn, transportId, 123);
|
||||
db.addTransportKeys(txn, contactId, keys);
|
||||
@@ -742,7 +740,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add the contact, transport and transport keys
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addTransport(txn, transportId, 123);
|
||||
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
|
||||
@@ -778,7 +776,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add the contact, transport and transport keys
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addTransport(txn, transportId, 123);
|
||||
db.updateTransportKeys(txn, Collections.singletonMap(contactId, keys));
|
||||
@@ -813,7 +811,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
|
||||
// Add a contact associated with the local author
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
|
||||
// Ensure contact is returned from database by Author ID
|
||||
@@ -838,18 +836,19 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a local author - no contacts should be associated
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
Collection<ContactId> contacts = db.getContacts(txn, localAuthorId);
|
||||
Collection<ContactId> contacts =
|
||||
db.getContacts(txn, localAuthor.getId());
|
||||
assertEquals(Collections.emptyList(), contacts);
|
||||
|
||||
// Add a contact associated with the local author
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
contacts = db.getContacts(txn, localAuthorId);
|
||||
contacts = db.getContacts(txn, localAuthor.getId());
|
||||
assertEquals(Collections.singletonList(contactId), contacts);
|
||||
|
||||
// Remove the local author - the contact should be removed
|
||||
db.removeLocalAuthor(txn, localAuthorId);
|
||||
contacts = db.getContacts(txn, localAuthorId);
|
||||
db.removeLocalAuthor(txn, localAuthor.getId());
|
||||
contacts = db.getContacts(txn, localAuthor.getId());
|
||||
assertEquals(Collections.emptyList(), contacts);
|
||||
assertFalse(db.containsContact(txn, contactId));
|
||||
|
||||
@@ -864,14 +863,14 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact - initially there should be no offered messages
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
assertEquals(0, db.countOfferedMessages(txn, contactId));
|
||||
|
||||
// Add some offered messages and count them
|
||||
List<MessageId> ids = new ArrayList<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
MessageId m = new MessageId(TestUtils.getRandomId());
|
||||
MessageId m = new MessageId(getRandomId());
|
||||
db.addOfferedMessage(txn, contactId, m);
|
||||
ids.add(m);
|
||||
}
|
||||
@@ -1056,7 +1055,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testMetadataQueries() throws Exception {
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId1 = new MessageId(getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId, timestamp, raw);
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
@@ -1160,7 +1159,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testMetadataQueriesOnlyForDeliveredMessages() throws Exception {
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId1 = new MessageId(getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId, timestamp, raw);
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
@@ -1231,10 +1230,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testMessageDependencies() throws Exception {
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId4 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId1 = new MessageId(getRandomId());
|
||||
MessageId messageId2 = new MessageId(getRandomId());
|
||||
MessageId messageId3 = new MessageId(getRandomId());
|
||||
MessageId messageId4 = new MessageId(getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId, timestamp, raw);
|
||||
Message message2 = new Message(messageId2, groupId, timestamp, raw);
|
||||
|
||||
@@ -1315,21 +1314,21 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
db.addMessage(txn, message, PENDING, true);
|
||||
|
||||
// Add a second group
|
||||
GroupId groupId1 = new GroupId(TestUtils.getRandomId());
|
||||
GroupId groupId1 = new GroupId(getRandomId());
|
||||
Group group1 = new Group(groupId1, clientId,
|
||||
TestUtils.getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH));
|
||||
getRandomBytes(MAX_GROUP_DESCRIPTOR_LENGTH));
|
||||
db.addGroup(txn, group1);
|
||||
|
||||
// Add a message to the second group
|
||||
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId1 = new MessageId(getRandomId());
|
||||
Message message1 = new Message(messageId1, groupId1, timestamp, raw);
|
||||
db.addMessage(txn, message1, DELIVERED, true);
|
||||
|
||||
// Create an ID for a missing message
|
||||
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId2 = new MessageId(getRandomId());
|
||||
|
||||
// Add another message to the first group
|
||||
MessageId messageId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId3 = new MessageId(getRandomId());
|
||||
Message message3 = new Message(messageId3, groupId, timestamp, raw);
|
||||
db.addMessage(txn, message3, DELIVERED, true);
|
||||
|
||||
@@ -1364,10 +1363,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetPendingMessagesForDelivery() throws Exception {
|
||||
MessageId mId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId4 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId1 = new MessageId(getRandomId());
|
||||
MessageId mId2 = new MessageId(getRandomId());
|
||||
MessageId mId3 = new MessageId(getRandomId());
|
||||
MessageId mId4 = new MessageId(getRandomId());
|
||||
Message m1 = new Message(mId1, groupId, timestamp, raw);
|
||||
Message m2 = new Message(mId2, groupId, timestamp, raw);
|
||||
Message m3 = new Message(mId3, groupId, timestamp, raw);
|
||||
@@ -1401,10 +1400,10 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetMessagesToShare() throws Exception {
|
||||
MessageId mId1 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId2 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId3 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId4 = new MessageId(TestUtils.getRandomId());
|
||||
MessageId mId1 = new MessageId(getRandomId());
|
||||
MessageId mId2 = new MessageId(getRandomId());
|
||||
MessageId mId3 = new MessageId(getRandomId());
|
||||
MessageId mId4 = new MessageId(getRandomId());
|
||||
Message m1 = new Message(mId1, groupId, timestamp, raw);
|
||||
Message m2 = new Message(mId2, groupId, timestamp, raw);
|
||||
Message m3 = new Message(mId3, groupId, timestamp, raw);
|
||||
@@ -1443,7 +1442,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -1512,9 +1511,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testDifferentLocalAuthorsCanHaveTheSameContact()
|
||||
throws Exception {
|
||||
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
LocalAuthor localAuthor1 = new LocalAuthor(localAuthorId1, "Carol",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||
LocalAuthor localAuthor1 = getLocalAuthor();
|
||||
|
||||
Database<Connection> db = open(false);
|
||||
Connection txn = db.startTransaction();
|
||||
@@ -1525,15 +1522,15 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add the same contact for each local author
|
||||
ContactId contactId =
|
||||
db.addContact(txn, author, localAuthorId, true, true);
|
||||
db.addContact(txn, author, localAuthor.getId(), true, true);
|
||||
ContactId contactId1 =
|
||||
db.addContact(txn, author, localAuthorId1, true, true);
|
||||
db.addContact(txn, author, localAuthor1.getId(), true, true);
|
||||
|
||||
// The contacts should be distinct
|
||||
assertNotEquals(contactId, contactId1);
|
||||
assertEquals(2, db.getContacts(txn).size());
|
||||
assertEquals(1, db.getContacts(txn, localAuthorId).size());
|
||||
assertEquals(1, db.getContacts(txn, localAuthorId1).size());
|
||||
assertEquals(1, db.getContacts(txn, localAuthor.getId()).size());
|
||||
assertEquals(1, db.getContacts(txn, localAuthor1.getId()).size());
|
||||
|
||||
db.commitTransaction(txn);
|
||||
db.close();
|
||||
@@ -1546,7 +1543,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact, a shared group and a shared message
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
db.addGroup(txn, group);
|
||||
db.addGroupVisibility(txn, contactId, groupId, true);
|
||||
@@ -1592,7 +1589,7 @@ public abstract class JdbcDatabaseTest extends BrambleTestCase {
|
||||
|
||||
// Add a contact
|
||||
db.addLocalAuthor(txn, localAuthor);
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthorId,
|
||||
assertEquals(contactId, db.addContact(txn, author, localAuthor.getId(),
|
||||
true, true));
|
||||
|
||||
// The contact should be active
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -23,6 +21,8 @@ import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.UNKNOWN;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.UNVERIFIED;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
@@ -30,11 +30,7 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
private final IdentityManager identityManager;
|
||||
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
private final Transaction txn = new Transaction(null, false);
|
||||
private final LocalAuthor localAuthor =
|
||||
new LocalAuthor(new AuthorId(TestUtils.getRandomId()),
|
||||
StringUtils.getRandomString(8),
|
||||
TestUtils.getRandomBytes(42), TestUtils.getRandomBytes(42),
|
||||
0);
|
||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
||||
private final Collection<LocalAuthor> localAuthors =
|
||||
Collections.singletonList(localAuthor);
|
||||
|
||||
@@ -80,7 +76,8 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetAuthorStatus() throws DbException {
|
||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
Author author = getAuthor();
|
||||
AuthorId authorId = author.getId();
|
||||
Collection<Contact> contacts = new ArrayList<>();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -95,20 +92,16 @@ public class IdentityManagerImplTest extends BrambleMockTestCase {
|
||||
assertEquals(UNKNOWN, identityManager.getAuthorStatus(authorId));
|
||||
|
||||
// add one unverified contact
|
||||
Author author = new Author(authorId, StringUtils.getRandomString(8),
|
||||
TestUtils.getRandomBytes(42));
|
||||
Contact contact =
|
||||
new Contact(new ContactId(1), author, localAuthor.getId(),
|
||||
false, true);
|
||||
Contact contact = new Contact(new ContactId(1), author,
|
||||
localAuthor.getId(), false, true);
|
||||
contacts.add(contact);
|
||||
|
||||
checkAuthorStatusContext(authorId, contacts);
|
||||
assertEquals(UNVERIFIED, identityManager.getAuthorStatus(authorId));
|
||||
|
||||
// add one verified contact
|
||||
Contact contact2 =
|
||||
new Contact(new ContactId(1), author, localAuthor.getId(),
|
||||
true, true);
|
||||
Contact contact2 = new Contact(new ContactId(1), author,
|
||||
localAuthor.getId(), true, true);
|
||||
contacts.add(contact2);
|
||||
|
||||
checkAuthorStatusContext(authorId, contacts);
|
||||
|
||||
@@ -11,8 +11,6 @@ import org.briarproject.bramble.api.data.MetadataParser;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.Metadata;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
@@ -31,16 +29,15 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.properties.TransportPropertyManager.CLIENT_ID;
|
||||
import static org.briarproject.bramble.api.properties.TransportPropertyManager.CLIENT_VERSION;
|
||||
import static org.briarproject.bramble.api.sync.Group.Visibility.SHARED;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
@@ -609,22 +606,10 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
||||
return new Group(g, CLIENT_ID, descriptor);
|
||||
}
|
||||
|
||||
private LocalAuthor getLocalAuthor() {
|
||||
AuthorId id = new AuthorId(getRandomId());
|
||||
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] privateKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
long created = System.currentTimeMillis();
|
||||
return new LocalAuthor(id, name, publicKey, privateKey, created);
|
||||
}
|
||||
|
||||
private Contact getContact(boolean active) {
|
||||
ContactId c = new ContactId(nextContactId++);
|
||||
AuthorId a = new AuthorId(getRandomId());
|
||||
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
return new Contact(c, new Author(a, name, publicKey),
|
||||
localAuthor.getId(), true, active);
|
||||
return new Contact(c, getAuthor(), localAuthor.getId(),
|
||||
true, active);
|
||||
}
|
||||
|
||||
private Message getMessage(GroupId g, long timestamp) {
|
||||
|
||||
@@ -9,7 +9,10 @@ import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
|
||||
public abstract class ValidatorTestCase extends BrambleMockTestCase {
|
||||
|
||||
@@ -21,16 +24,14 @@ public abstract class ValidatorTestCase extends BrambleMockTestCase {
|
||||
protected final AuthorFactory authorFactory =
|
||||
context.mock(AuthorFactory.class);
|
||||
|
||||
protected final MessageId messageId =
|
||||
new MessageId(TestUtils.getRandomId());
|
||||
protected final GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||
protected final MessageId messageId = new MessageId(getRandomId());
|
||||
protected final GroupId groupId = new GroupId(getRandomId());
|
||||
protected final long timestamp = 1234567890 * 1000L;
|
||||
protected final byte[] raw = TestUtils.getRandomBytes(123);
|
||||
protected final byte[] raw = getRandomBytes(123);
|
||||
protected final Message message =
|
||||
new Message(messageId, groupId, timestamp, raw);
|
||||
protected final ClientId clientId =
|
||||
new ClientId(StringUtils.getRandomString(123));
|
||||
protected final byte[] descriptor = TestUtils.getRandomBytes(123);
|
||||
protected final ClientId clientId = new ClientId(getRandomString(123));
|
||||
protected final byte[] descriptor = getRandomBytes(123);
|
||||
protected final Group group = new Group(groupId, clientId, descriptor);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@ import org.junit.Test;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
@@ -59,9 +61,7 @@ public class KeyManagerImplTest extends BrambleTestCase {
|
||||
@Before
|
||||
public void testStartService() throws Exception {
|
||||
Transaction txn = new Transaction(null, false);
|
||||
AuthorId remoteAuthorId = new AuthorId(getRandomId());
|
||||
Author remoteAuthor = new Author(remoteAuthorId, "author",
|
||||
getRandomBytes(42));
|
||||
Author remoteAuthor = getAuthor();
|
||||
AuthorId localAuthorId = new AuthorId(getRandomId());
|
||||
Collection<Contact> contacts = new ArrayList<>();
|
||||
contacts.add(new Contact(contactId, remoteAuthor, localAuthorId, true,
|
||||
@@ -101,12 +101,12 @@ public class KeyManagerImplTest extends BrambleTestCase {
|
||||
@Test
|
||||
public void testAddContact() throws Exception {
|
||||
SecretKey secretKey = getSecretKey();
|
||||
long timestamp = 42L;
|
||||
boolean alice = true;
|
||||
long timestamp = System.currentTimeMillis();
|
||||
boolean alice = new Random().nextBoolean();
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(transportKeyManager)
|
||||
.addContact(txn, contactId, secretKey, timestamp, alice);
|
||||
oneOf(transportKeyManager).addContact(txn, contactId, secretKey,
|
||||
timestamp, alice);
|
||||
}});
|
||||
|
||||
keyManager.addContact(txn, contactId, secretKey, timestamp, alice);
|
||||
@@ -121,8 +121,8 @@ public class KeyManagerImplTest extends BrambleTestCase {
|
||||
|
||||
@Test
|
||||
public void testGetStreamContextForUnknownTransport() throws Exception {
|
||||
assertEquals(null, keyManager
|
||||
.getStreamContext(contactId, unknownTransportId));
|
||||
assertEquals(null,
|
||||
keyManager.getStreamContext(contactId, unknownTransportId));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -44,8 +44,8 @@ class RssFeedAdapter extends BriarAdapter<Feed, RssFeedAdapter.FeedViewHolder> {
|
||||
ui.delete.setOnClickListener(v -> listener.onDeleteClick(item));
|
||||
|
||||
// Author
|
||||
if (item.getAuthor() != null) {
|
||||
ui.author.setText(item.getAuthor());
|
||||
if (item.getRssAuthor() != null) {
|
||||
ui.author.setText(item.getRssAuthor());
|
||||
ui.author.setVisibility(VISIBLE);
|
||||
ui.authorLabel.setVisibility(VISIBLE);
|
||||
} else {
|
||||
|
||||
@@ -6,9 +6,7 @@ import junit.framework.Assert;
|
||||
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.briar.android.TestBriarApplication;
|
||||
import org.briarproject.briar.android.controller.handler.UiResultExceptionHandler;
|
||||
import org.briarproject.briar.android.threaded.ThreadItemAdapter;
|
||||
@@ -29,7 +27,10 @@ import java.util.Arrays;
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.UNKNOWN;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -38,30 +39,19 @@ import static org.mockito.Mockito.verify;
|
||||
packageName = "org.briarproject.briar")
|
||||
public class ForumActivityTest {
|
||||
|
||||
private final static String AUTHOR_1 = "Author 1";
|
||||
private final static String AUTHOR_2 = "Author 2";
|
||||
private final static String AUTHOR_3 = "Author 3";
|
||||
private final static String AUTHOR_4 = "Author 4";
|
||||
private final static String AUTHOR_5 = "Author 5";
|
||||
private final static String AUTHOR_6 = "Author 6";
|
||||
|
||||
private final static String[] AUTHORS = {
|
||||
AUTHOR_1, AUTHOR_2, AUTHOR_3, AUTHOR_4, AUTHOR_5, AUTHOR_6
|
||||
};
|
||||
|
||||
private final static MessageId[] AUTHOR_IDS = new MessageId[AUTHORS.length];
|
||||
private final static MessageId[] MESSAGE_IDS = new MessageId[6];
|
||||
|
||||
static {
|
||||
for (int i = 0; i < AUTHOR_IDS.length; i++)
|
||||
AUTHOR_IDS[i] = new MessageId(TestUtils.getRandomId());
|
||||
for (int i = 0; i < MESSAGE_IDS.length; i++)
|
||||
MESSAGE_IDS[i] = new MessageId(getRandomId());
|
||||
}
|
||||
|
||||
private final static MessageId[] PARENT_AUTHOR_IDS = {
|
||||
private final static MessageId[] PARENT_IDS = {
|
||||
null,
|
||||
AUTHOR_IDS[0],
|
||||
AUTHOR_IDS[1],
|
||||
AUTHOR_IDS[2],
|
||||
AUTHOR_IDS[0],
|
||||
MESSAGE_IDS[0],
|
||||
MESSAGE_IDS[1],
|
||||
MESSAGE_IDS[2],
|
||||
MESSAGE_IDS[0],
|
||||
null
|
||||
};
|
||||
|
||||
@@ -86,7 +76,7 @@ public class ForumActivityTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("briar.GROUP_ID", TestUtils.getRandomId());
|
||||
intent.putExtra("briar.GROUP_ID", getRandomId());
|
||||
forumActivity = Robolectric.buildActivity(TestForumActivity.class,
|
||||
intent).create().start().resume().get();
|
||||
}
|
||||
@@ -94,11 +84,10 @@ public class ForumActivityTest {
|
||||
private ThreadItemList<ForumItem> getDummyData() {
|
||||
ForumItem[] forumItems = new ForumItem[6];
|
||||
for (int i = 0; i < forumItems.length; i++) {
|
||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
Author author = new Author(authorId, AUTHORS[i], publicKey);
|
||||
forumItems[i] = new ForumItem(AUTHOR_IDS[i], PARENT_AUTHOR_IDS[i],
|
||||
AUTHORS[i], System.currentTimeMillis(), author, UNKNOWN);
|
||||
Author author = getAuthor();
|
||||
String content = getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
||||
forumItems[i] = new ForumItem(MESSAGE_IDS[i], PARENT_IDS[i],
|
||||
content, System.currentTimeMillis(), author, UNKNOWN);
|
||||
forumItems[i].setLevel(LEVELS[i]);
|
||||
}
|
||||
ThreadItemList<ForumItem> list = new ThreadItemListImpl<>();
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
package org.briarproject.briar.api.blog;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||
|
||||
public interface BlogConstants {
|
||||
|
||||
/**
|
||||
* The maximum length of a blogs's name in UTF-8 bytes.
|
||||
*/
|
||||
int MAX_BLOG_NAME_LENGTH = MAX_AUTHOR_NAME_LENGTH;
|
||||
|
||||
/**
|
||||
* The maximum length of a blog post's body in bytes.
|
||||
*/
|
||||
@@ -24,9 +18,6 @@ public interface BlogConstants {
|
||||
String KEY_TYPE = "type";
|
||||
String KEY_TIMESTAMP = "timestamp";
|
||||
String KEY_TIME_RECEIVED = "timeReceived";
|
||||
String KEY_AUTHOR_ID = "id";
|
||||
String KEY_AUTHOR_NAME = "name";
|
||||
String KEY_PUBLIC_KEY = "publicKey";
|
||||
String KEY_AUTHOR = "author";
|
||||
String KEY_RSS_FEED = "rssFeed";
|
||||
String KEY_READ = "read";
|
||||
|
||||
@@ -16,26 +16,26 @@ public class Feed {
|
||||
private final Blog blog;
|
||||
private final LocalAuthor localAuthor;
|
||||
@Nullable
|
||||
private final String description, author;
|
||||
private final String description, rssAuthor;
|
||||
private final long added, updated, lastEntryTime;
|
||||
|
||||
public Feed(String url, Blog blog, LocalAuthor localAuthor,
|
||||
@Nullable String description, @Nullable String author, long added,
|
||||
long updated, long lastEntryTime) {
|
||||
|
||||
@Nullable String description, @Nullable String rssAuthor,
|
||||
long added, long updated, long lastEntryTime) {
|
||||
this.url = url;
|
||||
this.blog = blog;
|
||||
this.localAuthor = localAuthor;
|
||||
this.description = description;
|
||||
this.author = author;
|
||||
this.rssAuthor = rssAuthor;
|
||||
this.added = added;
|
||||
this.updated = updated;
|
||||
this.lastEntryTime = lastEntryTime;
|
||||
}
|
||||
|
||||
public Feed(String url, Blog blog, LocalAuthor localAuthor,
|
||||
@Nullable String description, @Nullable String author, long added) {
|
||||
this(url, blog, localAuthor, description, author, added, 0L, 0L);
|
||||
@Nullable String description, @Nullable String rssAuthor,
|
||||
long added) {
|
||||
this(url, blog, localAuthor, description, rssAuthor, added, 0L, 0L);
|
||||
}
|
||||
|
||||
public Feed(String url, Blog blog, LocalAuthor localAuthor, long added) {
|
||||
@@ -68,8 +68,8 @@ public class Feed {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
public String getRssAuthor() {
|
||||
return rssAuthor;
|
||||
}
|
||||
|
||||
public long getAdded() {
|
||||
|
||||
@@ -18,11 +18,10 @@ public interface FeedConstants {
|
||||
// group metadata keys
|
||||
String KEY_FEEDS = "feeds";
|
||||
String KEY_FEED_URL = "feedURL";
|
||||
String KEY_BLOG_TITLE = "blogTitle";
|
||||
String KEY_PUBLIC_KEY = "publicKey";
|
||||
String KEY_PRIVATE_KEY = "privateKey";
|
||||
String KEY_FEED_DESC = "feedDesc";
|
||||
String KEY_FEED_AUTHOR = "feedAuthor";
|
||||
String KEY_FEED_PRIVATE_KEY = "feedPrivateKey";
|
||||
String KEY_FEED_DESC = "feedDesc";
|
||||
String KEY_FEED_RSS_AUTHOR = "feedRssAuthor";
|
||||
String KEY_FEED_ADDED = "feedAdded";
|
||||
String KEY_FEED_UPDATED = "feedUpdated";
|
||||
String KEY_FEED_LAST_ENTRY = "feedLastEntryTime";
|
||||
|
||||
@@ -14,27 +14,16 @@ public interface ForumConstants {
|
||||
*/
|
||||
int FORUM_SALT_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* The maximum length of a forum post's content type in UTF-8 bytes.
|
||||
*/
|
||||
int MAX_CONTENT_TYPE_LENGTH = 50;
|
||||
|
||||
/**
|
||||
* The maximum length of a forum post's body in bytes.
|
||||
*/
|
||||
int MAX_FORUM_POST_BODY_LENGTH = MAX_MESSAGE_BODY_LENGTH - 1024;
|
||||
|
||||
/* Forum Sharing Constants */
|
||||
String FORUM_NAME = "forumName";
|
||||
String FORUM_SALT = "forumSalt";
|
||||
|
||||
// Database keys
|
||||
// Metadata keys
|
||||
String KEY_TIMESTAMP = "timestamp";
|
||||
String KEY_PARENT = "parent";
|
||||
String KEY_ID = "id";
|
||||
String KEY_NAME = "name";
|
||||
String KEY_PUBLIC_NAME = "publicKey";
|
||||
String KEY_AUTHOR = "author";
|
||||
String KEY_LOCAL = "local";
|
||||
String KEY_READ = "read";
|
||||
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ public interface PrivateGroupFactory {
|
||||
/**
|
||||
* Creates a private group with the given name and author.
|
||||
*/
|
||||
PrivateGroup createPrivateGroup(String name, Author author);
|
||||
PrivateGroup createPrivateGroup(String name, Author creator);
|
||||
|
||||
/**
|
||||
* Creates a private group with the given name, author and salt.
|
||||
*/
|
||||
PrivateGroup createPrivateGroup(String name, Author author, byte[] salt);
|
||||
PrivateGroup createPrivateGroup(String name, Author creator, byte[] salt);
|
||||
|
||||
/**
|
||||
* Parses a group and returns the corresponding PrivateGroup.
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
@@ -14,8 +13,7 @@ import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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.util.ValidationUtils.checkSize;
|
||||
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_VERSION;
|
||||
|
||||
@@ -24,15 +22,12 @@ import static org.briarproject.briar.api.blog.BlogManager.CLIENT_VERSION;
|
||||
class BlogFactoryImpl implements BlogFactory {
|
||||
|
||||
private final GroupFactory groupFactory;
|
||||
private final AuthorFactory authorFactory;
|
||||
private final ClientHelper clientHelper;
|
||||
|
||||
@Inject
|
||||
BlogFactoryImpl(GroupFactory groupFactory, AuthorFactory authorFactory,
|
||||
ClientHelper clientHelper) {
|
||||
BlogFactoryImpl(GroupFactory groupFactory, ClientHelper clientHelper) {
|
||||
|
||||
this.groupFactory = groupFactory;
|
||||
this.authorFactory = authorFactory;
|
||||
this.clientHelper = clientHelper;
|
||||
}
|
||||
|
||||
@@ -48,11 +43,7 @@ class BlogFactoryImpl implements BlogFactory {
|
||||
|
||||
private Blog createBlog(Author a, boolean rssFeed) {
|
||||
try {
|
||||
BdfList blog = BdfList.of(
|
||||
a.getName(),
|
||||
a.getPublicKey(),
|
||||
rssFeed
|
||||
);
|
||||
BdfList blog = BdfList.of(clientHelper.toList(a), rssFeed);
|
||||
byte[] descriptor = clientHelper.toByteArray(blog);
|
||||
Group g = groupFactory.createGroup(CLIENT_ID, CLIENT_VERSION,
|
||||
descriptor);
|
||||
@@ -63,20 +54,15 @@ class BlogFactoryImpl implements BlogFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blog parseBlog(Group group) throws FormatException {
|
||||
byte[] descriptor = group.getDescriptor();
|
||||
// Author name, public key, RSS feed
|
||||
BdfList blog = clientHelper.toList(descriptor);
|
||||
String name = blog.getString(0);
|
||||
if (name.length() > MAX_AUTHOR_NAME_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
byte[] publicKey = blog.getRaw(1);
|
||||
if (publicKey.length > MAX_PUBLIC_KEY_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
public Blog parseBlog(Group g) throws FormatException {
|
||||
// Author, RSS feed
|
||||
BdfList descriptor = clientHelper.toList(g.getDescriptor());
|
||||
checkSize(descriptor, 2);
|
||||
BdfList authorList = descriptor.getList(0);
|
||||
boolean rssFeed = descriptor.getBoolean(1);
|
||||
|
||||
Author author = authorFactory.createAuthor(name, publicKey);
|
||||
boolean rssFeed = blog.getBoolean(2);
|
||||
return new Blog(group, author, rssFeed);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
return new Blog(g, author, rssFeed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,13 +50,10 @@ import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.contact.ContactManager.RemoveContactHook;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_READ;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_RSS_FEED;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_TIMESTAMP;
|
||||
@@ -66,7 +63,6 @@ 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.WRAPPED_COMMENT;
|
||||
import static org.briarproject.briar.api.blog.MessageType.WRAPPED_POST;
|
||||
import static org.briarproject.briar.blog.BlogPostValidator.authorToBdfDictionary;
|
||||
|
||||
@NotNullByDefault
|
||||
class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
@@ -227,7 +223,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
meta.put(KEY_TYPE, POST.getInt());
|
||||
meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp());
|
||||
meta.put(KEY_AUTHOR, authorToBdfDictionary(p.getAuthor()));
|
||||
meta.put(KEY_AUTHOR, clientHelper.toList(p.getAuthor()));
|
||||
meta.put(KEY_READ, true);
|
||||
meta.put(KEY_RSS_FEED, b.isRssFeed());
|
||||
clientHelper.addLocalMessage(txn, p.getMessage(), meta, true);
|
||||
@@ -270,7 +266,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
meta.put(KEY_ORIGINAL_MSG_ID, message.getId());
|
||||
meta.put(KEY_ORIGINAL_PARENT_MSG_ID, parentOriginalId);
|
||||
meta.put(KEY_PARENT_MSG_ID, parentCurrentId);
|
||||
meta.put(KEY_AUTHOR, authorToBdfDictionary(author));
|
||||
meta.put(KEY_AUTHOR, clientHelper.toList(author));
|
||||
|
||||
// Send comment
|
||||
clientHelper.addLocalMessage(txn, message, meta, true);
|
||||
@@ -367,7 +363,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
"Unknown Message Type: " + type);
|
||||
}
|
||||
meta.put(KEY_ORIGINAL_MSG_ID, originalId);
|
||||
meta.put(KEY_AUTHOR, authorToBdfDictionary(header.getAuthor()));
|
||||
meta.put(KEY_AUTHOR, clientHelper.toList(header.getAuthor()));
|
||||
meta.put(KEY_TIMESTAMP, header.getTimestamp());
|
||||
meta.put(KEY_TIME_RECEIVED, header.getTimeReceived());
|
||||
|
||||
@@ -506,9 +502,9 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
// get all authors we need to get the status for
|
||||
Set<AuthorId> authors = new HashSet<>();
|
||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
||||
authors.add(new AuthorId(
|
||||
entry.getValue().getDictionary(KEY_AUTHOR)
|
||||
.getRaw(KEY_AUTHOR_ID)));
|
||||
BdfList authorList = entry.getValue().getList(KEY_AUTHOR);
|
||||
Author a = clientHelper.parseAndValidateAuthor(authorList);
|
||||
authors.add(a.getId());
|
||||
}
|
||||
// get statuses for all authors
|
||||
Map<AuthorId, Status> authorStatuses = new HashMap<>();
|
||||
@@ -573,19 +569,16 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
||||
long timestamp = meta.getLong(KEY_TIMESTAMP);
|
||||
long timeReceived = meta.getLong(KEY_TIME_RECEIVED, timestamp);
|
||||
|
||||
BdfDictionary d = meta.getDictionary(KEY_AUTHOR);
|
||||
AuthorId authorId = new AuthorId(d.getRaw(KEY_AUTHOR_ID));
|
||||
String name = d.getString(KEY_AUTHOR_NAME);
|
||||
byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY);
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
BdfList authorList = meta.getList(KEY_AUTHOR);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
boolean isFeedPost = meta.getBoolean(KEY_RSS_FEED, false);
|
||||
Status authorStatus;
|
||||
if (isFeedPost) {
|
||||
authorStatus = Status.NONE;
|
||||
} else if (authorStatuses.containsKey(authorId)) {
|
||||
authorStatus = authorStatuses.get(authorId);
|
||||
} else if (authorStatuses.containsKey(author.getId())) {
|
||||
authorStatus = authorStatuses.get(author.getId());
|
||||
} else {
|
||||
authorStatus = identityManager.getAuthorStatus(txn, authorId);
|
||||
authorStatus = identityManager.getAuthorStatus(txn, author.getId());
|
||||
}
|
||||
|
||||
boolean read = meta.getBoolean(KEY_READ, false);
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.briar.blog;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
@@ -44,15 +43,14 @@ public class BlogModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
BlogPostFactory provideBlogPostFactory(ClientHelper clientHelper,
|
||||
Clock clock) {
|
||||
return new BlogPostFactoryImpl(clientHelper, clock);
|
||||
BlogPostFactory provideBlogPostFactory(
|
||||
BlogPostFactoryImpl blogPostFactory) {
|
||||
return blogPostFactory;
|
||||
}
|
||||
|
||||
@Provides
|
||||
BlogFactory provideBlogFactory(GroupFactory groupFactory,
|
||||
AuthorFactory authorFactory, ClientHelper clientHelper) {
|
||||
return new BlogFactoryImpl(groupFactory, authorFactory, clientHelper);
|
||||
BlogFactory provideBlogFactory(BlogFactoryImpl blogFactory) {
|
||||
return blogFactory;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.client.BdfMessageValidator;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
@@ -31,13 +30,10 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATUR
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_READ;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_RSS_FEED;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_TIMESTAMP;
|
||||
@@ -115,9 +111,8 @@ class BlogPostValidator extends BdfMessageValidator {
|
||||
Blog b = blogFactory.parseBlog(g);
|
||||
Author a = b.getAuthor();
|
||||
try {
|
||||
clientHelper
|
||||
.verifySignature(SIGNING_LABEL_POST, sig, a.getPublicKey(),
|
||||
signed);
|
||||
clientHelper.verifySignature(SIGNING_LABEL_POST, sig,
|
||||
a.getPublicKey(), signed);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
}
|
||||
@@ -125,7 +120,7 @@ class BlogPostValidator extends BdfMessageValidator {
|
||||
// Return the metadata and dependencies
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
meta.put(KEY_ORIGINAL_MSG_ID, m.getId());
|
||||
meta.put(KEY_AUTHOR, authorToBdfDictionary(a));
|
||||
meta.put(KEY_AUTHOR, clientHelper.toList(a));
|
||||
meta.put(KEY_RSS_FEED, b.isRssFeed());
|
||||
return new BdfMessageContext(meta);
|
||||
}
|
||||
@@ -156,10 +151,9 @@ class BlogPostValidator extends BdfMessageValidator {
|
||||
|
||||
// Signature
|
||||
byte[] sig = body.getRaw(3);
|
||||
checkLength(sig, 0, MAX_SIGNATURE_LENGTH);
|
||||
BdfList signed =
|
||||
BdfList.of(g.getId(), m.getTimestamp(), comment, pOriginalId,
|
||||
currentId);
|
||||
checkLength(sig, 1, MAX_SIGNATURE_LENGTH);
|
||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), comment,
|
||||
pOriginalId, currentId);
|
||||
Blog b = blogFactory.parseBlog(g);
|
||||
Author a = b.getAuthor();
|
||||
try {
|
||||
@@ -175,7 +169,7 @@ class BlogPostValidator extends BdfMessageValidator {
|
||||
meta.put(KEY_ORIGINAL_MSG_ID, m.getId());
|
||||
meta.put(KEY_ORIGINAL_PARENT_MSG_ID, pOriginalId);
|
||||
meta.put(KEY_PARENT_MSG_ID, currentId);
|
||||
meta.put(KEY_AUTHOR, authorToBdfDictionary(a));
|
||||
meta.put(KEY_AUTHOR, clientHelper.toList(a));
|
||||
Collection<MessageId> dependencies = Collections.singleton(currentId);
|
||||
return new BdfMessageContext(meta, dependencies);
|
||||
}
|
||||
@@ -215,7 +209,7 @@ class BlogPostValidator extends BdfMessageValidator {
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
meta.put(KEY_ORIGINAL_MSG_ID, wMessage.getId());
|
||||
meta.put(KEY_TIMESTAMP, wTimestamp);
|
||||
meta.put(KEY_AUTHOR, c.getDictionary().getDictionary(KEY_AUTHOR));
|
||||
meta.put(KEY_AUTHOR, c.getDictionary().getList(KEY_AUTHOR));
|
||||
meta.put(KEY_RSS_FEED, wBlog.isRssFeed());
|
||||
return new BdfMessageContext(meta);
|
||||
}
|
||||
@@ -282,18 +276,10 @@ class BlogPostValidator extends BdfMessageValidator {
|
||||
meta.put(KEY_PARENT_MSG_ID, parentId);
|
||||
meta.put(KEY_TIMESTAMP, wTimestamp);
|
||||
if (comment != null) meta.put(KEY_COMMENT, comment);
|
||||
meta.put(KEY_AUTHOR, c.getDictionary().getDictionary(KEY_AUTHOR));
|
||||
meta.put(KEY_AUTHOR, c.getDictionary().getList(KEY_AUTHOR));
|
||||
return new BdfMessageContext(meta, dependencies);
|
||||
}
|
||||
|
||||
static BdfDictionary authorToBdfDictionary(Author a) {
|
||||
return BdfDictionary.of(
|
||||
new BdfEntry(KEY_AUTHOR_ID, a.getId()),
|
||||
new BdfEntry(KEY_AUTHOR_NAME, a.getName()),
|
||||
new BdfEntry(KEY_PUBLIC_KEY, a.getPublicKey())
|
||||
);
|
||||
}
|
||||
|
||||
private void addMessageMetadata(BdfMessageContext c, long time) {
|
||||
c.getDictionary().put(KEY_TIMESTAMP, time);
|
||||
c.getDictionary().put(KEY_TIME_RECEIVED, clock.currentTimeMillis());
|
||||
|
||||
@@ -3,10 +3,13 @@ package org.briarproject.briar.feed;
|
||||
import com.rometools.rome.feed.synd.SyndFeed;
|
||||
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
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.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
@@ -18,29 +21,31 @@ import org.briarproject.briar.api.feed.Feed;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_BLOG_TITLE;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_ADDED;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_AUTHOR;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_DESC;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_LAST_ENTRY;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_PRIVATE_KEY;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_RSS_AUTHOR;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_UPDATED;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEED_URL;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_PRIVATE_KEY;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_PUBLIC_KEY;
|
||||
|
||||
class FeedFactoryImpl implements FeedFactory {
|
||||
|
||||
private final CryptoComponent cryptoComponent;
|
||||
private final AuthorFactory authorFactory;
|
||||
private final BlogFactory blogFactory;
|
||||
private final ClientHelper clientHelper;
|
||||
private final Clock clock;
|
||||
|
||||
@Inject
|
||||
FeedFactoryImpl(CryptoComponent cryptoComponent,
|
||||
AuthorFactory authorFactory, BlogFactory blogFactory, Clock clock) {
|
||||
AuthorFactory authorFactory, BlogFactory blogFactory,
|
||||
ClientHelper clientHelper, Clock clock) {
|
||||
this.cryptoComponent = cryptoComponent;
|
||||
this.authorFactory = authorFactory;
|
||||
this.blogFactory = blogFactory;
|
||||
this.clientHelper = clientHelper;
|
||||
this.clock = clock;
|
||||
}
|
||||
|
||||
@@ -48,13 +53,12 @@ class FeedFactoryImpl implements FeedFactory {
|
||||
public Feed createFeed(String url, SyndFeed syndFeed) {
|
||||
String title = syndFeed.getTitle();
|
||||
if (title == null) title = "RSS";
|
||||
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,
|
||||
keyPair.getPublic().getEncoded(),
|
||||
keyPair.getPrivate().getEncoded());
|
||||
LocalAuthor localAuthor = authorFactory.createLocalAuthor(title,
|
||||
keyPair.getPublic().getEncoded(),
|
||||
keyPair.getPrivate().getEncoded());
|
||||
Blog blog = blogFactory.createFeedBlog(localAuthor);
|
||||
long added = clock.currentTimeMillis();
|
||||
|
||||
@@ -73,39 +77,40 @@ class FeedFactoryImpl implements FeedFactory {
|
||||
public Feed createFeed(BdfDictionary d) throws FormatException {
|
||||
String url = d.getString(KEY_FEED_URL);
|
||||
|
||||
String blogTitle = d.getString(KEY_BLOG_TITLE);
|
||||
byte[] publicKey = d.getRaw(KEY_PUBLIC_KEY);
|
||||
byte[] privateKey = d.getRaw(KEY_PRIVATE_KEY);
|
||||
LocalAuthor localAuthor = authorFactory
|
||||
.createLocalAuthor(blogTitle, publicKey, privateKey);
|
||||
BdfList authorList = d.getList(KEY_FEED_AUTHOR);
|
||||
byte[] privateKey = d.getRaw(KEY_FEED_PRIVATE_KEY);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
LocalAuthor localAuthor = authorFactory.createLocalAuthor(
|
||||
author.getFormatVersion(), author.getName(),
|
||||
author.getPublicKey(), privateKey);
|
||||
Blog blog = blogFactory.createFeedBlog(localAuthor);
|
||||
|
||||
String desc = d.getOptionalString(KEY_FEED_DESC);
|
||||
String author = d.getOptionalString(KEY_FEED_AUTHOR);
|
||||
String rssAuthor = d.getOptionalString(KEY_FEED_RSS_AUTHOR);
|
||||
long added = d.getLong(KEY_FEED_ADDED, 0L);
|
||||
long updated = d.getLong(KEY_FEED_UPDATED, 0L);
|
||||
long lastEntryTime = d.getLong(KEY_FEED_LAST_ENTRY, 0L);
|
||||
|
||||
return new Feed(url, blog, localAuthor, desc, author, added,
|
||||
return new Feed(url, blog, localAuthor, desc, rssAuthor, added,
|
||||
updated, lastEntryTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BdfDictionary feedToBdfDictionary(Feed feed) {
|
||||
LocalAuthor localAuthor = feed.getLocalAuthor();
|
||||
BdfList authorList = clientHelper.toList(localAuthor);
|
||||
BdfDictionary d = BdfDictionary.of(
|
||||
new BdfEntry(KEY_FEED_URL, feed.getUrl()),
|
||||
new BdfEntry(KEY_BLOG_TITLE, feed.getLocalAuthor().getName()),
|
||||
new BdfEntry(KEY_PUBLIC_KEY,
|
||||
feed.getLocalAuthor().getPublicKey()),
|
||||
new BdfEntry(KEY_PRIVATE_KEY,
|
||||
feed.getLocalAuthor().getPrivateKey()),
|
||||
new BdfEntry(KEY_FEED_AUTHOR, authorList),
|
||||
new BdfEntry(KEY_FEED_PRIVATE_KEY, localAuthor.getPrivateKey()),
|
||||
new BdfEntry(KEY_FEED_ADDED, feed.getAdded()),
|
||||
new BdfEntry(KEY_FEED_UPDATED, feed.getUpdated()),
|
||||
new BdfEntry(KEY_FEED_LAST_ENTRY, feed.getLastEntryTime())
|
||||
);
|
||||
if (feed.getDescription() != null)
|
||||
d.put(KEY_FEED_DESC, feed.getDescription());
|
||||
if (feed.getAuthor() != null) d.put(KEY_FEED_AUTHOR, feed.getAuthor());
|
||||
if (feed.getRssAuthor() != null)
|
||||
d.put(KEY_FEED_RSS_AUTHOR, feed.getRssAuthor());
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ class ForumFactoryImpl implements ForumFactory {
|
||||
@Inject
|
||||
ForumFactoryImpl(GroupFactory groupFactory, ClientHelper clientHelper,
|
||||
SecureRandom random) {
|
||||
|
||||
this.groupFactory = groupFactory;
|
||||
this.clientHelper = clientHelper;
|
||||
this.random = random;
|
||||
|
||||
@@ -47,11 +47,8 @@ import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_ID;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_LOCAL;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_NAME;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PUBLIC_NAME;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
|
||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||
|
||||
@@ -147,11 +144,7 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
||||
meta.put(KEY_TIMESTAMP, p.getMessage().getTimestamp());
|
||||
if (p.getParent() != null) meta.put(KEY_PARENT, p.getParent());
|
||||
Author a = p.getAuthor();
|
||||
BdfDictionary authorMeta = new BdfDictionary();
|
||||
authorMeta.put(KEY_ID, a.getId());
|
||||
authorMeta.put(KEY_NAME, a.getName());
|
||||
authorMeta.put(KEY_PUBLIC_NAME, a.getPublicKey());
|
||||
meta.put(KEY_AUTHOR, authorMeta);
|
||||
meta.put(KEY_AUTHOR, clientHelper.toList(a));
|
||||
meta.put(KEY_LOCAL, true);
|
||||
meta.put(MSG_KEY_READ, true);
|
||||
clientHelper.addLocalMessage(txn, p.getMessage(), meta, true);
|
||||
@@ -237,10 +230,9 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
||||
// get all authors we need to get the status for
|
||||
Set<AuthorId> authors = new HashSet<>();
|
||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
||||
BdfDictionary d =
|
||||
entry.getValue().getDictionary(KEY_AUTHOR, null);
|
||||
if (d != null)
|
||||
authors.add(new AuthorId(d.getRaw(KEY_ID)));
|
||||
BdfList authorList = entry.getValue().getList(KEY_AUTHOR);
|
||||
Author a = clientHelper.parseAndValidateAuthor(authorList);
|
||||
authors.add(a.getId());
|
||||
}
|
||||
// get statuses for all authors
|
||||
Map<AuthorId, Status> statuses = new HashMap<>();
|
||||
@@ -298,12 +290,9 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
||||
MessageId parentId = null;
|
||||
if (meta.containsKey(KEY_PARENT))
|
||||
parentId = new MessageId(meta.getRaw(KEY_PARENT));
|
||||
BdfDictionary authorDict = meta.getDictionary(KEY_AUTHOR);
|
||||
AuthorId authorId = new AuthorId(authorDict.getRaw(KEY_ID));
|
||||
String name = authorDict.getString(KEY_NAME);
|
||||
byte[] publicKey = authorDict.getRaw(KEY_PUBLIC_NAME);
|
||||
Author author = new Author(authorId, name, publicKey);
|
||||
Status status = statuses.get(authorId);
|
||||
BdfList authorList = meta.getList(KEY_AUTHOR);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
Status status = statuses.get(author.getId());
|
||||
if (status == null)
|
||||
status = identityManager.getAuthorStatus(txn, author.getId());
|
||||
boolean read = meta.getBoolean(MSG_KEY_READ);
|
||||
|
||||
@@ -2,16 +2,12 @@ package org.briarproject.briar.forum;
|
||||
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.forum.ForumFactory;
|
||||
import org.briarproject.briar.api.forum.ForumManager;
|
||||
import org.briarproject.briar.api.forum.ForumPostFactory;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@@ -34,10 +30,8 @@ public class ForumModule {
|
||||
@Singleton
|
||||
ForumManager provideForumManager(ForumManagerImpl forumManager,
|
||||
ValidationManager validationManager) {
|
||||
|
||||
validationManager.registerIncomingMessageHook(CLIENT_ID,
|
||||
forumManager);
|
||||
|
||||
return forumManager;
|
||||
}
|
||||
|
||||
@@ -48,19 +42,17 @@ public class ForumModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
ForumFactory provideForumFactory(GroupFactory groupFactory,
|
||||
ClientHelper clientHelper, SecureRandom random) {
|
||||
return new ForumFactoryImpl(groupFactory, clientHelper, random);
|
||||
ForumFactory provideForumFactory(ForumFactoryImpl forumFactory) {
|
||||
return forumFactory;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ForumPostValidator provideForumPostValidator(
|
||||
ValidationManager validationManager, AuthorFactory authorFactory,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock) {
|
||||
ForumPostValidator validator = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
ValidationManager validationManager, ClientHelper clientHelper,
|
||||
MetadataEncoder metadataEncoder, Clock clock) {
|
||||
ForumPostValidator validator = new ForumPostValidator(clientHelper,
|
||||
metadataEncoder, clock);
|
||||
validationManager.registerMessageValidator(CLIENT_ID, validator);
|
||||
return validator;
|
||||
}
|
||||
|
||||
@@ -39,8 +39,7 @@ class ForumPostFactoryImpl implements ForumPostFactory {
|
||||
if (StringUtils.utf8IsTooLong(body, MAX_FORUM_POST_BODY_LENGTH))
|
||||
throw new IllegalArgumentException();
|
||||
// Serialise the data to be signed
|
||||
BdfList authorList =
|
||||
BdfList.of(author.getName(), author.getPublicKey());
|
||||
BdfList authorList = clientHelper.toList(author);
|
||||
BdfList signed = BdfList.of(groupId, timestamp, parent, authorList,
|
||||
body);
|
||||
// Sign the data
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||
@@ -23,11 +22,13 @@ import java.util.Collections;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_READ;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||
import static org.briarproject.briar.api.forum.ForumPostFactory.SIGNING_LABEL_POST;
|
||||
|
||||
@@ -35,12 +36,9 @@ import static org.briarproject.briar.api.forum.ForumPostFactory.SIGNING_LABEL_PO
|
||||
@NotNullByDefault
|
||||
class ForumPostValidator extends BdfMessageValidator {
|
||||
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
ForumPostValidator(AuthorFactory authorFactory, ClientHelper clientHelper,
|
||||
ForumPostValidator(ClientHelper clientHelper,
|
||||
MetadataEncoder metadataEncoder, Clock clock) {
|
||||
super(clientHelper, metadataEncoder, clock);
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,24 +53,18 @@ class ForumPostValidator extends BdfMessageValidator {
|
||||
|
||||
// Author
|
||||
BdfList authorList = body.getList(1);
|
||||
// Name, public key
|
||||
checkSize(authorList, 2);
|
||||
String name = authorList.getString(0);
|
||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = authorList.getRaw(1);
|
||||
checkLength(publicKey, 0, MAX_PUBLIC_KEY_LENGTH);
|
||||
Author author = authorFactory.createAuthor(name, publicKey);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
|
||||
// Forum post body
|
||||
String forumPostBody = body.getString(2);
|
||||
checkLength(forumPostBody, 0, MAX_FORUM_POST_BODY_LENGTH);
|
||||
String content = body.getString(2);
|
||||
checkLength(content, 0, MAX_FORUM_POST_BODY_LENGTH);
|
||||
|
||||
// Signature
|
||||
byte[] sig = body.getRaw(3);
|
||||
checkLength(sig, 0, MAX_SIGNATURE_LENGTH);
|
||||
checkLength(sig, 1, MAX_SIGNATURE_LENGTH);
|
||||
// Verify the signature
|
||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), parent,
|
||||
authorList, forumPostBody);
|
||||
authorList, content);
|
||||
try {
|
||||
clientHelper.verifySignature(SIGNING_LABEL_POST, sig,
|
||||
author.getPublicKey(), signed);
|
||||
@@ -83,17 +75,13 @@ class ForumPostValidator extends BdfMessageValidator {
|
||||
// Return the metadata and dependencies
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
Collection<MessageId> dependencies = Collections.emptyList();
|
||||
meta.put("timestamp", m.getTimestamp());
|
||||
meta.put(KEY_TIMESTAMP, m.getTimestamp());
|
||||
if (parent != null) {
|
||||
meta.put("parent", parent);
|
||||
meta.put(KEY_PARENT, parent);
|
||||
dependencies = Collections.singletonList(new MessageId(parent));
|
||||
}
|
||||
BdfDictionary authorMeta = new BdfDictionary();
|
||||
authorMeta.put("id", author.getId());
|
||||
authorMeta.put("name", author.getName());
|
||||
authorMeta.put("publicKey", author.getPublicKey());
|
||||
meta.put("author", authorMeta);
|
||||
meta.put("read", false);
|
||||
meta.put(KEY_AUTHOR, authorList);
|
||||
meta.put(KEY_READ, false);
|
||||
return new BdfMessageContext(meta, dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,7 @@ class IntroduceeManager {
|
||||
d.put(ANSWERED, false);
|
||||
|
||||
// check if the contact we are introduced to does already exist
|
||||
// TODO: Exchange author format version
|
||||
AuthorId remoteAuthorId = authorFactory
|
||||
.createAuthor(message.getString(NAME),
|
||||
message.getRaw(PUBLIC_KEY)).getId();
|
||||
@@ -339,6 +340,7 @@ class IntroduceeManager {
|
||||
long timestamp = Math.min(ourTime, theirTime);
|
||||
|
||||
// Add the contact to the database as inactive
|
||||
// TODO: Exchange author format version
|
||||
Author remoteAuthor = authorFactory
|
||||
.createAuthor(localState.getString(NAME),
|
||||
localState.getRaw(PUBLIC_KEY));
|
||||
|
||||
@@ -87,6 +87,8 @@ class IntroductionValidator extends BdfQueueMessageValidator {
|
||||
|
||||
checkSize(message, 4, 5);
|
||||
|
||||
// TODO: Exchange author format version
|
||||
|
||||
// parse contact name
|
||||
String name = message.getString(2);
|
||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
@@ -131,7 +133,7 @@ class IntroductionValidator extends BdfQueueMessageValidator {
|
||||
|
||||
// parse ephemeral public key
|
||||
pubkey = message.getRaw(4);
|
||||
checkLength(pubkey, 0, MAX_PUBLIC_KEY_LENGTH);
|
||||
checkLength(pubkey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
|
||||
// parse transport properties
|
||||
tp = message.getDictionary(5);
|
||||
|
||||
@@ -4,15 +4,13 @@ import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ
|
||||
|
||||
interface GroupConstants {
|
||||
|
||||
// Database keys
|
||||
// Metadata keys
|
||||
String KEY_TYPE = "type";
|
||||
String KEY_TIMESTAMP = "timestamp";
|
||||
String KEY_READ = MSG_KEY_READ;
|
||||
String KEY_PARENT_MSG_ID = "parentMsgId";
|
||||
String KEY_PREVIOUS_MSG_ID = "previousMsgId";
|
||||
String KEY_MEMBER_ID = "memberId";
|
||||
String KEY_MEMBER_NAME = "memberName";
|
||||
String KEY_MEMBER_PUBLIC_KEY = "memberPublicKey";
|
||||
String KEY_MEMBER = "member";
|
||||
String KEY_INITIAL_JOIN_MSG = "initialJoinMsg";
|
||||
|
||||
String GROUP_KEY_MEMBERS = "members";
|
||||
|
||||
@@ -50,47 +50,65 @@ class GroupMessageFactoryImpl implements GroupMessageFactory {
|
||||
LocalAuthor member, @Nullable BdfList invite) {
|
||||
try {
|
||||
// Generate the signature
|
||||
int type = JOIN.getInt();
|
||||
BdfList toSign = BdfList.of(groupId, timestamp, type,
|
||||
member.getName(), member.getPublicKey(), invite);
|
||||
byte[] memberSignature = clientHelper
|
||||
.sign(SIGNING_LABEL_JOIN, toSign, member.getPrivateKey());
|
||||
BdfList memberList = clientHelper.toList(member);
|
||||
BdfList toSign = BdfList.of(
|
||||
groupId,
|
||||
timestamp,
|
||||
memberList,
|
||||
invite
|
||||
);
|
||||
byte[] memberSignature = clientHelper.sign(SIGNING_LABEL_JOIN,
|
||||
toSign, member.getPrivateKey());
|
||||
|
||||
// Compose the message
|
||||
BdfList body =
|
||||
BdfList.of(type, member.getName(),
|
||||
member.getPublicKey(), invite, memberSignature);
|
||||
BdfList body = BdfList.of(
|
||||
JOIN.getInt(),
|
||||
memberList,
|
||||
invite,
|
||||
memberSignature
|
||||
);
|
||||
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||
|
||||
return new GroupMessage(m, null, member);
|
||||
} catch (GeneralSecurityException | FormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (FormatException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupMessage createGroupMessage(GroupId groupId, long timestamp,
|
||||
@Nullable MessageId parentId, LocalAuthor author, String content,
|
||||
@Nullable MessageId parentId, LocalAuthor member, String content,
|
||||
MessageId previousMsgId) {
|
||||
try {
|
||||
// Generate the signature
|
||||
int type = POST.getInt();
|
||||
BdfList toSign = BdfList.of(groupId, timestamp, type,
|
||||
author.getName(), author.getPublicKey(), parentId,
|
||||
previousMsgId, content);
|
||||
byte[] signature = clientHelper
|
||||
.sign(SIGNING_LABEL_POST, toSign, author.getPrivateKey());
|
||||
BdfList memberList = clientHelper.toList(member);
|
||||
BdfList toSign = BdfList.of(
|
||||
groupId,
|
||||
timestamp,
|
||||
memberList,
|
||||
parentId,
|
||||
previousMsgId,
|
||||
content
|
||||
);
|
||||
byte[] signature = clientHelper.sign(SIGNING_LABEL_POST, toSign,
|
||||
member.getPrivateKey());
|
||||
|
||||
// Compose the message
|
||||
BdfList body =
|
||||
BdfList.of(type, author.getName(),
|
||||
author.getPublicKey(), parentId, previousMsgId,
|
||||
content, signature);
|
||||
BdfList body = BdfList.of(
|
||||
POST.getInt(),
|
||||
memberList,
|
||||
parentId,
|
||||
previousMsgId,
|
||||
content,
|
||||
signature
|
||||
);
|
||||
Message m = clientHelper.createMessage(groupId, timestamp, body);
|
||||
|
||||
return new GroupMessage(m, parentId, author);
|
||||
} catch (GeneralSecurityException | FormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
return new GroupMessage(m, parentId, member);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
} catch (FormatException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||
@@ -25,8 +24,6 @@ import java.util.Collection;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
@@ -37,9 +34,7 @@ import static org.briarproject.briar.api.privategroup.MessageType.POST;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_NAME;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_PREVIOUS_MSG_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_READ;
|
||||
@@ -51,16 +46,13 @@ import static org.briarproject.briar.privategroup.GroupConstants.KEY_TYPE;
|
||||
class GroupMessageValidator extends BdfMessageValidator {
|
||||
|
||||
private final PrivateGroupFactory privateGroupFactory;
|
||||
private final AuthorFactory authorFactory;
|
||||
private final GroupInvitationFactory groupInvitationFactory;
|
||||
|
||||
GroupMessageValidator(PrivateGroupFactory privateGroupFactory,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, AuthorFactory authorFactory,
|
||||
GroupInvitationFactory groupInvitationFactory) {
|
||||
Clock clock, GroupInvitationFactory groupInvitationFactory) {
|
||||
super(clientHelper, metadataEncoder, clock);
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
this.authorFactory = authorFactory;
|
||||
this.groupInvitationFactory = groupInvitationFactory;
|
||||
}
|
||||
|
||||
@@ -68,27 +60,22 @@ class GroupMessageValidator extends BdfMessageValidator {
|
||||
protected BdfMessageContext validateMessage(Message m, Group g,
|
||||
BdfList body) throws InvalidMessageException, FormatException {
|
||||
|
||||
checkSize(body, 5, 7);
|
||||
checkSize(body, 4, 6);
|
||||
|
||||
// message type (int)
|
||||
// Message type (int)
|
||||
int type = body.getLong(0).intValue();
|
||||
|
||||
// member_name (string)
|
||||
String memberName = body.getString(1);
|
||||
checkLength(memberName, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
// Member (list of int, string, raw)
|
||||
BdfList memberList = body.getList(1);
|
||||
Author member = clientHelper.parseAndValidateAuthor(memberList);
|
||||
|
||||
// member_public_key (raw)
|
||||
byte[] memberPublicKey = body.getRaw(2);
|
||||
checkLength(memberPublicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
|
||||
Author member = authorFactory.createAuthor(memberName, memberPublicKey);
|
||||
BdfMessageContext c;
|
||||
if (type == JOIN.getInt()) {
|
||||
c = validateJoin(m, g, body, member);
|
||||
addMessageMetadata(c, member, m.getTimestamp());
|
||||
addMessageMetadata(c, memberList, m.getTimestamp());
|
||||
} else if (type == POST.getInt()) {
|
||||
c = validatePost(m, g, body, member);
|
||||
addMessageMetadata(c, member, m.getTimestamp());
|
||||
addMessageMetadata(c, memberList, m.getTimestamp());
|
||||
} else {
|
||||
throw new InvalidMessageException("Unknown Message Type");
|
||||
}
|
||||
@@ -97,64 +84,54 @@ class GroupMessageValidator extends BdfMessageValidator {
|
||||
}
|
||||
|
||||
private BdfMessageContext validateJoin(Message m, Group g, BdfList body,
|
||||
Author member)
|
||||
throws InvalidMessageException, FormatException {
|
||||
Author member) throws FormatException {
|
||||
// Message type, member, optional invite, member's signature
|
||||
checkSize(body, 4);
|
||||
BdfList inviteList = body.getOptionalList(2);
|
||||
byte[] memberSignature = body.getRaw(3);
|
||||
checkLength(memberSignature, 1, MAX_SIGNATURE_LENGTH);
|
||||
|
||||
// The content is a BDF list with five elements
|
||||
checkSize(body, 5);
|
||||
// Invite is null if the member is the creator of the private group
|
||||
PrivateGroup pg = privateGroupFactory.parsePrivateGroup(g);
|
||||
|
||||
// invite is null if the member is the creator of the private group
|
||||
Author creator = pg.getCreator();
|
||||
boolean isCreator = false;
|
||||
BdfList invite = body.getOptionalList(3);
|
||||
if (invite == null) {
|
||||
if (!member.equals(creator))
|
||||
throw new InvalidMessageException();
|
||||
isCreator = true;
|
||||
boolean isCreator = member.equals(creator);
|
||||
if (isCreator) {
|
||||
if (inviteList != null) throw new FormatException();
|
||||
} else {
|
||||
if (member.equals(creator))
|
||||
throw new InvalidMessageException();
|
||||
|
||||
// Otherwise invite is a list with two elements
|
||||
checkSize(invite, 2);
|
||||
|
||||
// invite_timestamp (int)
|
||||
// join_timestamp must be greater than invite_timestamp
|
||||
long inviteTimestamp = invite.getLong(0);
|
||||
if (inviteList == null) throw new FormatException();
|
||||
// Timestamp, creator's signature
|
||||
checkSize(inviteList, 2);
|
||||
// Join timestamp must be greater than invite timestamp
|
||||
long inviteTimestamp = inviteList.getLong(0);
|
||||
if (m.getTimestamp() <= inviteTimestamp)
|
||||
throw new InvalidMessageException();
|
||||
|
||||
// creator_signature (raw)
|
||||
byte[] creatorSignature = invite.getRaw(1);
|
||||
throw new FormatException();
|
||||
byte[] creatorSignature = inviteList.getRaw(1);
|
||||
checkLength(creatorSignature, 1, MAX_SIGNATURE_LENGTH);
|
||||
|
||||
// the invite token is signed by the creator of the private group
|
||||
BdfList token = groupInvitationFactory
|
||||
.createInviteToken(creator.getId(), member.getId(),
|
||||
pg.getId(), inviteTimestamp);
|
||||
// The invite token is signed by the creator of the private group
|
||||
BdfList token = groupInvitationFactory.createInviteToken(
|
||||
creator.getId(), member.getId(), g.getId(),
|
||||
inviteTimestamp);
|
||||
try {
|
||||
clientHelper
|
||||
.verifySignature(SIGNING_LABEL_INVITE, creatorSignature,
|
||||
creator.getPublicKey(), token);
|
||||
clientHelper.verifySignature(SIGNING_LABEL_INVITE,
|
||||
creatorSignature, creator.getPublicKey(), token);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
|
||||
// member_signature (raw)
|
||||
// a signature with the member's private key over a list with 6 elements
|
||||
byte[] memberSignature = body.getRaw(4);
|
||||
checkLength(memberSignature, 1, MAX_SIGNATURE_LENGTH);
|
||||
|
||||
// Verify Signature
|
||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), JOIN.getInt(),
|
||||
member.getName(), member.getPublicKey(), invite);
|
||||
// Verify the member's signature
|
||||
BdfList memberList = body.getList(1); // Already validated
|
||||
BdfList signed = BdfList.of(
|
||||
g.getId(),
|
||||
m.getTimestamp(),
|
||||
memberList,
|
||||
inviteList
|
||||
);
|
||||
try {
|
||||
clientHelper.verifySignature(SIGNING_LABEL_JOIN, memberSignature,
|
||||
member.getPublicKey(), signed);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
// Return the metadata and no dependencies
|
||||
@@ -164,44 +141,38 @@ class GroupMessageValidator extends BdfMessageValidator {
|
||||
}
|
||||
|
||||
private BdfMessageContext validatePost(Message m, Group g, BdfList body,
|
||||
Author member)
|
||||
throws InvalidMessageException, FormatException {
|
||||
|
||||
// The content is a BDF list with seven elements
|
||||
checkSize(body, 7);
|
||||
|
||||
// parent_id (raw or null)
|
||||
// the identifier of the post to which this is a reply, if any
|
||||
byte[] parentId = body.getOptionalRaw(3);
|
||||
Author member) throws FormatException {
|
||||
// Message type, member, optional parent ID, previous message ID,
|
||||
// content, signature
|
||||
checkSize(body, 6);
|
||||
byte[] parentId = body.getOptionalRaw(2);
|
||||
checkLength(parentId, MessageId.LENGTH);
|
||||
|
||||
// previous_message_id (raw)
|
||||
// the identifier of the member's previous post or join message
|
||||
byte[] previousMessageId = body.getRaw(4);
|
||||
byte[] previousMessageId = body.getRaw(3);
|
||||
checkLength(previousMessageId, MessageId.LENGTH);
|
||||
|
||||
// content (string)
|
||||
String content = body.getString(5);
|
||||
String content = body.getString(4);
|
||||
checkLength(content, 1, MAX_GROUP_POST_BODY_LENGTH);
|
||||
|
||||
// signature (raw)
|
||||
// a signature with the member's private key over a list with 7 elements
|
||||
byte[] signature = body.getRaw(6);
|
||||
byte[] signature = body.getRaw(5);
|
||||
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
||||
|
||||
// Verify Signature
|
||||
BdfList signed = BdfList.of(g.getId(), m.getTimestamp(), POST.getInt(),
|
||||
member.getName(), member.getPublicKey(), parentId,
|
||||
previousMessageId, content);
|
||||
// Verify the member's signature
|
||||
BdfList memberList = body.getList(1); // Already validated
|
||||
BdfList signed = BdfList.of(
|
||||
g.getId(),
|
||||
m.getTimestamp(),
|
||||
memberList,
|
||||
parentId,
|
||||
previousMessageId,
|
||||
content
|
||||
);
|
||||
try {
|
||||
clientHelper.verifySignature(SIGNING_LABEL_POST, signature,
|
||||
member.getPublicKey(), signed);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new InvalidMessageException(e);
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
// The parent post, if any,
|
||||
// and the member's previous message are dependencies
|
||||
// The parent post, if any, and the member's previous message are
|
||||
// dependencies
|
||||
Collection<MessageId> dependencies = new ArrayList<>();
|
||||
if (parentId != null) dependencies.add(new MessageId(parentId));
|
||||
dependencies.add(new MessageId(previousMessageId));
|
||||
@@ -213,13 +184,11 @@ class GroupMessageValidator extends BdfMessageValidator {
|
||||
return new BdfMessageContext(meta, dependencies);
|
||||
}
|
||||
|
||||
private void addMessageMetadata(BdfMessageContext c, Author member,
|
||||
long time) {
|
||||
c.getDictionary().put(KEY_TIMESTAMP, time);
|
||||
private void addMessageMetadata(BdfMessageContext c, BdfList member,
|
||||
long timestamp) {
|
||||
c.getDictionary().put(KEY_MEMBER, member);
|
||||
c.getDictionary().put(KEY_TIMESTAMP, timestamp);
|
||||
c.getDictionary().put(KEY_READ, false);
|
||||
c.getDictionary().put(KEY_MEMBER_ID, member.getId());
|
||||
c.getDictionary().put(KEY_MEMBER_NAME, member.getName());
|
||||
c.getDictionary().put(KEY_MEMBER_PUBLIC_KEY, member.getPublicKey());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
@@ -17,6 +16,8 @@ import java.security.SecureRandom;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
|
||||
@@ -28,58 +29,55 @@ class PrivateGroupFactoryImpl implements PrivateGroupFactory {
|
||||
|
||||
private final GroupFactory groupFactory;
|
||||
private final ClientHelper clientHelper;
|
||||
private final AuthorFactory authorFactory;
|
||||
private final SecureRandom random;
|
||||
|
||||
@Inject
|
||||
PrivateGroupFactoryImpl(GroupFactory groupFactory,
|
||||
ClientHelper clientHelper, AuthorFactory authorFactory,
|
||||
SecureRandom random) {
|
||||
ClientHelper clientHelper, SecureRandom random) {
|
||||
|
||||
this.groupFactory = groupFactory;
|
||||
this.clientHelper = clientHelper;
|
||||
this.authorFactory = authorFactory;
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateGroup createPrivateGroup(String name, Author author) {
|
||||
public PrivateGroup createPrivateGroup(String name, Author creator) {
|
||||
int length = StringUtils.toUtf8(name).length;
|
||||
if (length == 0) throw new IllegalArgumentException("Group name empty");
|
||||
if (length > MAX_GROUP_NAME_LENGTH)
|
||||
throw new IllegalArgumentException(
|
||||
"Group name exceeds maximum length");
|
||||
if (length == 0 || length > MAX_GROUP_NAME_LENGTH)
|
||||
throw new IllegalArgumentException();
|
||||
byte[] salt = new byte[GROUP_SALT_LENGTH];
|
||||
random.nextBytes(salt);
|
||||
return createPrivateGroup(name, author, salt);
|
||||
return createPrivateGroup(name, creator, salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateGroup createPrivateGroup(String name, Author author,
|
||||
public PrivateGroup createPrivateGroup(String name, Author creator,
|
||||
byte[] salt) {
|
||||
try {
|
||||
BdfList group = BdfList.of(
|
||||
name,
|
||||
author.getName(),
|
||||
author.getPublicKey(),
|
||||
salt
|
||||
);
|
||||
BdfList creatorList = clientHelper.toList(creator);
|
||||
BdfList group = BdfList.of(creatorList, name, salt);
|
||||
byte[] descriptor = clientHelper.toByteArray(group);
|
||||
Group g = groupFactory.createGroup(CLIENT_ID, CLIENT_VERSION,
|
||||
descriptor);
|
||||
return new PrivateGroup(g, name, author, salt);
|
||||
return new PrivateGroup(g, name, creator, salt);
|
||||
} catch (FormatException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrivateGroup parsePrivateGroup(Group group) throws FormatException {
|
||||
byte[] descriptor = group.getDescriptor();
|
||||
BdfList list = clientHelper.toList(descriptor);
|
||||
Author a =
|
||||
authorFactory.createAuthor(list.getString(1), list.getRaw(2));
|
||||
return new PrivateGroup(group, list.getString(0), a, list.getRaw(3));
|
||||
public PrivateGroup parsePrivateGroup(Group g) throws FormatException {
|
||||
// Creator, group name, salt
|
||||
BdfList descriptor = clientHelper.toList(g.getDescriptor());
|
||||
checkSize(descriptor, 3);
|
||||
BdfList creatorList = descriptor.getList(0);
|
||||
String groupName = descriptor.getString(1);
|
||||
checkLength(groupName, 1, MAX_GROUP_NAME_LENGTH);
|
||||
byte[] salt = descriptor.getRaw(2);
|
||||
checkLength(salt, GROUP_SALT_LENGTH);
|
||||
|
||||
Author creator = clientHelper.parseAndValidateAuthor(creatorList);
|
||||
return new PrivateGroup(g, groupName, creator, salt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent;
|
||||
import org.briarproject.briar.client.BdfIncomingMessageHook;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -69,9 +68,7 @@ import static org.briarproject.briar.privategroup.GroupConstants.GROUP_KEY_MEMBE
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.GROUP_KEY_OUR_GROUP;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.GROUP_KEY_VISIBILITY;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_NAME;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_PREVIOUS_MSG_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_READ;
|
||||
@@ -139,7 +136,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
meta.put(KEY_TYPE, JOIN.getInt());
|
||||
meta.put(KEY_INITIAL_JOIN_MSG, creator);
|
||||
addMessageMetadata(meta, m, true);
|
||||
addMessageMetadata(meta, m);
|
||||
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
|
||||
messageTracker.trackOutgoingMessage(txn, m.getMessage());
|
||||
addMember(txn, m.getMessage().getGroupId(), m.getMember(), VISIBLE);
|
||||
@@ -217,7 +214,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
meta.put(KEY_TYPE, POST.getInt());
|
||||
if (m.getParent() != null)
|
||||
meta.put(KEY_PARENT_MSG_ID, m.getParent());
|
||||
addMessageMetadata(meta, m, true);
|
||||
addMessageMetadata(meta, m);
|
||||
GroupId g = m.getMessage().getGroupId();
|
||||
clientHelper.addLocalMessage(txn, m.getMessage(), meta, true);
|
||||
|
||||
@@ -239,13 +236,10 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
m.getMessage().getTimestamp(), m.getMember(), OURSELVES, true);
|
||||
}
|
||||
|
||||
private void addMessageMetadata(BdfDictionary meta, GroupMessage m,
|
||||
boolean read) {
|
||||
private void addMessageMetadata(BdfDictionary meta, GroupMessage m) {
|
||||
meta.put(KEY_MEMBER, clientHelper.toList(m.getMember()));
|
||||
meta.put(KEY_TIMESTAMP, m.getMessage().getTimestamp());
|
||||
meta.put(KEY_READ, read);
|
||||
meta.put(KEY_MEMBER_ID, m.getMember().getId());
|
||||
meta.put(KEY_MEMBER_NAME, m.getMember().getName());
|
||||
meta.put(KEY_MEMBER_PUBLIC_KEY, m.getMember().getPublicKey());
|
||||
meta.put(KEY_READ, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -316,9 +310,9 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
}
|
||||
|
||||
private String getMessageBody(BdfList body) throws FormatException {
|
||||
// type(0), member_name(1), member_public_key(2), parent_id(3),
|
||||
// previous_message_id(4), content(5), signature(6)
|
||||
return body.getString(5);
|
||||
// Message type (0), member (1), parent ID (2), previous message ID (3),
|
||||
// content (4), signature (5)
|
||||
return body.getString(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,8 +326,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
// get all authors we need to get the status for
|
||||
Set<AuthorId> authors = new HashSet<>();
|
||||
for (BdfDictionary meta : metadata.values()) {
|
||||
byte[] idBytes = meta.getRaw(KEY_MEMBER_ID);
|
||||
authors.add(new AuthorId(idBytes));
|
||||
authors.add(getAuthor(meta).getId());
|
||||
}
|
||||
// get statuses for all authors
|
||||
Map<AuthorId, Status> statuses = new HashMap<>();
|
||||
@@ -348,13 +341,11 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
if (meta.getLong(KEY_TYPE) == JOIN.getInt()) {
|
||||
Author member = getAuthor(meta);
|
||||
Visibility v = visibilities.get(member);
|
||||
headers.add(
|
||||
getJoinMessageHeader(txn, g, entry.getKey(), meta,
|
||||
statuses, v));
|
||||
headers.add(getJoinMessageHeader(txn, g, entry.getKey(),
|
||||
meta, statuses, v));
|
||||
} else {
|
||||
headers.add(
|
||||
getGroupMessageHeader(txn, g, entry.getKey(), meta,
|
||||
statuses));
|
||||
headers.add(getGroupMessageHeader(txn, g, entry.getKey(),
|
||||
meta, statuses));
|
||||
}
|
||||
}
|
||||
db.commitTransaction(txn);
|
||||
@@ -376,16 +367,16 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
}
|
||||
long timestamp = meta.getLong(KEY_TIMESTAMP);
|
||||
|
||||
Author author = getAuthor(meta);
|
||||
Author member = getAuthor(meta);
|
||||
Status status;
|
||||
if (statuses.containsKey(author.getId())) {
|
||||
status = statuses.get(author.getId());
|
||||
if (statuses.containsKey(member.getId())) {
|
||||
status = statuses.get(member.getId());
|
||||
} else {
|
||||
status = identityManager.getAuthorStatus(txn, author.getId());
|
||||
status = identityManager.getAuthorStatus(txn, member.getId());
|
||||
}
|
||||
boolean read = meta.getBoolean(KEY_READ);
|
||||
|
||||
return new GroupMessageHeader(g, id, parentId, timestamp, author,
|
||||
return new GroupMessageHeader(g, id, parentId, timestamp, member,
|
||||
status, read);
|
||||
}
|
||||
|
||||
@@ -475,8 +466,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
boolean foundMember = false, changed = false;
|
||||
for (int i = 0; i < members.size(); i++) {
|
||||
BdfDictionary d = members.getDictionary(i);
|
||||
AuthorId memberId = new AuthorId(d.getRaw(KEY_MEMBER_ID));
|
||||
if (a.equals(memberId)) {
|
||||
if (a.equals(getAuthor(d).getId())) {
|
||||
foundMember = true;
|
||||
// Don't update the visibility if the contact is already visible
|
||||
if (getVisibility(d) == INVISIBLE) {
|
||||
@@ -565,8 +555,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
if (timestamp <= previousMeta.getLong(KEY_TIMESTAMP))
|
||||
throw new FormatException();
|
||||
// previous message must be from same member
|
||||
if (!Arrays.equals(meta.getRaw(KEY_MEMBER_ID),
|
||||
previousMeta.getRaw(KEY_MEMBER_ID)))
|
||||
if (!getAuthor(meta).equals(getAuthor(previousMeta)))
|
||||
throw new FormatException();
|
||||
// previous message must be a POST or JOIN
|
||||
MessageType previousType = MessageType
|
||||
@@ -603,9 +592,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||
BdfList members = meta.getList(GROUP_KEY_MEMBERS);
|
||||
members.add(BdfDictionary.of(
|
||||
new BdfEntry(KEY_MEMBER_ID, a.getId()),
|
||||
new BdfEntry(KEY_MEMBER_NAME, a.getName()),
|
||||
new BdfEntry(KEY_MEMBER_PUBLIC_KEY, a.getPublicKey()),
|
||||
new BdfEntry(KEY_MEMBER, clientHelper.toList(a)),
|
||||
new BdfEntry(GROUP_KEY_VISIBILITY, v.getInt())
|
||||
));
|
||||
clientHelper.mergeGroupMetadata(txn, g, meta);
|
||||
@@ -615,10 +602,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
||||
}
|
||||
|
||||
private Author getAuthor(BdfDictionary meta) throws FormatException {
|
||||
AuthorId authorId = new AuthorId(meta.getRaw(KEY_MEMBER_ID));
|
||||
String name = meta.getString(KEY_MEMBER_NAME);
|
||||
byte[] publicKey = meta.getRaw(KEY_MEMBER_PUBLIC_KEY);
|
||||
return new Author(authorId, name, publicKey);
|
||||
return clientHelper.parseAndValidateAuthor(meta.getList(KEY_MEMBER));
|
||||
}
|
||||
|
||||
private Visibility getVisibility(BdfDictionary meta)
|
||||
|
||||
@@ -2,7 +2,6 @@ package org.briarproject.briar.privategroup;
|
||||
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.privategroup.GroupMessageFactory;
|
||||
@@ -54,12 +53,11 @@ public class PrivateGroupModule {
|
||||
GroupMessageValidator provideGroupMessageValidator(
|
||||
PrivateGroupFactory privateGroupFactory,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, AuthorFactory authorFactory,
|
||||
GroupInvitationFactory groupInvitationFactory,
|
||||
Clock clock, GroupInvitationFactory groupInvitationFactory,
|
||||
ValidationManager validationManager) {
|
||||
GroupMessageValidator validator = new GroupMessageValidator(
|
||||
privateGroupFactory, clientHelper, metadataEncoder, clock,
|
||||
authorFactory, groupInvitationFactory);
|
||||
groupInvitationFactory);
|
||||
validationManager.registerMessageValidator(CLIENT_ID, validator);
|
||||
return validator;
|
||||
}
|
||||
|
||||
@@ -140,10 +140,10 @@ abstract class AbstractProtocolEngine<S extends Session>
|
||||
return m;
|
||||
}
|
||||
|
||||
void markMessageVisibleInUi(Transaction txn, MessageId m, boolean visible)
|
||||
void markMessageVisibleInUi(Transaction txn, MessageId m)
|
||||
throws DbException {
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
messageEncoder.setVisibleInUi(meta, visible);
|
||||
messageEncoder.setVisibleInUi(meta, true);
|
||||
try {
|
||||
clientHelper.mergeMessageMetadata(txn, m, meta);
|
||||
} catch (FormatException e) {
|
||||
@@ -174,10 +174,9 @@ abstract class AbstractProtocolEngine<S extends Session>
|
||||
markMessageAvailableToAnswer(txn, m, false);
|
||||
}
|
||||
|
||||
void markInviteAccepted(Transaction txn, MessageId m, boolean accepted)
|
||||
throws DbException {
|
||||
void markInviteAccepted(Transaction txn, MessageId m) throws DbException {
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
messageEncoder.setInvitationAccepted(meta, accepted);
|
||||
messageEncoder.setInvitationAccepted(meta, true);
|
||||
try {
|
||||
clientHelper.mergeMessageMetadata(txn, m, meta);
|
||||
} catch (FormatException e) {
|
||||
|
||||
@@ -183,7 +183,7 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
// Send a JOIN message
|
||||
Message sent = sendJoinMessage(txn, s, false);
|
||||
// Mark the response visible in the UI
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
@@ -207,7 +207,7 @@ class CreatorProtocolEngine extends AbstractProtocolEngine<CreatorSession> {
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abort(txn, s);
|
||||
// Mark the response visible in the UI
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.briar.privategroup.invitation;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
@@ -53,13 +52,12 @@ public class GroupInvitationModule {
|
||||
@Singleton
|
||||
GroupInvitationValidator provideGroupInvitationValidator(
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, AuthorFactory authorFactory,
|
||||
PrivateGroupFactory privateGroupFactory,
|
||||
Clock clock, PrivateGroupFactory privateGroupFactory,
|
||||
MessageEncoder messageEncoder,
|
||||
ValidationManager validationManager) {
|
||||
GroupInvitationValidator validator = new GroupInvitationValidator(
|
||||
clientHelper, metadataEncoder, clock, authorFactory,
|
||||
privateGroupFactory, messageEncoder);
|
||||
clientHelper, metadataEncoder, clock, privateGroupFactory,
|
||||
messageEncoder);
|
||||
validationManager.registerMessageValidator(CLIENT_ID, validator);
|
||||
return validator;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
@@ -23,10 +22,7 @@ import java.security.GeneralSecurityException;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
@@ -43,18 +39,14 @@ import static org.briarproject.briar.privategroup.invitation.MessageType.LEAVE;
|
||||
@NotNullByDefault
|
||||
class GroupInvitationValidator extends BdfMessageValidator {
|
||||
|
||||
private final AuthorFactory authorFactory;
|
||||
private final PrivateGroupFactory privateGroupFactory;
|
||||
private final MessageEncoder messageEncoder;
|
||||
|
||||
@Inject
|
||||
GroupInvitationValidator(ClientHelper clientHelper,
|
||||
MetadataEncoder metadataEncoder, Clock clock,
|
||||
AuthorFactory authorFactory,
|
||||
PrivateGroupFactory privateGroupFactory,
|
||||
MessageEncoder messageEncoder) {
|
||||
super(clientHelper, metadataEncoder, clock);
|
||||
this.authorFactory = authorFactory;
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
this.messageEncoder = messageEncoder;
|
||||
}
|
||||
@@ -79,22 +71,20 @@ class GroupInvitationValidator extends BdfMessageValidator {
|
||||
|
||||
private BdfMessageContext validateInviteMessage(Message m, BdfList body)
|
||||
throws FormatException {
|
||||
checkSize(body, 7);
|
||||
String groupName = body.getString(1);
|
||||
// Message type, creator, group name, salt, optional message, signature
|
||||
checkSize(body, 6);
|
||||
BdfList creatorList = body.getList(1);
|
||||
String groupName = body.getString(2);
|
||||
checkLength(groupName, 1, MAX_GROUP_NAME_LENGTH);
|
||||
String creatorName = body.getString(2);
|
||||
checkLength(creatorName, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] creatorPublicKey = body.getRaw(3);
|
||||
checkLength(creatorPublicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] salt = body.getRaw(4);
|
||||
byte[] salt = body.getRaw(3);
|
||||
checkLength(salt, GROUP_SALT_LENGTH);
|
||||
String message = body.getOptionalString(5);
|
||||
String message = body.getOptionalString(4);
|
||||
checkLength(message, 1, MAX_GROUP_INVITATION_MSG_LENGTH);
|
||||
byte[] signature = body.getRaw(6);
|
||||
byte[] signature = body.getRaw(5);
|
||||
checkLength(signature, 1, MAX_SIGNATURE_LENGTH);
|
||||
// Create the private group
|
||||
Author creator = authorFactory.createAuthor(creatorName,
|
||||
creatorPublicKey);
|
||||
|
||||
// Validate the creator and create the private group
|
||||
Author creator = clientHelper.parseAndValidateAuthor(creatorList);
|
||||
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
|
||||
groupName, creator, salt);
|
||||
// Verify the signature
|
||||
@@ -105,7 +95,7 @@ class GroupInvitationValidator extends BdfMessageValidator {
|
||||
);
|
||||
try {
|
||||
clientHelper.verifySignature(SIGNING_LABEL_INVITE, signature,
|
||||
creatorPublicKey, signed);
|
||||
creator.getPublicKey(), signed);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||
if (inviteId == null) throw new IllegalStateException();
|
||||
markMessageAvailableToAnswer(txn, inviteId, false);
|
||||
// Record the response
|
||||
markInviteAccepted(txn, inviteId, true);
|
||||
markInviteAccepted(txn, inviteId);
|
||||
// Send a JOIN message
|
||||
Message sent = sendJoinMessage(txn, s, true);
|
||||
// Track the message
|
||||
@@ -228,7 +228,7 @@ class InviteeProtocolEngine extends AbstractProtocolEngine<InviteeSession> {
|
||||
if (!contact.getId().equals(m.getCreator().getId()))
|
||||
return abort(txn, s);
|
||||
// Mark the invite message visible in the UI and available to answer
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
markMessageAvailableToAnswer(txn, m.getId(), true);
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
|
||||
@@ -78,11 +78,11 @@ class MessageEncoderImpl implements MessageEncoder {
|
||||
GroupId privateGroupId, long timestamp, String groupName,
|
||||
Author creator, byte[] salt, @Nullable String message,
|
||||
byte[] signature) {
|
||||
BdfList creatorList = clientHelper.toList(creator);
|
||||
BdfList body = BdfList.of(
|
||||
INVITE.getValue(),
|
||||
creatorList,
|
||||
groupName,
|
||||
creator.getName(),
|
||||
creator.getPublicKey(),
|
||||
salt,
|
||||
message,
|
||||
signature
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_AVAILABLE_TO_ANSWER;
|
||||
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.MSG_KEY_INVITATION_ACCEPTED;
|
||||
@@ -39,7 +40,8 @@ class MessageParserImpl implements MessageParser {
|
||||
|
||||
@Inject
|
||||
MessageParserImpl(AuthorFactory authorFactory,
|
||||
PrivateGroupFactory privateGroupFactory, ClientHelper clientHelper) {
|
||||
PrivateGroupFactory privateGroupFactory,
|
||||
ClientHelper clientHelper) {
|
||||
this.authorFactory = authorFactory;
|
||||
this.privateGroupFactory = privateGroupFactory;
|
||||
this.clientHelper = clientHelper;
|
||||
@@ -97,13 +99,20 @@ class MessageParserImpl implements MessageParser {
|
||||
@Override
|
||||
public InviteMessage parseInviteMessage(Message m, BdfList body)
|
||||
throws FormatException {
|
||||
String groupName = body.getString(1);
|
||||
String creatorName = body.getString(2);
|
||||
byte[] creatorPublicKey = body.getRaw(3);
|
||||
byte[] salt = body.getRaw(4);
|
||||
String message = body.getOptionalString(5);
|
||||
byte[] signature = body.getRaw(6);
|
||||
Author creator = authorFactory.createAuthor(creatorName,
|
||||
// Message type, creator, group name, salt, optional message, signature
|
||||
BdfList creatorList = body.getList(1);
|
||||
String groupName = body.getString(2);
|
||||
byte[] salt = body.getRaw(3);
|
||||
String message = body.getOptionalString(4);
|
||||
byte[] signature = body.getRaw(5);
|
||||
|
||||
// Format version, name, public key
|
||||
int formatVersion = creatorList.getLong(0).intValue();
|
||||
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
||||
String creatorName = creatorList.getString(1);
|
||||
byte[] creatorPublicKey = creatorList.getRaw(2);
|
||||
|
||||
Author creator = authorFactory.createAuthor(formatVersion, creatorName,
|
||||
creatorPublicKey);
|
||||
PrivateGroup privateGroup = privateGroupFactory.createPrivateGroup(
|
||||
groupName, creator, salt);
|
||||
|
||||
@@ -12,6 +12,8 @@ import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.Author.FORMAT_VERSION;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
class BlogMessageParserImpl extends MessageParserImpl<Blog> {
|
||||
@@ -28,12 +30,19 @@ class BlogMessageParserImpl extends MessageParserImpl<Blog> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Blog createShareable(BdfList descriptor)
|
||||
throws FormatException {
|
||||
String name = descriptor.getString(0);
|
||||
byte[] publicKey = descriptor.getRaw(1);
|
||||
boolean rssFeed = descriptor.getBoolean(2);
|
||||
Author author = authorFactory.createAuthor(name, publicKey);
|
||||
protected Blog createShareable(BdfList descriptor) throws FormatException {
|
||||
// Author, RSS
|
||||
BdfList authorList = descriptor.getList(0);
|
||||
boolean rssFeed = descriptor.getBoolean(1);
|
||||
|
||||
// Format version, name, public key
|
||||
int formatVersion = authorList.getLong(0).intValue();
|
||||
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
||||
String name = authorList.getString(1);
|
||||
byte[] publicKey = authorList.getRaw(2);
|
||||
|
||||
Author author = authorFactory.createAuthor(formatVersion, name,
|
||||
publicKey);
|
||||
if (rssFeed) return blogFactory.createFeedBlog(author);
|
||||
else return blogFactory.createBlog(author);
|
||||
}
|
||||
|
||||
@@ -5,19 +5,13 @@ import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
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.util.ValidationUtils.checkLength;
|
||||
import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
|
||||
@Immutable
|
||||
@@ -25,35 +19,24 @@ import static org.briarproject.bramble.util.ValidationUtils.checkSize;
|
||||
class BlogSharingValidator extends SharingValidator {
|
||||
|
||||
private final BlogFactory blogFactory;
|
||||
private final AuthorFactory authorFactory;
|
||||
|
||||
@Inject
|
||||
BlogSharingValidator(MessageEncoder messageEncoder,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, BlogFactory blogFactory, AuthorFactory authorFactory) {
|
||||
Clock clock, BlogFactory blogFactory) {
|
||||
super(messageEncoder, clientHelper, metadataEncoder, clock);
|
||||
this.blogFactory = blogFactory;
|
||||
this.authorFactory = authorFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GroupId validateDescriptor(BdfList descriptor)
|
||||
throws FormatException {
|
||||
checkSize(descriptor, 3);
|
||||
String name = descriptor.getString(0);
|
||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = descriptor.getRaw(1);
|
||||
checkLength(publicKey, 1, MAX_PUBLIC_KEY_LENGTH);
|
||||
boolean rssFeed = descriptor.getBoolean(2);
|
||||
|
||||
Author author = authorFactory.createAuthor(name, publicKey);
|
||||
Blog blog;
|
||||
if (rssFeed) {
|
||||
blog = blogFactory.createFeedBlog(author);
|
||||
} else {
|
||||
blog = blogFactory.createBlog(author);
|
||||
}
|
||||
return blog.getId();
|
||||
// Author, RSS
|
||||
checkSize(descriptor, 2);
|
||||
BdfList authorList = descriptor.getList(0);
|
||||
boolean rssFeed = descriptor.getBoolean(1);
|
||||
Author author = clientHelper.parseAndValidateAuthor(authorList);
|
||||
if (rssFeed) return blogFactory.createFeedBlog(author).getId();
|
||||
else return blogFactory.createBlog(author).getId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ class ForumMessageParserImpl extends MessageParserImpl<Forum> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Forum createShareable(BdfList descriptor)
|
||||
throws FormatException {
|
||||
protected Forum createShareable(BdfList descriptor) throws FormatException {
|
||||
// Name, salt
|
||||
String name = descriptor.getString(0);
|
||||
byte[] salt = descriptor.getRaw(1);
|
||||
return forumFactory.createForum(name, salt);
|
||||
|
||||
@@ -35,6 +35,7 @@ class ForumSharingValidator extends SharingValidator {
|
||||
@Override
|
||||
protected GroupId validateDescriptor(BdfList descriptor)
|
||||
throws FormatException {
|
||||
// Name, salt
|
||||
checkSize(descriptor, 2);
|
||||
String name = descriptor.getString(0);
|
||||
checkLength(name, 1, MAX_FORUM_NAME_LENGTH);
|
||||
|
||||
@@ -112,9 +112,8 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
throw new DbException(e); // Invalid group descriptor
|
||||
}
|
||||
long localTimestamp = Math.max(timestamp, getLocalTimestamp(s));
|
||||
Message m = messageEncoder
|
||||
.encodeInviteMessage(s.getContactGroupId(), localTimestamp,
|
||||
s.getLastLocalMessageId(), descriptor, message);
|
||||
Message m = messageEncoder.encodeInviteMessage(s.getContactGroupId(),
|
||||
localTimestamp, s.getLastLocalMessageId(), descriptor, message);
|
||||
sendMessage(txn, m, INVITE, s.getShareableId(), true);
|
||||
return m;
|
||||
}
|
||||
@@ -143,7 +142,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
if (inviteId == null) throw new IllegalStateException();
|
||||
markMessageAvailableToAnswer(txn, inviteId, false);
|
||||
// Mark the invite message as accepted
|
||||
markInvitationAccepted(txn, inviteId, true);
|
||||
markInvitationAccepted(txn, inviteId);
|
||||
// Send a ACCEPT message
|
||||
Message sent = sendAcceptMessage(txn, s);
|
||||
// Track the message
|
||||
@@ -288,7 +287,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abortWithMessage(txn, s);
|
||||
// Mark the invite message visible in the UI and (un)available to answer
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
markMessageAvailableToAnswer(txn, m.getId(), available);
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
@@ -312,7 +311,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abortWithMessage(txn, s);
|
||||
// Mark the invite message visible in the UI and unavailable to answer
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
markMessageAvailableToAnswer(txn, m.getId(), false);
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
@@ -359,7 +358,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abortWithMessage(txn, s);
|
||||
// Mark the response visible in the UI
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
@@ -411,7 +410,7 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
if (!isValidDependency(s, m.getPreviousMessageId()))
|
||||
return abortWithMessage(txn, s);
|
||||
// Mark the response visible in the UI
|
||||
markMessageVisibleInUi(txn, m.getId(), true);
|
||||
markMessageVisibleInUi(txn, m.getId());
|
||||
// Track the message
|
||||
messageTracker.trackMessage(txn, m.getContactGroupId(),
|
||||
m.getTimestamp(), false);
|
||||
@@ -576,10 +575,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
}
|
||||
}
|
||||
|
||||
private void markMessageVisibleInUi(Transaction txn, MessageId m,
|
||||
boolean visible) throws DbException {
|
||||
private void markMessageVisibleInUi(Transaction txn, MessageId m)
|
||||
throws DbException {
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
messageEncoder.setVisibleInUi(meta, visible);
|
||||
messageEncoder.setVisibleInUi(meta, true);
|
||||
try {
|
||||
clientHelper.mergeMessageMetadata(txn, m, meta);
|
||||
} catch (FormatException e) {
|
||||
@@ -587,10 +586,10 @@ abstract class ProtocolEngineImpl<S extends Shareable>
|
||||
}
|
||||
}
|
||||
|
||||
private void markInvitationAccepted(Transaction txn, MessageId m,
|
||||
boolean accepted) throws DbException {
|
||||
private void markInvitationAccepted(Transaction txn, MessageId m)
|
||||
throws DbException {
|
||||
BdfDictionary meta = new BdfDictionary();
|
||||
messageEncoder.setInvitationAccepted(meta, accepted);
|
||||
messageEncoder.setInvitationAccepted(meta, true);
|
||||
try {
|
||||
clientHelper.mergeMessageMetadata(txn, m, meta);
|
||||
} catch (FormatException e) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.briarproject.briar.sharing;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.AuthorFactory;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.bramble.api.sync.ValidationManager;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
@@ -59,10 +58,10 @@ public class SharingModule {
|
||||
BlogSharingValidator provideBlogSharingValidator(
|
||||
ValidationManager validationManager, MessageEncoder messageEncoder,
|
||||
ClientHelper clientHelper, MetadataEncoder metadataEncoder,
|
||||
Clock clock, BlogFactory blogFactory, AuthorFactory authorFactory) {
|
||||
Clock clock, BlogFactory blogFactory) {
|
||||
BlogSharingValidator validator =
|
||||
new BlogSharingValidator(messageEncoder, clientHelper,
|
||||
metadataEncoder, clock, blogFactory, authorFactory);
|
||||
metadataEncoder, clock, blogFactory);
|
||||
validationManager.registerMessageValidator(BlogSharingManager.CLIENT_ID,
|
||||
validator);
|
||||
return validator;
|
||||
|
||||
@@ -190,8 +190,8 @@ public class TestDataCreatorImpl implements TestDataCreator {
|
||||
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
|
||||
byte[] publicKey = keyPair.getPublic().getEncoded();
|
||||
byte[] privateKey = keyPair.getPrivate().getEncoded();
|
||||
return authorFactory
|
||||
.createLocalAuthor(authorName, publicKey, privateKey);
|
||||
return authorFactory.createLocalAuthor(authorName, publicKey,
|
||||
privateKey);
|
||||
}
|
||||
|
||||
private SecretKey getSecretKey() {
|
||||
|
||||
@@ -12,7 +12,6 @@ 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.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
@@ -34,20 +33,16 @@ import org.junit.Test;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.NONE;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
|
||||
import static org.briarproject.bramble.api.identity.Author.Status.VERIFIED;
|
||||
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.sync.SyncConstants.MAX_MESSAGE_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_READ;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_RSS_FEED;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_TIMESTAMP;
|
||||
@@ -77,7 +72,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
context.mock(BlogPostFactory.class);
|
||||
|
||||
private final LocalAuthor localAuthor1, localAuthor2, rssLocalAuthor;
|
||||
private final BdfDictionary authorDict1, authorDict2, rssAuthorDict;
|
||||
private final BdfList authorList1, authorList2, rssAuthorList;
|
||||
private final Blog blog1, blog2, rssBlog;
|
||||
private final long timestamp, timeReceived;
|
||||
private final MessageId messageId, rssMessageId;
|
||||
@@ -89,12 +84,12 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
blogManager = new BlogManagerImpl(db, identityManager, clientHelper,
|
||||
metadataParser, blogFactory, blogPostFactory);
|
||||
|
||||
localAuthor1 = createLocalAuthor();
|
||||
localAuthor2 = createLocalAuthor();
|
||||
rssLocalAuthor = createLocalAuthor();
|
||||
authorDict1 = authorToBdfDictionary(localAuthor1);
|
||||
authorDict2 = authorToBdfDictionary(localAuthor2);
|
||||
rssAuthorDict = authorToBdfDictionary(rssLocalAuthor);
|
||||
localAuthor1 = getLocalAuthor();
|
||||
localAuthor2 = getLocalAuthor();
|
||||
rssLocalAuthor = getLocalAuthor();
|
||||
authorList1 = authorToBdfList(localAuthor1);
|
||||
authorList2 = authorToBdfList(localAuthor2);
|
||||
rssAuthorList = authorToBdfList(rssLocalAuthor);
|
||||
blog1 = createBlog(localAuthor1, false);
|
||||
blog2 = createBlog(localAuthor2, false);
|
||||
rssBlog = createBlog(rssLocalAuthor, true);
|
||||
@@ -174,12 +169,14 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_TYPE, POST.getInt()),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1),
|
||||
new BdfEntry(KEY_AUTHOR, authorList1),
|
||||
new BdfEntry(KEY_READ, false),
|
||||
new BdfEntry(KEY_RSS_FEED, false)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(VERIFIED));
|
||||
}});
|
||||
@@ -213,11 +210,16 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_TYPE, POST.getInt()),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorDict),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorList),
|
||||
new BdfEntry(KEY_READ, false),
|
||||
new BdfEntry(KEY_RSS_FEED, true)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList);
|
||||
will(returnValue(rssLocalAuthor));
|
||||
}});
|
||||
|
||||
blogManager.incomingMessage(txn, rssMessage, body, meta);
|
||||
context.assertIsSatisfied();
|
||||
|
||||
@@ -264,7 +266,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(KEY_TYPE, POST.getInt()),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1),
|
||||
new BdfEntry(KEY_AUTHOR, authorList1),
|
||||
new BdfEntry(KEY_READ, true),
|
||||
new BdfEntry(KEY_RSS_FEED, false)
|
||||
);
|
||||
@@ -276,7 +278,11 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(blog1.getGroup()));
|
||||
oneOf(blogFactory).parseBlog(blog1.getGroup());
|
||||
will(returnValue(blog1));
|
||||
oneOf(clientHelper).toList(localAuthor1);
|
||||
will(returnValue(authorList1));
|
||||
oneOf(clientHelper).addLocalMessage(txn, message, meta, true);
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(OURSELVES));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
@@ -310,7 +316,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
BdfDictionary meta = BdfDictionary.of(
|
||||
new BdfEntry(KEY_TYPE, POST.getInt()),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorDict),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorList),
|
||||
new BdfEntry(KEY_READ, true),
|
||||
new BdfEntry(KEY_RSS_FEED, true)
|
||||
);
|
||||
@@ -322,7 +328,11 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
will(returnValue(rssBlog.getGroup()));
|
||||
oneOf(blogFactory).parseBlog(rssBlog.getGroup());
|
||||
will(returnValue(rssBlog));
|
||||
oneOf(clientHelper).toList(rssLocalAuthor);
|
||||
will(returnValue(rssAuthorList));
|
||||
oneOf(clientHelper).addLocalMessage(txn, rssMessage, meta, true);
|
||||
oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList);
|
||||
will(returnValue(rssLocalAuthor));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
@@ -357,7 +367,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_TYPE, POST.getInt()),
|
||||
new BdfEntry(KEY_RSS_FEED, false),
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, messageId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1),
|
||||
new BdfEntry(KEY_AUTHOR, authorList1),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
|
||||
);
|
||||
@@ -371,7 +381,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId),
|
||||
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, messageId),
|
||||
new BdfEntry(KEY_PARENT_MSG_ID, messageId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1)
|
||||
new BdfEntry(KEY_AUTHOR, authorList1)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -381,14 +391,20 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
oneOf(blogPostFactory).createBlogComment(blog1.getId(),
|
||||
localAuthor1, comment, messageId, messageId);
|
||||
will(returnValue(commentMsg));
|
||||
oneOf(clientHelper).toList(localAuthor1);
|
||||
will(returnValue(authorList1));
|
||||
// Store the comment
|
||||
oneOf(clientHelper).addLocalMessage(txn, commentMsg, commentMeta,
|
||||
true);
|
||||
// Create the headers for the comment and its parent
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(OURSELVES));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn, messageId);
|
||||
will(returnValue(postMeta));
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(OURSELVES));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
@@ -447,7 +463,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_TYPE, WRAPPED_POST.getInt()),
|
||||
new BdfEntry(KEY_RSS_FEED, false),
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, messageId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1),
|
||||
new BdfEntry(KEY_AUTHOR, authorList1),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
|
||||
);
|
||||
@@ -461,7 +477,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId),
|
||||
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, messageId),
|
||||
new BdfEntry(KEY_PARENT_MSG_ID, wrappedPostId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict2)
|
||||
new BdfEntry(KEY_AUTHOR, authorList2)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -476,6 +492,8 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
blog1.getGroup().getDescriptor(), timestamp,
|
||||
originalPostBody);
|
||||
will(returnValue(wrappedPostMsg));
|
||||
oneOf(clientHelper).toList(localAuthor1);
|
||||
will(returnValue(authorList1));
|
||||
// Store the wrapped post
|
||||
oneOf(clientHelper).addLocalMessage(txn, wrappedPostMsg,
|
||||
wrappedPostMeta, true);
|
||||
@@ -483,15 +501,21 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
oneOf(blogPostFactory).createBlogComment(blog2.getId(),
|
||||
localAuthor2, comment, messageId, wrappedPostId);
|
||||
will(returnValue(commentMsg));
|
||||
oneOf(clientHelper).toList(localAuthor2);
|
||||
will(returnValue(authorList2));
|
||||
// Store the comment
|
||||
oneOf(clientHelper).addLocalMessage(txn, commentMsg, commentMeta,
|
||||
true);
|
||||
// Create the headers for the comment and the wrapped post
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList2);
|
||||
will(returnValue(localAuthor2));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor2.getId());
|
||||
will(returnValue(OURSELVES));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
wrappedPostId);
|
||||
will(returnValue(wrappedPostMeta));
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(VERIFIED));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
@@ -550,7 +574,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_TYPE, WRAPPED_POST.getInt()),
|
||||
new BdfEntry(KEY_RSS_FEED, true),
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, rssMessageId),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorDict),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorList),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
|
||||
);
|
||||
@@ -564,7 +588,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId),
|
||||
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, rssMessageId),
|
||||
new BdfEntry(KEY_PARENT_MSG_ID, wrappedPostId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1)
|
||||
new BdfEntry(KEY_AUTHOR, authorList1)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -579,6 +603,8 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
rssBlog.getGroup().getDescriptor(), timestamp,
|
||||
originalPostBody);
|
||||
will(returnValue(wrappedPostMsg));
|
||||
oneOf(clientHelper).toList(rssLocalAuthor);
|
||||
will(returnValue(rssAuthorList));
|
||||
// Store the wrapped post
|
||||
oneOf(clientHelper).addLocalMessage(txn, wrappedPostMsg,
|
||||
wrappedPostMeta, true);
|
||||
@@ -586,15 +612,21 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
oneOf(blogPostFactory).createBlogComment(blog1.getId(),
|
||||
localAuthor1, comment, rssMessageId, wrappedPostId);
|
||||
will(returnValue(commentMsg));
|
||||
oneOf(clientHelper).toList(localAuthor1);
|
||||
will(returnValue(authorList1));
|
||||
// Store the comment
|
||||
oneOf(clientHelper).addLocalMessage(txn, commentMsg, commentMeta,
|
||||
true);
|
||||
// Create the headers for the comment and the wrapped post
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(OURSELVES));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
wrappedPostId);
|
||||
will(returnValue(wrappedPostMeta));
|
||||
oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList);
|
||||
will(returnValue(rssLocalAuthor));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
@@ -655,7 +687,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_TYPE, WRAPPED_POST.getInt()),
|
||||
new BdfEntry(KEY_RSS_FEED, true),
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, messageId),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorDict),
|
||||
new BdfEntry(KEY_AUTHOR, rssAuthorList),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
|
||||
);
|
||||
@@ -667,7 +699,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_COMMENT, comment),
|
||||
new BdfEntry(KEY_PARENT_MSG_ID, rewrappedPostId),
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, originalCommentId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict1),
|
||||
new BdfEntry(KEY_AUTHOR, authorList1),
|
||||
new BdfEntry(KEY_TIMESTAMP, timestamp),
|
||||
new BdfEntry(KEY_TIME_RECEIVED, timeReceived)
|
||||
);
|
||||
@@ -682,7 +714,7 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
new BdfEntry(KEY_ORIGINAL_MSG_ID, localCommentId),
|
||||
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, originalCommentId),
|
||||
new BdfEntry(KEY_PARENT_MSG_ID, wrappedCommentId),
|
||||
new BdfEntry(KEY_AUTHOR, authorDict2)
|
||||
new BdfEntry(KEY_AUTHOR, authorList2)
|
||||
);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -694,6 +726,8 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
oneOf(blogPostFactory).rewrapWrappedPost(blog2.getId(),
|
||||
wrappedPostBody);
|
||||
will(returnValue(rewrappedPostMsg));
|
||||
oneOf(clientHelper).toList(rssLocalAuthor);
|
||||
will(returnValue(rssAuthorList));
|
||||
// Store the rewrapped post
|
||||
oneOf(clientHelper).addLocalMessage(txn, rewrappedPostMsg,
|
||||
rewrappedPostMeta, true);
|
||||
@@ -709,6 +743,8 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
blog1.getGroup().getDescriptor(), timestamp,
|
||||
originalCommentBody, rewrappedPostId);
|
||||
will(returnValue(wrappedCommentMsg));
|
||||
oneOf(clientHelper).toList(localAuthor1);
|
||||
will(returnValue(authorList1));
|
||||
// Store the wrapped comment
|
||||
oneOf(clientHelper).addLocalMessage(txn, wrappedCommentMsg,
|
||||
wrappedCommentMeta, true);
|
||||
@@ -717,21 +753,29 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
localAuthor2, localComment, originalCommentId,
|
||||
wrappedCommentId);
|
||||
will(returnValue(localCommentMsg));
|
||||
oneOf(clientHelper).toList(localAuthor2);
|
||||
will(returnValue(authorList2));
|
||||
// Store the new comment
|
||||
oneOf(clientHelper).addLocalMessage(txn, localCommentMsg,
|
||||
localCommentMeta, true);
|
||||
// Create the headers for the new comment, the wrapped comment and
|
||||
// the rewrapped post
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList2);
|
||||
will(returnValue(localAuthor2));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor2.getId());
|
||||
will(returnValue(OURSELVES));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
wrappedCommentId);
|
||||
will(returnValue(wrappedCommentMeta));
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList1);
|
||||
will(returnValue(localAuthor1));
|
||||
oneOf(identityManager).getAuthorStatus(txn, localAuthor1.getId());
|
||||
will(returnValue(VERIFIED));
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
rewrappedPostId);
|
||||
will(returnValue(rewrappedPostMeta));
|
||||
oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList);
|
||||
will(returnValue(rssLocalAuthor));
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
@@ -822,25 +866,14 @@ public class BlogManagerImplTest extends BriarTestCase {
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
|
||||
private LocalAuthor createLocalAuthor() {
|
||||
return new LocalAuthor(new AuthorId(getRandomId()),
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH),
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
getRandomBytes(123), System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private Blog createBlog(LocalAuthor localAuthor, boolean rssFeed) {
|
||||
GroupId groupId = new GroupId(getRandomId());
|
||||
Group group = new Group(groupId, CLIENT_ID, getRandomBytes(42));
|
||||
return new Blog(group, localAuthor, rssFeed);
|
||||
}
|
||||
|
||||
private BdfDictionary authorToBdfDictionary(Author a) {
|
||||
return BdfDictionary.of(
|
||||
new BdfEntry(KEY_AUTHOR_ID, a.getId()),
|
||||
new BdfEntry(KEY_AUTHOR_NAME, a.getName()),
|
||||
new BdfEntry(KEY_PUBLIC_KEY, a.getPublicKey())
|
||||
);
|
||||
private BdfList authorToBdfList(Author a) {
|
||||
return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,11 +3,9 @@ package org.briarproject.briar.blog;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupFactory;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
@@ -16,8 +14,6 @@ import org.briarproject.bramble.api.sync.MessageFactory;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.system.SystemClock;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import org.briarproject.briar.test.BriarTestCase;
|
||||
@@ -28,15 +24,15 @@ import org.junit.Test;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_AUTHOR_NAME;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_COMMENT;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_ORIGINAL_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_READ;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_RSS_FEED;
|
||||
import static org.briarproject.briar.api.blog.BlogManager.CLIENT_ID;
|
||||
@@ -54,7 +50,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
|
||||
private final Mockery context = new Mockery();
|
||||
private final Blog blog, rssBlog;
|
||||
private final BdfDictionary authorDict;
|
||||
private final BdfList authorList;
|
||||
private final byte[] descriptor;
|
||||
private final Group group;
|
||||
private final Message message;
|
||||
@@ -65,27 +61,24 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
private final BlogFactory blogFactory = context.mock(BlogFactory.class);
|
||||
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||
private final Author author;
|
||||
private final String body = StringUtils.getRandomString(42);
|
||||
private final String body = getRandomString(42);
|
||||
|
||||
public BlogPostValidatorTest() {
|
||||
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||
descriptor = TestUtils.getRandomBytes(42);
|
||||
GroupId groupId = new GroupId(getRandomId());
|
||||
descriptor = getRandomBytes(42);
|
||||
group = new Group(groupId, CLIENT_ID, descriptor);
|
||||
AuthorId authorId =
|
||||
new AuthorId(TestUtils.getRandomBytes(AuthorId.LENGTH));
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
author = new Author(authorId, "Author", publicKey);
|
||||
authorDict = BdfDictionary.of(
|
||||
new BdfEntry(KEY_AUTHOR_ID, author.getId()),
|
||||
new BdfEntry(KEY_AUTHOR_NAME, author.getName()),
|
||||
new BdfEntry(KEY_PUBLIC_KEY, author.getPublicKey())
|
||||
author = getAuthor();
|
||||
authorList = BdfList.of(
|
||||
author.getFormatVersion(),
|
||||
author.getName(),
|
||||
author.getPublicKey()
|
||||
);
|
||||
blog = new Blog(group, author, false);
|
||||
rssBlog = new Blog(group, author, true);
|
||||
|
||||
MessageId messageId = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId = new MessageId(getRandomId());
|
||||
long timestamp = System.currentTimeMillis();
|
||||
byte[] raw = TestUtils.getRandomBytes(123);
|
||||
byte[] raw = getRandomBytes(123);
|
||||
message = new Message(messageId, group.getId(), timestamp, raw);
|
||||
|
||||
MetadataEncoder metadataEncoder = context.mock(MetadataEncoder.class);
|
||||
@@ -110,7 +103,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
|
||||
private void testValidateProperBlogPost(Blog b, boolean rssFeed)
|
||||
throws IOException, GeneralSecurityException {
|
||||
byte[] sigBytes = TestUtils.getRandomBytes(42);
|
||||
byte[] sigBytes = getRandomBytes(42);
|
||||
BdfList m = BdfList.of(POST.getInt(), body, sigBytes);
|
||||
|
||||
BdfList signed = BdfList.of(b.getId(), message.getTimestamp(), body);
|
||||
@@ -118,7 +111,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
BdfDictionary result =
|
||||
validator.validateMessage(message, group, m).getDictionary();
|
||||
|
||||
assertEquals(authorDict, result.getDictionary(KEY_AUTHOR));
|
||||
assertEquals(authorList, result.getList(KEY_AUTHOR));
|
||||
assertFalse(result.getBoolean(KEY_READ));
|
||||
assertEquals(rssFeed, result.getBoolean(KEY_RSS_FEED));
|
||||
context.assertIsSatisfied();
|
||||
@@ -130,7 +123,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
BdfList content = BdfList.of(null, null, body);
|
||||
BdfList m = BdfList.of(POST.getInt(), content, null);
|
||||
|
||||
validator.validateMessage(message, group, m).getDictionary();
|
||||
validator.validateMessage(message, group, m);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
@@ -139,7 +132,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
BdfList content = BdfList.of(null, null, body, null);
|
||||
BdfList m = BdfList.of(POST.getInt(), content, null);
|
||||
|
||||
validator.validateMessage(message, group, m).getDictionary();
|
||||
validator.validateMessage(message, group, m);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,9 +140,9 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
throws IOException, GeneralSecurityException {
|
||||
// comment, parent_original_id, parent_id, signature
|
||||
String comment = "This is a blog comment";
|
||||
MessageId pOriginalId = new MessageId(TestUtils.getRandomId());
|
||||
MessageId currentId = new MessageId(TestUtils.getRandomId());
|
||||
byte[] sigBytes = TestUtils.getRandomBytes(42);
|
||||
MessageId pOriginalId = new MessageId(getRandomId());
|
||||
MessageId currentId = new MessageId(getRandomId());
|
||||
byte[] sigBytes = getRandomBytes(42);
|
||||
BdfList m = BdfList.of(COMMENT.getInt(), comment, pOriginalId,
|
||||
currentId, sigBytes);
|
||||
|
||||
@@ -160,7 +153,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
validator.validateMessage(message, group, m).getDictionary();
|
||||
|
||||
assertEquals(comment, result.getString(KEY_COMMENT));
|
||||
assertEquals(authorDict, result.getDictionary(KEY_AUTHOR));
|
||||
assertEquals(authorList, result.getList(KEY_AUTHOR));
|
||||
assertEquals(pOriginalId.getBytes(),
|
||||
result.getRaw(KEY_ORIGINAL_PARENT_MSG_ID));
|
||||
assertEquals(currentId.getBytes(), result.getRaw(KEY_PARENT_MSG_ID));
|
||||
@@ -172,9 +165,9 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
public void testValidateProperEmptyBlogComment()
|
||||
throws IOException, GeneralSecurityException {
|
||||
// comment, parent_original_id, signature, parent_current_id
|
||||
MessageId originalId = new MessageId(TestUtils.getRandomId());
|
||||
MessageId currentId = new MessageId(TestUtils.getRandomId());
|
||||
byte[] sigBytes = TestUtils.getRandomBytes(42);
|
||||
MessageId originalId = new MessageId(getRandomId());
|
||||
MessageId currentId = new MessageId(getRandomId());
|
||||
byte[] sigBytes = getRandomBytes(42);
|
||||
BdfList m = BdfList.of(COMMENT.getInt(), null, originalId, currentId,
|
||||
sigBytes);
|
||||
|
||||
@@ -203,7 +196,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
private void testValidateProperWrappedPost(Blog b, boolean rssFeed)
|
||||
throws IOException, GeneralSecurityException {
|
||||
// group descriptor, timestamp, content, signature
|
||||
byte[] sigBytes = TestUtils.getRandomBytes(42);
|
||||
byte[] sigBytes = getRandomBytes(42);
|
||||
BdfList m = BdfList.of(WRAPPED_POST.getInt(), descriptor,
|
||||
message.getTimestamp(), body, sigBytes);
|
||||
|
||||
@@ -211,7 +204,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
expectCrypto(b, SIGNING_LABEL_POST, signed, sigBytes);
|
||||
|
||||
BdfList originalList = BdfList.of(POST.getInt(), body, sigBytes);
|
||||
byte[] originalBody = TestUtils.getRandomBytes(42);
|
||||
byte[] originalBody = getRandomBytes(42);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(groupFactory).createGroup(CLIENT_ID, CLIENT_VERSION,
|
||||
@@ -230,7 +223,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
BdfDictionary result =
|
||||
validator.validateMessage(message, group, m).getDictionary();
|
||||
|
||||
assertEquals(authorDict, result.getDictionary(KEY_AUTHOR));
|
||||
assertEquals(authorList, result.getList(KEY_AUTHOR));
|
||||
assertEquals(rssFeed, result.getBoolean(KEY_RSS_FEED));
|
||||
context.assertIsSatisfied();
|
||||
}
|
||||
@@ -241,10 +234,10 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
// group descriptor, timestamp, comment, parent_original_id, signature,
|
||||
// parent_current_id
|
||||
String comment = "This is another comment";
|
||||
MessageId originalId = new MessageId(TestUtils.getRandomId());
|
||||
MessageId oldId = new MessageId(TestUtils.getRandomId());
|
||||
byte[] sigBytes = TestUtils.getRandomBytes(42);
|
||||
MessageId currentId = new MessageId(TestUtils.getRandomId());
|
||||
MessageId originalId = new MessageId(getRandomId());
|
||||
MessageId oldId = new MessageId(getRandomId());
|
||||
byte[] sigBytes = getRandomBytes(42);
|
||||
MessageId currentId = new MessageId(getRandomId());
|
||||
BdfList m = BdfList.of(WRAPPED_COMMENT.getInt(), descriptor,
|
||||
message.getTimestamp(), comment, originalId, oldId, sigBytes,
|
||||
currentId);
|
||||
@@ -255,7 +248,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
|
||||
BdfList originalList = BdfList.of(COMMENT.getInt(), comment,
|
||||
originalId, oldId, sigBytes);
|
||||
byte[] originalBody = TestUtils.getRandomBytes(42);
|
||||
byte[] originalBody = getRandomBytes(42);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(groupFactory).createGroup(CLIENT_ID, CLIENT_VERSION,
|
||||
@@ -273,7 +266,7 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
validator.validateMessage(message, group, m).getDictionary();
|
||||
|
||||
assertEquals(comment, result.getString(KEY_COMMENT));
|
||||
assertEquals(authorDict, result.getDictionary(KEY_AUTHOR));
|
||||
assertEquals(authorList, result.getList(KEY_AUTHOR));
|
||||
assertEquals(
|
||||
message.getId().getBytes(), result.getRaw(KEY_ORIGINAL_MSG_ID));
|
||||
assertEquals(currentId.getBytes(), result.getRaw(KEY_PARENT_MSG_ID));
|
||||
@@ -285,6 +278,8 @@ public class BlogPostValidatorTest extends BriarTestCase {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(blogFactory).parseBlog(group);
|
||||
will(returnValue(b));
|
||||
oneOf(clientHelper).toList(b.getAuthor());
|
||||
will(returnValue(authorList));
|
||||
oneOf(clientHelper)
|
||||
.verifySignature(label, sig, author.getPublicKey(), signed);
|
||||
}});
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
@@ -38,6 +37,7 @@ import javax.net.SocketFactory;
|
||||
|
||||
import okhttp3.Dns;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEEDS;
|
||||
@@ -66,10 +66,7 @@ public class FeedManagerImplTest extends BrambleMockTestCase {
|
||||
private final GroupId blogGroupId = new GroupId(getRandomId());
|
||||
private final Group blogGroup =
|
||||
new Group(blogGroupId, BlogManager.CLIENT_ID, getRandomBytes(42));
|
||||
private final AuthorId authorId = new AuthorId(getRandomId());
|
||||
private final LocalAuthor localAuthor =
|
||||
new LocalAuthor(authorId, "author", getRandomBytes(2),
|
||||
getRandomBytes(2), 0);
|
||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
||||
private final Blog blog = new Blog(blogGroup, localAuthor, true);
|
||||
private final Feed feed =
|
||||
new Feed("http://example.org", blog, localAuthor, 0);
|
||||
|
||||
@@ -6,21 +6,24 @@ import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Collection;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.KEY_READ;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_AUTHOR;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_PARENT;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.KEY_TIMESTAMP;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||
import static org.briarproject.briar.api.forum.ForumPostFactory.SIGNING_LABEL_POST;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
@@ -29,229 +32,101 @@ import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class ForumPostValidatorTest extends ValidatorTestCase {
|
||||
|
||||
private final MessageId parentId = new MessageId(TestUtils.getRandomId());
|
||||
private final String authorName =
|
||||
StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
private final byte[] authorPublicKey =
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final BdfList authorList = BdfList.of(authorName, authorPublicKey);
|
||||
private final String content =
|
||||
StringUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
||||
private final byte[] signature =
|
||||
TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
private final AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||
private final Author author =
|
||||
new Author(authorId, authorName, authorPublicKey);
|
||||
private final MessageId parentId = new MessageId(getRandomId());
|
||||
private final String content = getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
||||
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
private final Author author = getAuthor();
|
||||
private final String authorName = author.getName();
|
||||
private final byte[] authorPublicKey = author.getPublicKey();
|
||||
private final BdfList authorList = BdfList.of(author.getFormatVersion(),
|
||||
authorName, authorPublicKey);
|
||||
private final BdfList signedWithParent = BdfList.of(groupId, timestamp,
|
||||
parentId.getBytes(), authorList, content);
|
||||
private final BdfList signedWithoutParent = BdfList.of(groupId, timestamp,
|
||||
null, authorList, content);
|
||||
|
||||
private final ForumPostValidator v = new ForumPostValidator(clientHelper,
|
||||
metadataEncoder, clock);
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBody() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBody() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content, signature, 123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsNullParentId() throws Exception {
|
||||
expectCreateAuthor();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
|
||||
authorPublicKey, signedWithoutParent);
|
||||
}});
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(null, authorList, content, signature));
|
||||
assertExpectedContext(messageContext, false, authorName);
|
||||
assertExpectedContext(messageContext, false);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawParentId() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(123, authorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortParentId() throws Exception {
|
||||
byte[] invalidParentId = TestUtils.getRandomBytes(UniqueId.LENGTH - 1);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
byte[] invalidParentId = getRandomBytes(UniqueId.LENGTH - 1);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(invalidParentId, authorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongParentId() throws Exception {
|
||||
byte[] invalidParentId = TestUtils.getRandomBytes(UniqueId.LENGTH + 1);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
byte[] invalidParentId = getRandomBytes(UniqueId.LENGTH + 1);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(invalidParentId, authorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullAuthorList() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, null, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonListAuthorList() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, 123, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortAuthorList() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, new BdfList(), content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongAuthorList() throws Exception {
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, BdfList.of(1, 2, 3), content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullAuthorName() throws Exception {
|
||||
BdfList invalidAuthorList = BdfList.of(null, authorPublicKey);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringAuthorName() throws Exception {
|
||||
BdfList invalidAuthorList = BdfList.of(123, authorPublicKey);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortAuthorName() throws Exception {
|
||||
BdfList invalidAuthorList = BdfList.of("", authorPublicKey);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthAuthorName() throws Exception {
|
||||
String shortAuthorName = StringUtils.getRandomString(1);
|
||||
BdfList shortNameAuthorList =
|
||||
BdfList.of(shortAuthorName, authorPublicKey);
|
||||
Author shortNameAuthor =
|
||||
new Author(authorId, shortAuthorName, authorPublicKey);
|
||||
BdfList signedWithShortNameAuthor = BdfList.of(groupId, timestamp,
|
||||
parentId.getBytes(), shortNameAuthorList, content);
|
||||
|
||||
public void testRejectsInvalidAuthor() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(shortAuthorName, authorPublicKey);
|
||||
will(returnValue(shortNameAuthor));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
|
||||
authorPublicKey, signedWithShortNameAuthor);
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList);
|
||||
will(throwException(new FormatException()));
|
||||
}});
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(parentId, shortNameAuthorList, content, signature));
|
||||
assertExpectedContext(messageContext, true, shortAuthorName);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongAuthorName() throws Exception {
|
||||
String invalidAuthorName =
|
||||
StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH + 1);
|
||||
BdfList invalidAuthorList =
|
||||
BdfList.of(invalidAuthorName, authorPublicKey);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullAuthorPublicKey() throws Exception {
|
||||
BdfList invalidAuthorList = BdfList.of(authorName, null);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawAuthorPublicKey() throws Exception {
|
||||
BdfList invalidAuthorList = BdfList.of(authorName, 123);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongAuthorPublicKey() throws Exception {
|
||||
byte[] invalidAuthorPublicKey =
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1);
|
||||
BdfList invalidAuthorList =
|
||||
BdfList.of(authorName, invalidAuthorPublicKey);
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, invalidAuthorList, content, signature));
|
||||
BdfList.of(parentId, authorList, content, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullContent() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
expectCreateAuthor();
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, null, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringContent() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
expectCreateAuthor();
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, 123, signature));
|
||||
}
|
||||
@@ -262,74 +137,49 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
|
||||
BdfList signedWithShortContent = BdfList.of(groupId, timestamp,
|
||||
parentId.getBytes(), authorList, shortContent);
|
||||
|
||||
expectCreateAuthor();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
|
||||
authorPublicKey, signedWithShortContent);
|
||||
}});
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, shortContent, signature));
|
||||
assertExpectedContext(messageContext, true, authorName);
|
||||
assertExpectedContext(messageContext, true);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongContent() throws Exception {
|
||||
String invalidContent =
|
||||
StringUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH + 1);
|
||||
String invalidContent = getRandomString(MAX_FORUM_POST_BODY_LENGTH + 1);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
expectCreateAuthor();
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, invalidContent, signature));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullSignature() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
expectCreateAuthor();
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content, null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawSignature() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
expectCreateAuthor();
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content, 123));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongSignature() throws Exception {
|
||||
byte[] invalidSignature =
|
||||
TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH + 1);
|
||||
byte[] invalidSignature = getRandomBytes(MAX_SIGNATURE_LENGTH + 1);
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
expectCreateAuthor();
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content, invalidSignature));
|
||||
}
|
||||
@@ -337,16 +187,13 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsIfVerifyingSignatureThrowsFormatException()
|
||||
throws Exception {
|
||||
expectCreateAuthor();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
|
||||
authorPublicKey, signedWithParent);
|
||||
will(throwException(new FormatException()));
|
||||
}});
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content, signature));
|
||||
}
|
||||
@@ -354,39 +201,39 @@ public class ForumPostValidatorTest extends ValidatorTestCase {
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
public void testRejectsIfVerifyingSignatureThrowsGeneralSecurityException()
|
||||
throws Exception {
|
||||
expectCreateAuthor();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(authorName, authorPublicKey);
|
||||
will(returnValue(author));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
|
||||
authorPublicKey, signedWithParent);
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
}});
|
||||
|
||||
ForumPostValidator v = new ForumPostValidator(authorFactory,
|
||||
clientHelper, metadataEncoder, clock);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(parentId, authorList, content, signature));
|
||||
}
|
||||
|
||||
private void expectCreateAuthor() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
}
|
||||
|
||||
private void assertExpectedContext(BdfMessageContext messageContext,
|
||||
boolean hasParent, String authorName) throws FormatException {
|
||||
boolean hasParent) throws FormatException {
|
||||
BdfDictionary meta = messageContext.getDictionary();
|
||||
Collection<MessageId> dependencies = messageContext.getDependencies();
|
||||
if (hasParent) {
|
||||
assertEquals(4, meta.size());
|
||||
assertArrayEquals(parentId.getBytes(), meta.getRaw("parent"));
|
||||
assertArrayEquals(parentId.getBytes(), meta.getRaw(KEY_PARENT));
|
||||
assertEquals(1, dependencies.size());
|
||||
assertEquals(parentId, dependencies.iterator().next());
|
||||
} else {
|
||||
assertEquals(3, meta.size());
|
||||
assertEquals(0, dependencies.size());
|
||||
}
|
||||
assertEquals(timestamp, meta.getLong("timestamp").longValue());
|
||||
assertFalse(meta.getBoolean("read"));
|
||||
BdfDictionary authorMeta = meta.getDictionary("author");
|
||||
assertEquals(3, authorMeta.size());
|
||||
assertArrayEquals(authorId.getBytes(), authorMeta.getRaw("id"));
|
||||
assertEquals(authorName, authorMeta.getString("name"));
|
||||
assertArrayEquals(authorPublicKey, authorMeta.getRaw("publicKey"));
|
||||
assertEquals(timestamp, meta.getLong(KEY_TIMESTAMP).longValue());
|
||||
assertFalse(meta.getBoolean(KEY_READ));
|
||||
assertEquals(authorList, meta.getList(KEY_AUTHOR));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction.IntroduceeProtocolState;
|
||||
import org.briarproject.briar.test.BriarTestCase;
|
||||
@@ -40,6 +39,10 @@ import java.security.SecureRandom;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.briarproject.briar.api.introduction.IntroduceeProtocolState.AWAIT_REQUEST;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.ACCEPT;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.ADDED_CONTACT_ID;
|
||||
@@ -125,47 +128,41 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
authorFactory, contactManager, identityManager,
|
||||
introductionGroupFactory);
|
||||
|
||||
AuthorId authorId0 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author0 = new Author(authorId0, "Introducer",
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
AuthorId localAuthorId = new AuthorId(TestUtils.getRandomId());
|
||||
Author author0 = getAuthor();
|
||||
AuthorId localAuthorId = new AuthorId(getRandomId());
|
||||
ContactId contactId0 = new ContactId(234);
|
||||
introducer =
|
||||
new Contact(contactId0, author0, localAuthorId, true, true);
|
||||
|
||||
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author1 = new Author(authorId1, "Introducee1",
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author1 = getAuthor();
|
||||
AuthorId localAuthorId1 = new AuthorId(getRandomId());
|
||||
ContactId contactId1 = new ContactId(234);
|
||||
introducee1 =
|
||||
new Contact(contactId1, author1, localAuthorId1, true, true);
|
||||
|
||||
AuthorId authorId2 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author2 = new Author(authorId2, "Introducee2",
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
Author author2 = getAuthor();
|
||||
ContactId contactId2 = new ContactId(235);
|
||||
introducee2 =
|
||||
new Contact(contactId2, author2, localAuthorId, true, true);
|
||||
|
||||
ClientId clientId = IntroductionManagerImpl.CLIENT_ID;
|
||||
localGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
localGroup1 = new Group(new GroupId(getRandomId()),
|
||||
clientId, new byte[0]);
|
||||
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
introductionGroup1 = new Group(new GroupId(getRandomId()),
|
||||
clientId, new byte[0]);
|
||||
|
||||
sessionId = new SessionId(TestUtils.getRandomId());
|
||||
sessionId = new SessionId(getRandomId());
|
||||
localStateMessage = new Message(
|
||||
new MessageId(TestUtils.getRandomId()),
|
||||
new MessageId(getRandomId()),
|
||||
localGroup1.getId(),
|
||||
time,
|
||||
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||
getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||
);
|
||||
message1 = new Message(
|
||||
new MessageId(TestUtils.getRandomId()),
|
||||
new MessageId(getRandomId()),
|
||||
introductionGroup1.getId(),
|
||||
time,
|
||||
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||
getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||
);
|
||||
|
||||
txn = new Transaction(null, false);
|
||||
@@ -218,7 +215,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
// turn request message into a response
|
||||
msg.put(ACCEPT, true);
|
||||
msg.put(TIME, time);
|
||||
msg.put(E_PUBLIC_KEY, TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
msg.put(E_PUBLIC_KEY, getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
msg.put(TRANSPORT, new BdfDictionary());
|
||||
|
||||
context.checking(new Expectations() {{
|
||||
@@ -251,13 +248,13 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
// prepare state for incoming ACK
|
||||
state.put(STATE, IntroduceeProtocolState.AWAIT_ACK.ordinal());
|
||||
state.put(ADDED_CONTACT_ID, 2);
|
||||
byte[] nonce = TestUtils.getRandomBytes(42);
|
||||
byte[] nonce = getRandomBytes(42);
|
||||
state.put(NONCE, nonce);
|
||||
state.put(PUBLIC_KEY, introducee2.getAuthor().getPublicKey());
|
||||
|
||||
// create incoming ACK message
|
||||
byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
|
||||
byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
byte[] mac = getRandomBytes(MAC_LENGTH);
|
||||
byte[] sig = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
BdfDictionary ack = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ACK),
|
||||
new BdfEntry(SESSION_ID, sessionId),
|
||||
@@ -288,8 +285,8 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
throws FormatException, DbException, GeneralSecurityException {
|
||||
|
||||
byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
|
||||
byte[] nonce = TestUtils.getRandomBytes(MAC_LENGTH);
|
||||
byte[] sig = TestUtils.getRandomBytes(MAC_LENGTH);
|
||||
byte[] nonce = getRandomBytes(MAC_LENGTH);
|
||||
byte[] sig = getRandomBytes(MAC_LENGTH);
|
||||
|
||||
BdfDictionary state = new BdfDictionary();
|
||||
state.put(PUBLIC_KEY, publicKeyBytes);
|
||||
@@ -311,10 +308,9 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
|
||||
byte[] publicKeyBytes = introducee2.getAuthor().getPublicKey();
|
||||
BdfDictionary tp = BdfDictionary.of(new BdfEntry("fake", "fake"));
|
||||
byte[] ePublicKeyBytes =
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
|
||||
SecretKey macKey = TestUtils.getSecretKey();
|
||||
byte[] ePublicKeyBytes = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
byte[] mac = getRandomBytes(MAC_LENGTH);
|
||||
SecretKey macKey = getSecretKey();
|
||||
|
||||
// move state to where it would be after an ACK arrived
|
||||
BdfDictionary state = new BdfDictionary();
|
||||
@@ -325,7 +321,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
state.put(MAC, mac);
|
||||
state.put(MAC_KEY, macKey.getBytes());
|
||||
|
||||
byte[] signBytes = TestUtils.getRandomBytes(42);
|
||||
byte[] signBytes = getRandomBytes(42);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).toByteArray(
|
||||
BdfList.of(publicKeyBytes, ePublicKeyBytes, tp, time));
|
||||
@@ -348,7 +344,7 @@ public class IntroduceeManagerTest extends BriarTestCase {
|
||||
oneOf(cryptoComponent).mac(with(MAC_LABEL),
|
||||
with(samePropertyValuesAs(macKey)),
|
||||
with(array(equal(signBytes))));
|
||||
will(returnValue(TestUtils.getRandomBytes(MAC_LENGTH)));
|
||||
will(returnValue(getRandomBytes(MAC_LENGTH)));
|
||||
}});
|
||||
try {
|
||||
introduceeManager.verifyMac(state);
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.briar.test.BriarTestCase;
|
||||
import org.jmock.Expectations;
|
||||
import org.jmock.Mockery;
|
||||
@@ -27,7 +26,9 @@ import org.junit.Test;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.api.introduction.IntroducerProtocolState.AWAIT_RESPONSES;
|
||||
import static org.briarproject.briar.api.introduction.IntroducerProtocolState.PREPARE_REQUESTS;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.AUTHOR_ID_1;
|
||||
@@ -80,27 +81,23 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
new IntroducerManager(messageSender, clientHelper, clock,
|
||||
cryptoComponent, introductionGroupFactory);
|
||||
|
||||
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author1 = new Author(authorId1, "Introducee1",
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author1 = getAuthor();
|
||||
AuthorId localAuthorId1 = new AuthorId(getRandomId());
|
||||
ContactId contactId1 = new ContactId(234);
|
||||
introducee1 =
|
||||
new Contact(contactId1, author1, localAuthorId1, true, true);
|
||||
|
||||
AuthorId authorId2 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author2 = new Author(authorId2, "Introducee2",
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH));
|
||||
AuthorId localAuthorId2 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author2 = getAuthor();
|
||||
AuthorId localAuthorId2 = new AuthorId(getRandomId());
|
||||
ContactId contactId2 = new ContactId(235);
|
||||
introducee2 =
|
||||
new Contact(contactId2, author2, localAuthorId2, true, true);
|
||||
|
||||
localGroup0 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
localGroup0 = new Group(new GroupId(getRandomId()),
|
||||
getClientId(), new byte[0]);
|
||||
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
introductionGroup1 = new Group(new GroupId(getRandomId()),
|
||||
getClientId(), new byte[0]);
|
||||
introductionGroup2 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
introductionGroup2 = new Group(new GroupId(getRandomId()),
|
||||
getClientId(), new byte[0]);
|
||||
|
||||
context.assertIsSatisfied();
|
||||
@@ -113,8 +110,8 @@ public class IntroducerManagerTest extends BriarTestCase {
|
||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||
SecureRandom secureRandom = context.mock(SecureRandom.class);
|
||||
Bytes salt = new Bytes(new byte[64]);
|
||||
Message msg = new Message(new MessageId(TestUtils.getRandomId()),
|
||||
localGroup0.getId(), time, TestUtils.getRandomBytes(64));
|
||||
Message msg = new Message(new MessageId(getRandomId()),
|
||||
localGroup0.getId(), time, getRandomBytes(64));
|
||||
BdfDictionary state = new BdfDictionary();
|
||||
state.put(SESSION_ID, msg.getId());
|
||||
state.put(STORAGE_ID, msg.getId());
|
||||
|
||||
@@ -26,8 +26,6 @@ import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.TestDatabaseModule;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||
import org.briarproject.briar.api.introduction.IntroductionMessage;
|
||||
@@ -55,6 +53,8 @@ import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.client.MessageQueueManager.QUEUE_STATE_KEY;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.ALICE_MAC_KEY_LABEL;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.ALICE_NONCE_LABEL;
|
||||
@@ -485,9 +485,8 @@ public class IntroductionIntegrationTest
|
||||
new BdfEntry(TYPE, TYPE_REQUEST),
|
||||
new BdfEntry(SESSION_ID, sessionId),
|
||||
new BdfEntry(GROUP_ID, group.getId()),
|
||||
new BdfEntry(NAME, StringUtils.getRandomString(42)),
|
||||
new BdfEntry(PUBLIC_KEY,
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH))
|
||||
new BdfEntry(NAME, getRandomString(42)),
|
||||
new BdfEntry(PUBLIC_KEY, getRandomBytes(MAX_PUBLIC_KEY_LENGTH))
|
||||
);
|
||||
|
||||
// reset request received state
|
||||
|
||||
@@ -19,8 +19,6 @@ import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.sync.MessageStatus;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.client.MessageTracker;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.test.BriarTestCase;
|
||||
@@ -33,8 +31,11 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID_1;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID_2;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.ROLE;
|
||||
@@ -55,7 +56,7 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
private final ClientHelper clientHelper;
|
||||
private final MessageTracker messageTracker;
|
||||
private final IntroductionGroupFactory introductionGroupFactory;
|
||||
private final SessionId sessionId = new SessionId(TestUtils.getRandomId());
|
||||
private final SessionId sessionId = new SessionId(getRandomId());
|
||||
private final MessageId storageId = new MessageId(sessionId.getBytes());
|
||||
private final long time = 42L;
|
||||
private final Contact introducee1;
|
||||
@@ -66,33 +67,29 @@ public class IntroductionManagerImplTest extends BriarTestCase {
|
||||
private Transaction txn;
|
||||
|
||||
public IntroductionManagerImplTest() {
|
||||
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author1 = new Author(authorId1, "Introducee1",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
AuthorId localAuthorId1 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author1 = getAuthor();
|
||||
AuthorId localAuthorId1 = new AuthorId(getRandomId());
|
||||
ContactId contactId1 = new ContactId(234);
|
||||
introducee1 =
|
||||
new Contact(contactId1, author1, localAuthorId1, true, true);
|
||||
|
||||
AuthorId authorId2 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author2 = new Author(authorId2, "Introducee2",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
AuthorId localAuthorId2 = new AuthorId(TestUtils.getRandomId());
|
||||
Author author2 = getAuthor();
|
||||
AuthorId localAuthorId2 = new AuthorId(getRandomId());
|
||||
ContactId contactId2 = new ContactId(235);
|
||||
introducee2 =
|
||||
new Contact(contactId2, author2, localAuthorId2, true, true);
|
||||
|
||||
ClientId clientId = new ClientId(StringUtils.getRandomString(5));
|
||||
introductionGroup1 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
ClientId clientId = new ClientId(getRandomString(5));
|
||||
introductionGroup1 = new Group(new GroupId(getRandomId()),
|
||||
clientId, new byte[0]);
|
||||
introductionGroup2 = new Group(new GroupId(TestUtils.getRandomId()),
|
||||
introductionGroup2 = new Group(new GroupId(getRandomId()),
|
||||
clientId, new byte[0]);
|
||||
|
||||
message1 = new Message(
|
||||
new MessageId(TestUtils.getRandomId()),
|
||||
new MessageId(getRandomId()),
|
||||
introductionGroup1.getId(),
|
||||
time,
|
||||
TestUtils.getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||
getRandomBytes(MESSAGE_HEADER_LENGTH + 1)
|
||||
);
|
||||
|
||||
// mock ALL THE THINGS!!!
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.data.MetadataEncoder;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.sync.ClientId;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
@@ -14,20 +15,20 @@ import org.briarproject.bramble.api.sync.Message;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.system.SystemClock;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.client.SessionId;
|
||||
import org.briarproject.briar.test.BriarTestCase;
|
||||
import org.jmock.Mockery;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.ACCEPT;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.E_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.api.introduction.IntroductionConstants.GROUP_ID;
|
||||
@@ -59,14 +60,14 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
private final Clock clock = new SystemClock();
|
||||
|
||||
public IntroductionValidatorTest() {
|
||||
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||
ClientId clientId = new ClientId(StringUtils.getRandomString(5));
|
||||
byte[] descriptor = TestUtils.getRandomBytes(12);
|
||||
GroupId groupId = new GroupId(getRandomId());
|
||||
ClientId clientId = new ClientId(getRandomString(5));
|
||||
byte[] descriptor = getRandomBytes(12);
|
||||
group = new Group(groupId, clientId, descriptor);
|
||||
|
||||
MessageId messageId = new MessageId(TestUtils.getRandomId());
|
||||
MessageId messageId = new MessageId(getRandomId());
|
||||
long timestamp = System.currentTimeMillis();
|
||||
byte[] raw = TestUtils.getRandomBytes(123);
|
||||
byte[] raw = getRandomBytes(123);
|
||||
message = new Message(messageId, group.getId(), timestamp, raw);
|
||||
|
||||
|
||||
@@ -82,20 +83,17 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateProperIntroductionRequest() throws IOException {
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
String name = StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey =
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String text =
|
||||
StringUtils.getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
|
||||
public void testValidateProperIntroductionRequest() throws Exception {
|
||||
byte[] sessionId = getRandomId();
|
||||
String name = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String text = getRandomString(MAX_INTRODUCTION_MESSAGE_LENGTH);
|
||||
|
||||
BdfList body = BdfList.of(TYPE_REQUEST, sessionId,
|
||||
name, publicKey, text);
|
||||
|
||||
BdfDictionary result =
|
||||
validator.validateMessage(message, group, body)
|
||||
.getDictionary();
|
||||
validator.validateMessage(message, group, body).getDictionary();
|
||||
|
||||
assertEquals(Long.valueOf(TYPE_REQUEST), result.getLong(TYPE));
|
||||
assertEquals(sessionId, result.getRaw(SESSION_ID));
|
||||
@@ -106,7 +104,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionRequestWithNoName() throws IOException {
|
||||
public void testValidateIntroductionRequestWithNoName() throws Exception {
|
||||
BdfDictionary msg = getValidIntroductionRequest();
|
||||
|
||||
// no NAME is message
|
||||
@@ -118,8 +116,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionRequestWithLongName()
|
||||
throws IOException {
|
||||
public void testValidateIntroductionRequestWithLongName() throws Exception {
|
||||
// too long NAME in message
|
||||
BdfDictionary msg = getValidIntroductionRequest();
|
||||
msg.put(NAME, msg.get(NAME) + "x");
|
||||
@@ -132,7 +129,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionRequestWithWrongType()
|
||||
throws IOException {
|
||||
throws Exception {
|
||||
// wrong message type
|
||||
BdfDictionary msg = getValidIntroductionRequest();
|
||||
msg.put(TYPE, 324234);
|
||||
@@ -143,17 +140,16 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
private BdfDictionary getValidIntroductionRequest() throws FormatException {
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
String name = StringUtils.getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String text = StringUtils.getRandomString(MAX_MESSAGE_BODY_LENGTH);
|
||||
private BdfDictionary getValidIntroductionRequest() throws Exception {
|
||||
byte[] sessionId = getRandomId();
|
||||
Author author = getAuthor();
|
||||
String text = getRandomString(MAX_MESSAGE_BODY_LENGTH);
|
||||
|
||||
BdfDictionary msg = new BdfDictionary();
|
||||
msg.put(TYPE, TYPE_REQUEST);
|
||||
msg.put(SESSION_ID, sessionId);
|
||||
msg.put(NAME, name);
|
||||
msg.put(PUBLIC_KEY, publicKey);
|
||||
msg.put(NAME, author.getName());
|
||||
msg.put(PUBLIC_KEY, author.getPublicKey());
|
||||
msg.put(MSG, text);
|
||||
|
||||
return msg;
|
||||
@@ -164,16 +160,16 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateIntroductionAcceptResponse() throws IOException {
|
||||
byte[] groupId = TestUtils.getRandomId();
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
public void testValidateIntroductionAcceptResponse() throws Exception {
|
||||
byte[] groupId = getRandomId();
|
||||
byte[] sessionId = getRandomId();
|
||||
long time = clock.currentTimeMillis();
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String transportId = StringUtils
|
||||
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String transportId =
|
||||
getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
|
||||
BdfDictionary tProps = BdfDictionary.of(
|
||||
new BdfEntry(StringUtils.getRandomString(MAX_PROPERTY_LENGTH),
|
||||
StringUtils.getRandomString(MAX_PROPERTY_LENGTH))
|
||||
new BdfEntry(getRandomString(MAX_PROPERTY_LENGTH),
|
||||
getRandomString(MAX_PROPERTY_LENGTH))
|
||||
);
|
||||
BdfDictionary tp = BdfDictionary.of(
|
||||
new BdfEntry(transportId, tProps)
|
||||
@@ -204,8 +200,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateIntroductionDeclineResponse()
|
||||
throws IOException {
|
||||
public void testValidateIntroductionDeclineResponse() throws Exception {
|
||||
BdfDictionary msg = getValidIntroductionResponse(false);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getBoolean(ACCEPT));
|
||||
@@ -219,7 +214,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionResponseWithoutAccept()
|
||||
throws IOException {
|
||||
throws Exception {
|
||||
BdfDictionary msg = getValidIntroductionResponse(false);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID));
|
||||
|
||||
@@ -228,11 +223,11 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionResponseWithBrokenTp()
|
||||
throws IOException {
|
||||
throws Exception {
|
||||
BdfDictionary msg = getValidIntroductionResponse(true);
|
||||
BdfDictionary tp = msg.getDictionary(TRANSPORT);
|
||||
tp.put(StringUtils
|
||||
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH), "X");
|
||||
tp.put(
|
||||
getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH), "X");
|
||||
msg.put(TRANSPORT, tp);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
@@ -244,7 +239,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionResponseWithoutPublicKey()
|
||||
throws IOException {
|
||||
throws Exception {
|
||||
BdfDictionary msg = getValidIntroductionResponse(true);
|
||||
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
@@ -255,17 +250,17 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
private BdfDictionary getValidIntroductionResponse(boolean accept)
|
||||
throws FormatException {
|
||||
throws Exception {
|
||||
|
||||
byte[] groupId = TestUtils.getRandomId();
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
byte[] groupId = getRandomId();
|
||||
byte[] sessionId = getRandomId();
|
||||
long time = clock.currentTimeMillis();
|
||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String transportId = StringUtils
|
||||
.getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
|
||||
byte[] publicKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
String transportId =
|
||||
getRandomString(TransportId.MAX_TRANSPORT_ID_LENGTH);
|
||||
BdfDictionary tProps = BdfDictionary.of(
|
||||
new BdfEntry(StringUtils.getRandomString(MAX_PROPERTY_LENGTH),
|
||||
StringUtils.getRandomString(MAX_PROPERTY_LENGTH))
|
||||
new BdfEntry(getRandomString(MAX_PROPERTY_LENGTH),
|
||||
getRandomString(MAX_PROPERTY_LENGTH))
|
||||
);
|
||||
BdfDictionary tp = BdfDictionary.of(
|
||||
new BdfEntry(transportId, tProps)
|
||||
@@ -290,10 +285,10 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateProperIntroductionAck() throws IOException {
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
byte[] mac = TestUtils.getRandomBytes(MAC_LENGTH);
|
||||
byte[] sig = TestUtils.getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
public void testValidateProperIntroductionAck() throws Exception {
|
||||
byte[] sessionId = getRandomId();
|
||||
byte[] mac = getRandomBytes(MAC_LENGTH);
|
||||
byte[] sig = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
BdfList body = BdfList.of(TYPE_ACK, sessionId, mac, sig);
|
||||
|
||||
BdfDictionary result =
|
||||
@@ -307,11 +302,11 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateTooLongIntroductionAck() throws IOException {
|
||||
public void testValidateTooLongIntroductionAck() throws Exception {
|
||||
BdfDictionary msg = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ACK),
|
||||
new BdfEntry(SESSION_ID, TestUtils.getRandomId()),
|
||||
new BdfEntry("garbage", StringUtils.getRandomString(255))
|
||||
new BdfEntry(SESSION_ID, getRandomId()),
|
||||
new BdfEntry("garbage", getRandomString(255))
|
||||
);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getString("garbage"));
|
||||
@@ -321,7 +316,7 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateIntroductionAckWithLongSessionId()
|
||||
throws IOException {
|
||||
throws Exception {
|
||||
BdfDictionary msg = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ACK),
|
||||
new BdfEntry(SESSION_ID, new byte[SessionId.LENGTH + 1])
|
||||
@@ -336,8 +331,8 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
//
|
||||
|
||||
@Test
|
||||
public void testValidateProperIntroductionAbort() throws IOException {
|
||||
byte[] sessionId = TestUtils.getRandomId();
|
||||
public void testValidateProperIntroductionAbort() throws Exception {
|
||||
byte[] sessionId = getRandomId();
|
||||
|
||||
BdfDictionary msg = new BdfDictionary();
|
||||
msg.put(TYPE, TYPE_ABORT);
|
||||
@@ -354,11 +349,11 @@ public class IntroductionValidatorTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testValidateTooLongIntroductionAbort() throws IOException {
|
||||
public void testValidateTooLongIntroductionAbort() throws Exception {
|
||||
BdfDictionary msg = BdfDictionary.of(
|
||||
new BdfEntry(TYPE, TYPE_ABORT),
|
||||
new BdfEntry(SESSION_ID, TestUtils.getRandomId()),
|
||||
new BdfEntry("garbage", StringUtils.getRandomString(255))
|
||||
new BdfEntry(SESSION_ID, getRandomId()),
|
||||
new BdfEntry("garbage", getRandomString(255))
|
||||
);
|
||||
BdfList body = BdfList.of(msg.getLong(TYPE), msg.getRaw(SESSION_ID),
|
||||
msg.getString("garbage"));
|
||||
|
||||
@@ -8,9 +8,6 @@ import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.system.SystemModule;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.forum.ForumConstants;
|
||||
import org.briarproject.briar.api.forum.ForumPost;
|
||||
import org.briarproject.briar.api.forum.ForumPostFactory;
|
||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||
@@ -22,8 +19,9 @@ import javax.inject.Inject;
|
||||
|
||||
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.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_RECORD_PAYLOAD_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -47,12 +45,11 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivateMessageFitsIntoPacket() throws Exception {
|
||||
public void testPrivateMessageFitsIntoRecord() throws Exception {
|
||||
// Create a maximum-length private message
|
||||
GroupId groupId = new GroupId(getRandomId());
|
||||
long timestamp = Long.MAX_VALUE;
|
||||
String body =
|
||||
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
|
||||
String body = getRandomString(MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
||||
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
||||
groupId, timestamp, body);
|
||||
// Check the size of the serialised message
|
||||
@@ -63,27 +60,25 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForumPostFitsIntoPacket() throws Exception {
|
||||
public void testForumPostFitsIntoRecord() throws Exception {
|
||||
// Create a maximum-length author
|
||||
String authorName = StringUtils.getRandomString(
|
||||
MAX_AUTHOR_NAME_LENGTH);
|
||||
int formatVersion = Integer.MAX_VALUE;
|
||||
String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
|
||||
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
|
||||
LocalAuthor author = authorFactory
|
||||
.createLocalAuthor(authorName, authorPublic,
|
||||
privateKey.getEncoded());
|
||||
LocalAuthor author = authorFactory.createLocalAuthor(formatVersion,
|
||||
authorName, authorPublic, privateKey.getEncoded());
|
||||
// Create a maximum-length forum post
|
||||
GroupId groupId = new GroupId(getRandomId());
|
||||
long timestamp = Long.MAX_VALUE;
|
||||
MessageId parent = new MessageId(getRandomId());
|
||||
String body = StringUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
||||
String body = getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
||||
ForumPost post = forumPostFactory.createPost(groupId,
|
||||
timestamp, parent, author, body);
|
||||
// Check the size of the serialised message
|
||||
int length = post.getMessage().getRaw().length;
|
||||
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
|
||||
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH + 4
|
||||
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
|
||||
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
|
||||
+ MAX_FORUM_POST_BODY_LENGTH);
|
||||
assertTrue(length <= MAX_RECORD_PAYLOAD_LENGTH);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||
@@ -36,10 +34,12 @@ import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.api.transport.TransportConstants.TAG_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestPluginConfigModule.MAX_LATENCY;
|
||||
import static org.briarproject.bramble.test.TestPluginConfigModule.TRANSPORT_ID;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
@@ -47,16 +47,13 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
|
||||
private final static String ALICE = "Alice";
|
||||
private final static String BOB = "Bob";
|
||||
|
||||
private final File testDir = TestUtils.getTestDirectory();
|
||||
private final File testDir = getTestDirectory();
|
||||
private final File aliceDir = new File(testDir, "alice");
|
||||
private final File bobDir = new File(testDir, "bob");
|
||||
private final SecretKey master = TestUtils.getSecretKey();
|
||||
private final SecretKey master = getSecretKey();
|
||||
private final long timestamp = System.currentTimeMillis();
|
||||
private final AuthorId aliceId = new AuthorId(TestUtils.getRandomId());
|
||||
private final AuthorId bobId = new AuthorId(TestUtils.getRandomId());
|
||||
private final LocalAuthor aliceAuthor = getLocalAuthor();
|
||||
private final LocalAuthor bobAuthor = getLocalAuthor();
|
||||
|
||||
private SimplexMessagingIntegrationTestComponent alice, bob;
|
||||
|
||||
@@ -95,12 +92,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
lifecycleManager.startServices(null);
|
||||
lifecycleManager.waitForStartup();
|
||||
// Add an identity for Alice
|
||||
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||
identityManager.registerLocalAuthor(aliceAuthor);
|
||||
// Add Bob as a contact
|
||||
Author bobAuthor = new Author(bobId, BOB,
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
ContactId contactId = contactManager.addContact(bobAuthor,
|
||||
aliceAuthor.getId(), master, timestamp, true, true, true);
|
||||
|
||||
@@ -146,12 +139,8 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
lifecycleManager.startServices(null);
|
||||
lifecycleManager.waitForStartup();
|
||||
// Add an identity for Bob
|
||||
LocalAuthor bobAuthor = new LocalAuthor(bobId, BOB,
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||
identityManager.registerLocalAuthor(bobAuthor);
|
||||
// Add Alice as a contact
|
||||
Author aliceAuthor = new Author(aliceId, ALICE,
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
ContactId contactId = contactManager.addContact(aliceAuthor,
|
||||
bobAuthor.getId(), master, timestamp, false, true, true);
|
||||
// Set up an event listener
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.sync.InvalidMessageException;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||
@@ -21,9 +20,8 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
@@ -36,9 +34,7 @@ import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_POST_BODY_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_INITIAL_JOIN_MSG;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_NAME;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER_PUBLIC_KEY;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_MEMBER;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_PARENT_MSG_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_PREVIOUS_MSG_ID;
|
||||
import static org.briarproject.briar.privategroup.GroupConstants.KEY_READ;
|
||||
@@ -56,285 +52,334 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
|
||||
private final GroupInvitationFactory groupInvitationFactory =
|
||||
context.mock(GroupInvitationFactory.class);
|
||||
|
||||
private final String creatorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
private final String memberName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
private final byte[] creatorKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final byte[] memberKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final Author member = getAuthor();
|
||||
private final BdfList memberList = BdfList.of(
|
||||
member.getFormatVersion(),
|
||||
member.getName(),
|
||||
member.getPublicKey()
|
||||
);
|
||||
private final byte[] memberSignature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
private final Author creator = getAuthor();
|
||||
private final BdfList creatorList = BdfList.of(
|
||||
creator.getFormatVersion(),
|
||||
creator.getName(),
|
||||
creator.getPublicKey()
|
||||
);
|
||||
private final byte[] creatorSignature =
|
||||
getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
private final Author member =
|
||||
new Author(new AuthorId(getRandomId()), memberName, memberKey);
|
||||
private final Author creator =
|
||||
new Author(new AuthorId(getRandomId()), creatorName, creatorKey);
|
||||
private final long inviteTimestamp = 42L;
|
||||
private final long inviteTimestamp = message.getTimestamp() - 1;
|
||||
private final BdfList invite =
|
||||
BdfList.of(inviteTimestamp, creatorSignature);
|
||||
private final PrivateGroup privateGroup = new PrivateGroup(group,
|
||||
getRandomString(MAX_GROUP_NAME_LENGTH), creator,
|
||||
getRandomBytes(GROUP_SALT_LENGTH));
|
||||
private final BdfList token = BdfList.of("token");
|
||||
private final BdfList token = new BdfList();
|
||||
private final MessageId parentId = new MessageId(getRandomId());
|
||||
private final MessageId previousMsgId = new MessageId(getRandomId());
|
||||
private final String postContent =
|
||||
getRandomString(MAX_GROUP_POST_BODY_LENGTH);
|
||||
private final String content = getRandomString(MAX_GROUP_POST_BODY_LENGTH);
|
||||
|
||||
private final GroupMessageValidator validator =
|
||||
new GroupMessageValidator(privateGroupFactory, clientHelper,
|
||||
metadataEncoder, clock, authorFactory,
|
||||
groupInvitationFactory);
|
||||
metadataEncoder, clock, groupInvitationFactory);
|
||||
|
||||
// JOIN message
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortJoinMessage() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey, null);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongJoinMessage() throws Exception {
|
||||
expectCreateAuthor(creator);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey, null,
|
||||
signature, "");
|
||||
expectParseAuthor(memberList, member);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
memberSignature, "");
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithTooShortMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), "", memberKey, null,
|
||||
signature);
|
||||
public void testRejectsJoinWithNullAuthor() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), null, invite, memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinMessageWithTooLongMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(),
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), memberKey, null,
|
||||
signature);
|
||||
public void testRejectsJoinWithNonListAuthor() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), 123, invite, memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinMessageWithNullMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), null, memberKey, null,
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinMessageWithNonStringMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), getRandomBytes(5), memberKey,
|
||||
null, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithTooShortMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, new byte[0], null,
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithTooLongMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName,
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), null, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithNoullMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, null, null,
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithNonRawMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, "not raw", null,
|
||||
signature);
|
||||
public void testRejectsJoinWithInvalidAuthor() throws Exception {
|
||||
expectRejectAuthor(memberList);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithNonListInvitation() throws Exception {
|
||||
expectCreateAuthor(creator);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey,
|
||||
"not a list", signature);
|
||||
expectParseAuthor(memberList, member);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, "not a list",
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsCreatorJoinWithTooShortMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(creatorList, creator);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite,
|
||||
new byte[0]);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsCreatorJoinWithTooLongMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(creatorList, creator);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite,
|
||||
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsCreatorJoinWithNullMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(creatorList, creator);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite, null);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsCreatorJoinWithNonRawMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(creatorList, creator);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorList, invite,
|
||||
"not raw");
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsCreatorJoinWithInvalidMemberSignature()
|
||||
throws Exception {
|
||||
expectCreatorJoinMessage(false);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorList, null,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsCreatorJoin() throws Exception {
|
||||
expectJoinMessage(creator, null, true, true);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorName, creatorKey,
|
||||
null, signature);
|
||||
expectCreatorJoinMessage(true);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), creatorList, null,
|
||||
memberSignature);
|
||||
BdfMessageContext messageContext =
|
||||
validator.validateMessage(message, group, body);
|
||||
assertExpectedMessageContext(messageContext, JOIN, creator,
|
||||
assertExpectedMessageContext(messageContext, JOIN, creatorList,
|
||||
Collections.emptyList());
|
||||
assertTrue(messageContext.getDictionary()
|
||||
.getBoolean(KEY_INITIAL_JOIN_MSG));
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNullInvitation() throws Exception {
|
||||
expectCreateAuthor(member);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, null,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, null,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithTooShortInvitation() throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp);
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite = BdfList.of(inviteTimestamp);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithTooLongInvitation() throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature, "");
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite =
|
||||
BdfList.of(inviteTimestamp, creatorSignature, "");
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
public void testRejectsMemberJoinWithEqualInvitationTime()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(message.getTimestamp(), creatorSignature);
|
||||
expectCreateAuthor(member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
public void testRejectsMemberJoinWithLaterInvitationTime()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(message.getTimestamp() + 1,
|
||||
creatorSignature);
|
||||
expectCreateAuthor(member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNullInvitationTime()
|
||||
public void testRejectsMemberJoinWithEqualInvitationTime()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(null, creatorSignature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite =
|
||||
BdfList.of(message.getTimestamp(), creatorSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithLaterInvitationTime()
|
||||
throws Exception {
|
||||
BdfList invalidInvite =
|
||||
BdfList.of(message.getTimestamp() + 1, creatorSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNullInvitationTime() throws Exception {
|
||||
BdfList invalidInvite = BdfList.of(null, creatorSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNonLongInvitationTime()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of("not long", creatorSignature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite = BdfList.of("not long", creatorSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithTooShortCreatorSignature()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, new byte[0]);
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite = BdfList.of(inviteTimestamp, new byte[0]);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsJoinWithTooLongCreatorSignature()
|
||||
public void testRejectsMemberJoinWithTooLongCreatorSignature()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp,
|
||||
BdfList invalidInvite = BdfList.of(inviteTimestamp,
|
||||
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
|
||||
expectCreateAuthor(member);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNullCreatorSignature()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, null);
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite = BdfList.of(inviteTimestamp, null);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNonRawCreatorSignature()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, "not raw");
|
||||
expectCreateAuthor(member);
|
||||
BdfList invalidInvite = BdfList.of(inviteTimestamp, "not raw");
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invalidInvite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithInvalidCreatorSignature()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
|
||||
expectJoinMessage(member, invite, false, true);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
expectMemberJoinMessage(false, true);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithTooShortMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(memberList, member);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
new byte[0]);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithTooLongMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(memberList, member);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNullMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(memberList, member);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite, null);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithNonRawMemberSignature()
|
||||
throws Exception {
|
||||
expectParseAuthor(memberList, member);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite, "not raw");
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsMemberJoinWithInvalidMemberSignature()
|
||||
throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
|
||||
expectJoinMessage(member, invite, true, false);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
expectMemberJoinMessage(true, false);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMemberJoin() throws Exception {
|
||||
BdfList invite = BdfList.of(inviteTimestamp, creatorSignature);
|
||||
expectJoinMessage(member, invite, true, true);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberName, memberKey, invite,
|
||||
signature);
|
||||
expectMemberJoinMessage(true, true);
|
||||
BdfList body = BdfList.of(JOIN.getInt(), memberList, invite,
|
||||
memberSignature);
|
||||
BdfMessageContext messageContext =
|
||||
validator.validateMessage(message, group, body);
|
||||
assertExpectedMessageContext(messageContext, JOIN, member,
|
||||
assertExpectedMessageContext(messageContext, JOIN, memberList,
|
||||
Collections.emptyList());
|
||||
assertFalse(messageContext.getDictionary()
|
||||
.getBoolean(KEY_INITIAL_JOIN_MSG));
|
||||
}
|
||||
|
||||
private void expectCreateAuthor(Author member) {
|
||||
private void expectParseAuthor(BdfList authorList, Author author)
|
||||
throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(member.getName(),
|
||||
member.getPublicKey());
|
||||
will(returnValue(member));
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList);
|
||||
will(returnValue(author));
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectRejectAuthor(BdfList authorList) throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList);
|
||||
will(throwException(new FormatException()));
|
||||
}});
|
||||
}
|
||||
|
||||
@@ -345,26 +390,46 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectJoinMessage(Author member, BdfList invite,
|
||||
boolean creatorSigValid, boolean memberSigValid) throws Exception {
|
||||
BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
|
||||
JOIN.getInt(), member.getName(), member.getPublicKey(), invite);
|
||||
expectCreateAuthor(member);
|
||||
private void expectCreatorJoinMessage(boolean memberSigValid)
|
||||
throws Exception {
|
||||
BdfList signed = BdfList.of(
|
||||
group.getId(),
|
||||
message.getTimestamp(),
|
||||
creatorList,
|
||||
null
|
||||
);
|
||||
expectParseAuthor(creatorList, creator);
|
||||
expectParsePrivateGroup();
|
||||
context.checking(new Expectations() {{
|
||||
if (invite != null) {
|
||||
oneOf(groupInvitationFactory).createInviteToken(creator.getId(),
|
||||
member.getId(), privateGroup.getId(), inviteTimestamp);
|
||||
will(returnValue(token));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE,
|
||||
creatorSignature, creatorKey, token);
|
||||
if (!memberSigValid)
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
}
|
||||
if (memberSigValid) {
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_JOIN,
|
||||
memberSignature, creator.getPublicKey(), signed);
|
||||
if (!memberSigValid)
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectMemberJoinMessage(boolean creatorSigValid,
|
||||
boolean memberSigValid) throws Exception {
|
||||
BdfList signed = BdfList.of(
|
||||
group.getId(),
|
||||
message.getTimestamp(),
|
||||
memberList,
|
||||
invite
|
||||
);
|
||||
expectParseAuthor(memberList, member);
|
||||
expectParsePrivateGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(groupInvitationFactory).createInviteToken(creator.getId(),
|
||||
member.getId(), privateGroup.getId(), inviteTimestamp);
|
||||
will(returnValue(token));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE,
|
||||
creatorSignature, creator.getPublicKey(), token);
|
||||
if (!creatorSigValid) {
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
} else {
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_JOIN,
|
||||
signature, member.getPublicKey(), signed);
|
||||
if (!creatorSigValid)
|
||||
memberSignature, member.getPublicKey(), signed);
|
||||
if (!memberSigValid)
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
}
|
||||
}});
|
||||
@@ -374,219 +439,181 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortPost() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongPost() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent, signature, "");
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, memberSignature, "");
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooShortMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), "", memberKey, parentId,
|
||||
previousMsgId, postContent, signature);
|
||||
public void testRejectsPostWithNullAuthor() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), null, parentId, previousMsgId,
|
||||
content, memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooLongMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(),
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), memberKey,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
public void testRejectsPostWithNonListAuthor() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), 123, parentId, previousMsgId,
|
||||
content, memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNullMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), null, memberKey,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNonStringMemberName() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), getRandomBytes(5), memberKey,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooShortMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, new byte[0],
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooLongMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName,
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), parentId,
|
||||
previousMsgId, postContent, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNullMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, null,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNonRawMemberKey() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, "not raw",
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
public void testRejectsPostWithInvalidAuthor() throws Exception {
|
||||
expectRejectAuthor(memberList);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, memberSignature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooShortParentId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
getRandomBytes(MessageId.LENGTH - 1), previousMsgId,
|
||||
postContent, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList,
|
||||
getRandomBytes(MessageId.LENGTH - 1), previousMsgId, content,
|
||||
memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooLongParentId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
getRandomBytes(MessageId.LENGTH + 1), previousMsgId,
|
||||
postContent, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList,
|
||||
getRandomBytes(MessageId.LENGTH + 1), previousMsgId, content,
|
||||
memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNonRawParentId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
"not raw", previousMsgId, postContent, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, "not raw",
|
||||
previousMsgId, content, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooShortPreviousMsgId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, getRandomBytes(MessageId.LENGTH - 1), postContent,
|
||||
signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
getRandomBytes(MessageId.LENGTH - 1), content, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooLongPreviousMsgId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, getRandomBytes(MessageId.LENGTH + 1), postContent,
|
||||
signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
getRandomBytes(MessageId.LENGTH + 1), content, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNullPreviousMsgId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, null, postContent, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId, null,
|
||||
content, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNonRawPreviousMsgId() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, "not raw", postContent, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
"not raw", content, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooShortContent() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, "", signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, "", memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooLongContent() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId,
|
||||
getRandomString(MAX_GROUP_POST_BODY_LENGTH + 1), signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, getRandomString(MAX_GROUP_POST_BODY_LENGTH + 1),
|
||||
memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNullContent() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, null, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, null, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNonStringContent() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, getRandomBytes(5), signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, getRandomBytes(5), memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooShortSignature() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent, new byte[0]);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, new byte[0]);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithTooLongSignature() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent,
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content,
|
||||
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
|
||||
expectCreateAuthor(member);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNullSignature() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent,null);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, null);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithNonRawSignature() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent, "not raw");
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, "not raw");
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsPostWithInvalidSignature() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
expectPostMessage(member, parentId, false);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, memberSignature);
|
||||
expectPostMessage(parentId, false);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsPost() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
expectPostMessage(member, parentId, true);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, parentId,
|
||||
previousMsgId, content, memberSignature);
|
||||
expectPostMessage(parentId, true);
|
||||
BdfMessageContext messageContext =
|
||||
validator.validateMessage(message, group, body);
|
||||
assertExpectedMessageContext(messageContext, POST, member,
|
||||
assertExpectedMessageContext(messageContext, POST, memberList,
|
||||
Arrays.asList(parentId, previousMsgId));
|
||||
assertArrayEquals(previousMsgId.getBytes(),
|
||||
messageContext.getDictionary().getRaw(KEY_PREVIOUS_MSG_ID));
|
||||
@@ -596,12 +623,12 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
|
||||
|
||||
@Test
|
||||
public void testAcceptsTopLevelPost() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt(), memberName, memberKey, null,
|
||||
previousMsgId, postContent, signature);
|
||||
expectPostMessage(member, null, true);
|
||||
BdfList body = BdfList.of(POST.getInt(), memberList, null,
|
||||
previousMsgId, content, memberSignature);
|
||||
expectPostMessage(null, true);
|
||||
BdfMessageContext messageContext =
|
||||
validator.validateMessage(message, group, body);
|
||||
assertExpectedMessageContext(messageContext, POST, member,
|
||||
assertExpectedMessageContext(messageContext, POST, memberList,
|
||||
Collections.singletonList(previousMsgId));
|
||||
assertArrayEquals(previousMsgId.getBytes(),
|
||||
messageContext.getDictionary().getRaw(KEY_PREVIOUS_MSG_ID));
|
||||
@@ -609,39 +636,42 @@ public class GroupMessageValidatorTest extends ValidatorTestCase {
|
||||
messageContext.getDictionary().containsKey(KEY_PARENT_MSG_ID));
|
||||
}
|
||||
|
||||
private void expectPostMessage(Author member, MessageId parentId,
|
||||
boolean sigValid) throws Exception {
|
||||
BdfList signed = BdfList.of(group.getId(), message.getTimestamp(),
|
||||
POST.getInt(), member.getName(), member.getPublicKey(),
|
||||
private void expectPostMessage(MessageId parentId, boolean sigValid)
|
||||
throws Exception {
|
||||
BdfList signed = BdfList.of(
|
||||
group.getId(),
|
||||
message.getTimestamp(),
|
||||
memberList,
|
||||
parentId == null ? null : parentId.getBytes(),
|
||||
previousMsgId.getBytes(), postContent);
|
||||
expectCreateAuthor(member);
|
||||
previousMsgId.getBytes(),
|
||||
content
|
||||
);
|
||||
expectParseAuthor(memberList, member);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST, signature,
|
||||
member.getPublicKey(), signed);
|
||||
if (!sigValid) will(throwException(new GeneralSecurityException()));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_POST,
|
||||
memberSignature, member.getPublicKey(), signed);
|
||||
if (!sigValid)
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
}});
|
||||
}
|
||||
|
||||
private void assertExpectedMessageContext(BdfMessageContext c,
|
||||
MessageType type, Author member,
|
||||
MessageType type, BdfList member,
|
||||
Collection<MessageId> dependencies) throws FormatException {
|
||||
BdfDictionary d = c.getDictionary();
|
||||
assertEquals(type.getInt(), d.getLong(KEY_TYPE).intValue());
|
||||
assertEquals(message.getTimestamp(),
|
||||
d.getLong(KEY_TIMESTAMP).longValue());
|
||||
assertFalse(d.getBoolean(KEY_READ));
|
||||
assertEquals(member.getId().getBytes(), d.getRaw(KEY_MEMBER_ID));
|
||||
assertEquals(member.getName(), d.getString(KEY_MEMBER_NAME));
|
||||
assertEquals(member.getPublicKey(), d.getRaw(KEY_MEMBER_PUBLIC_KEY));
|
||||
assertEquals(member, d.getList(KEY_MEMBER));
|
||||
assertEquals(dependencies, c.getDependencies());
|
||||
}
|
||||
|
||||
@Test(expected = InvalidMessageException.class)
|
||||
public void testRejectsMessageWithUnknownType() throws Exception {
|
||||
BdfList body = BdfList.of(POST.getInt() + 1, memberName, memberKey,
|
||||
parentId, previousMsgId, postContent, signature);
|
||||
expectCreateAuthor(member);
|
||||
BdfList body = BdfList.of(POST.getInt() + 1, memberList,
|
||||
parentId, previousMsgId, content, memberSignature);
|
||||
expectParseAuthor(memberList, member);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,14 @@ import org.briarproject.briar.api.privategroup.PrivateGroupFactory;
|
||||
import org.briarproject.briar.api.privategroup.PrivateGroupManager;
|
||||
import org.jmock.Expectations;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.GROUP_SALT_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_NAME_LENGTH;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupManager.CLIENT_ID;
|
||||
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_CONTACT_ID;
|
||||
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
||||
@@ -59,14 +65,13 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
|
||||
protected final GroupId contactGroupId = new GroupId(getRandomId());
|
||||
protected final GroupId privateGroupId = new GroupId(getRandomId());
|
||||
protected final Group privateGroupGroup =
|
||||
new Group(privateGroupId, CLIENT_ID, getRandomBytes(5));
|
||||
private final AuthorId authorId = new AuthorId(getRandomId());
|
||||
protected final Author author =
|
||||
new Author(authorId, "Author", getRandomBytes(12));
|
||||
new Group(privateGroupId, CLIENT_ID, getRandomBytes(123));
|
||||
protected final Author author = getAuthor();
|
||||
protected final PrivateGroup privateGroup =
|
||||
new PrivateGroup(privateGroupGroup, "Private Group", author,
|
||||
getRandomBytes(8));
|
||||
protected final byte[] signature = getRandomBytes(42);
|
||||
new PrivateGroup(privateGroupGroup,
|
||||
getRandomString(MAX_GROUP_NAME_LENGTH), author,
|
||||
getRandomBytes(GROUP_SALT_LENGTH));
|
||||
protected final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
protected final MessageId lastLocalMessageId = new MessageId(getRandomId());
|
||||
protected final MessageId lastRemoteMessageId =
|
||||
new MessageId(getRandomId());
|
||||
@@ -74,20 +79,19 @@ public abstract class AbstractProtocolEngineTest extends BrambleMockTestCase {
|
||||
protected final long inviteTimestamp = 6L;
|
||||
protected final long messageTimestamp = inviteTimestamp + 1;
|
||||
protected final MessageId messageId = new MessageId(getRandomId());
|
||||
protected final Message message =
|
||||
new Message(messageId, contactGroupId, messageTimestamp,
|
||||
getRandomBytes(42));
|
||||
protected final Message message = new Message(messageId, contactGroupId,
|
||||
messageTimestamp, getRandomBytes(42));
|
||||
private final BdfDictionary meta =
|
||||
BdfDictionary.of(new BdfEntry("me", "ta"));
|
||||
protected final ContactId contactId = new ContactId(5);
|
||||
protected final Contact contact =
|
||||
new Contact(contactId, author, new AuthorId(getRandomId()), true,
|
||||
true);
|
||||
protected final Contact contact = new Contact(contactId, author,
|
||||
new AuthorId(getRandomId()), true, true);
|
||||
|
||||
protected final InviteMessage inviteMessage =
|
||||
new InviteMessage(new MessageId(getRandomId()), contactGroupId,
|
||||
privateGroupId, 0L, privateGroup.getName(),
|
||||
privateGroup.getCreator(), privateGroup.getSalt(), "msg",
|
||||
privateGroup.getCreator(), privateGroup.getSalt(),
|
||||
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH),
|
||||
signature);
|
||||
protected final JoinMessage joinMessage =
|
||||
new JoinMessage(new MessageId(getRandomId()), contactGroupId,
|
||||
|
||||
@@ -4,10 +4,8 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.UniqueId;
|
||||
import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||
@@ -18,9 +16,8 @@ import org.junit.Test;
|
||||
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
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_SIGNATURE_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
@@ -42,194 +39,149 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
|
||||
private final MessageEncoder messageEncoder =
|
||||
context.mock(MessageEncoder.class);
|
||||
|
||||
private final Author creator = getAuthor();
|
||||
private final BdfList creatorList = BdfList.of(
|
||||
creator.getFormatVersion(),
|
||||
creator.getName(),
|
||||
creator.getPublicKey()
|
||||
);
|
||||
private final String groupName = getRandomString(MAX_GROUP_NAME_LENGTH);
|
||||
private final String creatorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||
private final byte[] creatorKey = getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final Author creator =
|
||||
new Author(new AuthorId(getRandomId()), creatorName, creatorKey);
|
||||
private final byte[] salt = getRandomBytes(GROUP_SALT_LENGTH);
|
||||
private final PrivateGroup privateGroup =
|
||||
new PrivateGroup(group, groupName, creator, salt);
|
||||
private final String inviteText =
|
||||
private final String content =
|
||||
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH);
|
||||
private final byte[] signature = getRandomBytes(MAX_SIGNATURE_LENGTH);
|
||||
private final BdfDictionary meta =
|
||||
BdfDictionary.of(new BdfEntry("meta", "data"));
|
||||
private final PrivateGroup privateGroup =
|
||||
new PrivateGroup(group, groupName, creator, salt);
|
||||
private final BdfDictionary meta = new BdfDictionary();
|
||||
private final MessageId previousMessageId = new MessageId(getRandomId());
|
||||
|
||||
private final GroupInvitationValidator validator =
|
||||
new GroupInvitationValidator(clientHelper, metadataEncoder,
|
||||
clock, authorFactory, privateGroupFactory, messageEncoder);
|
||||
clock, privateGroupFactory, messageEncoder);
|
||||
|
||||
// INVITE Message
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortInviteMessage() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongInviteMessage() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText, signature, "");
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, signature, "");
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooShortGroupName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), "", creatorName,
|
||||
creatorKey, salt, inviteText, signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, "", salt,
|
||||
content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooLongGroupName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(),
|
||||
getRandomString(MAX_GROUP_NAME_LENGTH + 1), creatorName,
|
||||
creatorKey, salt, inviteText, signature);
|
||||
String tooLongName = getRandomString(MAX_GROUP_NAME_LENGTH + 1);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, tooLongName,
|
||||
salt, content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNullGroupName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), null, creatorName,
|
||||
creatorKey, salt, inviteText, signature);
|
||||
public void testRejectsInviteMessageWithNullGroupName() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, null, salt,
|
||||
content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNonStringGroupName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), getRandomBytes(5),
|
||||
creatorName, creatorKey, salt, inviteText, signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList,
|
||||
getRandomBytes(5), salt, content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooShortCreatorName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, "", creatorKey,
|
||||
salt, inviteText, signature);
|
||||
public void testRejectsInviteMessageWithNullCreator() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), null, groupName, salt,
|
||||
content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooLongCreatorName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName,
|
||||
getRandomString(MAX_AUTHOR_NAME_LENGTH + 1), creatorKey, salt,
|
||||
inviteText, signature);
|
||||
public void testRejectsInviteMessageWithNonListCreator() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), 123, groupName, salt,
|
||||
content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNullCreatorName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, null,
|
||||
creatorKey, salt, inviteText, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
public void testRejectsInviteMessageWithInvalidCreator() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAuthor(creatorList);
|
||||
will(throwException(new FormatException()));
|
||||
}});
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNonStringCreatorName()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName,
|
||||
getRandomBytes(5), creatorKey, salt, inviteText, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooShortCreatorKey()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
new byte[0], salt, inviteText, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooLongCreatorKey()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1), salt, inviteText,
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNullCreatorKey()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
null, salt, inviteText, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNonRawCreatorKey()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
"not raw", salt, inviteText, signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooShortGroupSalt()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, getRandomBytes(GROUP_SALT_LENGTH - 1), inviteText,
|
||||
signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
getRandomBytes(GROUP_SALT_LENGTH - 1), content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooLongGroupSalt()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, getRandomBytes(GROUP_SALT_LENGTH + 1), inviteText,
|
||||
signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
getRandomBytes(GROUP_SALT_LENGTH + 1), content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNullGroupSalt()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, null, inviteText, signature);
|
||||
public void testRejectsInviteMessageWithNullGroupSalt() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
null, content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNonRawGroupSalt()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, "not raw", inviteText, signature);
|
||||
public void testRejectsInviteMessageWithNonRawGroupSalt() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
"not raw", content, signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooShortContent() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, "", signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, "", signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooLongContent() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt,
|
||||
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH + 1),
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH + 1),
|
||||
signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInviteMessageWithNullContent() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, null, signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, null, signature);
|
||||
expectInviteMessage(false);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
@@ -237,57 +189,54 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNonStringContent()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, getRandomBytes(5), signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, getRandomBytes(5), signature);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooShortSignature()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText, new byte[0]);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, new byte[0]);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithTooLongSignature()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText,
|
||||
getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, getRandomBytes(MAX_SIGNATURE_LENGTH + 1));
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNullSignature()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText, null);
|
||||
public void testRejectsInviteMessageWithNullSignature() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, null);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithNonRawSignature()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText, "not raw");
|
||||
public void testRejectsInviteMessageWithNonRawSignature() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, "not raw");
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInviteMessageWithInvalidSignature()
|
||||
throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, null, signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, signature);
|
||||
expectInviteMessage(true);
|
||||
validator.validateMessage(message, group, body);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsValidInviteMessage() throws Exception {
|
||||
BdfList body = BdfList.of(INVITE.getValue(), groupName, creatorName,
|
||||
creatorKey, salt, inviteText, signature);
|
||||
BdfList body = BdfList.of(INVITE.getValue(), creatorList, groupName,
|
||||
salt, content, signature);
|
||||
expectInviteMessage(false);
|
||||
BdfMessageContext messageContext =
|
||||
validator.validateMessage(message, group, body);
|
||||
@@ -296,16 +245,19 @@ public class GroupInvitationValidatorTest extends ValidatorTestCase {
|
||||
}
|
||||
|
||||
private void expectInviteMessage(boolean exception) throws Exception {
|
||||
BdfList signed = BdfList.of(message.getTimestamp(),
|
||||
message.getGroupId(), privateGroup.getId());
|
||||
BdfList signed = BdfList.of(
|
||||
message.getTimestamp(),
|
||||
message.getGroupId(),
|
||||
privateGroup.getId()
|
||||
);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(creatorName, creatorKey);
|
||||
oneOf(clientHelper).parseAndValidateAuthor(creatorList);
|
||||
will(returnValue(creator));
|
||||
oneOf(privateGroupFactory).createPrivateGroup(groupName, creator,
|
||||
salt);
|
||||
will(returnValue(privateGroup));
|
||||
oneOf(clientHelper).verifySignature(SIGNING_LABEL_INVITE, signature,
|
||||
creatorKey, signed);
|
||||
creator.getPublicKey(), signed);
|
||||
if (exception) {
|
||||
will(throwException(new GeneralSecurityException()));
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.briar.api.client.ProtocolStateException;
|
||||
@@ -18,8 +17,11 @@ import java.util.Map;
|
||||
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.VISIBLE;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.privategroup.PrivateGroupConstants.MAX_GROUP_INVITATION_MSG_LENGTH;
|
||||
import static org.briarproject.briar.privategroup.invitation.InviteeState.ACCEPTED;
|
||||
import static org.briarproject.briar.privategroup.invitation.InviteeState.DISSOLVED;
|
||||
import static org.briarproject.briar.privategroup.invitation.InviteeState.ERROR;
|
||||
@@ -39,9 +41,7 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||
new InviteeProtocolEngine(db, clientHelper, privateGroupManager,
|
||||
privateGroupFactory, groupMessageFactory, identityManager,
|
||||
messageParser, messageEncoder, messageTracker, clock);
|
||||
private final LocalAuthor localAuthor =
|
||||
new LocalAuthor(new AuthorId(getRandomId()), "Local Author",
|
||||
getRandomBytes(12), getRandomBytes(12), 42L);
|
||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
||||
|
||||
private InviteeSession getDefaultSession(InviteeState state) {
|
||||
return new InviteeSession(contactGroupId, privateGroupId,
|
||||
@@ -323,13 +323,12 @@ public class InviteeProtocolEngineTest extends AbstractProtocolEngineTest {
|
||||
new InviteMessage(new MessageId(getRandomId()), contactGroupId,
|
||||
privateGroupId, session.getInviteTimestamp() + 1,
|
||||
privateGroup.getName(), privateGroup.getCreator(),
|
||||
privateGroup.getSalt(), "msg", signature);
|
||||
Author notCreator =
|
||||
new Author(new AuthorId(getRandomId()), "Not Creator",
|
||||
getRandomBytes(5));
|
||||
Contact notCreatorContact =
|
||||
new Contact(contactId, notCreator, localAuthor.getId(), true,
|
||||
true);
|
||||
privateGroup.getSalt(),
|
||||
getRandomString(MAX_GROUP_INVITATION_MSG_LENGTH),
|
||||
signature);
|
||||
Author notCreator = getAuthor();
|
||||
Contact notCreatorContact = new Contact(contactId, notCreator,
|
||||
localAuthor.getId(), true, true);
|
||||
|
||||
expectGetContactId();
|
||||
context.checking(new Expectations() {{
|
||||
|
||||
@@ -83,12 +83,10 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
||||
MessageParser<Blog> messageParser = context.mock(MessageParser.class);
|
||||
InvitationFactory<Blog, BlogInvitationResponse> invitationFactory =
|
||||
context.mock(InvitationFactory.class);
|
||||
blogSharingManager =
|
||||
new BlogSharingManagerImpl(db, clientHelper, metadataParser,
|
||||
messageParser, sessionEncoder, sessionParser,
|
||||
messageTracker, contactGroupFactory,
|
||||
engine, invitationFactory, identityManager,
|
||||
blogManager);
|
||||
blogSharingManager = new BlogSharingManagerImpl(db, clientHelper,
|
||||
metadataParser, messageParser, sessionEncoder, sessionParser,
|
||||
messageTracker, contactGroupFactory, engine, invitationFactory,
|
||||
identityManager, blogManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -228,13 +226,11 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
||||
private void expectPreShareShareable(Transaction txn, Contact contact,
|
||||
Blog blog, Map<MessageId, BdfDictionary> sessions)
|
||||
throws Exception {
|
||||
Group contactGroup =
|
||||
new Group(new GroupId(getRandomId()), CLIENT_ID,
|
||||
getRandomBytes(42));
|
||||
Group contactGroup = new Group(new GroupId(getRandomId()), CLIENT_ID,
|
||||
getRandomBytes(42));
|
||||
BdfDictionary sessionDict = new BdfDictionary();
|
||||
Message message =
|
||||
new Message(new MessageId(getRandomId()), contactGroup.getId(),
|
||||
42L, getRandomBytes(1337));
|
||||
Message message = new Message(new MessageId(getRandomId()),
|
||||
contactGroup.getId(), 42L, getRandomBytes(1337));
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(contactGroupFactory).createContactGroup(CLIENT_ID,
|
||||
CLIENT_VERSION, contact);
|
||||
@@ -242,9 +238,8 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(sessionParser)
|
||||
.getSessionQuery(new SessionId(blog.getId().getBytes()));
|
||||
will(returnValue(sessionDict));
|
||||
oneOf(clientHelper)
|
||||
.getMessageMetadataAsDictionary(txn, contactGroup.getId(),
|
||||
sessionDict);
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroup.getId(), sessionDict);
|
||||
will(returnValue(sessions));
|
||||
if (sessions.size() == 0) {
|
||||
oneOf(db).addGroup(txn, blog.getGroup());
|
||||
@@ -277,9 +272,8 @@ public class BlogSharingManagerImplTest extends BrambleMockTestCase {
|
||||
oneOf(sessionParser)
|
||||
.getSessionQuery(new SessionId(blog.getId().getBytes()));
|
||||
will(returnValue(sessionDict));
|
||||
oneOf(clientHelper)
|
||||
.getMessageMetadataAsDictionary(txn, contactGroup.getId(),
|
||||
sessionDict);
|
||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||
contactGroup.getId(), sessionDict);
|
||||
will(returnValue(sessions));
|
||||
if (sessions.size() == 1) {
|
||||
oneOf(sessionParser)
|
||||
|
||||
@@ -4,184 +4,130 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.api.blog.BlogConstants.MAX_BLOG_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.test.TestUtils.getAuthor;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
|
||||
import static org.briarproject.briar.sharing.MessageType.INVITE;
|
||||
|
||||
public class BlogSharingValidatorTest extends SharingValidatorTest {
|
||||
|
||||
private final AuthorId authorId = new AuthorId(getRandomId());
|
||||
private final String authorName = StringUtils.getRandomString(42);
|
||||
private final byte[] publicKey =
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||
private final Author author = new Author(authorId, authorName, publicKey);
|
||||
private final Author author = getAuthor();
|
||||
private final Blog blog = new Blog(group, author, false);
|
||||
private final BdfList descriptor = BdfList.of(authorName, publicKey, false);
|
||||
private final BdfList authorList = BdfList.of(author.getFormatVersion(),
|
||||
author.getName(), author.getPublicKey());
|
||||
private final BdfList descriptor = BdfList.of(authorList, false);
|
||||
private final String content =
|
||||
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
|
||||
getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
|
||||
|
||||
@Override
|
||||
SharingValidator getValidator() {
|
||||
return new BlogSharingValidator(messageEncoder, clientHelper,
|
||||
metadataEncoder, clock, blogFactory, authorFactory);
|
||||
metadataEncoder, clock, blogFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectCreateBlog();
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
content));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithNullContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectCreateBlog();
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
expectCreateBlog();
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), null, descriptor, null));
|
||||
assertExpectedContext(messageContext, null);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullBlogName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(null, publicKey, false);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringBlogName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(123, publicKey, false);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBlogName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of("", publicKey, false);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), null, descriptor, content));
|
||||
assertExpectedContext(context, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthBlogName() throws Exception {
|
||||
String shortBlogName = StringUtils.getRandomString(1);
|
||||
BdfList validDescriptor = BdfList.of(shortBlogName, publicKey, false);
|
||||
expectCreateBlog(shortBlogName, publicKey);
|
||||
public void testAcceptsInvitationForRssBlog() throws Exception {
|
||||
expectCreateRssBlog();
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
|
||||
null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
BdfList rssDescriptor = BdfList.of(authorList, true);
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, rssDescriptor,
|
||||
content));
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBlogName() throws Exception {
|
||||
String invalidBlogName =
|
||||
StringUtils.getRandomString(MAX_BLOG_NAME_LENGTH + 1);
|
||||
BdfList invalidDescriptor =
|
||||
BdfList.of(invalidBlogName, publicKey, false);
|
||||
v.validateMessage(message, group,
|
||||
public void testRejectsNullAuthor() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(null, false);
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullPublicKey() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(authorName, null, false);
|
||||
v.validateMessage(message, group,
|
||||
public void testRejectsNonListAuthor() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(123, false);
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawPublicKey() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(authorName, 123, false);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongPublicKey() throws Exception {
|
||||
byte[] invalidKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH + 1);
|
||||
BdfList invalidDescriptor = BdfList.of(authorName, invalidKey, false);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthPublicKey() throws Exception {
|
||||
byte[] key = TestUtils.getRandomBytes(1);
|
||||
BdfList validDescriptor = BdfList.of(authorName, key, false);
|
||||
|
||||
expectCreateBlog(authorName, key);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
|
||||
null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
expectCreateBlog();
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthContent() throws Exception {
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
String shortContent = getRandomString(1);
|
||||
expectCreateBlog();
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
shortContent));
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongContent() throws Exception {
|
||||
String invalidContent =
|
||||
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
|
||||
expectCreateBlog(authorName, publicKey);
|
||||
v.validateMessage(message, group,
|
||||
getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
|
||||
expectCreateBlog();
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
invalidContent));
|
||||
}
|
||||
|
||||
private void expectCreateBlog(String name, byte[] key) {
|
||||
private void expectCreateBlog() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(authorFactory).createAuthor(name, key);
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList);
|
||||
will(returnValue(author));
|
||||
oneOf(blogFactory).createBlog(author);
|
||||
will(returnValue(blog));
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectCreateRssBlog() throws Exception {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).parseAndValidateAuthor(authorList);
|
||||
will(returnValue(author));
|
||||
oneOf(blogFactory).createFeedBlog(author);
|
||||
will(returnValue(blog));
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package org.briarproject.briar.sharing;
|
||||
import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.api.forum.Forum;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.FORUM_SALT_LENGTH;
|
||||
import static org.briarproject.briar.api.forum.ForumConstants.MAX_FORUM_NAME_LENGTH;
|
||||
import static org.briarproject.briar.api.sharing.SharingConstants.MAX_INVITATION_MESSAGE_LENGTH;
|
||||
@@ -16,13 +16,12 @@ import static org.briarproject.briar.sharing.MessageType.INVITE;
|
||||
|
||||
public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
|
||||
private final String forumName =
|
||||
StringUtils.getRandomString(MAX_FORUM_NAME_LENGTH);
|
||||
private final byte[] salt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH);
|
||||
private final String forumName = getRandomString(MAX_FORUM_NAME_LENGTH);
|
||||
private final byte[] salt = getRandomBytes(FORUM_SALT_LENGTH);
|
||||
private final Forum forum = new Forum(group, forumName, salt);
|
||||
private final BdfList descriptor = BdfList.of(forumName, salt);
|
||||
private final String content =
|
||||
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
|
||||
getRandomString(MAX_INVITATION_MESSAGE_LENGTH);
|
||||
|
||||
@Override
|
||||
SharingValidator getValidator() {
|
||||
@@ -34,34 +33,34 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
public void testAcceptsInvitationWithContent() throws Exception {
|
||||
expectCreateForum(forumName);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
content));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithNullContent() throws Exception {
|
||||
expectCreateForum(forumName);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsInvitationWithNullPreviousMsgId() throws Exception {
|
||||
expectCreateForum(forumName);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), null, descriptor, null));
|
||||
assertExpectedContext(messageContext, null);
|
||||
assertExpectedContext(context, null);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullForumName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(null, salt);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
@@ -69,7 +68,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringForumName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(123, salt);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
@@ -77,29 +76,28 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortForumName() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of("", salt);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthForumName() throws Exception {
|
||||
String shortForumName = StringUtils.getRandomString(1);
|
||||
String shortForumName = getRandomString(1);
|
||||
BdfList validDescriptor = BdfList.of(shortForumName, salt);
|
||||
expectCreateForum(shortForumName);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, validDescriptor,
|
||||
null));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongForumName() throws Exception {
|
||||
String invalidForumName =
|
||||
StringUtils.getRandomString(MAX_FORUM_NAME_LENGTH + 1);
|
||||
String invalidForumName = getRandomString(MAX_FORUM_NAME_LENGTH + 1);
|
||||
BdfList invalidDescriptor = BdfList.of(invalidForumName, salt);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
@@ -107,7 +105,7 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullSalt() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(forumName, null);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
@@ -115,25 +113,25 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawSalt() throws Exception {
|
||||
BdfList invalidDescriptor = BdfList.of(forumName, 123);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortSalt() throws Exception {
|
||||
byte[] invalidSalt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH - 1);
|
||||
byte[] invalidSalt = getRandomBytes(FORUM_SALT_LENGTH - 1);
|
||||
BdfList invalidDescriptor = BdfList.of(forumName, invalidSalt);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongSalt() throws Exception {
|
||||
byte[] invalidSalt = TestUtils.getRandomBytes(FORUM_SALT_LENGTH + 1);
|
||||
byte[] invalidSalt = getRandomBytes(FORUM_SALT_LENGTH + 1);
|
||||
BdfList invalidDescriptor = BdfList.of(forumName, invalidSalt);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, invalidDescriptor,
|
||||
null));
|
||||
}
|
||||
@@ -141,26 +139,25 @@ public class ForumSharingValidatorTest extends SharingValidatorTest {
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonStringContent() throws Exception {
|
||||
expectCreateForum(forumName);
|
||||
v.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
123));
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, 123));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsMinLengthContent() throws Exception {
|
||||
expectCreateForum(forumName);
|
||||
expectEncodeMetadata(INVITE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, "1"));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongContent() throws Exception {
|
||||
String invalidContent =
|
||||
StringUtils.getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
|
||||
getRandomString(MAX_INVITATION_MESSAGE_LENGTH + 1);
|
||||
expectCreateForum(forumName);
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor,
|
||||
invalidContent));
|
||||
}
|
||||
|
||||
@@ -4,10 +4,8 @@ import org.briarproject.bramble.api.FormatException;
|
||||
import org.briarproject.bramble.api.UniqueId;
|
||||
import org.briarproject.bramble.api.client.BdfMessageContext;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.sync.MessageId;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.test.ValidatorTestCase;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
import org.briarproject.briar.api.forum.ForumFactory;
|
||||
@@ -18,6 +16,7 @@ import java.util.Collection;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.sharing.MessageType.ABORT;
|
||||
import static org.briarproject.briar.sharing.MessageType.ACCEPT;
|
||||
@@ -29,28 +28,26 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
public abstract class SharingValidatorTest extends ValidatorTestCase {
|
||||
|
||||
protected final MessageEncoder messageEncoder =
|
||||
context.mock(MessageEncoder.class);
|
||||
protected final ForumFactory forumFactory =
|
||||
context.mock(ForumFactory.class);
|
||||
protected final BlogFactory blogFactory = context.mock(BlogFactory.class);
|
||||
protected final SharingValidator v = getValidator();
|
||||
final MessageEncoder messageEncoder = context.mock(MessageEncoder.class);
|
||||
final ForumFactory forumFactory = context.mock(ForumFactory.class);
|
||||
final BlogFactory blogFactory = context.mock(BlogFactory.class);
|
||||
|
||||
protected final MessageId previousMsgId = new MessageId(getRandomId());
|
||||
private final BdfDictionary meta =
|
||||
BdfDictionary.of(new BdfEntry("meta", "data"));
|
||||
final SharingValidator validator = getValidator();
|
||||
|
||||
final MessageId previousMsgId = new MessageId(getRandomId());
|
||||
private final BdfDictionary meta = new BdfDictionary();
|
||||
|
||||
abstract SharingValidator getValidator();
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForInvitation() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForInvitation() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(INVITE.getValue(), previousMsgId, descriptor, null,
|
||||
123));
|
||||
}
|
||||
@@ -58,101 +55,101 @@ public abstract class SharingValidatorTest extends ValidatorTestCase {
|
||||
@Test
|
||||
public void testAcceptsAccept() throws Exception {
|
||||
expectEncodeMetadata(ACCEPT);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(ACCEPT.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsDecline() throws Exception {
|
||||
expectEncodeMetadata(DECLINE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(DECLINE.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsLeave() throws Exception {
|
||||
expectEncodeMetadata(LEAVE);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(LEAVE.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptsAbort() throws Exception {
|
||||
expectEncodeMetadata(ABORT);
|
||||
BdfMessageContext messageContext = v.validateMessage(message, group,
|
||||
BdfMessageContext context = validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId, previousMsgId));
|
||||
assertExpectedContext(messageContext, previousMsgId);
|
||||
assertExpectedContext(context, previousMsgId);
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullMessageType() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(null, groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonLongMessageType() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of("", groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsInvalidMessageType() throws Exception {
|
||||
int invalidMessageType = ABORT.getValue() + 1;
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(invalidMessageType, groupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNullSessionId() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), null, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsNonRawSessionId() throws Exception {
|
||||
v.validateMessage(message, group, BdfList.of(ABORT.getValue(), 123));
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), 123));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortSessionId() throws Exception {
|
||||
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH - 1);
|
||||
v.validateMessage(message, group,
|
||||
byte[] invalidGroupId = getRandomBytes(UniqueId.LENGTH - 1);
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongSessionId() throws Exception {
|
||||
byte[] invalidGroupId = TestUtils.getRandomBytes(UniqueId.LENGTH + 1);
|
||||
v.validateMessage(message, group,
|
||||
byte[] invalidGroupId = getRandomBytes(UniqueId.LENGTH + 1);
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), invalidGroupId, previousMsgId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooShortBodyForAbort() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId));
|
||||
}
|
||||
|
||||
@Test(expected = FormatException.class)
|
||||
public void testRejectsTooLongBodyForAbort() throws Exception {
|
||||
v.validateMessage(message, group,
|
||||
validator.validateMessage(message, group,
|
||||
BdfList.of(ABORT.getValue(), groupId, previousMsgId, 123));
|
||||
}
|
||||
|
||||
protected void expectEncodeMetadata(MessageType type) {
|
||||
void expectEncodeMetadata(MessageType type) {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(messageEncoder)
|
||||
.encodeMetadata(type, groupId, timestamp, false, false,
|
||||
false, false, false);
|
||||
oneOf(messageEncoder).encodeMetadata(type, groupId, timestamp,
|
||||
false, false, false, false, false);
|
||||
will(returnValue(meta));
|
||||
}});
|
||||
}
|
||||
|
||||
protected void assertExpectedContext(BdfMessageContext messageContext,
|
||||
void assertExpectedContext(BdfMessageContext messageContext,
|
||||
@Nullable MessageId previousMsgId) throws FormatException {
|
||||
Collection<MessageId> dependencies = messageContext.getDependencies();
|
||||
if (previousMsgId == null) {
|
||||
|
||||
@@ -30,7 +30,6 @@ import org.briarproject.bramble.lifecycle.LifecycleModule;
|
||||
import org.briarproject.bramble.properties.PropertiesModule;
|
||||
import org.briarproject.bramble.sync.SyncModule;
|
||||
import org.briarproject.bramble.system.SystemModule;
|
||||
import org.briarproject.bramble.test.TestPluginConfigModule;
|
||||
import org.briarproject.bramble.test.TestUtils;
|
||||
import org.briarproject.bramble.transport.TransportModule;
|
||||
import org.briarproject.briar.api.blog.BlogFactory;
|
||||
@@ -64,6 +63,7 @@ import static junit.framework.Assert.assertNotNull;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.INVALID;
|
||||
import static org.briarproject.bramble.api.sync.ValidationManager.State.PENDING;
|
||||
import static org.briarproject.bramble.test.TestPluginConfigModule.MAX_LATENCY;
|
||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@@ -328,7 +328,7 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
// Create an outgoing sync session
|
||||
SyncSession sessionFrom =
|
||||
fromSync.createSimplexOutgoingSession(toId, TestPluginConfigModule.MAX_LATENCY, out);
|
||||
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
|
||||
// Write whatever needs to be written
|
||||
sessionFrom.run();
|
||||
out.close();
|
||||
|
||||
Reference in New Issue
Block a user