From 294e6f5edf09b387f1eb8dea9504708a3727c48e Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Wed, 17 Nov 2021 11:30:43 +0100 Subject: [PATCH] add option to sync database after quick-unlocking the database. closes https://github.com/PhilippC/keepass2android/issues/188 --- src/Kp2aBusinessLogic/IKp2aApp.cs | 2 +- .../database/CheckDatabaseForChanges.cs | 2 +- .../database/SynchronizeCachedDatabase.cs | 3 +- src/keepass2android/GroupBaseActivity.cs | 78 +-------------- src/keepass2android/QuickUnlock.cs | 34 +++++-- .../Resources/values/config.xml | 2 + .../Resources/values/strings.xml | 3 + .../Resources/xml/preferences.xml | 10 +- src/keepass2android/SyncUtil.cs | 99 +++++++++++++++++++ src/keepass2android/app/App.cs | 21 +++- .../keepass2android-app.csproj | 1 + 11 files changed, 160 insertions(+), 95 deletions(-) create mode 100644 src/keepass2android/SyncUtil.cs diff --git a/src/Kp2aBusinessLogic/IKp2aApp.cs b/src/Kp2aBusinessLogic/IKp2aApp.cs index 6fa44411..d4602a17 100644 --- a/src/Kp2aBusinessLogic/IKp2aApp.cs +++ b/src/Kp2aBusinessLogic/IKp2aApp.cs @@ -119,7 +119,7 @@ namespace keepass2android /// IFileStorage GetFileStorage(IOConnectionInfo iocInfo, bool allowCache); - void TriggerReload(Context context); + void TriggerReload(Context context, Action actionOnResult /*if not null, called when the user selected yes (true) or no (false)*/); bool CheckForDuplicateUuids { get; } diff --git a/src/Kp2aBusinessLogic/database/CheckDatabaseForChanges.cs b/src/Kp2aBusinessLogic/database/CheckDatabaseForChanges.cs index 518a4abb..0986dfea 100644 --- a/src/Kp2aBusinessLogic/database/CheckDatabaseForChanges.cs +++ b/src/Kp2aBusinessLogic/database/CheckDatabaseForChanges.cs @@ -51,7 +51,7 @@ namespace keepass2android if (!MemUtil.ArraysEqual(_app.CurrentDb.KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash)) { - _app.TriggerReload(_context); + _app.TriggerReload(_context, null); Finish(true); } else diff --git a/src/Kp2aBusinessLogic/database/SynchronizeCachedDatabase.cs b/src/Kp2aBusinessLogic/database/SynchronizeCachedDatabase.cs index 5918c77f..ad58a493 100644 --- a/src/Kp2aBusinessLogic/database/SynchronizeCachedDatabase.cs +++ b/src/Kp2aBusinessLogic/database/SynchronizeCachedDatabase.cs @@ -85,8 +85,7 @@ namespace keepass2android { //only the remote file was modified -> reload database. //note: it's best to lock the database and do a complete reload here (also better for UI consistency in case something goes wrong etc.) - _app.TriggerReload(_context); - Finish(true); + _app.TriggerReload(_context, (bool result) => Finish(result)); } } else diff --git a/src/keepass2android/GroupBaseActivity.cs b/src/keepass2android/GroupBaseActivity.cs index bb0bec18..e0bdca09 100644 --- a/src/keepass2android/GroupBaseActivity.cs +++ b/src/keepass2android/GroupBaseActivity.cs @@ -28,7 +28,6 @@ using Android.Widget; using KeePassLib; using Android.Preferences; using KeePassLib.Interfaces; -using KeePassLib.Serialization; using KeePassLib.Utility; using keepass2android.Io; using keepass2android.database.edit; @@ -42,7 +41,6 @@ using Object = Java.Lang.Object; namespace keepass2android { - public abstract class GroupBaseActivity : LockCloseActivity { public const String KeyEntry = "entry"; @@ -1062,7 +1060,7 @@ namespace keepass2android return true; case Resource.Id.menu_sync: - Synchronize(); + new SyncUtil(this).SynchronizeDatabase(() => { }); return true; case Resource.Id.menu_work_offline: @@ -1073,7 +1071,7 @@ namespace keepass2android case Resource.Id.menu_work_online: App.Kp2a.OfflineMode = App.Kp2a.OfflineModePreference = false; UpdateOfflineModeMenu(); - Synchronize(); + new SyncUtil(this).SynchronizeDatabase(() => { }); return true; case Resource.Id.menu_open_other_db: AppTask.SetActivityResult(this, KeePass.ExitLoadAnotherDb); @@ -1096,77 +1094,7 @@ namespace keepass2android return base.OnOptionsItemSelected(item); } - public class SyncOtpAuxFile : RunnableOnFinish - { - private readonly IOConnectionInfo _ioc; - - public SyncOtpAuxFile(Activity activity, IOConnectionInfo ioc) - : base(activity,null) - { - _ioc = ioc; - } - - public override void Run() - { - StatusLogger.UpdateMessage(UiStringKey.SynchronizingOtpAuxFile); - try - { - //simply open the file. The file storage does a complete sync. - using (App.Kp2a.GetOtpAuxFileStorage(_ioc).OpenFileForRead(_ioc)) - { - } - - Finish(true); - } - catch (Exception e) - { - - Finish(false, e.Message); - } - - - } - - } - - private void Synchronize() - { - var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc); - RunnableOnFinish task; - OnFinish onFinish = new ActionOnFinish(this, (success, message, activity) => - { - if (!String.IsNullOrEmpty(message)) - Toast.MakeText(activity, message, ToastLength.Long).Show(); - - // Tell the adapter to refresh it's list - BaseAdapter adapter = (BaseAdapter)((GroupBaseActivity)activity)?.ListAdapter; - adapter?.NotifyDataSetChanged(); - - if (App.Kp2a.CurrentDb.OtpAuxFileIoc != null) - { - var task2 = new SyncOtpAuxFile(this, App.Kp2a.CurrentDb.OtpAuxFileIoc); - new ProgressTask(App.Kp2a, activity, task2).Run(true); - } - }); - - if (filestorage is CachingFileStorage) - { - - task = new SynchronizeCachedDatabase(this, App.Kp2a, onFinish); - } - else - { - - task = new CheckDatabaseForChanges(this, App.Kp2a, onFinish); - } - - - - - var progressTask = new ProgressTask(App.Kp2a, this, task); - progressTask.Run(); - - } + public override void OnBackPressed() { diff --git a/src/keepass2android/QuickUnlock.cs b/src/keepass2android/QuickUnlock.cs index abeb5785..14639cfd 100644 --- a/src/keepass2android/QuickUnlock.cs +++ b/src/keepass2android/QuickUnlock.cs @@ -212,10 +212,8 @@ namespace keepass2android pwd.Text = ExpectedPasswordPart; btn.PostDelayed(() => - { - - App.Kp2a.UnlockDatabase(); - Finish(); + { + UnlockAndSyncAndClose(); }, 500); @@ -327,20 +325,36 @@ namespace keepass2android { var expectedPasswordPart = ExpectedPasswordPart; if (pwd.Text == expectedPasswordPart) - { - Kp2aLog.Log("QuickUnlock successful!"); - App.Kp2a.UnlockDatabase(); - } + { + UnlockAndSyncAndClose(); + } else { Kp2aLog.Log("QuickUnlock not successful!"); App.Kp2a.Lock(false); Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show(); + Finish(); } - Finish(); + } - private string ExpectedPasswordPart + private void UnlockAndSyncAndClose() + { + App.Kp2a.UnlockDatabase(); + + if (PreferenceManager.GetDefaultSharedPreferences(this) + .GetBoolean(GetString(Resource.String.SyncAfterQuickUnlock_key), false)) + { + new SyncUtil(this).SynchronizeDatabase(Finish); + } + else + Finish(); + + + + } + + private string ExpectedPasswordPart { get { diff --git a/src/keepass2android/Resources/values/config.xml b/src/keepass2android/Resources/values/config.xml index c229f386..6e12f3e7 100644 --- a/src/keepass2android/Resources/values/config.xml +++ b/src/keepass2android/Resources/values/config.xml @@ -205,6 +205,8 @@ PreloadDatabaseEnabled true + SyncAfterQuickUnlock_key + ClearPasswordOnLeave \ No newline at end of file diff --git a/src/keepass2android/Resources/values/strings.xml b/src/keepass2android/Resources/values/strings.xml index c39fb461..d36f9b97 100644 --- a/src/keepass2android/Resources/values/strings.xml +++ b/src/keepass2android/Resources/values/strings.xml @@ -473,6 +473,9 @@ Pre-load database file Start background loading or downloading of the database file during password entry. + Sync after QuickUnlock + Synchronize database with remote file after unlocking with QuickUnlock. + Do you want to overwrite the existing binary with the same name? Overwrite existing binary? Overwrite diff --git a/src/keepass2android/Resources/xml/preferences.xml b/src/keepass2android/Resources/xml/preferences.xml index f2048dde..a81e01a7 100644 --- a/src/keepass2android/Resources/xml/preferences.xml +++ b/src/keepass2android/Resources/xml/preferences.xml @@ -567,7 +567,15 @@ android:defaultValue="@bool/PreloadDatabaseEnabled_default" android:title="@string/PreloadDatabaseEnabled_title" android:key="@string/PreloadDatabaseEnabled_key" /> - + + + { + if (!String.IsNullOrEmpty(message)) + Toast.MakeText(activity, message, ToastLength.Long).Show(); + + // Tell the adapter to refresh it's list + BaseAdapter adapter = (activity as GroupBaseActivity)?.ListAdapter; + adapter?.NotifyDataSetChanged(); + + if (App.Kp2a.CurrentDb?.OtpAuxFileIoc != null) + { + var task2 = new SyncOtpAuxFile(_activity, App.Kp2a.CurrentDb.OtpAuxFileIoc); + task2.OnFinishToRun = new ActionOnFinish(_activity, (b, s, activeActivity) => + { + runAfterSuccess(); + }); + new ProgressTask(App.Kp2a, activity, task2).Run(true); + } + else + { + runAfterSuccess(); + } + }); + + if (filestorage is CachingFileStorage) + { + + task = new SynchronizeCachedDatabase(_activity, App.Kp2a, onFinish); + } + else + { + + task = new CheckDatabaseForChanges(_activity, App.Kp2a, onFinish); + } + + + + + var progressTask = new ProgressTask(App.Kp2a, _activity, task); + progressTask.Run(); + + } + } +} \ No newline at end of file diff --git a/src/keepass2android/app/App.cs b/src/keepass2android/app/App.cs index b1274f6e..b0923e3f 100644 --- a/src/keepass2android/app/App.cs +++ b/src/keepass2android/app/App.cs @@ -460,14 +460,14 @@ namespace keepass2android } else { - AskForReload(activity); + AskForReload(activity, null); } } } - private void AskForReload(Activity activity) + private void AskForReload(Activity activity, Action actionOnResult) { AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title)); @@ -480,16 +480,27 @@ namespace keepass2android CurrentDb.ReloadRequested = true; activity.SetResult(KeePass.ExitReloadDb); activity.Finish(); + if (actionOnResult != null) + actionOnResult(true); }); builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), (dlgSender, dlgEvt) => { - + if (actionOnResult != null) + actionOnResult(false); }); + Dialog dialog = builder.Create(); + + dialog.SetOnDismissListener(new Util.DismissListener(() => + { + if (actionOnResult != null) + actionOnResult(false); + })); + dialog.Show(); } @@ -733,12 +744,12 @@ namespace keepass2android } } - public void TriggerReload(Context ctx) + public void TriggerReload(Context ctx, Action actionOnResult) { Handler handler = new Handler(Looper.MainLooper); handler.Post(() => { - AskForReload((Activity) ctx); + AskForReload((Activity) ctx, actionOnResult); }); } diff --git a/src/keepass2android/keepass2android-app.csproj b/src/keepass2android/keepass2android-app.csproj index 73ed0fbd..586766f5 100644 --- a/src/keepass2android/keepass2android-app.csproj +++ b/src/keepass2android/keepass2android-app.csproj @@ -207,6 +207,7 @@ +