GC: Event collections to be referenced by calendarID instead of folder (#636)

`data.Collection` of type event  `fullPath()` contain the calendar id
This commit is contained in:
Danny 2022-08-23 13:38:30 -04:00 committed by GitHub
parent 99908b914d
commit a1f79862f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 121 additions and 21 deletions

View File

@ -248,6 +248,49 @@ func (suite *ExchangeServiceSuite) TestGraphQueryFunctions() {
}
}
// TestParseCalendarIDFromEvent verifies that parse function
// works on the current accepted reference format of
// additional data["calendar@odata.associationLink"]
func (suite *ExchangeServiceSuite) TestParseCalendarIDFromEvent() {
tests := []struct {
name string
input string
checkError assert.ErrorAssertionFunc
}{
{
name: "Empty string",
input: "",
checkError: assert.Error,
},
{
name: "Invalid string",
input: "https://github.com/whyNot/calendarNot Used",
checkError: assert.Error,
},
{
name: "Missing calendarID not found",
input: "https://graph.microsoft.com/v1.0/users" +
"('invalid@onmicrosoft.com')/calendars(" +
"'')/$ref",
checkError: assert.Error,
},
{
name: "Valid string",
input: "https://graph.microsoft.com/v1.0/users" +
"('valid@onmicrosoft.com')/calendars(" +
"'AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAA" +
"DCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAEGAADSEBNbUIB9RL6ePDeF3FIYAAAZkDq1AAA=')/$ref",
checkError: assert.NoError,
},
}
for _, test := range tests {
suite.T().Run(test.name, func(t *testing.T) {
_, err := parseCalendarIDFromEvent(test.input)
test.checkError(t, err)
})
}
}
// TestIterativeFunctions verifies that GraphQuery to Iterate
// functions are valid for current versioning of msgraph-go-sdk
func (suite *ExchangeServiceSuite) TestIterativeFunctions() {

View File

@ -177,6 +177,28 @@ func GetMailFolderID(service graph.Service, folderName, user string) (*string, e
return folderID, errs
}
// parseCalendarIDFromEvent returns the M365 ID for a calendar
// @param reference: string from additionalData map of an event
// References should follow the form `https://... calendars('ID')/$ref`
// If the reference does not follow form an error is returned
func parseCalendarIDFromEvent(reference string) (string, error) {
stringArray := strings.Split(reference, "calendars('")
if len(stringArray) < 2 {
return "", errors.New("calendarID not found")
}
temp := stringArray[1]
stringArray = strings.Split(temp, "')/$ref")
if len(stringArray) < 2 {
return "", errors.New("calendarID not found")
}
calendarID := stringArray[0]
if len(calendarID) == 0 {
return "", errors.New("calendarID empty")
}
return calendarID, nil
}
// SetupExchangeCollectionVars is a helper function returns a sets
// Exchange.Type specific functions based on scope
func SetupExchangeCollectionVars(scope selectors.ExchangeScope) (

View File

@ -147,9 +147,10 @@ func GetAllUsersForTenant(gs graph.Service, user string) (absser.Parsable, error
}
// GetAllEvents for User. Default returns EventResponseCollection for future events.
// of the time that the call was made. There a
// of the time that the call was made. 'calendar' option must be present to gain
// access to additional data map in future calls.
func GetAllEventsForUser(gs graph.Service, user string) (absser.Parsable, error) {
options, err := optionsForEvents([]string{"id"})
options, err := optionsForEvents([]string{"id", "calendar"})
if err != nil {
return nil, err
}
@ -236,6 +237,10 @@ func IterateSelectAllMessagesForCollections(
}
}
// IterateSelectAllEventsForCollections
// utility function for iterating through events
// and storing events in collections based on
// the calendarID which originates from M365.
func IterateSelectAllEventsForCollections(
tenant string,
scope selectors.ExchangeScope,
@ -245,26 +250,8 @@ func IterateSelectAllEventsForCollections(
collections map[string]*Collection,
statusCh chan<- *support.ConnectorOperationStatus,
) func(any) bool {
var isDirectorySet bool
return func(eventItem any) bool {
eventFolder := "Events"
user := scope.Get(selectors.ExchangeUser)[0]
if !isDirectorySet {
service, err := createService(credentials, failFast)
if err != nil {
errs = support.WrapAndAppend(user, err, errs)
return true
}
edc := NewCollection(
user,
[]string{tenant, user, eventsCategory, eventFolder},
events,
service,
statusCh,
)
collections[eventFolder] = &edc
isDirectorySet = true
}
event, ok := eventItem.(models.Eventable)
if !ok {
@ -276,7 +263,55 @@ func IterateSelectAllEventsForCollections(
return true
}
collections[eventFolder].AddJob(*event.GetId())
adtl := event.GetAdditionalData()
value, ok := adtl["calendar@odata.associationLink"]
if !ok {
errs = support.WrapAndAppend(
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(
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)
if err != nil {
errs = support.WrapAndAppend(
user,
errors.Wrap(err, *event.GetId()),
errs,
)
return true
}
if _, ok := collections[directory]; !ok {
service, err := createService(credentials, failFast)
if err != nil {
errs = support.WrapAndAppend(user, err, errs)
return true
}
edc := NewCollection(
user,
[]string{tenant, user, eventsCategory, directory},
events,
service,
statusCh,
)
collections[directory] = &edc
}
collections[directory].AddJob(*event.GetId())
return true
}
}