add option to sync database after quick-unlocking the database. closes https://github.com/PhilippC/keepass2android/issues/188

This commit is contained in:
Philipp Crocoll
2021-11-17 11:30:43 +01:00
parent 7014f5d9f1
commit 294e6f5edf
11 changed files with 160 additions and 95 deletions

View File

@@ -119,7 +119,7 @@ namespace keepass2android
/// </summary>
IFileStorage GetFileStorage(IOConnectionInfo iocInfo, bool allowCache);
void TriggerReload(Context context);
void TriggerReload(Context context, Action<bool> actionOnResult /*if not null, called when the user selected yes (true) or no (false)*/);
bool CheckForDuplicateUuids { get; }

View File

@@ -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

View File

@@ -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

View File

@@ -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()
{

View File

@@ -213,9 +213,7 @@ namespace keepass2android
btn.PostDelayed(() =>
{
App.Kp2a.UnlockDatabase();
Finish();
UnlockAndSyncAndClose();
}, 500);
@@ -328,18 +326,34 @@ 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();
}
}
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

View File

@@ -205,6 +205,8 @@
<string name="PreloadDatabaseEnabled_key">PreloadDatabaseEnabled</string>
<bool name="PreloadDatabaseEnabled_default">true</bool>
<string name="SyncAfterQuickUnlock_key">SyncAfterQuickUnlock_key</string>
<string name="ClearPasswordOnLeave_key">ClearPasswordOnLeave</string>
</resources>

View File

@@ -473,6 +473,9 @@
<string name="PreloadDatabaseEnabled_title">Pre-load database file</string>
<string name="PreloadDatabaseEnabled_summary">Start background loading or downloading of the database file during password entry.</string>
<string name="SyncAfterQuickUnlock_title">Sync after QuickUnlock</string>
<string name="SyncAfterQuickUnlock_summary">Synchronize database with remote file after unlocking with QuickUnlock.</string>
<string name="AskOverwriteBinary">Do you want to overwrite the existing binary with the same name?</string>
<string name="AskOverwriteBinary_title">Overwrite existing binary?</string>
<string name="AskOverwriteBinary_yes">Overwrite</string>

View File

@@ -568,6 +568,14 @@
android:title="@string/PreloadDatabaseEnabled_title"
android:key="@string/PreloadDatabaseEnabled_key" />
<CheckBoxPreference
android:enabled="true"
android:persistent="true"
android:summary="@string/SyncAfterQuickUnlock_summary"
android:defaultValue="false"
android:title="@string/SyncAfterQuickUnlock_title"
android:key="@string/SyncAfterQuickUnlock_key" />
<CheckBoxPreference
android:key="@string/TanExpiresOnUse_key"
android:title="@string/TanExpiresOnUse_title"
android:summary="@string/TanExpiresOnUse_summary"

View File

@@ -0,0 +1,99 @@
using System;
using Android.App;
using Android.Widget;
using keepass2android.Io;
using KeePassLib.Serialization;
namespace keepass2android
{
public class SyncUtil
{
private Activity _activity;
public SyncUtil(Activity activity)
{
_activity = activity;
}
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);
}
}
}
public void SynchronizeDatabase(Action runAfterSuccess)
{
var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc);
RunnableOnFinish task;
OnFinish onFinish = new ActionOnFinish(_activity, (success, message, activity) =>
{
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();
}
}
}

View File

@@ -460,14 +460,14 @@ namespace keepass2android
}
else
{
AskForReload(activity);
AskForReload(activity, null);
}
}
}
private void AskForReload(Activity activity)
private void AskForReload(Activity activity, Action<bool> 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<bool> actionOnResult)
{
Handler handler = new Handler(Looper.MainLooper);
handler.Post(() =>
{
AskForReload((Activity) ctx);
AskForReload((Activity) ctx, actionOnResult);
});
}

View File

@@ -207,6 +207,7 @@
<Compile Include="settings\ExportKeyfileActivity.cs" />
<Compile Include="settings\IconSetPreference.cs" />
<Compile Include="SwitchImeActivity.cs" />
<Compile Include="SyncUtil.cs" />
<Compile Include="timeout\TimeoutHelper.cs" />
<Compile Include="GroupActivity.cs" />
<Compile Include="GroupBaseActivity.cs" />