From b4784b21288f5fb2fcd5bd6cedec359add263ab1 Mon Sep 17 00:00:00 2001 From: PhilippC Date: Fri, 15 Mar 2013 07:07:45 +0100 Subject: [PATCH] Added Check if Database changed --- src/keepass2android/Database.cs | 71 ++++++++++++++++--- src/keepass2android/KeePass.cs | 1 + src/keepass2android/LockCloseActivity.cs | 11 ++- src/keepass2android/LockCloseListActivity.cs | 11 ++- src/keepass2android/PasswordActivity.cs | 22 ++++++ .../Resources/Resource.designer.cs | 6 ++ .../Resources/values/strings.xml | 2 + src/keepass2android/database/edit/SaveDB.cs | 2 + src/keepass2android/timeout/TimeoutHelper.cs | 4 +- 9 files changed, 115 insertions(+), 15 deletions(-) diff --git a/src/keepass2android/Database.cs b/src/keepass2android/Database.cs index b632a95a..7f068a03 100644 --- a/src/keepass2android/Database.cs +++ b/src/keepass2android/Database.cs @@ -43,12 +43,14 @@ namespace keepass2android public PwGroup root; public PwDatabase pm; public IOConnectionInfo mIoc; + public DateTime mLastChangeDate; public SearchDbHelper searchHelper; public DrawableFactory drawFactory = new DrawableFactory(); private bool loaded = false; + private bool mReloadRequested = false; public bool Loaded { get { return loaded;} @@ -73,20 +75,64 @@ namespace keepass2android } } - + public bool DidOpenFileChange() + { + if ((Loaded == false) || (mIoc.IsLocalFile() == false)) + { + return false; + } + return System.IO.File.GetLastWriteTimeUtc(mIoc.Path) > mLastChangeDate; + } + + public void CheckForOpenFileChanged(Activity activity) + { + if (DidOpenFileChange()) + { + if (mReloadRequested) + { + + activity.SetResult(KeePass.EXIT_RELOAD_DB); + activity.Finish(); + } + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title)); + + builder.SetMessage(activity.GetString(Resource.String.AskReloadFile)); + + builder.SetPositiveButton(activity.GetString(Android.Resource.String.Yes), new EventHandler((dlgSender, dlgEvt) => + { + mReloadRequested = true; + activity.SetResult(KeePass.EXIT_RELOAD_DB); + activity.Finish(); + + })); + + builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), new EventHandler((dlgSender, dlgEvt) => + { + + })); + + + Dialog dialog = builder.Create(); + dialog.Show(); + } + } - public void LoadData (Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status) + public void LoadData(Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status) { mIoc = iocInfo; - KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase (); + KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase(); - KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey (); - key.AddUserKey (new KeePassLib.Keys.KcpPassword (password)); - if (!String.IsNullOrEmpty (keyfile)) { + KeePassLib.Keys.CompositeKey key = new KeePassLib.Keys.CompositeKey(); + key.AddUserKey(new KeePassLib.Keys.KcpPassword(password)); + if (!String.IsNullOrEmpty(keyfile)) + { - try { key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile)); } - catch(Exception) + try + { + key.AddUserKey(new KeePassLib.Keys.KcpKeyFile(keyfile)); + } catch (Exception) { throw new KeyFileException(); } @@ -94,6 +140,14 @@ namespace keepass2android pwDatabase.Open(iocInfo, key, status); + if (iocInfo.IsLocalFile()) + { + mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(iocInfo.Path); + } else + { + mLastChangeDate = DateTime.MinValue; + } + root = pwDatabase.RootGroup; populateGlobals(root); @@ -210,6 +264,7 @@ namespace keepass2android mIoc = null; loaded = false; locked = false; + mReloadRequested = false; } public void markAllGroupsAsDirty() { diff --git a/src/keepass2android/KeePass.cs b/src/keepass2android/KeePass.cs index 54dca7c0..cd84d28e 100644 --- a/src/keepass2android/KeePass.cs +++ b/src/keepass2android/KeePass.cs @@ -47,6 +47,7 @@ namespace keepass2android public const Android.App.Result EXIT_CLOSE_AFTER_SEARCH = Android.App.Result.FirstUser+6; public const Android.App.Result EXIT_CHANGE_DB = Android.App.Result.FirstUser+7; public const Android.App.Result EXIT_FORCE_LOCK_AND_CHANGE_DB = Android.App.Result.FirstUser+8; + public const Android.App.Result EXIT_RELOAD_DB = Android.App.Result.FirstUser+9; protected override void OnCreate (Bundle bundle) { diff --git a/src/keepass2android/LockCloseActivity.cs b/src/keepass2android/LockCloseActivity.cs index 09e3e57d..0feaa7b9 100644 --- a/src/keepass2android/LockCloseActivity.cs +++ b/src/keepass2android/LockCloseActivity.cs @@ -40,10 +40,15 @@ namespace keepass2android mIoc = App.getDB().mIoc; } - protected override void OnResume() { + + protected override void OnResume() + { base.OnResume(); - - TimeoutHelper.checkShutdown(this, mIoc); + + if (TimeoutHelper.checkShutdown(this, mIoc)) + return; + + App.getDB().CheckForOpenFileChanged(this); } diff --git a/src/keepass2android/LockCloseListActivity.cs b/src/keepass2android/LockCloseListActivity.cs index 146e80ed..c0237cff 100644 --- a/src/keepass2android/LockCloseListActivity.cs +++ b/src/keepass2android/LockCloseListActivity.cs @@ -50,12 +50,17 @@ namespace keepass2android { } - - protected override void OnResume() { + + protected override void OnResume() + { base.OnResume(); - TimeoutHelper.checkShutdown(this, mIoc); + if (TimeoutHelper.checkShutdown(this, mIoc)) + return; + + App.getDB().CheckForOpenFileChanged(this); } + } } diff --git a/src/keepass2android/PasswordActivity.cs b/src/keepass2android/PasswordActivity.cs index 06ea10e2..fd14cc7f 100644 --- a/src/keepass2android/PasswordActivity.cs +++ b/src/keepass2android/PasswordActivity.cs @@ -239,7 +239,29 @@ namespace keepass2android App.getDB().Locked = false; LaunchNextActivity(); break; + case KeePass.EXIT_RELOAD_DB: + //if the activity was killed, fill password/keyfile so the user can directly hit load again + if (App.getDB().Loaded) + { + if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpPassword))) + { + KcpPassword kcpPassword = (KcpPassword)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpPassword)); + String password = kcpPassword.Password.ReadString(); + + setEditText(Resource.Id.password, password); + + } + if (App.getDB().pm.MasterKey.ContainsType(typeof(KcpKeyFile))) + { + + KcpKeyFile kcpKeyfile = (KcpKeyFile)App.getDB().pm.MasterKey.GetUserKey(typeof(KcpKeyFile)); + + setEditText(Resource.Id.pass_keyfile, kcpKeyfile.Path); + } + } + unloadDatabase(); + break; case Android.App.Result.Ok: if (requestCode == Intents.REQUEST_CODE_FILE_BROWSE) { String filename = data.DataString; diff --git a/src/keepass2android/Resources/Resource.designer.cs b/src/keepass2android/Resources/Resource.designer.cs index 7276b1a9..ab2b5e52 100644 --- a/src/keepass2android/Resources/Resource.designer.cs +++ b/src/keepass2android/Resources/Resource.designer.cs @@ -1021,6 +1021,12 @@ namespace keepass2android // aapt resource value: 0x7f0500eb public const int AskOverwriteBinary_yes = 2131034347; + // aapt resource value: 0x7f0500f3 + public const int AskReloadFile = 2131034355; + + // aapt resource value: 0x7f0500f2 + public const int AskReloadFile_title = 2131034354; + // aapt resource value: 0x7f0500ed public const int AttachFailed = 2131034349; diff --git a/src/keepass2android/Resources/values/strings.xml b/src/keepass2android/Resources/values/strings.xml index 4f0a1411..1be88d0d 100644 --- a/src/keepass2android/Resources/values/strings.xml +++ b/src/keepass2android/Resources/values/strings.xml @@ -212,6 +212,8 @@ Do you want to delete this entry permanently? Press No to recycle. Do you want to delete this group permanently? Press No to recycle. Delete permanently? + Reload file? + The file which is currently open was changed by another program. Do you want to reload it? 30 seconds 1 minute diff --git a/src/keepass2android/database/edit/SaveDB.cs b/src/keepass2android/database/edit/SaveDB.cs index 4570823f..5e355b69 100644 --- a/src/keepass2android/database/edit/SaveDB.cs +++ b/src/keepass2android/database/edit/SaveDB.cs @@ -53,6 +53,8 @@ namespace keepass2android if (! mDontSave) { try { mDb.SaveData (mCtx); + if (mDb.mIoc.IsLocalFile()) + mDb.mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(mDb.mIoc.Path); } catch (Exception e) { /* TODO KPDesktop: * catch(Exception exSave) diff --git a/src/keepass2android/timeout/TimeoutHelper.cs b/src/keepass2android/timeout/TimeoutHelper.cs index bd588464..4994bf00 100644 --- a/src/keepass2android/timeout/TimeoutHelper.cs +++ b/src/keepass2android/timeout/TimeoutHelper.cs @@ -91,13 +91,15 @@ namespace keepass2android return ioc.GetDisplayName() != other.GetDisplayName(); } - public static void checkShutdown(Activity act, IOConnectionInfo ioc) { + public static bool checkShutdown(Activity act, IOConnectionInfo ioc) { if (( App.getDB().Loaded && (App.isShutdown() || App.getDB().Locked) ) || (iocChanged(ioc, App.getDB().mIoc))) //file was changed from ActionSend-Intent { act.SetResult(KeePass.EXIT_LOCK); act.Finish(); + return true; } + return false; } } }