mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Move DB key management into account manager.
This commit is contained in:
@@ -6,6 +6,7 @@ import android.content.SharedPreferences;
|
|||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.util.IoUtils;
|
import org.briarproject.bramble.util.IoUtils;
|
||||||
|
|
||||||
@@ -23,29 +24,29 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
|
|
||||||
private static final String PREF_DB_KEY = "key";
|
private static final String PREF_DB_KEY = "key";
|
||||||
|
|
||||||
private final SharedPreferences briarPrefs;
|
private final SharedPreferences prefs;
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AndroidAccountManager(DatabaseConfig databaseConfig,
|
AndroidAccountManager(DatabaseConfig databaseConfig,
|
||||||
SharedPreferences briarPrefs, Application app) {
|
CryptoComponent crypto, SharedPreferences prefs, Application app) {
|
||||||
super(databaseConfig);
|
super(databaseConfig, crypto);
|
||||||
this.briarPrefs = briarPrefs;
|
this.prefs = prefs;
|
||||||
appContext = app.getApplicationContext();
|
appContext = app.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getEncryptedDatabaseKey() {
|
protected String loadEncryptedDatabaseKey() {
|
||||||
String key = getDatabaseKeyFromPreferences();
|
String key = getDatabaseKeyFromPreferences();
|
||||||
if (key == null) key = super.getEncryptedDatabaseKey();
|
if (key == null) key = super.loadEncryptedDatabaseKey();
|
||||||
else migrateDatabaseKeyToFile(key);
|
else migrateDatabaseKeyToFile(key);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String getDatabaseKeyFromPreferences() {
|
private String getDatabaseKeyFromPreferences() {
|
||||||
String key = briarPrefs.getString(PREF_DB_KEY, null);
|
String key = prefs.getString(PREF_DB_KEY, null);
|
||||||
if (key == null) LOG.info("No database key in preferences");
|
if (key == null) LOG.info("No database key in preferences");
|
||||||
else LOG.info("Found database key in preferences");
|
else LOG.info("Found database key in preferences");
|
||||||
return key;
|
return key;
|
||||||
@@ -53,7 +54,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
|
|
||||||
private void migrateDatabaseKeyToFile(String key) {
|
private void migrateDatabaseKeyToFile(String key) {
|
||||||
if (storeEncryptedDatabaseKey(key)) {
|
if (storeEncryptedDatabaseKey(key)) {
|
||||||
if (briarPrefs.edit().remove(PREF_DB_KEY).commit())
|
if (prefs.edit().remove(PREF_DB_KEY).commit())
|
||||||
LOG.info("Database key migrated to file");
|
LOG.info("Database key migrated to file");
|
||||||
else LOG.warning("Database key not removed from preferences");
|
else LOG.warning("Database key not removed from preferences");
|
||||||
} else {
|
} else {
|
||||||
@@ -66,7 +67,7 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
super.deleteAccount();
|
super.deleteAccount();
|
||||||
SharedPreferences defaultPrefs =
|
SharedPreferences defaultPrefs =
|
||||||
PreferenceManager.getDefaultSharedPreferences(appContext);
|
PreferenceManager.getDefaultSharedPreferences(appContext);
|
||||||
deleteAppData(briarPrefs, defaultPrefs);
|
deleteAppData(prefs, defaultPrefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteAppData(SharedPreferences... clear) {
|
private void deleteAppData(SharedPreferences... clear) {
|
||||||
@@ -92,5 +93,4 @@ class AndroidAccountManager extends AccountManagerImpl
|
|||||||
if (!new File(dataDir, "cache").mkdir())
|
if (!new File(dataDir, "cache").mkdir())
|
||||||
LOG.warning("Could not recreate cache dir");
|
LOG.warning("Could not recreate cache dir");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.bramble.account;
|
|||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
@@ -27,6 +28,7 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
|
|||||||
context.mock(SharedPreferences.class);
|
context.mock(SharedPreferences.class);
|
||||||
private final DatabaseConfig databaseConfig =
|
private final DatabaseConfig databaseConfig =
|
||||||
context.mock(DatabaseConfig.class);
|
context.mock(DatabaseConfig.class);
|
||||||
|
private final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||||
private final SharedPreferences.Editor
|
private final SharedPreferences.Editor
|
||||||
editor = context.mock(SharedPreferences.Editor.class);
|
editor = context.mock(SharedPreferences.Editor.class);
|
||||||
private final Application app;
|
private final Application app;
|
||||||
@@ -52,7 +54,8 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
|
|||||||
allowing(app).getApplicationContext();
|
allowing(app).getApplicationContext();
|
||||||
will(returnValue(app));
|
will(returnValue(app));
|
||||||
}});
|
}});
|
||||||
accountManager = new AndroidAccountManager(databaseConfig, prefs, app);
|
accountManager = new AndroidAccountManager(databaseConfig, crypto,
|
||||||
|
prefs, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -71,7 +74,7 @@ public class AndroidAccountManagerTest extends BrambleMockTestCase {
|
|||||||
assertFalse(keyFile.exists());
|
assertFalse(keyFile.exists());
|
||||||
assertFalse(keyBackupFile.exists());
|
assertFalse(keyBackupFile.exists());
|
||||||
|
|
||||||
assertEquals(encryptedKeyHex, accountManager.getEncryptedDatabaseKey());
|
assertEquals(encryptedKeyHex, accountManager.loadEncryptedDatabaseKey());
|
||||||
|
|
||||||
assertTrue(keyFile.exists());
|
assertTrue(keyFile.exists());
|
||||||
assertTrue(keyBackupFile.exists());
|
assertTrue(keyBackupFile.exists());
|
||||||
|
|||||||
@@ -13,14 +13,13 @@ public interface AccountManager {
|
|||||||
@Nullable
|
@Nullable
|
||||||
SecretKey getDatabaseKey();
|
SecretKey getDatabaseKey();
|
||||||
|
|
||||||
void setDatabaseKey(SecretKey k);
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
String getEncryptedDatabaseKey();
|
|
||||||
|
|
||||||
boolean storeEncryptedDatabaseKey(String hex);
|
|
||||||
|
|
||||||
boolean accountExists();
|
boolean accountExists();
|
||||||
|
|
||||||
|
boolean createAccount(String password);
|
||||||
|
|
||||||
void deleteAccount();
|
void deleteAccount();
|
||||||
|
|
||||||
|
boolean signIn(String password);
|
||||||
|
|
||||||
|
boolean changePassword(String oldPassword, String newPassword);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.bramble.account;
|
package org.briarproject.bramble.account;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
@@ -20,6 +21,8 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -32,14 +35,16 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
private static final String DB_KEY_BACKUP_FILENAME = "db.key.bak";
|
private static final String DB_KEY_BACKUP_FILENAME = "db.key.bak";
|
||||||
|
|
||||||
private final DatabaseConfig databaseConfig;
|
private final DatabaseConfig databaseConfig;
|
||||||
|
private final CryptoComponent crypto;
|
||||||
private final File dbKeyFile, dbKeyBackupFile;
|
private final File dbKeyFile, dbKeyBackupFile;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private volatile SecretKey databaseKey = null;
|
private volatile SecretKey databaseKey = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AccountManagerImpl(DatabaseConfig databaseConfig) {
|
AccountManagerImpl(DatabaseConfig databaseConfig, CryptoComponent crypto) {
|
||||||
this.databaseConfig = databaseConfig;
|
this.databaseConfig = databaseConfig;
|
||||||
|
this.crypto = crypto;
|
||||||
File keyDir = databaseConfig.getDatabaseKeyDirectory();
|
File keyDir = databaseConfig.getDatabaseKeyDirectory();
|
||||||
dbKeyFile = new File(keyDir, DB_KEY_FILENAME);
|
dbKeyFile = new File(keyDir, DB_KEY_FILENAME);
|
||||||
dbKeyBackupFile = new File(keyDir, DB_KEY_BACKUP_FILENAME);
|
dbKeyBackupFile = new File(keyDir, DB_KEY_BACKUP_FILENAME);
|
||||||
@@ -56,14 +61,8 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
return databaseKey;
|
return databaseKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDatabaseKey(SecretKey k) {
|
|
||||||
databaseKey = k;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getEncryptedDatabaseKey() {
|
protected String loadEncryptedDatabaseKey() {
|
||||||
String key = readDbKeyFromFile(dbKeyFile);
|
String key = readDbKeyFromFile(dbKeyFile);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
LOG.info("No database key in primary file");
|
LOG.info("No database key in primary file");
|
||||||
@@ -94,8 +93,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected boolean storeEncryptedDatabaseKey(String hex) {
|
||||||
public boolean storeEncryptedDatabaseKey(String hex) {
|
|
||||||
LOG.info("Storing database key in file");
|
LOG.info("Storing database key in file");
|
||||||
// Create the directory if necessary
|
// Create the directory if necessary
|
||||||
if (databaseConfig.getDatabaseKeyDirectory().mkdirs())
|
if (databaseConfig.getDatabaseKeyDirectory().mkdirs())
|
||||||
@@ -141,14 +139,58 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accountExists() {
|
public boolean accountExists() {
|
||||||
return getEncryptedDatabaseKey() != null
|
return loadEncryptedDatabaseKey() != null
|
||||||
&& databaseConfig.getDatabaseDirectory().isDirectory();
|
&& databaseConfig.getDatabaseDirectory().isDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean createAccount(String password) {
|
||||||
|
SecretKey key = crypto.generateSecretKey();
|
||||||
|
if (!encryptAndStoreDatabaseKey(key, password)) return false;
|
||||||
|
databaseKey = key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean encryptAndStoreDatabaseKey(SecretKey key, String password) {
|
||||||
|
byte[] plaintext = key.getBytes();
|
||||||
|
byte[] ciphertext = crypto.encryptWithPassword(plaintext, password);
|
||||||
|
return storeEncryptedDatabaseKey(toHexString(ciphertext));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteAccount() {
|
public void deleteAccount() {
|
||||||
LOG.info("Deleting account");
|
LOG.info("Deleting account");
|
||||||
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
|
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
|
||||||
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
|
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean signIn(String password) {
|
||||||
|
SecretKey key = loadAndDecryptDatabaseKey(password);
|
||||||
|
if (key == null) return false;
|
||||||
|
databaseKey = key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private SecretKey loadAndDecryptDatabaseKey(String password) {
|
||||||
|
String hex = loadEncryptedDatabaseKey();
|
||||||
|
if (hex == null) {
|
||||||
|
LOG.warning("Failed to load encrypted database key");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
byte[] ciphertext = fromHexString(hex);
|
||||||
|
byte[] plaintext = crypto.decryptWithPassword(ciphertext, password);
|
||||||
|
if (plaintext == null) {
|
||||||
|
LOG.info("Failed to decrypt database key");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new SecretKey(plaintext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean changePassword(String oldPassword, String newPassword) {
|
||||||
|
SecretKey key = loadAndDecryptDatabaseKey(oldPassword);
|
||||||
|
return key != null && encryptAndStoreDatabaseKey(key, newPassword);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.bramble.account;
|
package org.briarproject.bramble.account;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.bramble.api.db.DatabaseConfig;
|
import org.briarproject.bramble.api.db.DatabaseConfig;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
@@ -29,6 +30,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
private final DatabaseConfig databaseConfig =
|
private final DatabaseConfig databaseConfig =
|
||||||
context.mock(DatabaseConfig.class);
|
context.mock(DatabaseConfig.class);
|
||||||
|
private final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
||||||
|
|
||||||
private final byte[] encryptedKey = getRandomBytes(123);
|
private final byte[] encryptedKey = getRandomBytes(123);
|
||||||
private final String encryptedKeyHex = toHexString(encryptedKey);
|
private final String encryptedKeyHex = toHexString(encryptedKey);
|
||||||
@@ -46,7 +48,8 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
allowing(databaseConfig).getDatabaseKeyDirectory();
|
allowing(databaseConfig).getDatabaseKeyDirectory();
|
||||||
will(returnValue(keyDir));
|
will(returnValue(keyDir));
|
||||||
}});
|
}});
|
||||||
accountManager = new AccountManagerImpl(databaseConfig);
|
assertTrue(keyDir.mkdirs());
|
||||||
|
accountManager = new AccountManagerImpl(databaseConfig, crypto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -60,7 +63,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertFalse(keyBackupFile.exists());
|
assertFalse(keyBackupFile.exists());
|
||||||
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
|
assertEquals(encryptedKeyHex, loadDatabaseKey(keyFile));
|
||||||
|
|
||||||
assertEquals(encryptedKeyHex, accountManager.getEncryptedDatabaseKey());
|
assertEquals(encryptedKeyHex, accountManager.loadEncryptedDatabaseKey());
|
||||||
|
|
||||||
assertTrue(keyFile.exists());
|
assertTrue(keyFile.exists());
|
||||||
assertFalse(keyBackupFile.exists());
|
assertFalse(keyBackupFile.exists());
|
||||||
@@ -78,7 +81,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertTrue(keyBackupFile.exists());
|
assertTrue(keyBackupFile.exists());
|
||||||
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
|
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
|
||||||
|
|
||||||
assertEquals(encryptedKeyHex, accountManager.getEncryptedDatabaseKey());
|
assertEquals(encryptedKeyHex, accountManager.loadEncryptedDatabaseKey());
|
||||||
|
|
||||||
assertFalse(keyFile.exists());
|
assertFalse(keyFile.exists());
|
||||||
assertTrue(keyBackupFile.exists());
|
assertTrue(keyBackupFile.exists());
|
||||||
@@ -90,7 +93,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertFalse(keyFile.exists());
|
assertFalse(keyFile.exists());
|
||||||
assertFalse(keyBackupFile.exists());
|
assertFalse(keyBackupFile.exists());
|
||||||
|
|
||||||
assertNull(accountManager.getEncryptedDatabaseKey());
|
assertNull(accountManager.loadEncryptedDatabaseKey());
|
||||||
|
|
||||||
assertFalse(keyFile.exists());
|
assertFalse(keyFile.exists());
|
||||||
assertFalse(keyBackupFile.exists());
|
assertFalse(keyBackupFile.exists());
|
||||||
@@ -134,13 +137,7 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
|
assertEquals(encryptedKeyHex, loadDatabaseKey(keyBackupFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
deleteTestDirectory(testDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void storeDatabaseKey(File f, String hex) throws IOException {
|
private void storeDatabaseKey(File f, String hex) throws IOException {
|
||||||
f.getParentFile().mkdirs();
|
|
||||||
FileOutputStream out = new FileOutputStream(f);
|
FileOutputStream out = new FileOutputStream(f);
|
||||||
out.write(hex.getBytes("UTF-8"));
|
out.write(hex.getBytes("UTF-8"));
|
||||||
out.flush();
|
out.flush();
|
||||||
@@ -155,4 +152,9 @@ public class AccountManagerImplTest extends BrambleMockTestCase {
|
|||||||
reader.close();
|
reader.close();
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
deleteTestDirectory(testDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public interface PasswordController {
|
|||||||
void validatePassword(String password,
|
void validatePassword(String password,
|
||||||
ResultHandler<Boolean> resultHandler);
|
ResultHandler<Boolean> resultHandler);
|
||||||
|
|
||||||
void changePassword(String password, String newPassword,
|
void changePassword(String oldPassword, String newPassword,
|
||||||
ResultHandler<Boolean> resultHandler);
|
ResultHandler<Boolean> resultHandler);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,28 @@
|
|||||||
package org.briarproject.briar.android.login;
|
package org.briarproject.briar.android.login;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
|
||||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
|
||||||
import org.briarproject.briar.android.controller.handler.ResultHandler;
|
import org.briarproject.briar.android.controller.handler.ResultHandler;
|
||||||
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.logDuration;
|
|
||||||
import static org.briarproject.bramble.util.LogUtils.now;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class PasswordControllerImpl implements PasswordController {
|
public class PasswordControllerImpl implements PasswordController {
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(PasswordControllerImpl.class.getName());
|
|
||||||
|
|
||||||
protected final AccountManager accountManager;
|
protected final AccountManager accountManager;
|
||||||
protected final Executor cryptoExecutor;
|
protected final Executor ioExecutor;
|
||||||
protected final CryptoComponent crypto;
|
|
||||||
private final PasswordStrengthEstimator strengthEstimator;
|
private final PasswordStrengthEstimator strengthEstimator;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
PasswordControllerImpl(AccountManager accountManager,
|
PasswordControllerImpl(AccountManager accountManager,
|
||||||
@CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto,
|
@IoExecutor Executor ioExecutor,
|
||||||
PasswordStrengthEstimator strengthEstimator) {
|
PasswordStrengthEstimator strengthEstimator) {
|
||||||
this.accountManager = accountManager;
|
this.accountManager = accountManager;
|
||||||
this.cryptoExecutor = cryptoExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.crypto = crypto;
|
|
||||||
this.strengthEstimator = strengthEstimator;
|
this.strengthEstimator = strengthEstimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,47 +34,17 @@ public class PasswordControllerImpl implements PasswordController {
|
|||||||
@Override
|
@Override
|
||||||
public void validatePassword(String password,
|
public void validatePassword(String password,
|
||||||
ResultHandler<Boolean> resultHandler) {
|
ResultHandler<Boolean> resultHandler) {
|
||||||
byte[] encrypted = getEncryptedKey();
|
ioExecutor.execute(() ->
|
||||||
cryptoExecutor.execute(() -> {
|
resultHandler.onResult(accountManager.signIn(password)));
|
||||||
byte[] key = crypto.decryptWithPassword(encrypted, password);
|
|
||||||
if (key == null) {
|
|
||||||
resultHandler.onResult(false);
|
|
||||||
} else {
|
|
||||||
accountManager.setDatabaseKey(new SecretKey(key));
|
|
||||||
resultHandler.onResult(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void changePassword(String password, String newPassword,
|
public void changePassword(String oldPassword, String newPassword,
|
||||||
ResultHandler<Boolean> resultHandler) {
|
ResultHandler<Boolean> resultHandler) {
|
||||||
byte[] encrypted = getEncryptedKey();
|
ioExecutor.execute(() -> {
|
||||||
cryptoExecutor.execute(() -> {
|
boolean changed =
|
||||||
byte[] key = crypto.decryptWithPassword(encrypted, password);
|
accountManager.changePassword(oldPassword, newPassword);
|
||||||
if (key == null) {
|
resultHandler.onResult(changed);
|
||||||
resultHandler.onResult(false);
|
|
||||||
} else {
|
|
||||||
String hex =
|
|
||||||
encryptDatabaseKey(new SecretKey(key), newPassword);
|
|
||||||
boolean stored = accountManager.storeEncryptedDatabaseKey(hex);
|
|
||||||
resultHandler.onResult(stored);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getEncryptedKey() {
|
|
||||||
String hex = accountManager.getEncryptedDatabaseKey();
|
|
||||||
if (hex == null)
|
|
||||||
throw new IllegalStateException("Encrypted database key is null");
|
|
||||||
return StringUtils.fromHexString(hex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@CryptoExecutor
|
|
||||||
String encryptDatabaseKey(SecretKey key, String password) {
|
|
||||||
long start = now();
|
|
||||||
byte[] encrypted = crypto.encryptWithPassword(key.getBytes(), password);
|
|
||||||
logDuration(LOG, "Key derivation", start);
|
|
||||||
return StringUtils.toHexString(encrypted);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,10 @@ package org.briarproject.briar.android.login;
|
|||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.CryptoExecutor;
|
|
||||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.android.controller.handler.ResultHandler;
|
import org.briarproject.briar.android.controller.handler.ResultHandler;
|
||||||
import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
import org.briarproject.briar.android.controller.handler.UiResultHandler;
|
||||||
@@ -32,10 +30,10 @@ public class SetupControllerImpl extends PasswordControllerImpl
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SetupControllerImpl(AccountManager accountManager,
|
SetupControllerImpl(AccountManager accountManager,
|
||||||
@CryptoExecutor Executor cryptoExecutor, CryptoComponent crypto,
|
@IoExecutor Executor ioExecutor,
|
||||||
PasswordStrengthEstimator strengthEstimator,
|
PasswordStrengthEstimator strengthEstimator,
|
||||||
IdentityManager identityManager) {
|
IdentityManager identityManager) {
|
||||||
super(accountManager, cryptoExecutor, crypto, strengthEstimator);
|
super(accountManager, ioExecutor, strengthEstimator);
|
||||||
this.identityManager = identityManager;
|
this.identityManager = identityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,10 +81,10 @@ public class SetupControllerImpl extends PasswordControllerImpl
|
|||||||
@Override
|
@Override
|
||||||
public void createAccount() {
|
public void createAccount() {
|
||||||
SetupActivity setupActivity = this.setupActivity;
|
SetupActivity setupActivity = this.setupActivity;
|
||||||
UiResultHandler<Void> resultHandler =
|
UiResultHandler<Boolean> resultHandler =
|
||||||
new UiResultHandler<Void>(setupActivity) {
|
new UiResultHandler<Boolean>(setupActivity) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(Void result) {
|
public void onResultUi(Boolean result) {
|
||||||
if (setupActivity == null)
|
if (setupActivity == null)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
setupActivity.showApp();
|
setupActivity.showApp();
|
||||||
@@ -96,23 +94,19 @@ public class SetupControllerImpl extends PasswordControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Package access for testing
|
// Package access for testing
|
||||||
void createAccount(ResultHandler<Void> resultHandler) {
|
void createAccount(ResultHandler<Boolean> resultHandler) {
|
||||||
SetupActivity setupActivity = this.setupActivity;
|
SetupActivity setupActivity = this.setupActivity;
|
||||||
if (setupActivity == null) throw new IllegalStateException();
|
if (setupActivity == null) throw new IllegalStateException();
|
||||||
String authorName = setupActivity.getAuthorName();
|
String authorName = setupActivity.getAuthorName();
|
||||||
if (authorName == null) throw new IllegalStateException();
|
if (authorName == null) throw new IllegalStateException();
|
||||||
String password = setupActivity.getPassword();
|
String password = setupActivity.getPassword();
|
||||||
if (password == null) throw new IllegalStateException();
|
if (password == null) throw new IllegalStateException();
|
||||||
cryptoExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
LOG.info("Creating account");
|
LOG.info("Creating account");
|
||||||
LocalAuthor localAuthor =
|
LocalAuthor localAuthor =
|
||||||
identityManager.createLocalAuthor(authorName);
|
identityManager.createLocalAuthor(authorName);
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.registerLocalAuthor(localAuthor);
|
||||||
SecretKey key = crypto.generateSecretKey();
|
resultHandler.onResult(accountManager.createAccount(password));
|
||||||
String hex = encryptDatabaseKey(key, password);
|
|
||||||
accountManager.storeEncryptedDatabaseKey(hex);
|
|
||||||
accountManager.setDatabaseKey(key);
|
|
||||||
resultHandler.onResult(null);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.briar.android.login;
|
package org.briarproject.briar.android.login;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||||
@@ -13,46 +12,28 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
import static junit.framework.Assert.assertFalse;
|
import static junit.framework.Assert.assertFalse;
|
||||||
import static junit.framework.Assert.assertTrue;
|
import static junit.framework.Assert.assertTrue;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
public class PasswordControllerImplTest extends BrambleMockTestCase {
|
public class PasswordControllerImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
private final AccountManager accountManager =
|
private final AccountManager accountManager =
|
||||||
context.mock(AccountManager.class);
|
context.mock(AccountManager.class);
|
||||||
private final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
|
||||||
private final PasswordStrengthEstimator estimator =
|
private final PasswordStrengthEstimator estimator =
|
||||||
context.mock(PasswordStrengthEstimator.class);
|
context.mock(PasswordStrengthEstimator.class);
|
||||||
|
|
||||||
private final Executor cryptoExecutor = new ImmediateExecutor();
|
private final Executor ioExecutor = new ImmediateExecutor();
|
||||||
|
|
||||||
private final String oldPassword = "some.old.pass";
|
private final String oldPassword = "some.old.pass";
|
||||||
private final String newPassword = "some.new.pass";
|
private final String newPassword = "some.new.pass";
|
||||||
private final byte[] oldEncryptedKey = getRandomBytes(123);
|
|
||||||
private final byte[] newEncryptedKey = getRandomBytes(123);
|
|
||||||
private final byte[] key = getSecretKey().getBytes();
|
|
||||||
private final String oldEncryptedKeyHex = toHexString(oldEncryptedKey);
|
|
||||||
private final String newEncryptedKeyHex = toHexString(newEncryptedKey);
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChangePasswordReturnsTrue() {
|
public void testChangePasswordReturnsTrue() {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// Look up the encrypted DB key
|
oneOf(accountManager).changePassword(oldPassword, newPassword);
|
||||||
oneOf(accountManager).getEncryptedDatabaseKey();
|
|
||||||
will(returnValue(oldEncryptedKeyHex));
|
|
||||||
// Decrypt and re-encrypt the key
|
|
||||||
oneOf(crypto).decryptWithPassword(oldEncryptedKey, oldPassword);
|
|
||||||
will(returnValue(key));
|
|
||||||
oneOf(crypto).encryptWithPassword(key, newPassword);
|
|
||||||
will(returnValue(newEncryptedKey));
|
|
||||||
// Store the new key
|
|
||||||
oneOf(accountManager).storeEncryptedDatabaseKey(newEncryptedKeyHex);
|
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
PasswordControllerImpl p = new PasswordControllerImpl(accountManager,
|
PasswordControllerImpl p = new PasswordControllerImpl(accountManager,
|
||||||
cryptoExecutor, crypto, estimator);
|
ioExecutor, estimator);
|
||||||
|
|
||||||
AtomicBoolean capturedResult = new AtomicBoolean(false);
|
AtomicBoolean capturedResult = new AtomicBoolean(false);
|
||||||
p.changePassword(oldPassword, newPassword, capturedResult::set);
|
p.changePassword(oldPassword, newPassword, capturedResult::set);
|
||||||
@@ -62,16 +43,12 @@ public class PasswordControllerImplTest extends BrambleMockTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testChangePasswordReturnsFalseIfOldPasswordIsWrong() {
|
public void testChangePasswordReturnsFalseIfOldPasswordIsWrong() {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
// Look up the encrypted DB key
|
oneOf(accountManager).changePassword(oldPassword, newPassword);
|
||||||
oneOf(accountManager).getEncryptedDatabaseKey();
|
will(returnValue(false));
|
||||||
will(returnValue(oldEncryptedKeyHex));
|
|
||||||
// Try to decrypt the key - the password is wrong
|
|
||||||
oneOf(crypto).decryptWithPassword(oldEncryptedKey, oldPassword);
|
|
||||||
will(returnValue(null));
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
PasswordControllerImpl p = new PasswordControllerImpl(accountManager,
|
PasswordControllerImpl p = new PasswordControllerImpl(accountManager,
|
||||||
cryptoExecutor, crypto, estimator);
|
ioExecutor, estimator);
|
||||||
|
|
||||||
AtomicBoolean capturedResult = new AtomicBoolean(true);
|
AtomicBoolean capturedResult = new AtomicBoolean(true);
|
||||||
p.changePassword(oldPassword, newPassword, capturedResult::set);
|
p.changePassword(oldPassword, newPassword, capturedResult::set);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
package org.briarproject.briar.android.login;
|
package org.briarproject.briar.android.login;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator;
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
@@ -18,30 +16,23 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
import static junit.framework.Assert.assertTrue;
|
import static junit.framework.Assert.assertTrue;
|
||||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
import static org.briarproject.bramble.test.TestUtils.getLocalAuthor;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
|
|
||||||
public class SetupControllerImplTest extends BrambleMockTestCase {
|
public class SetupControllerImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
private final AccountManager accountManager =
|
private final AccountManager accountManager =
|
||||||
context.mock(AccountManager.class);
|
context.mock(AccountManager.class);
|
||||||
private final CryptoComponent crypto = context.mock(CryptoComponent.class);
|
|
||||||
private final PasswordStrengthEstimator estimator =
|
private final PasswordStrengthEstimator estimator =
|
||||||
context.mock(PasswordStrengthEstimator.class);
|
context.mock(PasswordStrengthEstimator.class);
|
||||||
private final IdentityManager identityManager =
|
private final IdentityManager identityManager =
|
||||||
context.mock(IdentityManager.class);
|
context.mock(IdentityManager.class);
|
||||||
private final SetupActivity setupActivity;
|
private final SetupActivity setupActivity;
|
||||||
|
|
||||||
private final Executor cryptoExecutor = new ImmediateExecutor();
|
private final Executor ioExecutor = new ImmediateExecutor();
|
||||||
|
|
||||||
private final String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
private final String authorName = getRandomString(MAX_AUTHOR_NAME_LENGTH);
|
||||||
private final String password = "some.strong.pass";
|
private final String password = "some.strong.pass";
|
||||||
private final LocalAuthor localAuthor = getLocalAuthor();
|
private final LocalAuthor localAuthor = getLocalAuthor();
|
||||||
private final byte[] encryptedKey = getRandomBytes(123);
|
|
||||||
private final String encryptedKeyHex = toHexString(encryptedKey);
|
|
||||||
private final SecretKey key = getSecretKey();
|
|
||||||
|
|
||||||
public SetupControllerImplTest() {
|
public SetupControllerImplTest() {
|
||||||
context.setImposteriser(ClassImposteriser.INSTANCE);
|
context.setImposteriser(ClassImposteriser.INSTANCE);
|
||||||
@@ -64,21 +55,13 @@ public class SetupControllerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(identityManager).createLocalAuthor(authorName);
|
oneOf(identityManager).createLocalAuthor(authorName);
|
||||||
will(returnValue(localAuthor));
|
will(returnValue(localAuthor));
|
||||||
oneOf(identityManager).registerLocalAuthor(localAuthor);
|
oneOf(identityManager).registerLocalAuthor(localAuthor);
|
||||||
// Generate a database key
|
// Create the account
|
||||||
oneOf(crypto).generateSecretKey();
|
oneOf(accountManager).createAccount(password);
|
||||||
will(returnValue(key));
|
|
||||||
// Encrypt the key with the password
|
|
||||||
oneOf(crypto).encryptWithPassword(key.getBytes(), password);
|
|
||||||
will(returnValue(encryptedKey));
|
|
||||||
// Store the encrypted key
|
|
||||||
oneOf(accountManager).storeEncryptedDatabaseKey(encryptedKeyHex);
|
|
||||||
will(returnValue(true));
|
will(returnValue(true));
|
||||||
// Pass the database key to the account manager
|
|
||||||
oneOf(accountManager).setDatabaseKey(key);
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
SetupControllerImpl s = new SetupControllerImpl(accountManager,
|
SetupControllerImpl s = new SetupControllerImpl(accountManager,
|
||||||
cryptoExecutor, crypto, estimator, identityManager);
|
ioExecutor, estimator, identityManager);
|
||||||
s.setSetupActivity(setupActivity);
|
s.setSetupActivity(setupActivity);
|
||||||
|
|
||||||
AtomicBoolean called = new AtomicBoolean(false);
|
AtomicBoolean called = new AtomicBoolean(false);
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import org.junit.Test;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getSecretKey;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -54,7 +53,7 @@ public class FeedManagerIntegrationTest extends BriarTestCase {
|
|||||||
LocalAuthor localAuthor = identityManager.createLocalAuthor("feedTest");
|
LocalAuthor localAuthor = identityManager.createLocalAuthor("feedTest");
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.registerLocalAuthor(localAuthor);
|
||||||
|
|
||||||
component.getAccountManager().setDatabaseKey(getSecretKey());
|
component.getAccountManager().createAccount("password");
|
||||||
|
|
||||||
lifecycleManager = component.getLifecycleManager();
|
lifecycleManager = component.getLifecycleManager();
|
||||||
lifecycleManager.startServices();
|
lifecycleManager.startServices();
|
||||||
|
|||||||
@@ -100,11 +100,11 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
private ContactId setUp(SimplexMessagingIntegrationTestComponent device,
|
private ContactId setUp(SimplexMessagingIntegrationTestComponent device,
|
||||||
LocalAuthor local, Author remote, boolean alice) throws Exception {
|
LocalAuthor local, Author remote, boolean alice) throws Exception {
|
||||||
// Create a database key
|
|
||||||
device.getAccountManager().setDatabaseKey(getSecretKey());
|
|
||||||
// Add an identity for the user
|
// Add an identity for the user
|
||||||
IdentityManager identityManager = device.getIdentityManager();
|
IdentityManager identityManager = device.getIdentityManager();
|
||||||
identityManager.registerLocalAuthor(local);
|
identityManager.registerLocalAuthor(local);
|
||||||
|
// Create an account
|
||||||
|
device.getAccountManager().createAccount("password");
|
||||||
// Start the lifecycle manager
|
// Start the lifecycle manager
|
||||||
LifecycleManager lifecycleManager = device.getLifecycleManager();
|
LifecycleManager lifecycleManager = device.getLifecycleManager();
|
||||||
lifecycleManager.startServices();
|
lifecycleManager.startServices();
|
||||||
|
|||||||
@@ -140,9 +140,9 @@ public abstract class BriarIntegrationTest<C extends BriarIntegrationTestCompone
|
|||||||
assertTrue(testDir.mkdirs());
|
assertTrue(testDir.mkdirs());
|
||||||
createComponents();
|
createComponents();
|
||||||
|
|
||||||
c0.getAccountManager().setDatabaseKey(getSecretKey());
|
c0.getAccountManager().createAccount("password");
|
||||||
c1.getAccountManager().setDatabaseKey(getSecretKey());
|
c1.getAccountManager().createAccount("password");
|
||||||
c2.getAccountManager().setDatabaseKey(getSecretKey());
|
c2.getAccountManager().createAccount("password");
|
||||||
identityManager0 = c0.getIdentityManager();
|
identityManager0 = c0.getIdentityManager();
|
||||||
identityManager1 = c1.getIdentityManager();
|
identityManager1 = c1.getIdentityManager();
|
||||||
identityManager2 = c2.getIdentityManager();
|
identityManager2 = c2.getIdentityManager();
|
||||||
|
|||||||
Reference in New Issue
Block a user