From 1929b2307f13ec193b62cf991683d5c5b95199e1 Mon Sep 17 00:00:00 2001 From: Keepers <104464746+ryanfkeepers@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:31:34 -0600 Subject: [PATCH] reduce filter selector flags to single strings (#393) * reduce filter selector flags to single strings Since it doesn't make sense for many of the filter-type selector flags to receive multiple input values (ex: what would --received-after date1,date2 result in?), the filter flags are getting reduced to single-string values. --- src/cli/backup/exchange.go | 30 +++++++++++++++--------------- src/cli/backup/exchange_test.go | 27 +++------------------------ src/cli/restore/exchange.go | 30 +++++++++++++++--------------- src/cli/restore/exchange_test.go | 27 +++------------------------ src/pkg/selectors/exchange.go | 28 +++++++++++++--------------- src/pkg/selectors/exchange_test.go | 12 ++++++------ src/pkg/selectors/selectors.go | 2 ++ 7 files changed, 57 insertions(+), 99 deletions(-) diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index 5fb6ccf51..5c0bea99a 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -27,10 +27,10 @@ var ( contactFolder []string email []string emailFolder []string - emailReceivedAfter []string - emailReceivedBefore []string - emailSender []string - emailSubject []string + emailReceivedAfter string + emailReceivedBefore string + emailSender string + emailSubject string event []string user []string ) @@ -93,10 +93,10 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { cobra.CheckErr(fs.MarkHidden("event")) // exchange-info flags - fs.StringArrayVar(&emailReceivedAfter, "email-received-after", nil, "Select backup details where the email was received after this datetime") - fs.StringArrayVar(&emailReceivedBefore, "email-received-before", nil, "Select backup details where the email was received before this datetime") - fs.StringArrayVar(&emailSender, "email-sender", nil, "Select backup details where the email sender matches this user id") - fs.StringArrayVar(&emailSubject, "email-subject", nil, "Select backup details where the email subject lines contain this value") + fs.StringVar(&emailReceivedAfter, "email-received-after", "", "Select backup details where the email was received after this datetime") + fs.StringVar(&emailReceivedBefore, "email-received-before", "", "Select backup details where the email was received before this datetime") + fs.StringVar(&emailSender, "email-sender", "", "Select backup details where the email sender matches this user id") + fs.StringVar(&emailSubject, "email-subject", "", "Select backup details where the email subject lines contain this value") } return c @@ -392,7 +392,7 @@ func includeExchangeEvents(sel *selectors.ExchangeRestore, users, events []strin // builds the info-selector filters for `backup details exchange` func filterExchangeBackupDetailInfoSelectors( sel *selectors.ExchangeRestore, - emailReceivedAfter, emailReceivedBefore, emailSender, emailSubject []string, + emailReceivedAfter, emailReceivedBefore, emailSender, emailSubject string, ) { filterExchangeInfoMailReceivedAfter(sel, emailReceivedAfter) filterExchangeInfoMailReceivedBefore(sel, emailReceivedBefore) @@ -400,32 +400,32 @@ func filterExchangeBackupDetailInfoSelectors( filterExchangeInfoMailSubject(sel, emailSubject) } -func filterExchangeInfoMailReceivedAfter(sel *selectors.ExchangeRestore, receivedAfter []string) { +func filterExchangeInfoMailReceivedAfter(sel *selectors.ExchangeRestore, receivedAfter string) { if len(receivedAfter) == 0 { return } sel.Filter(sel.MailReceivedAfter(receivedAfter)) } -func filterExchangeInfoMailReceivedBefore(sel *selectors.ExchangeRestore, receivedBefore []string) { +func filterExchangeInfoMailReceivedBefore(sel *selectors.ExchangeRestore, receivedBefore string) { if len(receivedBefore) == 0 { return } sel.Filter(sel.MailReceivedBefore(receivedBefore)) } -func filterExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender []string) { +func filterExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender string) { if len(sender) == 0 { return } - sel.Filter(sel.MailSender(sender)) + sel.Filter(sel.MailSender([]string{sender})) } -func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject []string) { +func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject string) { if len(subject) == 0 { return } - sel.Filter(sel.MailSubject(subject)) + sel.Filter(sel.MailSubject([]string{subject})) } // checks all flags for correctness and interdependencies diff --git a/src/cli/backup/exchange_test.go b/src/cli/backup/exchange_test.go index 7f63715ad..e9febc7a5 100644 --- a/src/cli/backup/exchange_test.go +++ b/src/cli/backup/exchange_test.go @@ -481,12 +481,11 @@ func (suite *ExchangeSuite) TestIncludeExchangeBackupDetailDataSelectors() { } func (suite *ExchangeSuite) TestFilterExchangeBackupDetailInfoSelectors() { - stub := []string{"id-stub"} - twoStubs := []string{"smarfs", "fnords"} - any := []string{utils.Wildcard} + stub := "id-stub" + any := utils.Wildcard table := []struct { name string - after, before, sender, subject []string + after, before, sender, subject string expectFilterLen int }{ { @@ -503,11 +502,6 @@ func (suite *ExchangeSuite) TestFilterExchangeBackupDetailInfoSelectors() { after: stub, expectFilterLen: 1, }, - { - name: "multiple receivedAfter", - after: twoStubs, - expectFilterLen: 1, - }, { name: "any receivedBefore", before: any, @@ -518,11 +512,6 @@ func (suite *ExchangeSuite) TestFilterExchangeBackupDetailInfoSelectors() { before: stub, expectFilterLen: 1, }, - { - name: "multiple receivedBefore", - before: twoStubs, - expectFilterLen: 1, - }, { name: "any sender", sender: any, @@ -533,11 +522,6 @@ func (suite *ExchangeSuite) TestFilterExchangeBackupDetailInfoSelectors() { sender: stub, expectFilterLen: 1, }, - { - name: "multiple senders", - sender: twoStubs, - expectFilterLen: 1, - }, { name: "any subject", subject: any, @@ -548,11 +532,6 @@ func (suite *ExchangeSuite) TestFilterExchangeBackupDetailInfoSelectors() { subject: stub, expectFilterLen: 1, }, - { - name: "multiple subjects", - subject: twoStubs, - expectFilterLen: 1, - }, { name: "one of each", after: stub, diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index 4bad24049..cf5868268 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -22,10 +22,10 @@ var ( contactFolder []string email []string emailFolder []string - emailReceivedAfter []string - emailReceivedBefore []string - emailSender []string - emailSubject []string + emailReceivedAfter string + emailReceivedBefore string + emailSender string + emailSubject string event []string user []string ) @@ -65,10 +65,10 @@ func addExchangeCommands(parent *cobra.Command) *cobra.Command { cobra.CheckErr(fs.MarkHidden("event")) // exchange-info flags - fs.StringArrayVar(&emailReceivedAfter, "email-received-after", nil, "Restore mail where the email was received after this datetime") - fs.StringArrayVar(&emailReceivedBefore, "email-received-before", nil, "Restore mail where the email was received before this datetime") - fs.StringArrayVar(&emailSender, "email-sender", nil, "Restore mail where the email sender matches this user id") - fs.StringArrayVar(&emailSubject, "email-subject", nil, "Restore mail where the email subject lines contain this value") + fs.StringVar(&emailReceivedAfter, "email-received-after", "", "Restore mail where the email was received after this datetime") + fs.StringVar(&emailReceivedBefore, "email-received-before", "", "Restore mail where the email was received before this datetime") + fs.StringVar(&emailSender, "email-sender", "", "Restore mail where the email sender matches this user id") + fs.StringVar(&emailSubject, "email-subject", "", "Restore mail where the email subject lines contain this value") // others options.AddOperationFlags(c) @@ -221,7 +221,7 @@ func includeExchangeEvents(sel *selectors.ExchangeRestore, users, events []strin // builds the info-selector filters for `restore exchange` func filterExchangeRestoreInfoSelectors( sel *selectors.ExchangeRestore, - emailReceivedAfter, emailReceivedBefore, emailSender, emailSubject []string, + emailReceivedAfter, emailReceivedBefore, emailSender, emailSubject string, ) { filterExchangeInfoMailReceivedAfter(sel, emailReceivedAfter) filterExchangeInfoMailReceivedBefore(sel, emailReceivedBefore) @@ -229,32 +229,32 @@ func filterExchangeRestoreInfoSelectors( filterExchangeInfoMailSubject(sel, emailSubject) } -func filterExchangeInfoMailReceivedAfter(sel *selectors.ExchangeRestore, receivedAfter []string) { +func filterExchangeInfoMailReceivedAfter(sel *selectors.ExchangeRestore, receivedAfter string) { if len(receivedAfter) == 0 { return } sel.Filter(sel.MailReceivedAfter(receivedAfter)) } -func filterExchangeInfoMailReceivedBefore(sel *selectors.ExchangeRestore, receivedBefore []string) { +func filterExchangeInfoMailReceivedBefore(sel *selectors.ExchangeRestore, receivedBefore string) { if len(receivedBefore) == 0 { return } sel.Filter(sel.MailReceivedBefore(receivedBefore)) } -func filterExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender []string) { +func filterExchangeInfoMailSender(sel *selectors.ExchangeRestore, sender string) { if len(sender) == 0 { return } - sel.Filter(sel.MailSender(sender)) + sel.Filter(sel.MailSender([]string{sender})) } -func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject []string) { +func filterExchangeInfoMailSubject(sel *selectors.ExchangeRestore, subject string) { if len(subject) == 0 { return } - sel.Filter(sel.MailSubject(subject)) + sel.Filter(sel.MailSubject([]string{subject})) } // checks all flags for correctness and interdependencies diff --git a/src/cli/restore/exchange_test.go b/src/cli/restore/exchange_test.go index 75c85c232..9c9c6d46f 100644 --- a/src/cli/restore/exchange_test.go +++ b/src/cli/restore/exchange_test.go @@ -317,12 +317,11 @@ func (suite *ExchangeSuite) TestIncludeExchangeRestoreDataSelectors() { } func (suite *ExchangeSuite) TestFilterExchangeRestoreInfoSelectors() { - stub := []string{"id-stub"} - twoStubs := []string{"a-stub", "b-stub"} - any := []string{utils.Wildcard} + stub := "id-stub" + any := utils.Wildcard table := []struct { name string - after, before, sender, subject []string + after, before, sender, subject string expectFilterLen int }{ { @@ -339,11 +338,6 @@ func (suite *ExchangeSuite) TestFilterExchangeRestoreInfoSelectors() { after: stub, expectFilterLen: 1, }, - { - name: "multiple receivedAfter", - after: twoStubs, - expectFilterLen: 1, - }, { name: "any receivedBefore", before: any, @@ -354,11 +348,6 @@ func (suite *ExchangeSuite) TestFilterExchangeRestoreInfoSelectors() { before: stub, expectFilterLen: 1, }, - { - name: "multiple receivedBefore", - before: twoStubs, - expectFilterLen: 1, - }, { name: "any senders", sender: any, @@ -369,11 +358,6 @@ func (suite *ExchangeSuite) TestFilterExchangeRestoreInfoSelectors() { sender: stub, expectFilterLen: 1, }, - { - name: "multiple senders", - sender: twoStubs, - expectFilterLen: 1, - }, { name: "any subjects", subject: any, @@ -384,11 +368,6 @@ func (suite *ExchangeSuite) TestFilterExchangeRestoreInfoSelectors() { subject: stub, expectFilterLen: 1, }, - { - name: "multiple subjects", - subject: twoStubs, - expectFilterLen: 1, - }, { name: "one of each", after: stub, diff --git a/src/pkg/selectors/exchange.go b/src/pkg/selectors/exchange.go index 65f77d752..24bb34cd4 100644 --- a/src/pkg/selectors/exchange.go +++ b/src/pkg/selectors/exchange.go @@ -292,30 +292,28 @@ func makeExchangeFilterScope(cat, filterCat exchangeCategory, vs []string) Excha } } -// Produces one or more exchange mail received-after filter scopes. +// Produces an exchange mail received-after filter scope. // Matches any mail which was received after the timestring. -// If any slice contains selectors.Any, that slice is reduced to [selectors.Any] -// If any slice contains selectors.None, that slice is reduced to [selectors.None] -// If any slice is empty, it defaults to [selectors.None] -func (sr *ExchangeRestore) MailReceivedAfter(timeStrings []string) []ExchangeScope { +// If the input equals selectors.Any, the scope will match all times. +// If the input is empty or selectors.None, the scope will always fail comparisons. +func (sr *ExchangeRestore) MailReceivedAfter(timeStrings string) []ExchangeScope { return []ExchangeScope{ - makeExchangeFilterScope(ExchangeMail, ExchangeInfoMailReceivedAfter, timeStrings), + makeExchangeFilterScope(ExchangeMail, ExchangeInfoMailReceivedAfter, []string{timeStrings}), } } -// Produces one or more exchange mail received-before filter scopes. -// Matches any mail whose mail subject contains one of the provided strings. -// If any slice contains selectors.Any, that slice is reduced to [selectors.Any] -// If any slice contains selectors.None, that slice is reduced to [selectors.None] -// If any slice is empty, it defaults to [selectors.None] -func (sr *ExchangeRestore) MailReceivedBefore(timeStrings []string) []ExchangeScope { +// Produces an exchange mail received-before filter scope. +// Matches any mail which was received before the timestring. +// If the input equals selectors.Any, the scope will match all times. +// If the input is empty or selectors.None, the scope will always fail comparisons. +func (sr *ExchangeRestore) MailReceivedBefore(timeStrings string) []ExchangeScope { return []ExchangeScope{ - makeExchangeFilterScope(ExchangeMail, ExchangeInfoMailReceivedBefore, timeStrings), + makeExchangeFilterScope(ExchangeMail, ExchangeInfoMailReceivedBefore, []string{timeStrings}), } } // Produces one or more exchange mail sender filter scopes. -// Matches any mail which was received after the timestring. +// Matches any mail whose mail sender equals one of the provided strings. // If any slice contains selectors.Any, that slice is reduced to [selectors.Any] // If any slice contains selectors.None, that slice is reduced to [selectors.None] // If any slice is empty, it defaults to [selectors.None] @@ -326,7 +324,7 @@ func (sr *ExchangeRestore) MailSender(senderIDs []string) []ExchangeScope { } // Produces one or more exchange mail subject line filter scopes. -// Matches any mail which was received before the timestring. +// Matches any mail whose mail subject contains one of the provided strings. // If any slice contains selectors.Any, that slice is reduced to [selectors.Any] // If any slice contains selectors.None, that slice is reduced to [selectors.None] // If any slice is empty, it defaults to [selectors.None] diff --git a/src/pkg/selectors/exchange_test.go b/src/pkg/selectors/exchange_test.go index 533ca1dc1..167a8705a 100644 --- a/src/pkg/selectors/exchange_test.go +++ b/src/pkg/selectors/exchange_test.go @@ -519,12 +519,12 @@ func (suite *ExchangeSourceSuite) TestExchangeScope_MatchesInfo() { {"mail with a different subject", es.MailSubject([]string{"fancy"}), assert.False}, {"mail with the matching subject", es.MailSubject([]string{subject}), assert.True}, {"mail with a substring subject match", es.MailSubject([]string{subject[5:9]}), assert.True}, - {"mail received after the epoch", es.MailReceivedAfter([]string{common.FormatTime(epoch)}), assert.True}, - {"mail received after now", es.MailReceivedAfter([]string{common.FormatTime(now)}), assert.False}, - {"mail received after sometime later", es.MailReceivedAfter([]string{common.FormatTime(then)}), assert.False}, - {"mail received before the epoch", es.MailReceivedBefore([]string{common.FormatTime(epoch)}), assert.False}, - {"mail received before now", es.MailReceivedBefore([]string{common.FormatTime(now)}), assert.False}, - {"mail received before sometime later", es.MailReceivedBefore([]string{common.FormatTime(then)}), assert.True}, + {"mail received after the epoch", es.MailReceivedAfter(common.FormatTime(epoch)), assert.True}, + {"mail received after now", es.MailReceivedAfter(common.FormatTime(now)), assert.False}, + {"mail received after sometime later", es.MailReceivedAfter(common.FormatTime(then)), assert.False}, + {"mail received before the epoch", es.MailReceivedBefore(common.FormatTime(epoch)), assert.False}, + {"mail received before now", es.MailReceivedBefore(common.FormatTime(now)), assert.False}, + {"mail received before sometime later", es.MailReceivedBefore(common.FormatTime(then)), assert.True}, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { diff --git a/src/pkg/selectors/selectors.go b/src/pkg/selectors/selectors.go index 552d11e56..510b523c5 100644 --- a/src/pkg/selectors/selectors.go +++ b/src/pkg/selectors/selectors.go @@ -31,6 +31,8 @@ const ( Filter = "filter" ) +// The granularity exprerssed by the scope. Groups imply non-item granularity, +// such as a directory. Items are individual files or objects. const ( // AnyTgt is the target value used to select "any data of " // Ex: {user: u1, events: AnyTgt) => all events for user u1.