Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 1e715d17 authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #3701 from k9mail/refactor_Storage_migration

[Refactoring] Extract migration logic from 'Storage' class
parents 907eabeb 272b2e3c
Loading
Loading
Loading
Loading
+39 −95
Original line number Original line Diff line number Diff line
package com.fsck.k9.preferences;
package com.fsck.k9.preferences;




import java.net.URI;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
@@ -15,9 +14,10 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.database.sqlite.SQLiteStatement;
import android.os.SystemClock;
import android.os.SystemClock;


import com.fsck.k9.helper.UrlEncodingHelper;
import com.fsck.k9.helper.Utility;
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;
import timber.log.Timber;


public class Storage {
public class Storage {
@@ -36,106 +36,38 @@ public class Storage {
    private Context context = null;
    private Context context = null;


    private SQLiteDatabase openDB() {
    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) {
        db.beginTransaction();
            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 {
        try {
                        String storeUriStr = Base64.decode(readValue(mDb, uuid + ".storeUri"));
            if (db.getVersion() < 1) {
                        String transportUriStr = Base64.decode(readValue(mDb, uuid + ".transportUri"));
                createStorageDatabase(db);

                        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 {
            } else {
                                String authType = userInfoParts[0];
                StorageMigrations.upgradeDatabase(db, migrationsHelper);
                                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;
            db.setVersion(DB_VERSION);
                        } else if (storeUriStr.startsWith("webdav")) {
            db.setTransactionSuccessful();
                            String[] userInfoParts = uri.getUserInfo().split(":", 2);
        } finally {
                            String usernameEnc = UrlEncodingHelper.encodeUtf8(userInfoParts[0]);
            db.endTransaction();

                            String passwordEnc = "";
                            if (userInfoParts.length > 1) {
                                passwordEnc = ":" + UrlEncodingHelper.encodeUtf8(userInfoParts[1]);
                            }

                            newUserInfo = usernameEnc + passwordEnc;
        }
        }


                        if (newUserInfo != null) {
        if (db.getVersion() != DB_VERSION) {
                            URI newUri = new URI(uri.getScheme(), newUserInfo, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
            throw new RuntimeException("Storage database upgrade failed!");
                            String newStoreUriStr = Base64.encode(newUri.toString());
                            writeValue(mDb, uuid + ".storeUri", newStoreUriStr);
                        }
                    } catch (Exception e) {
                        Timber.e(e, "ooops");
                    }
                }
        }
        }


            mDb.setVersion(DB_VERSION);
        return db;
    }
    }


        if (mDb.getVersion() != DB_VERSION) {
    private void createStorageDatabase(SQLiteDatabase db) {
        Timber.i("Creating Storage database");
        Timber.i("Creating Storage database");
            mDb.execSQL("DROP TABLE IF EXISTS preferences_storage");

            mDb.execSQL("CREATE TABLE preferences_storage " +
        db.execSQL("DROP TABLE IF EXISTS preferences_storage");
        db.execSQL("CREATE TABLE preferences_storage " +
                    "(primkey TEXT PRIMARY KEY ON CONFLICT REPLACE, value TEXT)");
                    "(primkey TEXT PRIMARY KEY ON CONFLICT REPLACE, value TEXT)");
            mDb.setVersion(DB_VERSION);
        db.setVersion(DB_VERSION);
        }
        return mDb;
    }
    }



    public static Storage getStorage(Context context) {
    public static Storage getStorage(Context context) {
        Storage tmpStorage = storages.get(context);
        Storage tmpStorage = storages.get(context);
        if (tmpStorage != null) {
        if (tmpStorage != null) {
@@ -342,4 +274,16 @@ public class Storage {
            Timber.e("Error writing key '%s', value = '%s'", key, value);
            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);
        }
    };
}
}
+100 −0
Original line number Original line Diff line number Diff line
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");
                }
            }
        }
    }
}
+12 −0
Original line number Original line Diff line number Diff line
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)
    }
}
+8 −0
Original line number Original line Diff line number Diff line
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?)
}