diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationStoreIntegrationShould.java similarity index 52% rename from core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreIntegrationShould.java rename to core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationStoreIntegrationShould.java index 08b2490101..bb4245ca73 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationStoreIntegrationShould.java @@ -28,62 +28,21 @@ package org.hisp.dhis.android.core.configuration.internal; -import android.content.Context; - -import androidx.test.InstrumentationRegistry; - -import org.hisp.dhis.android.core.arch.storage.internal.AndroidSecureStore; -import org.hisp.dhis.android.core.arch.storage.internal.ObjectKeyValueStore; import org.hisp.dhis.android.core.data.configuration.ConfigurationSamples; +import org.hisp.dhis.android.core.data.database.ObjectStoreAbstractIntegrationShould; +import org.hisp.dhis.android.core.utils.integration.mock.TestDatabaseAdapterFactory; import org.hisp.dhis.android.core.utils.runner.D2JunitRunner; -import org.junit.Before; -import org.junit.Test; import org.junit.runner.RunWith; -import java.io.IOException; - -import okhttp3.HttpUrl; - -import static com.google.common.truth.Truth.assertThat; - @RunWith(D2JunitRunner.class) -public class ConfigurationSecureStoreIntegrationShould { - - private final Configuration configuration; - private final ObjectKeyValueStore configurationSecureStore; - - public ConfigurationSecureStoreIntegrationShould() { - Context context = InstrumentationRegistry.getTargetContext().getApplicationContext(); - this.configurationSecureStore = new ConfigurationSecureStoreImpl(new AndroidSecureStore(context)); - this.configuration = buildObject(); - } - - @Before - public void setUp() throws IOException { - configurationSecureStore.remove(); - } - - @Test - public void configure_and_get() { - configurationSecureStore.set(configuration); - Configuration objectFromDb = configurationSecureStore.get(); - assertThat(objectFromDb.serverUrl()).isEqualTo(HttpUrl.parse("http://testserver.org/api/")); - } - - @Test - public void configure_and_remove() { - configurationSecureStore.set(configuration); - configurationSecureStore.remove(); - assertThat(configurationSecureStore.get()).isNull(); - } +public class ConfigurationStoreIntegrationShould extends ObjectStoreAbstractIntegrationShould { - @Test - public void overwrite_and_not_fail_in_a_consecutive_configuration() { - configurationSecureStore.set(configuration); - configurationSecureStore.set(configuration); - assertThat(configurationSecureStore.get()).isNotNull(); + public ConfigurationStoreIntegrationShould() { + super(ConfigurationStore.create(TestDatabaseAdapterFactory.get()), + ConfigurationTableInfo.TABLE_INFO, TestDatabaseAdapterFactory.get()); } + @Override protected Configuration buildObject() { return ConfigurationSamples.getConfiguration(); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigrationIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigrationIntegrationShould.java index 8eeb01f55b..57746aaac0 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigrationIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigrationIntegrationShould.java @@ -34,11 +34,11 @@ import org.hisp.dhis.android.core.arch.db.access.DatabaseAdapter; import org.hisp.dhis.android.core.arch.db.access.internal.DatabaseAdapterFactory; +import org.hisp.dhis.android.core.arch.db.stores.internal.ObjectStore; import org.hisp.dhis.android.core.arch.storage.internal.InMemorySecureStore; import org.hisp.dhis.android.core.arch.storage.internal.InMemoryUnsecureStore; import org.hisp.dhis.android.core.arch.storage.internal.InsecureStore; import org.hisp.dhis.android.core.arch.storage.internal.ObjectKeyValueStore; -import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; import org.hisp.dhis.android.core.common.ObjectWithUid; import org.hisp.dhis.android.core.user.UserCredentials; import org.hisp.dhis.android.core.user.internal.UserCredentialsStore; @@ -51,8 +51,6 @@ import java.io.IOException; import java.util.Arrays; -import okhttp3.HttpUrl; - import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.configuration.internal.DatabaseConfigurationMigration.OLD_DBNAME; @@ -79,16 +77,13 @@ public class DatabaseConfigurationMigrationIntegrationShould { .user(ObjectWithUid.create("user")) .build(); - private ObjectKeyValueStore oldConfigurationStore; private ObjectKeyValueStore newConfigurationStore; @Before public void setUp() throws IOException { - SecureStore secureStore = new InMemorySecureStore(); InsecureStore insecureStore = new InMemoryUnsecureStore(); - oldConfigurationStore = new ConfigurationSecureStoreImpl(secureStore); newConfigurationStore = DatabaseConfigurationInsecureStore.get(insecureStore); - migration = new DatabaseConfigurationMigration(context, oldConfigurationStore, newConfigurationStore, + migration = new DatabaseConfigurationMigration(context, newConfigurationStore, transformer, nameGenerator, renamer, databaseAdapterFactory); } @@ -96,7 +91,6 @@ public void setUp() throws IOException { public void delete_empty_database() { DatabaseAdapter databaseAdapter = databaseAdapterFactory.newParentDatabaseAdapter(); databaseAdapterFactory.createOrOpenDatabase(databaseAdapter, OLD_DBNAME, false); - oldConfigurationStore.set(Configuration.forServerUrl(HttpUrl.parse(URL_STR))); assertThat(Arrays.asList(context.databaseList()).contains(OLD_DBNAME)).isTrue(); migration.apply(); @@ -107,8 +101,7 @@ public void delete_empty_database() { public void rename_database_with_credentials() { DatabaseAdapter databaseAdapter = databaseAdapterFactory.newParentDatabaseAdapter(); databaseAdapterFactory.createOrOpenDatabase(databaseAdapter, OLD_DBNAME, false); - oldConfigurationStore.set(Configuration.forServerUrl(HttpUrl.parse(URL_STR))); - setCredentials(databaseAdapter); + setCredentialsAndServerUrl(databaseAdapter); assertThat(Arrays.asList(context.databaseList()).contains(OLD_DBNAME)).isTrue(); migration.apply(); @@ -138,20 +131,16 @@ public void return_existing_new_configuration_if_old_configuration_null() { public void return_empty_new_configuration_if_existing_empty_database() { DatabaseAdapter databaseAdapter = databaseAdapterFactory.newParentDatabaseAdapter(); databaseAdapterFactory.createOrOpenDatabase(databaseAdapter, OLD_DBNAME, false); - oldConfigurationStore.set(Configuration.forServerUrl(HttpUrl.parse(URL_STR))); assertThat(migration.apply()).isNull(); } - @Test - public void delete_old_configuration_after_applying_migration() { - oldConfigurationStore.set(Configuration.forServerUrl(HttpUrl.parse(URL_STR))); - assertThat(migration.apply()).isNull(); - assertThat(oldConfigurationStore.get()).isNull(); - } + public void setCredentialsAndServerUrl(DatabaseAdapter databaseAdapter) { + databaseAdapter.setForeignKeyConstraintsEnabled(false); - public void setCredentials(DatabaseAdapter databaseAdapter) { UserCredentialsStore credentialsStore = UserCredentialsStoreImpl.create(databaseAdapter); - databaseAdapter.setForeignKeyConstraintsEnabled(false); credentialsStore.insert(credentials); + + ObjectStore configurationStore = ConfigurationStore.create(databaseAdapter); + configurationStore.insert(Configuration.forServerUrl(URL_STR)); } } \ No newline at end of file diff --git a/core/src/main/assets/migrations/66.sql b/core/src/main/assets/migrations/66.sql index 4a185940a7..e69de29bb2 100644 --- a/core/src/main/assets/migrations/66.sql +++ b/core/src/main/assets/migrations/66.sql @@ -1 +0,0 @@ -DROP TABLE IF EXISTS Configuration; \ No newline at end of file diff --git a/core/src/main/assets/snapshots/71.sql b/core/src/main/assets/snapshots/71.sql index a85e4e417b..92a482f7a6 100644 --- a/core/src/main/assets/snapshots/71.sql +++ b/core/src/main/assets/snapshots/71.sql @@ -1,3 +1,4 @@ +CREATE TABLE Configuration (_id INTEGER PRIMARY KEY AUTOINCREMENT, serverUrl TEXT NOT NULL UNIQUE); CREATE TABLE User (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, birthday TEXT, education TEXT, gender TEXT, jobTitle TEXT, surname TEXT, firstName TEXT, introduction TEXT, employer TEXT, interests TEXT, languages TEXT, email TEXT, phoneNumber TEXT, nationality TEXT); CREATE TABLE UserCredentials (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, username TEXT, user TEXT NOT NULL UNIQUE, FOREIGN KEY (user) REFERENCES User (uid) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED); CREATE TABLE OrganisationUnit (_id INTEGER PRIMARY KEY AUTOINCREMENT, uid TEXT NOT NULL UNIQUE, code TEXT, name TEXT, displayName TEXT, created TEXT, lastUpdated TEXT, shortName TEXT, displayShortName TEXT, description TEXT, displayDescription TEXT, path TEXT, openingDate TEXT, closedDate TEXT, level INTEGER, parent TEXT, displayNamePath TEXT, geometryType TEXT, geometryCoordinates TEXT); diff --git a/core/src/main/java/org/hisp/dhis/android/core/D2Manager.java b/core/src/main/java/org/hisp/dhis/android/core/D2Manager.java index e46da63ee5..4322c89ac7 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/D2Manager.java +++ b/core/src/main/java/org/hisp/dhis/android/core/D2Manager.java @@ -113,7 +113,7 @@ public static Single instantiateD2(@NonNull D2Configuration d2Config) { } ObjectKeyValueStore credentialsSecureStore = new CredentialsSecureStoreImpl(secureStore); - MultiUserDatabaseManagerForD2Manager.create(databaseAdapter, d2Config.context(), secureStore, insecureStore, + MultiUserDatabaseManagerForD2Manager.create(databaseAdapter, d2Config.context(), insecureStore, databaseAdapterFactory) .loadIfLogged(credentialsSecureStore.get()); diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/Configuration.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/Configuration.java index c2d17dd9e0..2a757a1916 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/Configuration.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/Configuration.java @@ -28,17 +28,29 @@ package org.hisp.dhis.android.core.configuration.internal; +import android.database.Cursor; + import androidx.annotation.NonNull; import com.google.auto.value.AutoValue; -import okhttp3.HttpUrl; +import org.hisp.dhis.android.core.common.BaseObject; +import org.hisp.dhis.android.core.common.CoreObject; +/** + * Old configuration class. Needs to be kept for migration from SDK version previous to 1.1.0 + * Use {@link DatabasesConfiguration} instead. + */ @AutoValue -public abstract class Configuration { +@Deprecated +public abstract class Configuration implements CoreObject { @NonNull - public abstract HttpUrl serverUrl(); + public abstract String serverUrl(); + + public static Configuration create(Cursor cursor) { + return $AutoValue_Configuration.createFromCursor(cursor); + } public abstract Builder toBuilder(); @@ -47,13 +59,15 @@ public static Builder builder() { } @AutoValue.Builder - public abstract static class Builder { - public abstract Builder serverUrl(HttpUrl serverUrl); + public abstract static class Builder extends BaseObject.Builder { + public abstract Builder id(Long id); + + public abstract Builder serverUrl(String serverUrl); public abstract Configuration build(); } - public static Configuration forServerUrl(HttpUrl url) { + static Configuration forServerUrl(String url) { return Configuration.builder().serverUrl(url).build(); } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationPackageDIModule.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationPackageDIModule.java index 1229575b96..c69c56e9d5 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationPackageDIModule.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationPackageDIModule.java @@ -28,9 +28,6 @@ package org.hisp.dhis.android.core.configuration.internal; -import android.content.Context; - -import org.hisp.dhis.android.core.arch.db.access.internal.DatabaseAdapterFactory; import org.hisp.dhis.android.core.arch.storage.internal.InsecureStore; import org.hisp.dhis.android.core.arch.storage.internal.ObjectKeyValueStore; import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; @@ -62,14 +59,6 @@ DatabaseEncryptionPasswordManager passwordManager(SecureStore secureStore) { return DatabaseEncryptionPasswordManager.create(secureStore); } - @Provides - @Reusable - DatabaseConfigurationMigration configurationMigration(Context context, SecureStore secureStore, - InsecureStore insecureStore, - DatabaseAdapterFactory adapterFactory) { - return DatabaseConfigurationMigration.create(context, secureStore, insecureStore, adapterFactory); - } - @Provides @Reusable ConstantModule module(ConstantModuleImpl impl) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationStore.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationStore.java new file mode 100644 index 0000000000..86e57c6b20 --- /dev/null +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationStore.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.hisp.dhis.android.core.configuration.internal; + +import org.hisp.dhis.android.core.arch.db.access.DatabaseAdapter; +import org.hisp.dhis.android.core.arch.db.stores.binders.internal.StatementBinder; +import org.hisp.dhis.android.core.arch.db.stores.internal.ObjectStore; +import org.hisp.dhis.android.core.arch.db.stores.internal.StoreFactory; + +final class ConfigurationStore { + + private static final StatementBinder BINDER = (o, w) -> + w.bind(1, o.serverUrl()); + + private ConfigurationStore() { + } + + static ObjectStore create(DatabaseAdapter databaseAdapter) { + return StoreFactory.objectStore(databaseAdapter, ConfigurationTableInfo.TABLE_INFO, BINDER, + Configuration::create); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreImpl.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationTableInfo.java similarity index 59% rename from core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreImpl.java rename to core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationTableInfo.java index 8d01651c0a..d34f151705 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreImpl.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationTableInfo.java @@ -28,42 +28,43 @@ package org.hisp.dhis.android.core.configuration.internal; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import org.hisp.dhis.android.core.arch.db.tableinfos.TableInfo; +import org.hisp.dhis.android.core.arch.helpers.CollectionsHelper; +import org.hisp.dhis.android.core.common.CoreColumns; -import org.hisp.dhis.android.core.arch.storage.internal.ObjectKeyValueStore; -import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; +final class ConfigurationTableInfo { -import okhttp3.HttpUrl; - -public final class ConfigurationSecureStoreImpl implements ObjectKeyValueStore { - - private static final String SERVER_URL = "server_url"; + private ConfigurationTableInfo() { + } - private final SecureStore secureStore; + public static final TableInfo TABLE_INFO = new TableInfo() { - public ConfigurationSecureStoreImpl(@NonNull SecureStore secureStore) { - this.secureStore = secureStore; - } + @Override + public String name() { + return "Configuration"; + } - @Override - public void set(@NonNull Configuration configuration) { - if (configuration == null) { - throw new IllegalArgumentException("configuration == null"); + @Override + public CoreColumns columns() { + return new Columns(); } + }; - secureStore.setData(SERVER_URL, configuration.serverUrl().toString()); - } + public static class Columns extends CoreColumns { + static final String SERVER_URL = "serverUrl"; - @Nullable - @Override - public Configuration get() { - String serverUrl = secureStore.getData(SERVER_URL); - return serverUrl == null ? null : Configuration.forServerUrl(HttpUrl.parse(serverUrl)); - } + @Override + public String[] all() { + return CollectionsHelper.appendInNewArray(super.all(), + SERVER_URL + ); + } - @Override - public void remove() { - secureStore.removeData(SERVER_URL); + @Override + public String[] whereUpdate() { + return CollectionsHelper.appendInNewArray(super.whereUpdate(), + SERVER_URL + ); + } } } \ No newline at end of file diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigration.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigration.java index 0ae0934e4c..a8a9b16342 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigration.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationMigration.java @@ -32,19 +32,20 @@ import org.hisp.dhis.android.core.arch.db.access.DatabaseAdapter; import org.hisp.dhis.android.core.arch.db.access.internal.DatabaseAdapterFactory; +import org.hisp.dhis.android.core.arch.db.stores.internal.ObjectStore; import org.hisp.dhis.android.core.arch.storage.internal.InsecureStore; import org.hisp.dhis.android.core.arch.storage.internal.ObjectKeyValueStore; -import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; import org.hisp.dhis.android.core.user.UserCredentials; import org.hisp.dhis.android.core.user.internal.UserCredentialsStore; import org.hisp.dhis.android.core.user.internal.UserCredentialsStoreImpl; +import java.util.Arrays; + class DatabaseConfigurationMigration { static final String OLD_DBNAME = "dhis.db"; private final Context context; - private final ObjectKeyValueStore oldConfigurationStore; private final ObjectKeyValueStore newConfigurationStore; private final DatabaseConfigurationTransformer transformer; private final DatabaseNameGenerator nameGenerator; @@ -52,14 +53,12 @@ class DatabaseConfigurationMigration { private final DatabaseAdapterFactory databaseAdapterFactory; DatabaseConfigurationMigration(Context context, - ObjectKeyValueStore oldConfigurationStore, ObjectKeyValueStore newConfigurationStore, DatabaseConfigurationTransformer transformer, DatabaseNameGenerator nameGenerator, DatabaseRenamer renamer, DatabaseAdapterFactory databaseAdapterFactory) { this.context = context; - this.oldConfigurationStore = oldConfigurationStore; this.newConfigurationStore = newConfigurationStore; this.transformer = transformer; this.nameGenerator = nameGenerator; @@ -68,40 +67,47 @@ class DatabaseConfigurationMigration { } DatabasesConfiguration apply() { - Configuration oldConfiguration = oldConfigurationStore.get(); - if (oldConfiguration == null) { - return newConfigurationStore.get(); - } else { - oldConfigurationStore.remove(); + boolean oldDatabaseExist = Arrays.asList(context.databaseList()).contains(OLD_DBNAME); + if (oldDatabaseExist) { DatabaseAdapter databaseAdapter = databaseAdapterFactory.newParentDatabaseAdapter(); databaseAdapterFactory.createOrOpenDatabase(databaseAdapter, OLD_DBNAME, false); - UserCredentialsStore userCredentialsStore = UserCredentialsStoreImpl.create(databaseAdapter); - UserCredentials credentials = userCredentialsStore.selectFirst(); - String username = credentials == null ? null : credentials.username(); + + String username = getUsername(databaseAdapter); + String serverUrl = getServerUrl(databaseAdapter); databaseAdapter.close(); - String databaseName = nameGenerator.getDatabaseName(oldConfiguration.serverUrl().toString(), - username, false); - if (username == null) { + if (username == null || serverUrl == null) { context.deleteDatabase(OLD_DBNAME); return null; } else { + String databaseName = nameGenerator.getDatabaseName(serverUrl, username, false); renamer.renameDatabase(OLD_DBNAME, databaseName); - DatabasesConfiguration newConfiguration = transformer.transform(oldConfiguration, databaseName, - username); + DatabasesConfiguration newConfiguration = transformer.transform(serverUrl, databaseName, username); newConfigurationStore.set(newConfiguration); return newConfiguration; } + } else { + return newConfigurationStore.get(); } } + private String getUsername(DatabaseAdapter databaseAdapter) { + UserCredentialsStore store = UserCredentialsStoreImpl.create(databaseAdapter); + UserCredentials credentials = store.selectFirst(); + return credentials == null ? null : credentials.username(); + } + + private String getServerUrl(DatabaseAdapter databaseAdapter) { + ObjectStore store = ConfigurationStore.create(databaseAdapter); + Configuration configuration = store.selectFirst(); + return configuration == null ? null : configuration.serverUrl(); + } + static DatabaseConfigurationMigration create(Context context, - SecureStore secureStore, InsecureStore insecureStore, DatabaseAdapterFactory databaseAdapterFactory) { return new DatabaseConfigurationMigration( context, - new ConfigurationSecureStoreImpl(secureStore), DatabaseConfigurationInsecureStore.get(insecureStore), new DatabaseConfigurationTransformer(), new DatabaseNameGenerator(), diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationTransformer.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationTransformer.java index 7502729575..c507542a4a 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationTransformer.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseConfigurationTransformer.java @@ -35,11 +35,11 @@ final class DatabaseConfigurationTransformer { - public DatabasesConfiguration transform(Configuration oldConfiguration, String databaseName, String username) { + public DatabasesConfiguration transform(String serverUrl, String databaseName, String username) { return DatabasesConfiguration.builder() - .loggedServerUrl(oldConfiguration.serverUrl().toString()) + .loggedServerUrl(serverUrl) .servers(Collections.singletonList(DatabaseServerConfiguration.builder() - .serverUrl(oldConfiguration.serverUrl().toString()) + .serverUrl(serverUrl) .users(Collections.singletonList( DatabaseUserConfiguration.builder() .username(username) diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseEncryptionPasswordManager.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseEncryptionPasswordManager.java index 02a4130145..f731e9b0ab 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseEncryptionPasswordManager.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseEncryptionPasswordManager.java @@ -30,12 +30,12 @@ import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; -public class DatabaseEncryptionPasswordManager { +public final class DatabaseEncryptionPasswordManager { private final SecureStore secureStore; private final DatabaseEncryptionPasswordGenerator passwordGenerator; - DatabaseEncryptionPasswordManager(SecureStore secureStore, + private DatabaseEncryptionPasswordManager(SecureStore secureStore, DatabaseEncryptionPasswordGenerator passwordGenerator) { this.secureStore = secureStore; this.passwordGenerator = passwordGenerator; diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseNameGenerator.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseNameGenerator.java index 0709ba39a4..6f0f3116a6 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseNameGenerator.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/DatabaseNameGenerator.java @@ -28,6 +28,9 @@ package org.hisp.dhis.android.core.configuration.internal; +import androidx.annotation.VisibleForTesting; + +@VisibleForTesting public final class DatabaseNameGenerator { String getDatabaseName(String serverUrl, String username, boolean encrypt) { diff --git a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/MultiUserDatabaseManagerForD2Manager.java b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/MultiUserDatabaseManagerForD2Manager.java index 016f2164f6..8463b4323e 100644 --- a/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/MultiUserDatabaseManagerForD2Manager.java +++ b/core/src/main/java/org/hisp/dhis/android/core/configuration/internal/MultiUserDatabaseManagerForD2Manager.java @@ -37,7 +37,6 @@ import org.hisp.dhis.android.core.arch.db.access.internal.DatabaseAdapterFactory; import org.hisp.dhis.android.core.arch.storage.internal.Credentials; import org.hisp.dhis.android.core.arch.storage.internal.InsecureStore; -import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; public class MultiUserDatabaseManagerForD2Manager { @@ -58,12 +57,12 @@ public class MultiUserDatabaseManagerForD2Manager { } public static MultiUserDatabaseManagerForD2Manager create(DatabaseAdapter databaseAdapter, Context context, - SecureStore secureStore, InsecureStore insecureStore, + InsecureStore insecureStore, DatabaseAdapterFactory databaseAdapterFactory) { return new MultiUserDatabaseManagerForD2Manager(databaseAdapter, DatabaseConfigurationHelper.create(), - DatabaseConfigurationMigration.create(context, secureStore, - insecureStore, databaseAdapterFactory), databaseAdapterFactory); + DatabaseConfigurationMigration.create(context, insecureStore, databaseAdapterFactory), + databaseAdapterFactory); } public void loadIfLogged(Credentials credentials) { diff --git a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/configuration/ConfigurationSamples.java b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/configuration/ConfigurationSamples.java index 6eb3b3d101..0b0146f216 100644 --- a/core/src/sharedTest/java/org/hisp/dhis/android/core/data/configuration/ConfigurationSamples.java +++ b/core/src/sharedTest/java/org/hisp/dhis/android/core/data/configuration/ConfigurationSamples.java @@ -30,13 +30,12 @@ import org.hisp.dhis.android.core.configuration.internal.Configuration; -import okhttp3.HttpUrl; - public class ConfigurationSamples { public static Configuration getConfiguration() { return Configuration.builder() - .serverUrl(HttpUrl.parse("http://testserver.org/api/")) + .id(1L) + .serverUrl("http://testserver.org/api/") .build(); } } \ No newline at end of file diff --git a/core/src/test/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreShould.java b/core/src/test/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreShould.java deleted file mode 100644 index 3ff9bcab68..0000000000 --- a/core/src/test/java/org/hisp/dhis/android/core/configuration/internal/ConfigurationSecureStoreShould.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2004-2019, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package org.hisp.dhis.android.core.configuration.internal; - -import org.hisp.dhis.android.core.arch.storage.internal.ObjectKeyValueStore; -import org.hisp.dhis.android.core.arch.storage.internal.SecureStore; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import okhttp3.HttpUrl; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(JUnit4.class) -public class ConfigurationSecureStoreShould { - - @Mock - private SecureStore store; - - private ObjectKeyValueStore configurationSecureStore; - - private final static String KEY = "server_url"; - - private final String SERVER_URL = "http://testserver.org/"; - - private final Configuration configuration = Configuration.forServerUrl(HttpUrl.parse(SERVER_URL)); - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - configurationSecureStore = new ConfigurationSecureStoreImpl(store); - } - - @Test - public void return_correct_values_when_configuration_manager_is_configured_with_saved_store() { - when(store.getData(KEY)).thenReturn(SERVER_URL); - - Configuration dbConfiguration = configurationSecureStore.get(); - - verify(store).getData(KEY); - assertThat(dbConfiguration).isEqualTo(configuration); - } - - @Test - public void thrown_illegal_argument_exception_after_configure_with_null_argument() { - try { - configurationSecureStore.set(null); - - fail("IllegalArgumentException was not thrown"); - } catch (IllegalArgumentException illegalArgumentException) { - // swallow exception - } - } - - @Test - public void return_null_if_configuration_is_not_persisted() { - Configuration configuration = configurationSecureStore.get(); - - verify(store).getData(KEY); - assertThat(configuration).isNull(); - } - - @Test - public void invoke_remove_data_on_secure_store_when_remove_method_is_called() { - configurationSecureStore.remove(); - verify(store).removeData(KEY); - } - - @Test - public void invoke_set_data_on_secure_store_when_configuring() { - configurationSecureStore.set(configuration); - verify(store).setData(KEY, SERVER_URL); - } -} \ No newline at end of file