Merge pull request #3701 from k9mail/refactor_Storage_migration

[Refactoring] Extract migration logic from 'Storage' class
This commit is contained in:
cketti 2018-11-11 02:19:18 +01:00 committed by GitHub
commit 1e715d17f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 158 additions and 94 deletions

View file

@ -1,7 +1,6 @@
package com.fsck.k9.preferences;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -15,9 +14,10 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.SystemClock;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.preferences.migrations.StorageMigrations;
import com.fsck.k9.preferences.migrations.StorageMigrationsHelper;
import org.jetbrains.annotations.NotNull;
import timber.log.Timber;
public class Storage {
@ -36,105 +36,37 @@ public class Storage {
private Context context = null;
private SQLiteDatabase openDB() {
SQLiteDatabase mDb = context.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
SQLiteDatabase db = context.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
if (mDb.getVersion() == 1) {
Timber.i("Updating preferences to urlencoded username/password");
String accountUuids = readValue(mDb, "accountUuids");
if (accountUuids != null && accountUuids.length() != 0) {
String[] uuids = accountUuids.split(",");
for (String uuid : uuids) {
try {
String storeUriStr = Base64.decode(readValue(mDb, uuid + ".storeUri"));
String transportUriStr = Base64.decode(readValue(mDb, uuid + ".transportUri"));
URI uri = new URI(transportUriStr);
String newUserInfo = null;
if (transportUriStr != null) {
String[] userInfoParts = uri.getUserInfo().split(":");
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = "";
String authType = "";
if (userInfoParts.length > 1) {
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
}
if (userInfoParts.length > 2) {
authType = ":" + userInfoParts[2];
}
newUserInfo = usernameEnc + passwordEnc + authType;
}
if (newUserInfo != null) {
URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
String newTransportUriStr = Base64.encode(newUri.toString());
writeValue(mDb, uuid + ".transportUri", newTransportUriStr);
}
uri = new URI(storeUriStr);
newUserInfo = null;
if (storeUriStr.startsWith("imap")) {
String[] userInfoParts = uri.getUserInfo().split(":");
if (userInfoParts.length == 2) {
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
newUserInfo = usernameEnc + ":" + passwordEnc;
} else {
String authType = userInfoParts[0];
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
String passwordEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[2]);
newUserInfo = authType + ":" + usernameEnc + ":" + passwordEnc;
}
} else if (storeUriStr.startsWith("pop3")) {
String[] userInfoParts = uri.getUserInfo().split(":", 2);
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = "";
if (userInfoParts.length > 1) {
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
}
newUserInfo = usernameEnc + passwordEnc;
} else if (storeUriStr.startsWith("webdav")) {
String[] userInfoParts = uri.getUserInfo().split(":", 2);
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = "";
if (userInfoParts.length > 1) {
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
}
newUserInfo = usernameEnc + passwordEnc;
}
if (newUserInfo != null) {
URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
String newStoreUriStr = Base64.encode(newUri.toString());
writeValue(mDb, uuid + ".storeUri", newStoreUriStr);
}
} catch (Exception e) {
Timber.e(e, "ooops");
}
}
db.beginTransaction();
try {
if (db.getVersion() < 1) {
createStorageDatabase(db);
} else {
StorageMigrations.upgradeDatabase(db, migrationsHelper);
}
mDb.setVersion(DB_VERSION);
db.setVersion(DB_VERSION);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (mDb.getVersion() != DB_VERSION) {
Timber.i("Creating Storage database");
mDb.execSQL("DROP TABLE IF EXISTS preferences_storage");
mDb.execSQL("CREATE TABLE preferences_storage " +
"(primkey TEXT PRIMARY KEY ON CONFLICT REPLACE, value TEXT)");
mDb.setVersion(DB_VERSION);
if (db.getVersion() != DB_VERSION) {
throw new RuntimeException("Storage database upgrade failed!");
}
return mDb;
return db;
}
private void createStorageDatabase(SQLiteDatabase db) {
Timber.i("Creating Storage database");
db.execSQL("DROP TABLE IF EXISTS preferences_storage");
db.execSQL("CREATE TABLE preferences_storage " +
"(primkey TEXT PRIMARY KEY ON CONFLICT REPLACE, value TEXT)");
db.setVersion(DB_VERSION);
}
public static Storage getStorage(Context context) {
Storage tmpStorage = storages.get(context);
@ -342,4 +274,16 @@ public class Storage {
Timber.e("Error writing key '%s', value = '%s'", key, value);
}
}
private StorageMigrationsHelper migrationsHelper = new StorageMigrationsHelper() {
@Override
public void writeValue(@NotNull SQLiteDatabase db, @NotNull String key, String value) {
Storage.this.writeValue(db, key, value);
}
@Override
public String readValue(@NotNull SQLiteDatabase db, @NotNull String key) {
return Storage.this.readValue(db, key);
}
};
}

View file

@ -0,0 +1,100 @@
package com.fsck.k9.preferences.migrations;
import java.net.URI;
import android.database.sqlite.SQLiteDatabase;
import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.mail.filter.Base64;
import timber.log.Timber;
public class StorageMigrationTo2 {
public static void urlEncodeUserNameAndPassword(SQLiteDatabase db, StorageMigrationsHelper migrationsHelper) {
Timber.i("Updating preferences to urlencoded username/password");
String accountUuids = migrationsHelper.readValue(db, "accountUuids");
if (accountUuids != null && accountUuids.length() != 0) {
String[] uuids = accountUuids.split(",");
for (String uuid : uuids) {
try {
String storeUriStr = Base64.decode(migrationsHelper.readValue(db, uuid + ".storeUri"));
String transportUriStr = Base64.decode(migrationsHelper.readValue(db, uuid + ".transportUri"));
URI uri = new URI(transportUriStr);
String newUserInfo = null;
if (transportUriStr != null) {
String[] userInfoParts = uri.getUserInfo().split(":");
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = "";
String authType = "";
if (userInfoParts.length > 1) {
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
}
if (userInfoParts.length > 2) {
authType = ":" + userInfoParts[2];
}
newUserInfo = usernameEnc + passwordEnc + authType;
}
if (newUserInfo != null) {
URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(),
uri.getQuery(), uri.getFragment());
String newTransportUriStr = Base64.encode(newUri.toString());
migrationsHelper.writeValue(db, uuid + ".transportUri", newTransportUriStr);
}
uri = new URI(storeUriStr);
newUserInfo = null;
if (storeUriStr.startsWith("imap")) {
String[] userInfoParts = uri.getUserInfo().split(":");
if (userInfoParts.length == 2) {
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
newUserInfo = usernameEnc + ":" + passwordEnc;
} else {
String authType = userInfoParts[0];
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
String passwordEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[2]);
newUserInfo = authType + ":" + usernameEnc + ":" + passwordEnc;
}
} else if (storeUriStr.startsWith("pop3")) {
String[] userInfoParts = uri.getUserInfo().split(":", 2);
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = "";
if (userInfoParts.length > 1) {
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
}
newUserInfo = usernameEnc + passwordEnc;
} else if (storeUriStr.startsWith("webdav")) {
String[] userInfoParts = uri.getUserInfo().split(":", 2);
String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
String passwordEnc = "";
if (userInfoParts.length > 1) {
passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
}
newUserInfo = usernameEnc + passwordEnc;
}
if (newUserInfo != null) {
URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(),
uri.getQuery(), uri.getFragment());
String newStoreUriStr = Base64.encode(newUri.toString());
migrationsHelper.writeValue(db, uuid + ".storeUri", newStoreUriStr);
}
} catch (Exception e) {
Timber.e(e, "ooops");
}
}
}
}
}

View file

@ -0,0 +1,12 @@
package com.fsck.k9.preferences.migrations
import android.database.sqlite.SQLiteDatabase
internal object StorageMigrations {
@JvmStatic
fun upgradeDatabase(db: SQLiteDatabase, migrationsHelper: StorageMigrationsHelper) {
val oldVersion = db.version
if (oldVersion <= 1) StorageMigrationTo2.urlEncodeUserNameAndPassword(db, migrationsHelper)
}
}

View file

@ -0,0 +1,8 @@
package com.fsck.k9.preferences.migrations
import android.database.sqlite.SQLiteDatabase
interface StorageMigrationsHelper {
fun readValue(db: SQLiteDatabase, key: String): String?
fun writeValue(db: SQLiteDatabase, key: String, value: String?)
}