From e9e697f0a563e9e0da4a22fa1c9c04fa6a5f79af Mon Sep 17 00:00:00 2001 From: Anand Date: Tue, 14 Dec 2021 15:38:55 +0530 Subject: [PATCH 1/4] ref issue #10 - Search multiple terms using AND operator --- actions.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/actions.go b/actions.go index 35c8ae2..14cf150 100644 --- a/actions.go +++ b/actions.go @@ -511,12 +511,15 @@ func findCurrentEntry(term string) error { var err error var entries []Entry + var terms []string if err = checkActiveDatabase(); err != nil { return err } - err, entries = searchDatabaseEntry(term) + terms = strings.Split(term, " ") + + err, entries = searchDatabaseEntries(terms, "AND") if err != nil || len(entries) == 0 { fmt.Printf("Entry for query \"%s\" not found\n", term) return err From 03e5ef01ef476c3a4e32897adfc89f2146f9cd29 Mon Sep 17 00:00:00 2001 From: Anand Date: Tue, 14 Dec 2021 15:39:21 +0530 Subject: [PATCH 2/4] ref issue #10 - Search multiple terms using AND operator --- db.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/db.go b/db.go index 423085f..410e1a0 100644 --- a/db.go +++ b/db.go @@ -229,7 +229,7 @@ func addNewDatabaseEntry(title, userName, url, passwd, notes string, customEntri err, db = openActiveDatabase() if err == nil && db != nil { - // result := db.Debug().Create(&entry) + // result := db.Debug().Create(&entry) result := db.Create(&entry) if result.Error == nil && result.RowsAffected == 1 { // Add custom fields if given @@ -341,6 +341,73 @@ func searchDatabaseEntry(term string) (error, []Entry) { } +// Union of two entry arrays +func union(entry1 []Entry, entry2 []Entry) []Entry { + + m := make(map[int]bool) + + for _, item := range entry1 { + m[item.ID] = true + } + + for _, item := range entry2 { + if _, ok := m[item.ID]; !ok { + entry1 = append(entry1, item) + } + } + + return entry1 +} + +// Intersection of two entry arrays +func intersection(entry1 []Entry, entry2 []Entry) []Entry { + + var common []Entry + + m := make(map[int]bool) + + for _, item := range entry1 { + m[item.ID] = true + } + + for _, item := range entry2 { + if _, ok := m[item.ID]; ok { + common = append(common, item) + } + } + + return common +} + +// Search database for the given terms and returns matches according to operator +func searchDatabaseEntries(terms []string, operator string) (error, []Entry) { + + var err error + var finalEntries []Entry + + for idx, term := range terms { + var entries []Entry + + err, entries = searchDatabaseEntry(term) + if err != nil { + fmt.Printf("Error searching for term: %s - \"%s\"\n", term, err.Error()) + return err, entries + } + + if idx == 0 { + finalEntries = entries + } else { + if operator == "AND" { + finalEntries = intersection(finalEntries, entries) + } else if operator == "OR" { + finalEntries = union(finalEntries, entries) + } + } + } + + return nil, finalEntries +} + // Remove a given database entry func removeDatabaseEntry(entry *Entry) error { From c3bbb258c126e59942c8b3d0cca5e8f8dbf80674 Mon Sep 17 00:00:00 2001 From: Anand Date: Tue, 14 Dec 2021 15:39:47 +0530 Subject: [PATCH 3/4] ref issue #10 - Search multiple terms using AND operator --- main.go | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index a182f13..026de6f 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/pythonhacker/argparse" "os" + "strings" ) const VERSION = 0.3 @@ -86,13 +87,16 @@ func performAction(optMap map[string]interface{}) { "edit": WrapperMaxKryptStringFunc(editCurrentEntry), "init": initNewDatabase, "list-entry": WrapperMaxKryptStringFunc(listCurrentEntry), - "find": WrapperMaxKryptStringFunc(findCurrentEntry), "remove": WrapperMaxKryptStringFunc(removeCurrentEntry), "clone": WrapperMaxKryptStringFunc(copyCurrentEntry), "use-db": setActiveDatabasePath, "export": exportToFile, } + stringListActionsMap := map[string]actionFunc{ + "find": WrapperMaxKryptStringFunc(findCurrentEntry), + } + stringActions2Map := map[string]actionFunc2{ "decrypt": decryptDatabase, } @@ -146,6 +150,18 @@ func performAction(optMap map[string]interface{}) { } } + for key, mappedFunc := range stringListActionsMap { + if len(*optMap[key].(*[]string)) > 0 { + + var vals = *(optMap[key].(*[]string)) + // Convert to single string + var singleVal = strings.Join(vals, " ") + mappedFunc(singleVal) + flag = true + break + } + } + if flag { return } @@ -171,7 +187,6 @@ func initializeCmdLine(parser *argparse.Parser) map[string]interface{} { {"C", "clone", "Clone an entry with ", "", ""}, {"R", "remove", "Remove an entry with or ", "", ""}, {"U", "use-db", "Set as active database", "", ""}, - {"f", "find", "Search entries with ", "", ""}, {"E", "edit", "Edit entry by ", "", ""}, {"l", "list-entry", "List entry by ", "", ""}, {"x", "export", "Export all entries to ", "", ""}, @@ -181,6 +196,14 @@ func initializeCmdLine(parser *argparse.Parser) map[string]interface{} { optMap[opt.Long] = parser.String(opt.Short, opt.Long, &argparse.Options{Help: opt.Help, Path: opt.Path}) } + stringListOptions := []CmdOption{ + {"f", "find", "Search entries with terms", " ...", ""}, + } + + for _, opt := range stringListOptions { + optMap[opt.Long] = parser.StringList(opt.Short, opt.Long, &argparse.Options{Help: opt.Help, Path: opt.Path}) + } + boolOptions := []CmdOption{ {"e", "encrypt", "Encrypt the current database", "", ""}, {"A", "add", "Add a new entry", "", ""}, From 3624934f5e437b3e1c5c25142b1ad52363f70ef4 Mon Sep 17 00:00:00 2001 From: Anand Date: Tue, 14 Dec 2021 15:43:30 +0530 Subject: [PATCH 4/4] ref issue #10 - Added readme entry for searching with multiple terms --- README.md | 68 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 970efa3..512d257 100644 --- a/README.md +++ b/README.md @@ -69,38 +69,39 @@ The binary will be installed in `/usr/local/bin` folder. Usage ===== - $ ./varuh -h + $ varuh -h usage: varuh [-h|--help] [-I|--init ""] [-d|--decrypt ""] [-C|--clone ""] [-R|--remove ""] [-U|--use-db - ""] [-f|--find ""] [-E|--edit ""] - [-l|--list-entry ""] [-x|--export ""] [-e|--encrypt] - [-A|--add] [-p|--path] [-a|--list-all] [-g|--genpass] [-s|--show] - [-c|--copy] [-y|--assume-yes] [-v|--version] + ""] [-E|--edit ""] [-l|--list-entry ""] + [-x|--export ""] [-f|--find "" [-f|--find "" + ...]] [-e|--encrypt] [-A|--add] [-p|--path] [-a|--list-all] + [-g|--genpass] [-s|--show] [-c|--copy] [-y|--assume-yes] + [-v|--version] Password manager for the command line for Unix like operating systems Options: - -h --help Print help information - -I --init Initialize a new database - -d --decrypt Decrypt password database - -C --clone Clone an entry with - -R --remove Remove an entry with or - -U --use-db Set as active database - -f --find Search entries with - -E --edit Edit entry by - -l --list-entry List entry by - -x --export Export all entries to - -e --encrypt Encrypt the current database - -A --add Add a new entry - -p --path Show current database path - -a --list-all List all entries in current database - -g --genpass Generate a strong password (length: 12 - 16) - -s --show Show passwords when listing entries - -c --copy Copy password to clipboard - -y --assume-yes Assume yes to actions requiring confirmation - -v --version Show version information and exit + -h --help Print help information + -I --init Initialize a new database + -d --decrypt Decrypt password database + -C --clone Clone an entry with + -R --remove Remove an entry with or + -U --use-db Set as active database + -E --edit Edit entry by + -l --list-entry List entry by + -x --export Export all entries to + -f --find ... Search entries with terms + -e --encrypt Encrypt the current database + -A --add Add a new entry + -p --path Show current database path + -a --list-all List all entries in current database + -g --genpass Generate a strong password (length: 12 - 16) + -s --show Show passwords when listing entries + -c --copy Copy password to clipboard + -y --assume-yes Assume yes to actions requiring confirmation + -v --version Show version information and exit AUTHORS @@ -441,6 +442,25 @@ An entry can be searched on its title, username, URL or notes. Search is case-in Modified: 2021-21-25 15:09:51 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +## To search using multiple terms + +The `-f` option supports multiple terms, so you can specify this more than one time to narrow a search down to a specific entry. + + $ varuh -f google -f anand + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ID: 8 + Title: Google account + User: anandpillai@alumni.iitm.ac.in + URL: + Password: ********** + Notes: + Modified: 2021-21-25 15:02:50 + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + $ varuh -f google -f priya + Entry for "google priya" not found + ## To list all entries To list all entries, use the option `-a`.