GC: Restore: Retrieve CalendarID Feature (#687)
Feature added to be able to retrieve containerID for `exchange.Event` types.
This commit is contained in:
parent
7a8c6eaf78
commit
b5a5378113
28
src/internal/connector/exchange/calendar.go
Normal file
28
src/internal/connector/exchange/calendar.go
Normal file
@ -0,0 +1,28 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
)
|
||||
|
||||
// calendarDisplayable is a transformative struct that aligns
|
||||
// models.Calendarable interface with the displayable interface.
|
||||
type calendarDisplayable struct {
|
||||
models.Calendarable
|
||||
}
|
||||
|
||||
// GetDisplayName returns the *string of the calendar name
|
||||
func (c calendarDisplayable) GetDisplayName() *string {
|
||||
return c.GetName()
|
||||
}
|
||||
|
||||
// CreateCalendarDisplayable helper function to create the
|
||||
// calendarDisplayable during msgraph-sdk-go iterative process
|
||||
// @param entry is the input supplied by pageIterator.Iterate()
|
||||
func CreateCalendarDisplayable(entry any) *calendarDisplayable {
|
||||
calendar, ok := entry.(models.Calendarable)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &calendarDisplayable{calendar}
|
||||
}
|
||||
@ -86,6 +86,41 @@ func (suite *ExchangeServiceSuite) TestCreateService() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ExchangeServiceSuite) TestOptionsForCalendars() {
|
||||
tests := []struct {
|
||||
name string
|
||||
params []string
|
||||
checkError assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "Empty Literal",
|
||||
params: []string{},
|
||||
checkError: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "Invalid Parameter",
|
||||
params: []string{"status"},
|
||||
checkError: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "Invalid Parameters",
|
||||
params: []string{"status", "height", "month"},
|
||||
checkError: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "Valid Parameters",
|
||||
params: []string{"changeKey", "events", "owner"},
|
||||
checkError: assert.NoError,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
_, err := optionsForCalendars(test.params)
|
||||
test.checkError(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestOptionsForMessages checks to ensure approved query
|
||||
// options are added to the type specific RequestBuildConfiguration. Expected
|
||||
// will be +1 on all select parameters
|
||||
@ -255,6 +290,10 @@ func (suite *ExchangeServiceSuite) TestGraphQueryFunctions() {
|
||||
name: "GraphQuery: Get All Events for User",
|
||||
function: GetAllEventsForUser,
|
||||
},
|
||||
{
|
||||
name: "GraphQuery: Get All Calendars for User",
|
||||
function: GetAllCalendarNamesForUser,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@ -311,49 +350,61 @@ func (suite *ExchangeServiceSuite) TestParseCalendarIDFromEvent() {
|
||||
|
||||
// TestGetMailFolderID verifies the ability to retrieve folder ID of folders
|
||||
// at the top level of the file tree
|
||||
func (suite *ExchangeServiceSuite) TestGetFolderID() {
|
||||
func (suite *ExchangeServiceSuite) TestGetContainerID() {
|
||||
userID := tester.M365UserID(suite.T())
|
||||
tests := []struct {
|
||||
name string
|
||||
folderName string
|
||||
containerName string
|
||||
// category references the current optionId :: TODO --> use selector fields
|
||||
category optionIdentifier
|
||||
checkError assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "Mail Valid",
|
||||
folderName: "Inbox",
|
||||
containerName: "Inbox",
|
||||
category: messages,
|
||||
checkError: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "Mail Invalid",
|
||||
folderName: "FolderThatIsNotHere",
|
||||
containerName: "FolderThatIsNotHere",
|
||||
category: messages,
|
||||
checkError: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "Contact Invalid",
|
||||
folderName: "FolderThatIsNotHereContacts",
|
||||
containerName: "FolderThatIsNotHereContacts",
|
||||
category: contacts,
|
||||
checkError: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "Contact Valid",
|
||||
folderName: "TrialFolder",
|
||||
containerName: "TrialFolder",
|
||||
category: contacts,
|
||||
checkError: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "Event Invalid",
|
||||
containerName: "NotAValid?@V'vCalendar",
|
||||
category: events,
|
||||
checkError: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "Event Valid",
|
||||
containerName: "Calendar",
|
||||
category: events,
|
||||
checkError: assert.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
_, err := GetFolderID(
|
||||
_, err := GetContainerID(
|
||||
suite.es,
|
||||
test.folderName,
|
||||
test.containerName,
|
||||
userID,
|
||||
test.category)
|
||||
test.checkError(t, err, "Unable to find folder: "+test.folderName)
|
||||
test.checkError(t, err, "error with container: "+test.containerName)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,15 +10,16 @@ func _() {
|
||||
var x [1]struct{}
|
||||
_ = x[unknown-0]
|
||||
_ = x[folders-1]
|
||||
_ = x[events-2]
|
||||
_ = x[messages-3]
|
||||
_ = x[users-4]
|
||||
_ = x[contacts-5]
|
||||
_ = x[calendars-2]
|
||||
_ = x[events-3]
|
||||
_ = x[messages-4]
|
||||
_ = x[users-5]
|
||||
_ = x[contacts-6]
|
||||
}
|
||||
|
||||
const _optionIdentifier_name = "unknownfolderseventsmessagesuserscontacts"
|
||||
const _optionIdentifier_name = "unknownfolderscalendarseventsmessagesuserscontacts"
|
||||
|
||||
var _optionIdentifier_index = [...]uint8{0, 7, 14, 20, 28, 33, 41}
|
||||
var _optionIdentifier_index = [...]uint8{0, 7, 14, 23, 29, 37, 42, 50}
|
||||
|
||||
func (i optionIdentifier) String() string {
|
||||
if i < 0 || i >= optionIdentifier(len(_optionIdentifier_index)-1) {
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
msuser "github.com/microsoftgraph/msgraph-sdk-go/users"
|
||||
mscalendars "github.com/microsoftgraph/msgraph-sdk-go/users/item/calendars"
|
||||
mscontactfolder "github.com/microsoftgraph/msgraph-sdk-go/users/item/contactfolders"
|
||||
mscontacts "github.com/microsoftgraph/msgraph-sdk-go/users/item/contacts"
|
||||
msevents "github.com/microsoftgraph/msgraph-sdk-go/users/item/events"
|
||||
@ -17,6 +20,15 @@ import (
|
||||
// selectors for M365 objects
|
||||
//------------------------------------------------------------
|
||||
var (
|
||||
fieldsForCalendars = map[string]int{
|
||||
"changeKey": 1,
|
||||
"events": 2,
|
||||
"id": 3,
|
||||
"isDefaultCalendar": 4,
|
||||
"name": 5,
|
||||
"owner": 6,
|
||||
}
|
||||
|
||||
fieldsForEvents = map[string]int{
|
||||
"calendar": 1,
|
||||
"end": 2,
|
||||
@ -79,6 +91,7 @@ type optionIdentifier int
|
||||
const (
|
||||
unknown optionIdentifier = iota
|
||||
folders
|
||||
calendars
|
||||
events
|
||||
messages
|
||||
users
|
||||
@ -104,9 +117,12 @@ func categoryToOptionIdentifier(category string) optionIdentifier {
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
// exchange.Query Option Section
|
||||
//------------------------------------------------
|
||||
// These functions can be used to filter a response on M365
|
||||
// Graph queries and reduce / filter the amount of data returned
|
||||
// which reduces the overall latency of complex calls
|
||||
//----------------------------------------------------------------
|
||||
|
||||
// optionsForMessages - used to select allowable options for exchange.Mail types
|
||||
// @param moreOps is []string of options(e.g. "parentFolderId, subject")
|
||||
@ -146,6 +162,30 @@ func OptionsForSingleMessage(moreOps []string) (*msitem.MessageItemRequestBuilde
|
||||
return options, nil
|
||||
}
|
||||
|
||||
// optionsForCalendars places allowed options for exchange.Calendar object
|
||||
// @param moreOps should reflect elements from fieldsForCalendars
|
||||
// @return is first call in Calendars().GetWithRequestConfigurationAndResponseHandler
|
||||
func optionsForCalendars(moreOps []string) (
|
||||
*mscalendars.CalendarsRequestBuilderGetRequestConfiguration,
|
||||
error,
|
||||
) {
|
||||
selecting, err := buildOptions(moreOps, calendars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requestParams := &mscalendars.CalendarsRequestBuilderGetQueryParameters{
|
||||
Select: selecting,
|
||||
}
|
||||
options := &mscalendars.CalendarsRequestBuilderGetRequestConfiguration{
|
||||
QueryParameters: requestParams,
|
||||
}
|
||||
|
||||
return options, nil
|
||||
}
|
||||
|
||||
// optionsForContactFolders places allowed options for exchange.ContactFolder object
|
||||
// @return is first call in ContactFolders().GetWithRequestConfigurationAndResponseHandler
|
||||
func optionsForContactFolders(moreOps []string) (
|
||||
*mscontactfolder.ContactFoldersRequestBuilderGetRequestConfiguration,
|
||||
error,
|
||||
@ -246,10 +286,12 @@ func buildOptions(options []string, optID optionIdentifier) ([]string, error) {
|
||||
)
|
||||
|
||||
switch optID {
|
||||
case events:
|
||||
allowedOptions = fieldsForEvents
|
||||
case calendars:
|
||||
allowedOptions = fieldsForCalendars
|
||||
case contacts:
|
||||
allowedOptions = fieldsForContacts
|
||||
case events:
|
||||
allowedOptions = fieldsForEvents
|
||||
case folders:
|
||||
allowedOptions = fieldsForFolders
|
||||
case users:
|
||||
@ -265,7 +307,7 @@ func buildOptions(options []string, optID optionIdentifier) ([]string, error) {
|
||||
for _, entry := range options {
|
||||
_, ok := allowedOptions[entry]
|
||||
if !ok {
|
||||
return nil, errors.New("unsupported option")
|
||||
return nil, fmt.Errorf("unsupported option: %v", entry)
|
||||
}
|
||||
|
||||
returnedOptions = append(returnedOptions, entry)
|
||||
|
||||
@ -151,16 +151,17 @@ func GetAllMailFolders(gs graph.Service, user, nameContains string) ([]MailFolde
|
||||
return mfs, err
|
||||
}
|
||||
|
||||
// GetFolderID query function to retrieve the M365 ID based on the folder's displayName.
|
||||
// @param folderName the target folder's display name. Case sensitive
|
||||
// GetContainerID query function to retrieve a container's M365 ID.
|
||||
// @param containerName is the target's name, user-readable and case sensitive
|
||||
// @param category switches query and iteration to support multiple exchange applications
|
||||
// @returns a *string if the folder exists. If the folder does not exist returns nil, error-> folder not found
|
||||
func GetFolderID(service graph.Service, folderName, user string, category optionIdentifier) (*string, error) {
|
||||
func GetContainerID(service graph.Service, containerName, user string, category optionIdentifier) (*string, error) {
|
||||
var (
|
||||
errs error
|
||||
folderID *string
|
||||
targetID *string
|
||||
query GraphQuery
|
||||
transform absser.ParsableFactory
|
||||
isCalendar bool
|
||||
)
|
||||
|
||||
switch category {
|
||||
@ -170,6 +171,10 @@ func GetFolderID(service graph.Service, folderName, user string, category option
|
||||
case contacts:
|
||||
query = GetAllContactFolderNamesForUser
|
||||
transform = models.CreateContactFolderFromDiscriminatorValue
|
||||
case events:
|
||||
query = GetAllCalendarNamesForUser
|
||||
transform = models.CreateCalendarCollectionResponseFromDiscriminatorValue
|
||||
isCalendar = true
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported category %s for GetFolderID()", category)
|
||||
}
|
||||
@ -192,10 +197,11 @@ func GetFolderID(service graph.Service, folderName, user string, category option
|
||||
return nil, err
|
||||
}
|
||||
|
||||
callbackFunc := iterateFindFolderID(category,
|
||||
&folderID,
|
||||
folderName,
|
||||
callbackFunc := iterateFindFolderID(
|
||||
&targetID,
|
||||
containerName,
|
||||
service.Adapter().GetBaseUrl(),
|
||||
isCalendar,
|
||||
errs,
|
||||
)
|
||||
|
||||
@ -203,11 +209,11 @@ func GetFolderID(service graph.Service, folderName, user string, category option
|
||||
return nil, support.WrapAndAppend(service.Adapter().GetBaseUrl(), err, errs)
|
||||
}
|
||||
|
||||
if folderID == nil {
|
||||
if targetID == nil {
|
||||
return nil, ErrFolderNotFound
|
||||
}
|
||||
|
||||
return folderID, errs
|
||||
return targetID, errs
|
||||
}
|
||||
|
||||
// parseCalendarIDFromEvent returns the M365 ID for a calendar
|
||||
@ -298,7 +304,7 @@ func establishFolder(
|
||||
folderName, user string,
|
||||
optID optionIdentifier,
|
||||
) (string, error) {
|
||||
folderID, err := GetFolderID(service, folderName, user, optID)
|
||||
folderID, err := GetContainerID(service, folderName, user, optID)
|
||||
if err == nil {
|
||||
return *folderID, nil
|
||||
}
|
||||
|
||||
@ -305,14 +305,20 @@ func IterateFilterFolderDirectoriesForCollections(
|
||||
// the displayable interface. If folder exists, the function updates the
|
||||
// folderID memory address that was passed in.
|
||||
func iterateFindFolderID(
|
||||
category optionIdentifier,
|
||||
folderID **string,
|
||||
folderName, errorIdentifier string,
|
||||
isCalendar bool,
|
||||
errs error,
|
||||
) func(any) bool {
|
||||
return func(entry any) bool {
|
||||
switch category {
|
||||
case messages, contacts:
|
||||
if isCalendar {
|
||||
entry = CreateCalendarDisplayable(entry)
|
||||
|
||||
if entry == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
folder, ok := entry.(displayable)
|
||||
if !ok {
|
||||
errs = support.WrapAndAppend(
|
||||
@ -328,8 +334,7 @@ func iterateFindFolderID(
|
||||
return true
|
||||
}
|
||||
|
||||
name := *folder.GetDisplayName()
|
||||
if folderName == name {
|
||||
if folderName == *folder.GetDisplayName() {
|
||||
if folder.GetId() == nil {
|
||||
return true // invalid folder
|
||||
}
|
||||
@ -340,9 +345,5 @@ func iterateFindFolderID(
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +55,15 @@ func GetAllFolderNamesForUser(gs graph.Service, user string) (absser.Parsable, e
|
||||
return gs.Client().UsersById(user).MailFolders().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
||||
}
|
||||
|
||||
func GetAllCalendarNamesForUser(gs graph.Service, user string) (absser.Parsable, error) {
|
||||
options, err := optionsForCalendars([]string{"name"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gs.Client().UsersById(user).Calendars().GetWithRequestConfigurationAndResponseHandler(options, nil)
|
||||
}
|
||||
|
||||
// GetAllContactFolderNamesForUser is a GraphQuery function for getting ContactFolderId
|
||||
// and display names for contacts. All other information is omitted.
|
||||
// Does not return the primary Contact Folder
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user