Fix --users "*' not finding user in tenant (#2033)

## Description

DataCollections validation step was still using the full resourceOwner list in the selector to validate every backup, rather than checking only the DiscreteOwner.

## Does this PR need a docs update or release note?

- [x]  No 

## Type of change

- [x] 🐛 Bugfix

## Issue(s)

* #1617

## Test Plan

- [x]  Unit test
This commit is contained in:
Keepers 2023-01-04 17:29:21 -07:00 committed by GitHub
parent bb5b2f23e9
commit edc4426b9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 31 deletions

View File

@ -272,7 +272,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error {
sel := exchangeBackupCreateSelectors(user, exchangeData)
users, err := m365.UserIDs(ctx, acct)
users, err := m365.UserPNs(ctx, acct)
if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to retrieve M365 users"))
}

View File

@ -194,7 +194,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error {
sel := oneDriveBackupCreateSelectors(user)
users, err := m365.UserIDs(ctx, acct)
users, err := m365.UserPNs(ctx, acct)
if err != nil {
return Only(ctx, errors.Wrap(err, "Failed to retrieve M365 users"))
}

View File

@ -98,8 +98,6 @@ func (gc *GraphConnector) DataCollections(
func verifyBackupInputs(sels selectors.Selector, userPNs, siteIDs []string) error {
var ids []string
resourceOwners := sels.DiscreteResourceOwners()
switch sels.Service {
case selectors.ServiceExchange, selectors.ServiceOneDrive:
ids = userPNs
@ -115,10 +113,8 @@ func verifyBackupInputs(sels selectors.Selector, userPNs, siteIDs []string) erro
normROs[strings.ToLower(id)] = struct{}{}
}
for _, ro := range resourceOwners {
if _, ok := normROs[strings.ToLower(ro)]; !ok {
return fmt.Errorf("included resource owner %s not found within tenant", ro)
}
if _, ok := normROs[strings.ToLower(sels.DiscreteOwner)]; !ok {
return fmt.Errorf("resource owner [%s] not found within tenant", sels.DiscreteOwner)
}
return nil

View File

@ -131,12 +131,11 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection
}
// TestInvalidUserForDataCollections ensures verification process for users
func (suite *ConnectorDataCollectionIntegrationSuite) TestInvalidUserForDataCollections() {
func (suite *ConnectorDataCollectionIntegrationSuite) TestDataCollections_invalidResourceOwner() {
ctx, flush := tester.NewContext()
defer flush()
invalidUser := "foo@example.com"
selUsers := []string{invalidUser}
owners := []string{"snuffleupagus"}
connector := loadConnector(ctx, suite.T(), Users)
tests := []struct {
@ -146,16 +145,51 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestInvalidUserForDataColl
{
name: "invalid exchange backup user",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup(selUsers)
sel.Include(sel.MailFolders(selUsers, selectors.Any()))
sel := selectors.NewExchangeBackup(owners)
sel.Include(sel.MailFolders(owners, selectors.Any()))
return sel.Selector
},
},
{
name: "Invalid onedrive backup user",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup(selUsers)
sel.Include(sel.Folders(selUsers, selectors.Any()))
sel := selectors.NewOneDriveBackup(owners)
sel.Include(sel.Folders(owners, selectors.Any()))
return sel.Selector
},
},
{
name: "Invalid sharepoint backup site",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup(owners)
sel.Include(sel.Libraries(owners, selectors.Any()))
return sel.Selector
},
},
{
name: "missing exchange backup user",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup(owners)
sel.Include(sel.MailFolders(owners, selectors.Any()))
sel.DiscreteOwner = ""
return sel.Selector
},
},
{
name: "missing onedrive backup user",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup(owners)
sel.Include(sel.Folders(owners, selectors.Any()))
sel.DiscreteOwner = ""
return sel.Selector
},
},
{
name: "missing sharepoint backup site",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup(owners)
sel.Include(sel.Libraries(owners, selectors.Any()))
sel.DiscreteOwner = ""
return sel.Selector
},
},

View File

@ -227,19 +227,7 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() {
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"})
sel.Include(sel.MailFolders([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"}, selectors.Any()))
return sel.Selector
},
},
{
name: "Multiple Valid Users",
checkError: assert.NoError,
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup(
[]string{"elliotReid@someHospital.org", "johnDorian@someHospital.org", "christurk@somehospital.org"},
)
sel.Include(
sel.Users([]string{"elliotReid@someHospital.org", "johnDorian@someHospital.org", "christurk@somehospital.org"}))
sel.DiscreteOwner = "janitor@someHospital.org"
return sel.Selector
},
},
@ -268,18 +256,21 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
name: "Valid User",
checkError: assert.NoError,
excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org"})
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"})
sel.Exclude(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any()))
sel.DiscreteOwner = "elliotReid@someHospital.org"
return sel.Selector
},
filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org"})
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"})
sel.Filter(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any()))
sel.DiscreteOwner = "elliotReid@someHospital.org"
return sel.Selector
},
includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org"})
sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org", "foo@SomeCompany.org"})
sel.Include(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any()))
sel.DiscreteOwner = "elliotReid@someHospital.org"
return sel.Selector
},
},
@ -308,16 +299,19 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"})
sel.Exclude(sel.Sites([]string{"abc.site.foo", "bar.site.baz"}))
sel.DiscreteOwner = "abc.site.foo"
return sel.Selector
},
filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"})
sel.Filter(sel.Sites([]string{"abc.site.foo", "bar.site.baz"}))
sel.DiscreteOwner = "abc.site.foo"
return sel.Selector
},
includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"})
sel.Include(sel.Sites([]string{"abc.site.foo", "bar.site.baz"}))
sel.DiscreteOwner = "abc.site.foo"
return sel.Selector
},
},
@ -327,16 +321,19 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices
excludes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"})
sel.Exclude(sel.Sites([]string{"fnords.smarfs.brawnhilda"}))
sel.DiscreteOwner = "fnords.smarfs.brawnhilda"
return sel.Selector
},
filters: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"})
sel.Filter(sel.Sites([]string{"fnords.smarfs.brawnhilda"}))
sel.DiscreteOwner = "fnords.smarfs.brawnhilda"
return sel.Selector
},
includes: func(t *testing.T) selectors.Selector {
sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"})
sel.Include(sel.Sites([]string{"fnords.smarfs.brawnhilda"}))
sel.DiscreteOwner = "fnords.smarfs.brawnhilda"
return sel.Selector
},
},

View File

@ -58,6 +58,22 @@ func UserIDs(ctx context.Context, m365Account account.Account) ([]string, error)
return ret, nil
}
// UserPNs retrieves all user principleNames in the tenant. Principle Names
// can be used analogous userIDs in graph API queries.
func UserPNs(ctx context.Context, m365Account account.Account) ([]string, error) {
users, err := Users(ctx, m365Account)
if err != nil {
return nil, err
}
ret := make([]string, 0, len(users))
for _, u := range users {
ret = append(ret, u.PrincipalName)
}
return ret, nil
}
// SiteURLs returns a list of SharePoint site WebURLs in the specified M365 tenant
func SiteURLs(ctx context.Context, m365Account account.Account) ([]string, error) {
gc, err := connector.NewGraphConnector(ctx, m365Account, connector.Sites)