diff --git a/src/pkg/selectors/exchange.go b/src/pkg/selectors/exchange.go index a6a52af78..f095bec96 100644 --- a/src/pkg/selectors/exchange.go +++ b/src/pkg/selectors/exchange.go @@ -260,7 +260,22 @@ func (s *exchange) Users(users []string) []ExchangeScope { // ------------------- // Filter Factories -// Produces an exchange mail received-after filter scope. +// ContactName produces one or more exchange contact name filter scopes. +// Matches any contact whose name contains the provided string. +// 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) ContactName(senderID string) []ExchangeScope { + return []ExchangeScope{ + makeFilterScope[ExchangeScope]( + ExchangeContact, + ExchangeFilterContactName, + []string{senderID}, + wrapFilter(filters.In)), + } +} + +// MailReceivedAfter produces an exchange mail received-after filter scope. // Matches any mail which was received after 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. @@ -274,7 +289,7 @@ func (sr *ExchangeRestore) MailReceivedAfter(timeStrings string) []ExchangeScope } } -// Produces an exchange mail received-before filter scope. +// MailReceivedBefore 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. @@ -288,8 +303,8 @@ func (sr *ExchangeRestore) MailReceivedBefore(timeStrings string) []ExchangeScop } } -// Produces one or more exchange mail sender filter scopes. -// Matches any mail whose mail sender equals one of the provided strings. +// MailSender produces one or more exchange mail sender filter scopes. +// Matches any mail whose sender 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] @@ -303,8 +318,8 @@ func (sr *ExchangeRestore) MailSender(senderIDs []string) []ExchangeScope { } } -// Produces one or more exchange mail subject line filter scopes. -// Matches any mail whose mail subject contains one of the provided strings. +// MailSubject produces one or more exchange mail subject line filter scopes. +// Matches any mail whose 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] @@ -376,11 +391,15 @@ const ( ExchangeMail exchangeCategory = "ExchangeMail" ExchangeMailFolder exchangeCategory = "ExchangeFolder" ExchangeUser exchangeCategory = "ExchangeUser" + // append new data cats here + // filterable topics identified by exchange ExchangeFilterMailSender exchangeCategory = "ExchangeFilterMailSender" ExchangeFilterMailSubject exchangeCategory = "ExchangeFilterMailSubject" ExchangeFilterMailReceivedAfter exchangeCategory = "ExchangeFilterMailReceivedAfter" ExchangeFilterMailReceivedBefore exchangeCategory = "ExchangeFilterMailReceivedBefore" + ExchangeFilterContactName exchangeCategory = "ExchangeFilterContactName" + // append new filter cats here ) // exchangePathSet describes the category type keys used in Exchange paths. @@ -407,7 +426,7 @@ func (ec exchangeCategory) String() string { // Ex: ExchangeUser.leafCat() => ExchangeUser func (ec exchangeCategory) leafCat() categorizer { switch ec { - case ExchangeContact, ExchangeContactFolder: + case ExchangeContact, ExchangeContactFolder, ExchangeFilterContactName: return ExchangeContact case ExchangeMail, ExchangeMailFolder, ExchangeFilterMailReceivedAfter, ExchangeFilterMailReceivedBefore, ExchangeFilterMailSender, ExchangeFilterMailSubject: @@ -606,6 +625,8 @@ func (s ExchangeScope) matchesInfo(info *details.ExchangeInfo) bool { i := "" switch filterCat { + case ExchangeFilterContactName: + i = info.ContactName case ExchangeFilterMailSender: i = info.Sender case ExchangeFilterMailSubject: diff --git a/src/pkg/selectors/exchange_test.go b/src/pkg/selectors/exchange_test.go index af3f19e07..53212aa40 100644 --- a/src/pkg/selectors/exchange_test.go +++ b/src/pkg/selectors/exchange_test.go @@ -646,6 +646,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() { es := NewExchangeRestore() const ( + name = "smarf mcfnords" sender = "smarf@2many.cooks" subject = "I have seen the fnords!" ) @@ -655,9 +656,10 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() { now = time.Now() then = now.Add(1 * time.Minute) info = &details.ExchangeInfo{ - Sender: sender, - Subject: subject, - Received: now, + Sender: sender, + Subject: subject, + Received: now, + ContactName: name, } ) @@ -681,6 +683,9 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() { {"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}, + {"contact with a different name", es.ContactName("blarps"), assert.False}, + {"contact with the same name", es.ContactName(name), assert.True}, + {"contact with a subname search", es.ContactName(name[2:5]), assert.True}, } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) {