From 52676eb1139939e5c84a976216d4bed671c7cab3 Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Mon, 13 Jan 2020 13:13:54 +0100 Subject: [PATCH] make sure we ask if user wants to remember the selected entry even when he didn't select "Choose another entry" (but used search directly), closes https://github.com/PhilippC/keepass2android/issues/742 --- src/keepass2android/ShareUrlResults.cs | 92 +++++++++--------- src/keepass2android/app/AppTask.cs | 127 +++++++------------------ 2 files changed, 86 insertions(+), 133 deletions(-) diff --git a/src/keepass2android/ShareUrlResults.cs b/src/keepass2android/ShareUrlResults.cs index 6e57e122..e4c8961d 100644 --- a/src/keepass2android/ShareUrlResults.cs +++ b/src/keepass2android/ShareUrlResults.cs @@ -100,53 +100,19 @@ namespace keepass2android } private void Query(string url, bool autoReturnFromQuery) - { - try - { - foreach (var db in App.Kp2a.OpenDatabases) - { - PwGroup resultsForThisDb; - //first: search for exact url - resultsForThisDb = db.SearchForExactUrl(url); - if (!url.StartsWith("androidapp://")) - { - //if no results, search for host (e.g. "accounts.google.com") - if (!resultsForThisDb.Entries.Any()) - resultsForThisDb = db.SearchForHost(url, false); - //if still no results, search for host, allowing subdomains ("www.google.com" in entry is ok for "accounts.google.com" in search (but not the other way around) - if (!resultsForThisDb.Entries.Any()) - resultsForThisDb = db.SearchForHost(url, true); - - } - //if no results returned up to now, try to search through other fields as well: - if (!resultsForThisDb.Entries.Any()) - resultsForThisDb = db.SearchForText(url); - //search for host as text - if (!resultsForThisDb.Entries.Any()) - resultsForThisDb = db.SearchForText(UrlUtil.GetHost(url.Trim())); - - if (Group == null) - { - Group = resultsForThisDb; - } - else - { - foreach (var entry in resultsForThisDb.Entries) - { - Group.AddEntry(entry, false,false); - } - } - - } - - } catch (Exception e) + { + + try + { + Group = GetSearchResultsForUrl(url); + } catch (Exception e) { Toast.MakeText(this, e.Message, ToastLength.Long).Show(); SetResult(Result.Canceled); Finish(); return; } - + //if there is exactly one match: open the entry if ((Group.Entries.Count() == 1) && autoReturnFromQuery && PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.AutoReturnFromQuery_key),true)) { @@ -166,7 +132,7 @@ namespace keepass2android View selectOtherEntry = FindViewById (Resource.Id.select_other_entry); - var newTask = new SelectEntryForUrlTask(url); + var newTask = new SearchUrlTask() {AutoReturnFromQuery = false, UrlToSearchFor = url}; if (AppTask is SelectEntryTask currentSelectTask) newTask.ShowUserNotifications = currentSelectTask.ShowUserNotifications; @@ -195,7 +161,47 @@ namespace keepass2android Util.MoveBottomBarButtons(Resource.Id.select_other_entry, Resource.Id.add_url_entry, Resource.Id.bottom_bar, this); } - public override bool OnSearchRequested() + public static PwGroup GetSearchResultsForUrl(string url) + { + PwGroup resultsGroup = null; + foreach (var db in App.Kp2a.OpenDatabases) + { + //first: search for exact url + var resultsForThisDb = db.SearchForExactUrl(url); + if (!url.StartsWith("androidapp://")) + { + //if no results, search for host (e.g. "accounts.google.com") + if (!resultsForThisDb.Entries.Any()) + resultsForThisDb = db.SearchForHost(url, false); + //if still no results, search for host, allowing subdomains ("www.google.com" in entry is ok for "accounts.google.com" in search (but not the other way around) + if (!resultsForThisDb.Entries.Any()) + resultsForThisDb = db.SearchForHost(url, true); + } + + //if no results returned up to now, try to search through other fields as well: + if (!resultsForThisDb.Entries.Any()) + resultsForThisDb = db.SearchForText(url); + //search for host as text + if (!resultsForThisDb.Entries.Any()) + resultsForThisDb = db.SearchForText(UrlUtil.GetHost(url.Trim())); + + if (resultsGroup == null) + { + resultsGroup = resultsForThisDb; + } + else + { + foreach (var entry in resultsForThisDb.Entries) + { + resultsGroup.AddEntry(entry, false, false); + } + } + } + + return resultsGroup; + } + + public override bool OnSearchRequested() { Intent i = new Intent(this, typeof(SearchActivity)); AppTask.ToIntent(i); diff --git a/src/keepass2android/app/AppTask.cs b/src/keepass2android/app/AppTask.cs index 81782cc3..8417917e 100644 --- a/src/keepass2android/app/AppTask.cs +++ b/src/keepass2android/app/AppTask.cs @@ -436,9 +436,43 @@ namespace keepass2android { if (App.Kp2a.LastOpenedEntry != null) App.Kp2a.LastOpenedEntry.SearchUrl = UrlToSearchFor; - base.CompleteOnCreateEntryActivity(activity); - } - } + + + //if the database is readonly (or no URL exists), don't offer to modify the URL + if ((App.Kp2a.CurrentDb.CanWrite == false) || (String.IsNullOrEmpty(UrlToSearchFor) || keepass2android.ShareUrlResults.GetSearchResultsForUrl(UrlToSearchFor).Entries.Any(e => e == activity.Entry) )) + { + base.CompleteOnCreateEntryActivity(activity); + return; + } + + AskAddUrlThenCompleteCreate(activity, UrlToSearchFor); + } + + + /// + /// brings up a dialog asking the user whether he wants to add the given URL to the entry for automatic finding + /// + public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url) + { + AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.SetTitle(activity.GetString(Resource.String.AddUrlToEntryDialog_title)); + + builder.SetMessage(activity.GetString(Resource.String.AddUrlToEntryDialog_text, new Java.Lang.Object[] { url })); + + builder.SetPositiveButton(activity.GetString(Resource.String.yes), (dlgSender, dlgEvt) => + { + activity.AddUrlToEntry(url, (EntryActivity thenActiveActivity) => base.CompleteOnCreateEntryActivity(thenActiveActivity)); + }); + + builder.SetNegativeButton(activity.GetString(Resource.String.no), (dlgSender, dlgEvt) => + { + base.CompleteOnCreateEntryActivity(activity); + }); + + Dialog dialog = builder.Create(); + dialog.Show(); + } + } /// @@ -510,93 +544,6 @@ namespace keepass2android } } - /// - /// User is about to select an entry. When selected, ask whether the url he was searching for earlier should be stored - /// in the selected entry for later use. - /// - public class SelectEntryForUrlTask: SelectEntryTask - { - /// - /// default constructor for creating from Bundle - /// - public SelectEntryForUrlTask() - { - - } - - public SelectEntryForUrlTask(string url) - { - UrlToSearchFor = url; - ShowUserNotifications = true; - } - - public const String UrlToSearchKey = "UrlToSearch"; - - public string UrlToSearchFor - { - get; - set; - } - - public override void Setup(Bundle b) - { - base.Setup(b); - UrlToSearchFor = b.GetString(UrlToSearchKey); - } - public override IEnumerable Extras - { - get - { - foreach (IExtra e in base.Extras) - yield return e; - yield return new StringExtra { Key = UrlToSearchKey, Value = UrlToSearchFor }; - } - } - - public override void CompleteOnCreateEntryActivity(EntryActivity activity) - { - if (App.Kp2a.LastOpenedEntry != null) - App.Kp2a.LastOpenedEntry.SearchUrl = UrlToSearchFor; - - //if the database is readonly (or no URL exists), don't offer to modify the URL - if ((App.Kp2a.CurrentDb.CanWrite == false) || (String.IsNullOrEmpty(UrlToSearchFor))) - { - base.CompleteOnCreateEntryActivity(activity); - return; - } - - - - AskAddUrlThenCompleteCreate(activity, UrlToSearchFor); - - } - - /// - /// brings up a dialog asking the user whether he wants to add the given URL to the entry for automatic finding - /// - public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url) - { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.SetTitle(activity.GetString(Resource.String.AddUrlToEntryDialog_title)); - - builder.SetMessage(activity.GetString(Resource.String.AddUrlToEntryDialog_text, new Java.Lang.Object[] { url })); - - builder.SetPositiveButton(activity.GetString(Resource.String.yes), (dlgSender, dlgEvt) => - { - activity.AddUrlToEntry(url, (EntryActivity thenActiveActivity) => base.CompleteOnCreateEntryActivity(thenActiveActivity)); - }); - - builder.SetNegativeButton(activity.GetString(Resource.String.no), (dlgSender, dlgEvt) => - { - base.CompleteOnCreateEntryActivity(activity); - }); - - Dialog dialog = builder.Create(); - dialog.Show(); - } - - } - /// /// User is about to move entries and/or groups to another group