GC: User Validation Feature (#1261)

## Description
verifyBackupInputs() is a newly created function that ensures that a selector given to GraphConnector is valid to continue.
Test src file:  `graph_connector_test.go` expanded. 
<!-- Insert PR description-->

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🌻 Feature
- [x] 🐛 Bugfix


## Issue(s)

<!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. -->
*closes  #1258<issue>

## Test Plan

- [x]  Unit test
This commit is contained in:
Danny 2022-10-21 18:36:56 -04:00 committed by GitHub
parent 597e689417
commit 2d29258caf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 152 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import (
"context"
"fmt"
"runtime/trace"
"strings"
"sync"
"github.com/hashicorp/go-multierror"
@ -377,9 +378,15 @@ func IsNonRecoverableError(e error) bool {
return errors.As(e, &nonRecoverable)
}
// DataCollections utility function to launch backup operations for exchange and onedrive
func (gc *GraphConnector) DataCollections(ctx context.Context, sels selectors.Selector) ([]data.Collection, error) {
defer trace.StartRegion(ctx, "gc:dataCollections:"+sels.Service.String()).End()
err := verifyBackupInputs(sels, gc.Users)
if err != nil {
return nil, err
}
switch sels.Service {
case selectors.ServiceExchange:
return gc.ExchangeDataCollection(ctx, sels)
@ -433,3 +440,49 @@ func (gc *GraphConnector) OneDriveDataCollections(
return collections, errs
}
func verifyBackupInputs(sel selectors.Selector, mapOfUsers map[string]string) error {
var personnel []string
// retrieve users from selectors
switch sel.Service {
case selectors.ServiceExchange:
backup, err := sel.ToExchangeBackup()
if err != nil {
return err
}
for _, scope := range backup.Scopes() {
temp := scope.Get(selectors.ExchangeUser)
personnel = append(personnel, temp...)
}
case selectors.ServiceOneDrive:
backup, err := sel.ToOneDriveBackup()
if err != nil {
return err
}
for _, user := range backup.Scopes() {
temp := user.Get(selectors.OneDriveUser)
personnel = append(personnel, temp...)
}
default:
return errors.New("service %s not supported")
}
// verify personnel
normUsers := map[string]struct{}{}
for k := range mapOfUsers {
normUsers[strings.ToLower(k)] = struct{}{}
}
for _, user := range personnel {
if _, ok := normUsers[strings.ToLower(user)]; !ok {
return fmt.Errorf("%s user not found within tenant", user)
}
}
return nil
}

View File

@ -204,3 +204,64 @@ func (suite *DisconnectedGraphConnectorSuite) TestRestoreFailsBadService() {
assert.Equal(t, 0, status.FolderCount)
assert.Equal(t, 0, status.Successful)
}
func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() {
users := make(map[string]string)
users["elliotReid@someHospital.org"] = ""
users["chrisTurk@someHospital.org"] = ""
users["carlaEspinosa@someHospital.org"] = ""
users["bobKelso@someHospital.org"] = ""
users["johnDorian@someHospital.org"] = ""
tests := []struct {
name string
getSelector func(t *testing.T) selectors.Selector
checkError assert.ErrorAssertionFunc
}{
{
name: "Invalid User",
checkError: assert.Error,
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup()
sel.Include(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any()))
return sel.Selector
},
},
{
name: "Valid Single User",
checkError: assert.NoError,
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup()
sel.Include(sel.MailFolders([]string{"bobkelso@someHospital.org"}, selectors.Any()))
return sel.Selector
},
},
{
name: "Partial invalid user",
checkError: assert.Error,
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup()
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()
sel.Include(
sel.Users([]string{"elliotReid@someHospital.org", "johnDorian@someHospital.org", "christurk@somehospital.org"}))
return sel.Selector
},
},
}
for _, test := range tests {
suite.T().Run(test.name, func(t *testing.T) {
err := verifyBackupInputs(test.getSelector(t), users)
test.checkError(t, err)
})
}
}

View File

@ -79,6 +79,44 @@ func (suite *GraphConnectorIntegrationSuite) TestSetTenantUsers() {
suite.Greater(len(newConnector.Users), 0)
}
// TestInvalidUserForDataCollections ensures verification process for users
func (suite *GraphConnectorIntegrationSuite) TestInvalidUserForDataCollections() {
ctx, flush := tester.NewContext()
defer flush()
invalidUser := "foo@example.com"
connector := loadConnector(ctx, suite.T())
tests := []struct {
name string
getSelector func(t *testing.T) selectors.Selector
}{
{
name: "invalid exchange backup user",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewExchangeBackup()
sel.Include(sel.MailFolders([]string{invalidUser}, selectors.Any()))
return sel.Selector
},
},
{
name: "Invalid onedrive backup user",
getSelector: func(t *testing.T) selectors.Selector {
sel := selectors.NewOneDriveBackup()
sel.Include(sel.Folders([]string{invalidUser}, selectors.Any()))
return sel.Selector
},
},
}
for _, test := range tests {
suite.T().Run(test.name, func(t *testing.T) {
collections, err := connector.DataCollections(ctx, test.getSelector(t))
assert.Error(t, err)
assert.Empty(t, collections)
})
}
}
// TestExchangeDataCollection verifies interface between operation and
// GraphConnector remains stable to receive a non-zero amount of Collections
// for the Exchange Package. Enabled exchange applications: