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:
parent
597e689417
commit
2d29258caf
@ -6,6 +6,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime/trace"
|
"runtime/trace"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
@ -377,9 +378,15 @@ func IsNonRecoverableError(e error) bool {
|
|||||||
return errors.As(e, &nonRecoverable)
|
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) {
|
func (gc *GraphConnector) DataCollections(ctx context.Context, sels selectors.Selector) ([]data.Collection, error) {
|
||||||
defer trace.StartRegion(ctx, "gc:dataCollections:"+sels.Service.String()).End()
|
defer trace.StartRegion(ctx, "gc:dataCollections:"+sels.Service.String()).End()
|
||||||
|
|
||||||
|
err := verifyBackupInputs(sels, gc.Users)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
switch sels.Service {
|
switch sels.Service {
|
||||||
case selectors.ServiceExchange:
|
case selectors.ServiceExchange:
|
||||||
return gc.ExchangeDataCollection(ctx, sels)
|
return gc.ExchangeDataCollection(ctx, sels)
|
||||||
@ -433,3 +440,49 @@ func (gc *GraphConnector) OneDriveDataCollections(
|
|||||||
|
|
||||||
return collections, errs
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -204,3 +204,64 @@ func (suite *DisconnectedGraphConnectorSuite) TestRestoreFailsBadService() {
|
|||||||
assert.Equal(t, 0, status.FolderCount)
|
assert.Equal(t, 0, status.FolderCount)
|
||||||
assert.Equal(t, 0, status.Successful)
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -79,6 +79,44 @@ func (suite *GraphConnectorIntegrationSuite) TestSetTenantUsers() {
|
|||||||
suite.Greater(len(newConnector.Users), 0)
|
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
|
// TestExchangeDataCollection verifies interface between operation and
|
||||||
// GraphConnector remains stable to receive a non-zero amount of Collections
|
// GraphConnector remains stable to receive a non-zero amount of Collections
|
||||||
// for the Exchange Package. Enabled exchange applications:
|
// for the Exchange Package. Enabled exchange applications:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user