diff --git a/src/internal/connector/exchange/iterators_test.go b/src/internal/connector/exchange/iterators_test.go index 6af549891..2a0279a35 100644 --- a/src/internal/connector/exchange/iterators_test.go +++ b/src/internal/connector/exchange/iterators_test.go @@ -77,12 +77,12 @@ func loadService(t *testing.T) *exchangeService { // functions are valid for current versioning of msgraph-go-sdk func (suite *ExchangeIteratorSuite) TestIterativeFunctions() { var ( - ctx = context.Background() - t = suite.T() - mailScope, contactScope selectors.ExchangeScope - userID = tester.M365UserID(t) - sel = selectors.NewExchangeBackup() - service = loadService(t) + ctx = context.Background() + t = suite.T() + mailScope, contactScope, eventScope selectors.ExchangeScope + userID = tester.M365UserID(t) + sel = selectors.NewExchangeBackup() + service = loadService(t) ) sel.Include(sel.Users([]string{userID})) @@ -100,6 +100,10 @@ func (suite *ExchangeIteratorSuite) TestIterativeFunctions() { if scope.IncludesCategory(selectors.ExchangeMail) { mailScope = scope } + + if scope.IncludesCategory(selectors.ExchangeEvent) { + eventScope = scope + } } tests := []struct { @@ -126,6 +130,12 @@ func (suite *ExchangeIteratorSuite) TestIterativeFunctions() { iterativeFunction: IterateSelectAllDescendablesForCollections, scope: contactScope, transformer: models.CreateContactFromDiscriminatorValue, + }, { + name: "Events Iterative Check", + queryFunction: GetAllCalendarNamesForUser, + iterativeFunction: IterateSelectAllEventsFromCalendars, + scope: eventScope, + transformer: models.CreateCalendarCollectionResponseFromDiscriminatorValue, }, { name: "Folder Iterative Check", queryFunction: GetAllFolderNamesForUser, diff --git a/src/internal/connector/exchange/service_functions.go b/src/internal/connector/exchange/service_functions.go index be5288fb3..35a591f37 100644 --- a/src/internal/connector/exchange/service_functions.go +++ b/src/internal/connector/exchange/service_functions.go @@ -281,9 +281,9 @@ func SetupExchangeCollectionVars(scope selectors.ExchangeScope) ( } if scope.IncludesCategory(selectors.ExchangeEvent) { - return models.CreateEventCollectionResponseFromDiscriminatorValue, - GetAllEventsForUser, - IterateSelectAllEventsForCollections, + return models.CreateCalendarCollectionResponseFromDiscriminatorValue, + GetAllCalendarNamesForUser, + IterateSelectAllEventsFromCalendars, nil } diff --git a/src/internal/connector/exchange/service_iterators.go b/src/internal/connector/exchange/service_iterators.go index 68f21b5ab..6709669d9 100644 --- a/src/internal/connector/exchange/service_iterators.go +++ b/src/internal/connector/exchange/service_iterators.go @@ -2,7 +2,6 @@ package exchange import ( "context" - "fmt" "strings" "github.com/microsoftgraph/msgraph-sdk-go/models" @@ -203,79 +202,88 @@ func IterateSelectAllDescendablesForCollections( // utility function for iterating through events // and storing events in collections based on // the calendarID which originates from M365. -func IterateSelectAllEventsForCollections( +func IterateSelectAllEventsFromCalendars( ctx context.Context, qp graph.QueryParams, errs error, collections map[string]*Collection, statusUpdater support.StatusUpdater, ) func(any) bool { - return func(eventItem any) bool { - event, ok := eventItem.(models.Eventable) + return func(pageItem any) bool { + if pageItem == nil { + return true + } + + shell, ok := pageItem.(models.Calendarable) if !ok { errs = support.WrapAndAppend( qp.User, - errors.New("event iteration failure"), - errs, - ) + errors.New("calendar event"), + errs) return true } - adtl := event.GetAdditionalData() - - value, ok := adtl["calendar@odata.associationLink"] - if !ok { - errs = support.WrapAndAppend( - qp.User, - fmt.Errorf("%s: does not support calendar look up", *event.GetId()), - errs, - ) - - return true - } - - link, ok := value.(*string) - if !ok || link == nil { - errs = support.WrapAndAppend( - qp.User, - fmt.Errorf("%s: unable to obtain calendar event data", *event.GetId()), - errs, - ) - - return true - } - // calendars and events are not easily correlated - // helper function retrieves calendarID from url - directory, err := parseCalendarIDFromEvent(*link) + service, err := createService(qp.Credentials, qp.FailFast) if err != nil { errs = support.WrapAndAppend( qp.User, - errors.Wrap(err, *event.GetId()), + errors.Wrap(err, "unable to create service during IterateSelectAllEventsFromCalendars"), errs, ) return true } - if _, ok := collections[directory]; !ok { + eventResponseable, err := service.Client(). + UsersById(qp.User). + CalendarsById(*shell.GetId()). + Events().Get() + if err != nil { + errs = support.WrapAndAppend( + qp.User, + err, + errs, + ) + } + + directory := shell.GetName() + owner := shell.GetOwner() + + // Conditional Guard Checks + if eventResponseable == nil || + directory == nil || + owner == nil { + return true + } + + eventables := eventResponseable.GetValue() + // Clause is true when Calendar has does not have any events + if eventables == nil { + return true + } + + if _, ok := collections[*directory]; !ok { service, err := createService(qp.Credentials, qp.FailFast) if err != nil { errs = support.WrapAndAppend(qp.User, err, errs) + return true } edc := NewCollection( qp.User, - []string{qp.Credentials.TenantID, qp.User, path.EventsCategory.String(), directory}, + []string{qp.Credentials.TenantID, qp.User, path.EventsCategory.String(), *directory}, events, service, statusUpdater, ) - collections[directory] = &edc + collections[*directory] = &edc } - collections[directory].AddJob(*event.GetId()) + for _, event := range eventables { + collections[*directory].AddJob(*event.GetId()) + } return true } diff --git a/src/internal/connector/exchange/service_query.go b/src/internal/connector/exchange/service_query.go index 2134aa5cf..ac0b05b2a 100644 --- a/src/internal/connector/exchange/service_query.go +++ b/src/internal/connector/exchange/service_query.go @@ -55,7 +55,7 @@ func GetAllFolderNamesForUser(gs graph.Service, user string) (absser.Parsable, e } func GetAllCalendarNamesForUser(gs graph.Service, user string) (absser.Parsable, error) { - options, err := optionsForCalendars([]string{"name"}) + options, err := optionsForCalendars([]string{"name", "owner"}) if err != nil { return nil, err }