Enable wsl for most of internal/connector package (#680)

* Lint part of internal/connector package with wsl

* Cleanup some wsl lint errors in connector package
This commit is contained in:
ashmrtn 2022-08-30 13:13:00 -07:00 committed by GitHub
parent ee57c7cb6c
commit e3abc281d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 240 additions and 22 deletions

View File

@ -80,5 +80,13 @@ issues:
- revive - revive
text: "import-shadowing:.*'suite' shadows" text: "import-shadowing:.*'suite' shadows"
# Temporarily skip linting wsl on `connector` package until fixes are merged. # Temporarily skip linting wsl on `connector` package until fixes are merged.
- path: internal/connector/ - path: internal/connector/graph_connector_test.go
linters: wsl
- path: internal/connector/graph_connector.go
linters: wsl
- path: internal/connector/exchange/exchange_service_test.go
linters: wsl
- path: internal/connector/exchange/service_functions.go
linters: wsl
- path: internal/connector/onedrive
linters: wsl linters: wsl

View File

@ -22,19 +22,23 @@ func EventInfo(evt models.Eventable) *details.ExchangeInfo {
GetEmailAddress(). GetEmailAddress().
GetAddress() GetAddress()
} }
if evt.GetSubject() != nil { if evt.GetSubject() != nil {
subject = *evt.GetSubject() subject = *evt.GetSubject()
} }
if evt.GetStart() != nil && if evt.GetStart() != nil &&
evt.GetStart().GetDateTime() != nil { evt.GetStart().GetDateTime() != nil {
// timeString has 'Z' literal added to ensure the stored // timeString has 'Z' literal added to ensure the stored
// DateTime is not: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC) // DateTime is not: time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC)
timeString := *evt.GetStart().GetDateTime() + "Z" timeString := *evt.GetStart().GetDateTime() + "Z"
output, err := common.ParseTime(timeString) output, err := common.ParseTime(timeString)
if err == nil { if err == nil {
start = output start = output
} }
} }
return &details.ExchangeInfo{ return &details.ExchangeInfo{
Organizer: organizer, Organizer: organizer,
Subject: subject, Subject: subject,

View File

@ -29,6 +29,7 @@ func (suite *EventSuite) TestEventInfo() {
now := initial.Format(common.StandardTimeFormat) now := initial.Format(common.StandardTimeFormat)
suite.T().Logf("Initial: %v\nFormatted: %v\n", initial, now) suite.T().Logf("Initial: %v\nFormatted: %v\n", initial, now)
tests := []struct { tests := []struct {
name string name string
evtAndRP func() (models.Eventable, *details.ExchangeInfo) evtAndRP func() (models.Eventable, *details.ExchangeInfo)

View File

@ -73,6 +73,7 @@ func NewCollection(
fullPath: fullPath, fullPath: fullPath,
collectionType: collectionType, collectionType: collectionType,
} }
return collection return collection
} }
@ -118,9 +119,11 @@ func (col *Collection) populateByOptionIdentifier(
errs error errs error
success int success int
) )
defer func() { defer func() {
col.finishPopulation(ctx, success, errs) col.finishPopulation(ctx, success, errs)
}() }()
user := col.user user := col.user
objectWriter := kw.NewJsonSerializationWriter() objectWriter := kw.NewJsonSerializationWriter()
// get QueryBasedonIdentifier // get QueryBasedonIdentifier
@ -140,8 +143,10 @@ func (col *Collection) populateByOptionIdentifier(
if col.service.ErrPolicy() { if col.service.ErrPolicy() {
break break
} }
continue continue
} }
err = serializeFunc(ctx, col.service.Client(), objectWriter, col.data, response, user) err = serializeFunc(ctx, col.service.Client(), objectWriter, col.data, response, user)
if err != nil { if err != nil {
errs = support.WrapAndAppendf(user, err, errs) errs = support.WrapAndAppendf(user, err, errs)
@ -149,6 +154,7 @@ func (col *Collection) populateByOptionIdentifier(
if col.service.ErrPolicy() { if col.service.ErrPolicy() {
break break
} }
continue continue
} }
@ -188,7 +194,9 @@ func eventToDataCollection(
user string, user string,
) error { ) error {
var err error var err error
defer objectWriter.Close() defer objectWriter.Close()
event, ok := parsable.(models.Eventable) event, ok := parsable.(models.Eventable)
if !ok { if !ok {
return fmt.Errorf("expected Eventable, got %T", parsable) return fmt.Errorf("expected Eventable, got %T", parsable)
@ -196,6 +204,7 @@ func eventToDataCollection(
if *event.GetHasAttachments() { if *event.GetHasAttachments() {
var retriesErr error var retriesErr error
for count := 0; count < numberOfRetries; count++ { for count := 0; count < numberOfRetries; count++ {
attached, err := client. attached, err := client.
UsersById(user). UsersById(user).
@ -203,30 +212,37 @@ func eventToDataCollection(
Attachments(). Attachments().
Get() Get()
retriesErr = err retriesErr = err
if err == nil && attached != nil { if err == nil && attached != nil {
event.SetAttachments(attached.GetValue()) event.SetAttachments(attached.GetValue())
break break
} }
} }
if retriesErr != nil { if retriesErr != nil {
logger.Ctx(ctx).Debug("exceeded maximum retries") logger.Ctx(ctx).Debug("exceeded maximum retries")
return support.WrapAndAppend( return support.WrapAndAppend(
*event.GetId(), *event.GetId(),
errors.Wrap(retriesErr, "attachment failed"), errors.Wrap(retriesErr, "attachment failed"),
nil) nil)
} }
} }
err = objectWriter.WriteObjectValue("", event) err = objectWriter.WriteObjectValue("", event)
if err != nil { if err != nil {
return support.SetNonRecoverableError(errors.Wrap(err, *event.GetId())) return support.SetNonRecoverableError(errors.Wrap(err, *event.GetId()))
} }
byteArray, err := objectWriter.GetSerializedContent() byteArray, err := objectWriter.GetSerializedContent()
if err != nil { if err != nil {
return support.WrapAndAppend(*event.GetId(), errors.Wrap(err, "serializing content"), nil) return support.WrapAndAppend(*event.GetId(), errors.Wrap(err, "serializing content"), nil)
} }
if byteArray != nil { if byteArray != nil {
dataChannel <- &Stream{id: *event.GetId(), message: byteArray, info: EventInfo(event)} dataChannel <- &Stream{id: *event.GetId(), message: byteArray, info: EventInfo(event)}
} }
return nil return nil
} }
@ -240,21 +256,26 @@ func contactToDataCollection(
user string, user string,
) error { ) error {
defer objectWriter.Close() defer objectWriter.Close()
contact, ok := parsable.(models.Contactable) contact, ok := parsable.(models.Contactable)
if !ok { if !ok {
return fmt.Errorf("expected Contactable, got %T", parsable) return fmt.Errorf("expected Contactable, got %T", parsable)
} }
err := objectWriter.WriteObjectValue("", contact) err := objectWriter.WriteObjectValue("", contact)
if err != nil { if err != nil {
return support.SetNonRecoverableError(errors.Wrap(err, *contact.GetId())) return support.SetNonRecoverableError(errors.Wrap(err, *contact.GetId()))
} }
byteArray, err := objectWriter.GetSerializedContent() byteArray, err := objectWriter.GetSerializedContent()
if err != nil { if err != nil {
return support.WrapAndAppend(*contact.GetId(), err, nil) return support.WrapAndAppend(*contact.GetId(), err, nil)
} }
if byteArray != nil { if byteArray != nil {
dataChannel <- &Stream{id: *contact.GetId(), message: byteArray, info: ContactInfo(contact)} dataChannel <- &Stream{id: *contact.GetId(), message: byteArray, info: ContactInfo(contact)}
} }
return nil return nil
} }
@ -268,11 +289,14 @@ func messageToDataCollection(
user string, user string,
) error { ) error {
var err error var err error
defer objectWriter.Close() defer objectWriter.Close()
aMessage, ok := parsable.(models.Messageable) aMessage, ok := parsable.(models.Messageable)
if !ok { if !ok {
return fmt.Errorf("expected Messageable, got %T", parsable) return fmt.Errorf("expected Messageable, got %T", parsable)
} }
adtl := aMessage.GetAdditionalData() adtl := aMessage.GetAdditionalData()
if len(adtl) > 2 { if len(adtl) > 2 {
aMessage, err = support.ConvertFromMessageable(adtl, aMessage) aMessage, err = support.ConvertFromMessageable(adtl, aMessage)
@ -280,9 +304,11 @@ func messageToDataCollection(
return err return err
} }
} }
if *aMessage.GetHasAttachments() { if *aMessage.GetHasAttachments() {
// getting all the attachments might take a couple attempts due to filesize // getting all the attachments might take a couple attempts due to filesize
var retriesErr error var retriesErr error
for count := 0; count < numberOfRetries; count++ { for count := 0; count < numberOfRetries; count++ {
attached, err := client. attached, err := client.
UsersById(user). UsersById(user).
@ -290,11 +316,13 @@ func messageToDataCollection(
Attachments(). Attachments().
Get() Get()
retriesErr = err retriesErr = err
if err == nil { if err == nil {
aMessage.SetAttachments(attached.GetValue()) aMessage.SetAttachments(attached.GetValue())
break break
} }
} }
if retriesErr != nil { if retriesErr != nil {
logger.Ctx(ctx).Debug("exceeded maximum retries") logger.Ctx(ctx).Debug("exceeded maximum retries")
return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(retriesErr, "attachment failed"), nil) return support.WrapAndAppend(*aMessage.GetId(), errors.Wrap(retriesErr, "attachment failed"), nil)
@ -313,6 +341,7 @@ func messageToDataCollection(
} }
dataChannel <- &Stream{id: *aMessage.GetId(), message: byteArray, info: MessageInfo(aMessage)} dataChannel <- &Stream{id: *aMessage.GetId(), message: byteArray, info: MessageInfo(aMessage)}
return nil return nil
} }

View File

@ -30,11 +30,15 @@ func (suite *ExchangeDataCollectionSuite) TestExchangeDataReader_Valid() {
} }
func (suite *ExchangeDataCollectionSuite) TestExchangeDataReader_Empty() { func (suite *ExchangeDataCollectionSuite) TestExchangeDataReader_Empty() {
var empty []byte var (
expected := int64(0) empty []byte
expected int64
)
ed := &Stream{message: empty} ed := &Stream{message: empty}
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
received, err := buf.ReadFrom(ed.ToReader()) received, err := buf.ReadFrom(ed.ToReader())
suite.Equal(expected, received) suite.Equal(expected, received)
assert.Nil(suite.T(), err, "received buf.Readfrom error ") assert.Nil(suite.T(), err, "received buf.Readfrom error ")
} }
@ -67,9 +71,11 @@ func (suite *ExchangeDataCollectionSuite) TestExchangeCollection_AddJob() {
fullPath: []string{"Today", "is", "currently", "different"}, fullPath: []string{"Today", "is", "currently", "different"},
} }
suite.Zero(len(eoc.jobs)) suite.Zero(len(eoc.jobs))
shopping := []string{"tomotoes", "potatoes", "pasta", "ice tea"} shopping := []string{"tomotoes", "potatoes", "pasta", "ice tea"}
for _, item := range shopping { for _, item := range shopping {
eoc.AddJob(item) eoc.AddJob(item)
} }
suite.Equal(len(shopping), len(eoc.jobs)) suite.Equal(len(shopping), len(eoc.jobs))
} }

View File

@ -24,6 +24,7 @@ func (suite *ExchangeIteratorSuite) TestDisplayable() {
bytes := mockconnector.GetMockContactBytes("Displayable") bytes := mockconnector.GetMockContactBytes("Displayable")
contact, err := support.CreateContactFromBytes(bytes) contact, err := support.CreateContactFromBytes(bytes)
require.NoError(t, err) require.NoError(t, err)
aDisplayable, ok := contact.(displayable) aDisplayable, ok := contact.(displayable)
assert.True(t, ok) assert.True(t, ok)
assert.NotNil(t, aDisplayable.GetId()) assert.NotNil(t, aDisplayable.GetId())
@ -35,6 +36,7 @@ func (suite *ExchangeIteratorSuite) TestDescendable() {
bytes := mockconnector.GetMockMessageBytes("Descendable") bytes := mockconnector.GetMockMessageBytes("Descendable")
message, err := support.CreateMessageFromBytes(bytes) message, err := support.CreateMessageFromBytes(bytes)
require.NoError(t, err) require.NoError(t, err)
aDescendable, ok := message.(descendable) aDescendable, ok := message.(descendable)
assert.True(t, ok) assert.True(t, ok)
assert.NotNil(t, aDescendable.GetId()) assert.NotNil(t, aDescendable.GetId())

View File

@ -12,17 +12,21 @@ func MessageInfo(msg models.Messageable) *details.ExchangeInfo {
sender := "" sender := ""
subject := "" subject := ""
received := time.Time{} received := time.Time{}
if msg.GetSender() != nil && if msg.GetSender() != nil &&
msg.GetSender().GetEmailAddress() != nil && msg.GetSender().GetEmailAddress() != nil &&
msg.GetSender().GetEmailAddress().GetAddress() != nil { msg.GetSender().GetEmailAddress().GetAddress() != nil {
sender = *msg.GetSender().GetEmailAddress().GetAddress() sender = *msg.GetSender().GetEmailAddress().GetAddress()
} }
if msg.GetSubject() != nil { if msg.GetSubject() != nil {
subject = *msg.GetSubject() subject = *msg.GetSubject()
} }
if msg.GetReceivedDateTime() != nil { if msg.GetReceivedDateTime() != nil {
received = *msg.GetReceivedDateTime() received = *msg.GetReceivedDateTime()
} }
return &details.ExchangeInfo{ return &details.ExchangeInfo{
Sender: sender, Sender: sender,
Subject: subject, Subject: subject,

View File

@ -116,12 +116,14 @@ func optionsForMessages(moreOps []string) (*msmessage.MessagesRequestBuilderGetR
if err != nil { if err != nil {
return nil, err return nil, err
} }
requestParameters := &msmessage.MessagesRequestBuilderGetQueryParameters{ requestParameters := &msmessage.MessagesRequestBuilderGetQueryParameters{
Select: selecting, Select: selecting,
} }
options := &msmessage.MessagesRequestBuilderGetRequestConfiguration{ options := &msmessage.MessagesRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters, QueryParameters: requestParameters,
} }
return options, nil return options, nil
} }
@ -133,12 +135,14 @@ func OptionsForSingleMessage(moreOps []string) (*msitem.MessageItemRequestBuilde
if err != nil { if err != nil {
return nil, err return nil, err
} }
requestParams := &msitem.MessageItemRequestBuilderGetQueryParameters{ requestParams := &msitem.MessageItemRequestBuilderGetQueryParameters{
Select: selecting, Select: selecting,
} }
options := &msitem.MessageItemRequestBuilderGetRequestConfiguration{ options := &msitem.MessageItemRequestBuilderGetRequestConfiguration{
QueryParameters: requestParams, QueryParameters: requestParams,
} }
return options, nil return options, nil
} }
@ -150,12 +154,14 @@ func optionsForContactFolders(moreOps []string) (
if err != nil { if err != nil {
return nil, err return nil, err
} }
requestParameters := &mscontactfolder.ContactFoldersRequestBuilderGetQueryParameters{ requestParameters := &mscontactfolder.ContactFoldersRequestBuilderGetQueryParameters{
Select: selecting, Select: selecting,
} }
options := &mscontactfolder.ContactFoldersRequestBuilderGetRequestConfiguration{ options := &mscontactfolder.ContactFoldersRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters, QueryParameters: requestParameters,
} }
return options, nil return options, nil
} }
@ -174,6 +180,7 @@ func optionsForMailFolders(moreOps []string) (*msfolder.MailFoldersRequestBuilde
options := &msfolder.MailFoldersRequestBuilderGetRequestConfiguration{ options := &msfolder.MailFoldersRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters, QueryParameters: requestParameters,
} }
return options, nil return options, nil
} }
@ -184,12 +191,14 @@ func optionsForEvents(moreOps []string) (*msevents.EventsRequestBuilderGetReques
if err != nil { if err != nil {
return nil, err return nil, err
} }
requestParameters := &msevents.EventsRequestBuilderGetQueryParameters{ requestParameters := &msevents.EventsRequestBuilderGetQueryParameters{
Select: selecting, Select: selecting,
} }
options := &msevents.EventsRequestBuilderGetRequestConfiguration{ options := &msevents.EventsRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters, QueryParameters: requestParameters,
} }
return options, nil return options, nil
} }
@ -200,12 +209,14 @@ func optionsForContacts(moreOps []string) (*mscontacts.ContactsRequestBuilderGet
if err != nil { if err != nil {
return nil, err return nil, err
} }
requestParameters := &mscontacts.ContactsRequestBuilderGetQueryParameters{ requestParameters := &mscontacts.ContactsRequestBuilderGetQueryParameters{
Select: selecting, Select: selecting,
} }
options := &mscontacts.ContactsRequestBuilderGetRequestConfiguration{ options := &mscontacts.ContactsRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters, QueryParameters: requestParameters,
} }
return options, nil return options, nil
} }
@ -214,12 +225,14 @@ func optionsForUsers(moreOps []string) (*msuser.UsersRequestBuilderGetRequestCon
if err != nil { if err != nil {
return nil, err return nil, err
} }
requestParams := &msuser.UsersRequestBuilderGetQueryParameters{ requestParams := &msuser.UsersRequestBuilderGetQueryParameters{
Select: selecting, Select: selecting,
} }
options := &msuser.UsersRequestBuilderGetRequestConfiguration{ options := &msuser.UsersRequestBuilderGetRequestConfiguration{
QueryParameters: requestParams, QueryParameters: requestParams,
} }
return options, nil return options, nil
} }
@ -227,8 +240,10 @@ func optionsForUsers(moreOps []string) (*msuser.UsersRequestBuilderGetRequestCon
// @return is a pair. The first is a string literal of allowable options based on the object type, // @return is a pair. The first is a string literal of allowable options based on the object type,
// the second is an error. An error is returned if an unsupported option or optionIdentifier was used // the second is an error. An error is returned if an unsupported option or optionIdentifier was used
func buildOptions(options []string, optID optionIdentifier) ([]string, error) { func buildOptions(options []string, optID optionIdentifier) ([]string, error) {
var allowedOptions map[string]int var (
returnedOptions := []string{"id"} allowedOptions map[string]int
returnedOptions = []string{"id"}
)
switch optID { switch optID {
case events: case events:
@ -255,5 +270,6 @@ func buildOptions(options []string, optID optionIdentifier) ([]string, error) {
returnedOptions = append(returnedOptions, entry) returnedOptions = append(returnedOptions, entry)
} }
return returnedOptions, nil return returnedOptions, nil
} }

View File

@ -51,9 +51,12 @@ func IterateSelectAllDescendablesForCollections(
collections map[string]*Collection, collections map[string]*Collection,
statusCh chan<- *support.ConnectorOperationStatus, statusCh chan<- *support.ConnectorOperationStatus,
) func(any) bool { ) func(any) bool {
var isCategorySet bool var (
var collectionType optionIdentifier isCategorySet bool
var category string collectionType optionIdentifier
category string
)
return func(pageItem any) bool { return func(pageItem any) bool {
// Defines the type of collection being created within the function // Defines the type of collection being created within the function
if !isCategorySet { if !isCategorySet {
@ -61,10 +64,12 @@ func IterateSelectAllDescendablesForCollections(
collectionType = messages collectionType = messages
category = mailCategory category = mailCategory
} }
if scope.IncludesCategory(selectors.ExchangeContact) { if scope.IncludesCategory(selectors.ExchangeContact) {
collectionType = contacts collectionType = contacts
category = contactsCategory category = contactsCategory
} }
isCategorySet = true isCategorySet = true
} }
@ -81,6 +86,7 @@ func IterateSelectAllDescendablesForCollections(
errs = support.WrapAndAppend(user, err, errs) errs = support.WrapAndAppend(user, err, errs)
return true return true
} }
edc := NewCollection( edc := NewCollection(
user, user,
[]string{credentials.TenantID, user, category, directory}, []string{credentials.TenantID, user, category, directory},
@ -90,7 +96,9 @@ func IterateSelectAllDescendablesForCollections(
) )
collections[directory] = &edc collections[directory] = &edc
} }
collections[directory].AddJob(*entry.GetId()) collections[directory].AddJob(*entry.GetId())
return true return true
} }
} }
@ -116,10 +124,12 @@ func IterateSelectAllEventsForCollections(
errors.New("event iteration failure"), errors.New("event iteration failure"),
errs, errs,
) )
return true return true
} }
adtl := event.GetAdditionalData() adtl := event.GetAdditionalData()
value, ok := adtl["calendar@odata.associationLink"] value, ok := adtl["calendar@odata.associationLink"]
if !ok { if !ok {
errs = support.WrapAndAppend( errs = support.WrapAndAppend(
@ -127,8 +137,10 @@ func IterateSelectAllEventsForCollections(
fmt.Errorf("%s: does not support calendar look up", *event.GetId()), fmt.Errorf("%s: does not support calendar look up", *event.GetId()),
errs, errs,
) )
return true return true
} }
link, ok := value.(*string) link, ok := value.(*string)
if !ok || link == nil { if !ok || link == nil {
errs = support.WrapAndAppend( errs = support.WrapAndAppend(
@ -136,6 +148,7 @@ func IterateSelectAllEventsForCollections(
fmt.Errorf("%s: unable to obtain calendar event data", *event.GetId()), fmt.Errorf("%s: unable to obtain calendar event data", *event.GetId()),
errs, errs,
) )
return true return true
} }
// calendars and events are not easily correlated // calendars and events are not easily correlated
@ -147,16 +160,17 @@ func IterateSelectAllEventsForCollections(
errors.Wrap(err, *event.GetId()), errors.Wrap(err, *event.GetId()),
errs, errs,
) )
return true return true
} }
if _, ok := collections[directory]; !ok { if _, ok := collections[directory]; !ok {
service, err := createService(credentials, failFast) service, err := createService(credentials, failFast)
if err != nil { if err != nil {
errs = support.WrapAndAppend(user, err, errs) errs = support.WrapAndAppend(user, err, errs)
return true return true
} }
edc := NewCollection( edc := NewCollection(
user, user,
[]string{credentials.TenantID, user, eventsCategory, directory}, []string{credentials.TenantID, user, eventsCategory, directory},
@ -168,6 +182,7 @@ func IterateSelectAllEventsForCollections(
} }
collections[directory].AddJob(*event.GetId()) collections[directory].AddJob(*event.GetId())
return true return true
} }
} }
@ -185,9 +200,9 @@ func IterateAndFilterMessagesForCollections(
statusCh chan<- *support.ConnectorOperationStatus, statusCh chan<- *support.ConnectorOperationStatus,
) func(any) bool { ) func(any) bool {
var isFilterSet bool var isFilterSet bool
return func(messageItem any) bool { return func(messageItem any) bool {
if !isFilterSet { if !isFilterSet {
err := CollectMailFolders( err := CollectMailFolders(
scope, scope,
user, user,
@ -200,6 +215,7 @@ func IterateAndFilterMessagesForCollections(
errs = support.WrapAndAppend(user, err, errs) errs = support.WrapAndAppend(user, err, errs)
return false return false
} }
isFilterSet = true isFilterSet = true
} }
@ -213,7 +229,9 @@ func IterateAndFilterMessagesForCollections(
if _, ok = collections[directory]; !ok { if _, ok = collections[directory]; !ok {
return true return true
} }
collections[directory].AddJob(*message.GetId()) collections[directory].AddJob(*message.GetId())
return true return true
} }
} }
@ -231,6 +249,7 @@ func IterateFilterFolderDirectoriesForCollections(
service graph.Service service graph.Service
err error err error
) )
return func(folderItem any) bool { return func(folderItem any) bool {
folder, ok := folderItem.(displayable) folder, ok := folderItem.(displayable)
if !ok { if !ok {
@ -246,10 +265,13 @@ func IterateFilterFolderDirectoriesForCollections(
if folder.GetDisplayName() == nil { if folder.GetDisplayName() == nil {
return true return true
} }
if !scope.Contains(selectors.ExchangeMailFolder, *folder.GetDisplayName()) { if !scope.Contains(selectors.ExchangeMailFolder, *folder.GetDisplayName()) {
return true return true
} }
directory := *folder.GetId() directory := *folder.GetId()
service, err = createService(credentials, failFast) service, err = createService(credentials, failFast)
if err != nil { if err != nil {
errs = support.WrapAndAppend( errs = support.WrapAndAppend(
@ -260,8 +282,10 @@ func IterateFilterFolderDirectoriesForCollections(
), ),
errs, errs,
) )
return true return true
} }
temp := NewCollection( temp := NewCollection(
user, user,
[]string{credentials.TenantID, user, mailCategory, directory}, []string{credentials.TenantID, user, mailCategory, directory},
@ -296,21 +320,27 @@ func iterateFindFolderID(
errors.New("struct does not implement displayable"), errors.New("struct does not implement displayable"),
errs, errs,
) )
return true return true
} }
// Display name not set on folder // Display name not set on folder
if folder.GetDisplayName() == nil { if folder.GetDisplayName() == nil {
return true return true
} }
name := *folder.GetDisplayName() name := *folder.GetDisplayName()
if folderName == name { if folderName == name {
if folder.GetId() == nil { if folder.GetId() == nil {
return true // invalid folder return true // invalid folder
} }
*folderID = folder.GetId() *folderID = folder.GetId()
return false return false
} }
return true return true
default: default:
return false return false
} }

View File

@ -35,6 +35,7 @@ func GetAllMessagesForUser(gs graph.Service, user string) (absser.Parsable, erro
// GetAllContactsForUser is a GraphQuery function for querying all the contacts in a user's account // GetAllContactsForUser is a GraphQuery function for querying all the contacts in a user's account
func GetAllContactsForUser(gs graph.Service, user string) (absser.Parsable, error) { func GetAllContactsForUser(gs graph.Service, user string) (absser.Parsable, error) {
selecting := []string{"parentFolderId"} selecting := []string{"parentFolderId"}
options, err := optionsForContacts(selecting) options, err := optionsForContacts(selecting)
if err != nil { if err != nil {
return nil, err return nil, err
@ -62,6 +63,7 @@ func GetAllContactFolderNamesForUser(gs graph.Service, user string) (absser.Pars
if err != nil { if err != nil {
return nil, err return nil, err
} }
return gs.Client().UsersById(user).ContactFolders().GetWithRequestConfigurationAndResponseHandler(options, nil) return gs.Client().UsersById(user).ContactFolders().GetWithRequestConfigurationAndResponseHandler(options, nil)
} }
@ -69,10 +71,12 @@ func GetAllContactFolderNamesForUser(gs graph.Service, user string) (absser.Pars
// that contains the UserID and email for each user. All other information is omitted // that contains the UserID and email for each user. All other information is omitted
func GetAllUsersForTenant(gs graph.Service, user string) (absser.Parsable, error) { func GetAllUsersForTenant(gs graph.Service, user string) (absser.Parsable, error) {
selecting := []string{"userPrincipalName"} selecting := []string{"userPrincipalName"}
options, err := optionsForUsers(selecting) options, err := optionsForUsers(selecting)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return gs.Client().Users().GetWithRequestConfigurationAndResponseHandler(options, nil) return gs.Client().Users().GetWithRequestConfigurationAndResponseHandler(options, nil)
} }
@ -155,5 +159,6 @@ func CollectMailFolders(
if iterateFailure != nil { if iterateFailure != nil {
err = support.WrapAndAppend(user+" iterate failure", iterateFailure, err) err = support.WrapAndAppend(user+" iterate failure", iterateFailure, err)
} }
return err return err
} }

View File

@ -14,6 +14,7 @@ func CreateAdapter(tenant, client, secret string) (*msgraphsdk.GraphRequestAdapt
if err != nil { if err != nil {
return nil, err return nil, err
} }
auth, err := ka.NewAzureIdentityAuthenticationProviderWithScopes( auth, err := ka.NewAzureIdentityAuthenticationProviderWithScopes(
cred, cred,
[]string{"https://graph.microsoft.com/.default"}, []string{"https://graph.microsoft.com/.default"},
@ -21,6 +22,8 @@ func CreateAdapter(tenant, client, secret string) (*msgraphsdk.GraphRequestAdapt
if err != nil { if err != nil {
return nil, err return nil, err
} }
adapter, err := msgraphsdk.NewGraphRequestAdapter(auth) adapter, err := msgraphsdk.NewGraphRequestAdapter(auth)
return adapter, err return adapter, err
} }

View File

@ -76,6 +76,7 @@ func (suite *DisconnectedGraphConnectorSuite) TestBuild() {
names["Axel"] = "Foley" names["Axel"] = "Foley"
first := buildFromMap(true, names) first := buildFromMap(true, names)
last := buildFromMap(false, names) last := buildFromMap(false, names)
suite.Contains(first, "Al") suite.Contains(first, "Al")
suite.Contains(first, "Ellen") suite.Contains(first, "Ellen")
suite.Contains(first, "Axel") suite.Contains(first, "Axel")
@ -86,6 +87,7 @@ func (suite *DisconnectedGraphConnectorSuite) TestBuild() {
func (suite *DisconnectedGraphConnectorSuite) TestInterfaceAlignment() { func (suite *DisconnectedGraphConnectorSuite) TestInterfaceAlignment() {
var dc data.Collection var dc data.Collection
concrete := mockconnector.NewMockExchangeCollection([]string{"a", "path"}, 1) concrete := mockconnector.NewMockExchangeCollection([]string{"a", "path"}, 1)
dc = concrete dc = concrete
assert.NotNil(suite.T(), dc) assert.NotNil(suite.T(), dc)
@ -97,6 +99,7 @@ func (suite *DisconnectedGraphConnectorSuite) TestGraphConnector_Status() {
} }
suite.Equal(len(gc.PrintableStatus()), 0) suite.Equal(len(gc.PrintableStatus()), 0)
gc.incrementAwaitingMessages() gc.incrementAwaitingMessages()
go func() { go func() {
status := support.CreateStatus( status := support.CreateStatus(
context.Background(), context.Background(),

View File

@ -41,6 +41,7 @@ func NewMockExchangeCollection(pathRepresentation []string, numMessagesToReturn
c.Data = append(c.Data, GetMockMessageBytes("From: NewMockExchangeCollection")) c.Data = append(c.Data, GetMockMessageBytes("From: NewMockExchangeCollection"))
c.Names = append(c.Names, uuid.NewString()) c.Names = append(c.Names, uuid.NewString())
} }
return c return c
} }
@ -55,6 +56,7 @@ func (medc *MockExchangeDataCollection) Items() <-chan data.Stream {
go func() { go func() {
defer close(res) defer close(res)
for i := 0; i < medc.messageCount; i++ { for i := 0; i < medc.messageCount; i++ {
res <- &MockExchangeData{ res <- &MockExchangeData{
ID: medc.Names[i], ID: medc.Names[i],
@ -114,6 +116,7 @@ func GetMockContactBytes(middleName string) []byte {
contact := "{\"id\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAEOAADSEBNbUIB9RL6ePDeF3FIYAABS7DZnAAA=\",\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('foobar%408qzvrj.onmicrosoft.com')/contacts/$entity\",\"@odata.etag\":\"W/\\\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\\\"\",\"categories\":[],\"changeKey\":\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\",\"createdDateTime\":\"2019-08-04T06:55:33Z\",\"lastModifiedDateTime\":\"2019-08-04T06:55:33Z\",\"businessAddress\":{},\"businessPhones\":[],\"children\":[],\"displayName\":\"Santiago Quail\",\"emailAddresses\":[],\"fileAs\":\"Quail, Santiago\"," + contact := "{\"id\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAEOAADSEBNbUIB9RL6ePDeF3FIYAABS7DZnAAA=\",\"@odata.context\":\"https://graph.microsoft.com/v1.0/$metadata#users('foobar%408qzvrj.onmicrosoft.com')/contacts/$entity\",\"@odata.etag\":\"W/\\\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\\\"\",\"categories\":[],\"changeKey\":\"EQAAABYAAADSEBNbUIB9RL6ePDeF3FIYAABSx4Tr\",\"createdDateTime\":\"2019-08-04T06:55:33Z\",\"lastModifiedDateTime\":\"2019-08-04T06:55:33Z\",\"businessAddress\":{},\"businessPhones\":[],\"children\":[],\"displayName\":\"Santiago Quail\",\"emailAddresses\":[],\"fileAs\":\"Quail, Santiago\"," +
//nolint:lll //nolint:lll
"\"givenName\":\"Santiago " + middleName + "\",\"homeAddress\":{},\"homePhones\":[],\"imAddresses\":[],\"otherAddress\":{},\"parentFolderId\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9FIYAAAAAAEOAAA=\",\"personalNotes\":\"\",\"surname\":\"Quail\"}" "\"givenName\":\"Santiago " + middleName + "\",\"homeAddress\":{},\"homePhones\":[],\"imAddresses\":[],\"otherAddress\":{},\"parentFolderId\":\"AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwAuAAAAAADCNgjhM9FIYAAAAAAEOAAA=\",\"personalNotes\":\"\",\"surname\":\"Quail\"}"
return []byte(contact) return []byte(contact)
} }
@ -130,6 +133,7 @@ func GetMockEventBytes(subject string) []byte {
":{\"emailAddress\":{\"address\":\"foobar3@8qzvrj.onmicrosoft.com\",\"name\":\"Anu Pierson\"}},\"originalEndTimeZone\":\"UTC\",\"originalStartTimeZone\":\"UTC\",\"reminderMinutesBeforeStart\":15,\"responseRequested\":true,\"responseStatus\":{\"response\":\"notResponded\",\"time\":\"0001-01-01T00:00:00Z\"},\"sensitivity\":\"normal\",\"showAs\":\"tentative\",\"start\":{\"dateTime\":\"2022-04-28T03:41:58.0000000\",\"timeZone\":\"UTC\"}," + ":{\"emailAddress\":{\"address\":\"foobar3@8qzvrj.onmicrosoft.com\",\"name\":\"Anu Pierson\"}},\"originalEndTimeZone\":\"UTC\",\"originalStartTimeZone\":\"UTC\",\"reminderMinutesBeforeStart\":15,\"responseRequested\":true,\"responseStatus\":{\"response\":\"notResponded\",\"time\":\"0001-01-01T00:00:00Z\"},\"sensitivity\":\"normal\",\"showAs\":\"tentative\",\"start\":{\"dateTime\":\"2022-04-28T03:41:58.0000000\",\"timeZone\":\"UTC\"}," +
"\"subject\":\" " + subject + "\"subject\":\" " + subject +
"Review + Lunch\",\"type\":\"singleInstance\",\"webLink\":\"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA%3D&exvsurl=1&path=/calendar/item\"}" "Review + Lunch\",\"type\":\"singleInstance\",\"webLink\":\"https://outlook.office365.com/owa/?itemid=AAMkAGZmNjNlYjI3LWJlZWYtNGI4Mi04YjMyLTIxYThkNGQ4NmY1MwBGAAAAAADCNgjhM9QmQYWNcI7hCpPrBwDSEBNbUIB9RL6ePDeF3FIYAAAAAAENAADSEBNbUIB9RL6ePDeF3FIYAAAAAG76AAA%3D&exvsurl=1&path=/calendar/item\"}"
return []byte(event) return []byte(event)
} }

View File

@ -33,6 +33,7 @@ func (suite *MockExchangeCollectionSuite) TestMockExchangeCollection() {
assert.NoError(suite.T(), err) assert.NoError(suite.T(), err)
messagesRead++ messagesRead++
} }
assert.Equal(suite.T(), 2, messagesRead) assert.Equal(suite.T(), 2, messagesRead)
} }
@ -46,6 +47,7 @@ func (suite *MockExchangeCollectionSuite) TestMockExchangeCollection_NewExchange
for stream := range mdc.Items() { for stream := range mdc.Items() {
_, err := buf.ReadFrom(stream.ToReader()) _, err := buf.ReadFrom(stream.ToReader())
assert.NoError(t, err) assert.NoError(t, err)
byteArray := buf.Bytes() byteArray := buf.Bytes()
something, err := support.CreateFromBytes(byteArray, models.CreateMessageFromDiscriminatorValue) something, err := support.CreateFromBytes(byteArray, models.CreateMessageFromDiscriminatorValue)
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -47,6 +47,7 @@ func GetNumberOfErrors(err error) int {
if err == nil { if err == nil {
return 0 return 0
} }
result, _, wasFound := strings.Cut(err.Error(), " ") result, _, wasFound := strings.Cut(err.Error(), " ")
if wasFound { if wasFound {
aNum, err := strconv.Atoi(result) aNum, err := strconv.Atoi(result)
@ -54,6 +55,7 @@ func GetNumberOfErrors(err error) int {
return aNum return aNum
} }
} }
return 1 return 1
} }
@ -62,13 +64,16 @@ func GetNumberOfErrors(err error) int {
// depends on ConnectorStackErrorTrace // depends on ConnectorStackErrorTrace
func ListErrors(multi multierror.Error) string { func ListErrors(multi multierror.Error) string {
aString := "" aString := ""
for idx, err := range multi.Errors { for idx, err := range multi.Errors {
detail := ConnectorStackErrorTrace(err) detail := ConnectorStackErrorTrace(err)
if detail == "" { if detail == "" {
detail = fmt.Sprintf("%v", err) detail = fmt.Sprintf("%v", err)
} }
aString = aString + fmt.Sprintf("\n\tErr: %d %v", idx+1, detail) aString = aString + fmt.Sprintf("\n\tErr: %d %v", idx+1, detail)
} }
return aString return aString
} }
@ -80,6 +85,7 @@ func concatenateStringFromPointers(orig string, pointers []*string) string {
orig = strings.Join([]string{orig, *pointer}, " ") orig = strings.Join([]string{orig, *pointer}, " ")
} }
} }
return orig return orig
} }
@ -87,6 +93,7 @@ func concatenateStringFromPointers(orig string, pointers []*string) string {
// stack trace for oDataError types from querying the M365 back store. // stack trace for oDataError types from querying the M365 back store.
func ConnectorStackErrorTrace(e error) string { func ConnectorStackErrorTrace(e error) string {
eMessage := "" eMessage := ""
if oDataError, ok := e.(msgraph_errors.ODataErrorable); ok { if oDataError, ok := e.(msgraph_errors.ODataErrorable); ok {
// Get MainError // Get MainError
mainErr := oDataError.GetError() mainErr := oDataError.GetError()
@ -102,10 +109,12 @@ func ConnectorStackErrorTrace(e error) string {
inners := mainErr.GetInnererror() inners := mainErr.GetInnererror()
eMessage = concatenateStringFromPointers(eMessage, eMessage = concatenateStringFromPointers(eMessage,
[]*string{code, subject, target}) []*string{code, subject, target})
// Get Error Details // Get Error Details
// code, message, target // code, message, target
if details != nil { if details != nil {
eMessage = eMessage + "\nDetails Section:" eMessage = eMessage + "\nDetails Section:"
for idx, detail := range details { for idx, detail := range details {
dMessage := fmt.Sprintf("Detail %d:", idx) dMessage := fmt.Sprintf("Detail %d:", idx)
c := detail.GetCode() c := detail.GetCode()
@ -116,6 +125,7 @@ func ConnectorStackErrorTrace(e error) string {
eMessage = eMessage + dMessage eMessage = eMessage + dMessage
} }
} }
if inners != nil { if inners != nil {
eMessage = eMessage + "\nConnector Section:" eMessage = eMessage + "\nConnector Section:"
client := inners.GetClientRequestId() client := inners.GetClientRequestId()
@ -124,5 +134,6 @@ func ConnectorStackErrorTrace(e error) string {
[]*string{client, rID}) []*string{client, rID})
} }
} }
return eMessage return eMessage
} }

View File

@ -25,30 +25,38 @@ func (suite *GraphConnectorErrorSuite) TestWrapAndAppend() {
returnErr := WrapAndAppend("arc376", err2, err1) returnErr := WrapAndAppend("arc376", err2, err1)
suite.True(strings.Contains(returnErr.Error(), "arc376")) suite.True(strings.Contains(returnErr.Error(), "arc376"))
suite.Error(returnErr) suite.Error(returnErr)
multi := &multierror.Error{Errors: []error{err1, err2}} multi := &multierror.Error{Errors: []error{err1, err2}}
suite.True(strings.Contains(ListErrors(*multi), "two")) // Does not contain the wrapped information suite.True(strings.Contains(ListErrors(*multi), "two")) // Does not contain the wrapped information
suite.T().Log(ListErrors(*multi)) suite.T().Log(ListErrors(*multi))
} }
func (suite *GraphConnectorErrorSuite) TestWrapAndAppend_OnVar() { func (suite *GraphConnectorErrorSuite) TestWrapAndAppend_OnVar() {
var err1 error var (
id := "xi2058" err1 error
id = "xi2058"
)
received := WrapAndAppend(id, errors.New("network error"), err1) received := WrapAndAppend(id, errors.New("network error"), err1)
suite.True(strings.Contains(received.Error(), id)) suite.True(strings.Contains(received.Error(), id))
} }
func (suite *GraphConnectorErrorSuite) TestAsRecoverableError() { func (suite *GraphConnectorErrorSuite) TestAsRecoverableError() {
err := assert.AnError err := assert.AnError
var rcv RecoverableGCError
rcv := RecoverableGCError{}
suite.False(errors.As(err, &rcv)) suite.False(errors.As(err, &rcv))
aRecoverable := SetRecoverableError(err) aRecoverable := SetRecoverableError(err)
suite.True(errors.As(aRecoverable, &rcv)) suite.True(errors.As(aRecoverable, &rcv))
} }
func (suite *GraphConnectorErrorSuite) TestAsNonRecoverableError() { func (suite *GraphConnectorErrorSuite) TestAsNonRecoverableError() {
err := assert.AnError err := assert.AnError
var noRecover NonRecoverableGCError
noRecover := NonRecoverableGCError{}
suite.False(errors.As(err, &noRecover)) suite.False(errors.As(err, &noRecover))
nonRecoverable := SetNonRecoverableError(err) nonRecoverable := SetNonRecoverableError(err)
suite.True(errors.As(nonRecoverable, &noRecover)) suite.True(errors.As(nonRecoverable, &noRecover))
} }
@ -70,12 +78,15 @@ func (suite *GraphConnectorErrorSuite) TestWrapAndAppendf() {
} }
func (suite *GraphConnectorErrorSuite) TestConcatenateStringFromPointers() { func (suite *GraphConnectorErrorSuite) TestConcatenateStringFromPointers() {
var s1, s2, s3 *string var (
var outString string outString string
v1 := "Corso" v1 = "Corso"
v3 := "remains" v3 = "remains"
s1 = &v1 s1 = &v1
s3 = &v3 s2 *string
s3 = &v3
)
outString = concatenateStringFromPointers(outString, []*string{s1, s2, s3}) outString = concatenateStringFromPointers(outString, []*string{s1, s2, s3})
suite.True(strings.Contains(outString, v1)) suite.True(strings.Contains(outString, v1))
suite.True(strings.Contains(outString, v3)) suite.True(strings.Contains(outString, v3))

View File

@ -18,6 +18,7 @@ func CreateFromBytes(bytes []byte, createFunc absser.ParsableFactory) (absser.Pa
if err != nil { if err != nil {
return nil, err return nil, err
} }
return anObject, nil return anObject, nil
} }
@ -27,7 +28,9 @@ func CreateMessageFromBytes(bytes []byte) (models.Messageable, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
message := aMessage.(models.Messageable) message := aMessage.(models.Messageable)
return message, nil return message, nil
} }
@ -38,7 +41,9 @@ func CreateContactFromBytes(bytes []byte) (models.Contactable, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
contact := parsable.(models.Contactable) contact := parsable.(models.Contactable)
return contact, nil return contact, nil
} }
@ -48,6 +53,8 @@ func CreateEventFromBytes(bytes []byte) (models.Eventable, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
event := parsable.(models.Eventable) event := parsable.(models.Eventable)
return event, nil return event, nil
} }

View File

@ -44,48 +44,58 @@ func CloneMessageableFields(orig, message models.Messageable) models.Messageable
message.SetMultiValueExtendedProperties(orig.GetMultiValueExtendedProperties()) message.SetMultiValueExtendedProperties(orig.GetMultiValueExtendedProperties())
message.SetUniqueBody(orig.GetUniqueBody()) message.SetUniqueBody(orig.GetUniqueBody())
message.SetWebLink(orig.GetWebLink()) message.SetWebLink(orig.GetWebLink())
return message return message
} }
func ToMessage(orig models.Messageable) models.Messageable { func ToMessage(orig models.Messageable) models.Messageable {
message := models.NewMessage() message := models.NewMessage()
temp := CloneMessageableFields(orig, message) temp := CloneMessageableFields(orig, message)
aMessage, ok := temp.(*models.Message) aMessage, ok := temp.(*models.Message)
if !ok { if !ok {
return nil return nil
} }
return aMessage return aMessage
} }
func SetEventMessageRequest(orig models.Messageable, adtl map[string]any) (models.EventMessageRequestable, error) { func SetEventMessageRequest(orig models.Messageable, adtl map[string]any) (models.EventMessageRequestable, error) {
aMessage := models.NewEventMessageRequest() aMessage := models.NewEventMessageRequest()
temp := CloneMessageableFields(orig, aMessage) temp := CloneMessageableFields(orig, aMessage)
message, ok := temp.(models.EventMessageRequestable) message, ok := temp.(models.EventMessageRequestable)
if !ok { if !ok {
return nil, errors.New(*orig.GetId() + " failed to convert to eventMessageRequestable") return nil, errors.New(*orig.GetId() + " failed to convert to eventMessageRequestable")
} }
newMessage, err := SetAdditionalDataToEventMessage(adtl, message) newMessage, err := SetAdditionalDataToEventMessage(adtl, message)
if err != nil { if err != nil {
return nil, errors.Wrap(err, *orig.GetId()+" eventMessageRequest could not set additional data") return nil, errors.Wrap(err, *orig.GetId()+" eventMessageRequest could not set additional data")
} }
additional, err := buildMapFromAdditional(eventRequestableFields, adtl) additional, err := buildMapFromAdditional(eventRequestableFields, adtl)
if err != nil { if err != nil {
return nil, errors.Wrap(err, *orig.GetId()+" eventMessageRequest failed on method buildMapFromAdditional") return nil, errors.Wrap(err, *orig.GetId()+" eventMessageRequest failed on method buildMapFromAdditional")
} }
message, ok = newMessage.(models.EventMessageRequestable) message, ok = newMessage.(models.EventMessageRequestable)
if !ok { if !ok {
return nil, errors.New(*orig.GetId() + " failed to convert to eventMessageRequestable") return nil, errors.New(*orig.GetId() + " failed to convert to eventMessageRequestable")
} }
eventMessage, err := setEventRequestableFields(message, additional) eventMessage, err := setEventRequestableFields(message, additional)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return eventMessage, nil return eventMessage, nil
} }
func SetEventMessageResponse(orig models.Messageable, adtl map[string]any) (models.EventMessageResponseable, error) { func SetEventMessageResponse(orig models.Messageable, adtl map[string]any) (models.EventMessageResponseable, error) {
aMessage := models.NewEventMessageResponse() aMessage := models.NewEventMessageResponse()
temp := CloneMessageableFields(orig, aMessage) temp := CloneMessageableFields(orig, aMessage)
message, ok := temp.(models.EventMessageResponseable) message, ok := temp.(models.EventMessageResponseable)
if !ok { if !ok {
return nil, errors.New(*orig.GetId() + " failed to convert to eventMessageRequestable") return nil, errors.New(*orig.GetId() + " failed to convert to eventMessageRequestable")
@ -95,14 +105,17 @@ func SetEventMessageResponse(orig models.Messageable, adtl map[string]any) (mode
if err != nil { if err != nil {
return nil, errors.Wrap(err, *orig.GetId()+" eventMessageResponse could not set additional data") return nil, errors.Wrap(err, *orig.GetId()+" eventMessageResponse could not set additional data")
} }
message, ok = newMessage.(models.EventMessageResponseable) message, ok = newMessage.(models.EventMessageResponseable)
if !ok { if !ok {
return nil, errors.New("unable to create event message responseable from " + *orig.GetId()) return nil, errors.New("unable to create event message responseable from " + *orig.GetId())
} }
additional, err := buildMapFromAdditional(eventResponsableFields, adtl) additional, err := buildMapFromAdditional(eventResponsableFields, adtl)
if err != nil { if err != nil {
return nil, errors.Wrap(err, *orig.GetId()+" eventMessageResponse failed on method buildMapFromAdditional") return nil, errors.Wrap(err, *orig.GetId()+" eventMessageResponse failed on method buildMapFromAdditional")
} }
for key, val := range additional { for key, val := range additional {
switch key { switch key {
case "responseType": case "responseType":
@ -110,6 +123,7 @@ func SetEventMessageResponse(orig models.Messageable, adtl map[string]any) (mode
if err != nil { if err != nil {
return nil, errors.Wrap(err, *orig.GetId()+"failure to parse response type") return nil, errors.Wrap(err, *orig.GetId()+"failure to parse response type")
} }
rType, ok := temp.(*models.ResponseType) rType, ok := temp.(*models.ResponseType)
if !ok { if !ok {
return nil, fmt.Errorf( return nil, fmt.Errorf(
@ -119,11 +133,14 @@ func SetEventMessageResponse(orig models.Messageable, adtl map[string]any) (mode
temp, temp,
) )
} }
message.SetResponseType(rType) message.SetResponseType(rType)
default: default:
return nil, errors.New(key + " not supported for setEventMessageResponse") return nil, errors.New(key + " not supported for setEventMessageResponse")
} }
} }
return message, nil return message, nil
} }
@ -131,28 +148,35 @@ func SetEventMessageResponse(orig models.Messageable, adtl map[string]any) (mode
// type until upstream can make the appropriate changes // type until upstream can make the appropriate changes
func ConvertFromMessageable(adtl map[string]any, orig models.Messageable) (models.EventMessageable, error) { func ConvertFromMessageable(adtl map[string]any, orig models.Messageable) (models.EventMessageable, error) {
var aType string var aType string
aPointer, ok := adtl["@odata.type"] aPointer, ok := adtl["@odata.type"]
if !ok { if !ok {
return nil, errors.New("unknown data type: no @odata.type field") return nil, errors.New("unknown data type: no @odata.type field")
} }
ptr, ok := aPointer.(*string) ptr, ok := aPointer.(*string)
if !ok { if !ok {
return nil, errors.New("unknown map type encountered") return nil, errors.New("unknown map type encountered")
} }
aType = *ptr aType = *ptr
if aType == "#microsoft.graph.eventMessageRequest" { if aType == "#microsoft.graph.eventMessageRequest" {
eventRequest, err := SetEventMessageRequest(orig, adtl) eventRequest, err := SetEventMessageRequest(orig, adtl)
if err != nil { if err != nil {
return nil, err return nil, err
} }
eventRequest.SetId(orig.GetId()) eventRequest.SetId(orig.GetId())
return eventRequest, err return eventRequest, err
} }
if aType == "#microsoft.graph.eventMessageResponse" { if aType == "#microsoft.graph.eventMessageResponse" {
eventMessage, err := SetEventMessageResponse(orig, adtl) eventMessage, err := SetEventMessageResponse(orig, adtl)
if err != nil { if err != nil {
return nil, err return nil, err
} }
eventMessage.SetId(orig.GetId()) eventMessage.SetId(orig.GetId())
return eventMessage, nil return eventMessage, nil
@ -164,24 +188,30 @@ func ConvertFromMessageable(adtl map[string]any, orig models.Messageable) (model
// buildMapFromAdditional returns a submap of map[string]*string from map[string]any // buildMapFromAdditional returns a submap of map[string]*string from map[string]any
func buildMapFromAdditional(list []string, adtl map[string]any) (map[string]*string, error) { func buildMapFromAdditional(list []string, adtl map[string]any) (map[string]*string, error) {
returnMap := make(map[string]*string) returnMap := make(map[string]*string)
for _, entry := range list { for _, entry := range list {
ptr, ok := adtl[entry] ptr, ok := adtl[entry]
if !ok { if !ok {
continue continue
} }
value, ok := ptr.(*string) value, ok := ptr.(*string)
if !ok { if !ok {
boolConvert, ok := ptr.(*bool) boolConvert, ok := ptr.(*bool)
if !ok { if !ok {
return nil, errors.New("unsupported value type: key: " + entry + fmt.Sprintf(" with type: %T", ptr)) return nil, errors.New("unsupported value type: key: " + entry + fmt.Sprintf(" with type: %T", ptr))
} }
aBool := *boolConvert aBool := *boolConvert
boolString := strconv.FormatBool(aBool) boolString := strconv.FormatBool(aBool)
returnMap[entry] = &boolString returnMap[entry] = &boolString
continue continue
} }
returnMap[entry] = value returnMap[entry] = value
} }
return returnMap, nil return returnMap, nil
} }
@ -196,25 +226,32 @@ func setEventRequestableFields(
if err != nil { if err != nil {
return nil, errors.Wrap(err, *em.GetId()+": failed on models.ParseMeetingRequestType") return nil, errors.Wrap(err, *em.GetId()+": failed on models.ParseMeetingRequestType")
} }
rType, ok := temp.(*models.MeetingRequestType) rType, ok := temp.(*models.MeetingRequestType)
if !ok { if !ok {
return nil, errors.New(*em.GetId() + ": failed to set meeting request type") return nil, errors.New(*em.GetId() + ": failed to set meeting request type")
} }
em.SetMeetingRequestType(rType) em.SetMeetingRequestType(rType)
case "responseRequested": case "responseRequested":
boolValue, err := strconv.ParseBool(*value) boolValue, err := strconv.ParseBool(*value)
if err != nil { if err != nil {
return nil, errors.Wrap(err, *em.GetId()+": failed to set responseRequested") return nil, errors.Wrap(err, *em.GetId()+": failed to set responseRequested")
} }
em.SetResponseRequested(&boolValue) em.SetResponseRequested(&boolValue)
case "allowNewTimeProposals": case "allowNewTimeProposals":
boolValue, err := strconv.ParseBool(*value) boolValue, err := strconv.ParseBool(*value)
if err != nil { if err != nil {
return nil, errors.Wrap(err, *em.GetId()+": failed to set allowNewTimeProposals") return nil, errors.Wrap(err, *em.GetId()+": failed to set allowNewTimeProposals")
} }
em.SetAllowNewTimeProposals(&boolValue) em.SetAllowNewTimeProposals(&boolValue)
} }
} }
return em, nil return em, nil
} }
@ -226,14 +263,17 @@ func SetAdditionalDataToEventMessage(
for key, entry := range adtl { for key, entry := range adtl {
if key == "endDateTime" { if key == "endDateTime" {
dateTime := models.NewDateTimeTimeZone() dateTime := models.NewDateTimeTimeZone()
mapped, ok := entry.(map[string]*kw.JsonParseNode) mapped, ok := entry.(map[string]*kw.JsonParseNode)
if ok { if ok {
for key, val := range mapped { for key, val := range mapped {
node := *val node := *val
value, err := node.GetStringValue() value, err := node.GetStringValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
switch key { switch key {
case "dateTime": case "dateTime":
dateTime.SetDateTime(value) dateTime.SetDateTime(value)
@ -242,21 +282,27 @@ func SetAdditionalDataToEventMessage(
default: default:
return nil, errors.New("key not supported DateTime") return nil, errors.New("key not supported DateTime")
} }
newMessage.SetEndDateTime(dateTime) newMessage.SetEndDateTime(dateTime)
} }
continue continue
} }
} }
if key == "startDateTime" { if key == "startDateTime" {
dateTime := models.NewDateTimeTimeZone() dateTime := models.NewDateTimeTimeZone()
mapped, ok := entry.(map[string]*kw.JsonParseNode) mapped, ok := entry.(map[string]*kw.JsonParseNode)
if ok { if ok {
for key, val := range mapped { for key, val := range mapped {
node := *val node := *val
value, err := node.GetStringValue() value, err := node.GetStringValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
switch key { switch key {
case "dateTime": case "dateTime":
dateTime.SetDateTime(value) dateTime.SetDateTime(value)
@ -264,23 +310,28 @@ func SetAdditionalDataToEventMessage(
dateTime.SetTimeZone(value) dateTime.SetTimeZone(value)
default: default:
return nil, errors.New("key not supported DateTime") return nil, errors.New("key not supported DateTime")
} }
newMessage.SetStartDateTime(dateTime) newMessage.SetStartDateTime(dateTime)
} }
continue continue
} }
} }
if key == "location" { if key == "location" {
aLocation := models.NewLocation() aLocation := models.NewLocation()
mapped, ok := entry.(map[string]*kw.JsonParseNode) mapped, ok := entry.(map[string]*kw.JsonParseNode)
if ok { if ok {
for key, val := range mapped { for key, val := range mapped {
node := *val node := *val
value, err := node.GetStringValue() value, err := node.GetStringValue()
if err != nil { if err != nil {
return nil, errors.New("map[string]*JsonParseNode conversion failure") return nil, errors.New("map[string]*JsonParseNode conversion failure")
} }
switch key { switch key {
case "displayName": case "displayName":
aLocation.SetDisplayName(value) aLocation.SetDisplayName(value)
@ -289,16 +340,20 @@ func SetAdditionalDataToEventMessage(
if err != nil { if err != nil {
return nil, errors.New("location type parse failure") return nil, errors.New("location type parse failure")
} }
lType, ok := temp.(*models.LocationType) lType, ok := temp.(*models.LocationType)
if !ok { if !ok {
return nil, errors.New("location type interface failure") return nil, errors.New("location type interface failure")
} }
aLocation.SetLocationType(lType) aLocation.SetLocationType(lType)
} }
} }
} }
newMessage.SetLocation(aLocation) newMessage.SetLocation(aLocation)
} }
value, ok := entry.(*string) value, ok := entry.(*string)
if ok { if ok {
switch key { switch key {
@ -307,31 +362,40 @@ func SetAdditionalDataToEventMessage(
if err != nil { if err != nil {
return nil, err return nil, err
} }
newMessage.SetIsAllDay(&boolValue) newMessage.SetIsAllDay(&boolValue)
case "isDelegated": case "isDelegated":
boolValue, err := strconv.ParseBool(*value) boolValue, err := strconv.ParseBool(*value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
newMessage.SetIsDelegated(&boolValue) newMessage.SetIsDelegated(&boolValue)
case "isOutOfDate": case "isOutOfDate":
boolValue, err := strconv.ParseBool(*value) boolValue, err := strconv.ParseBool(*value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
newMessage.SetIsOutOfDate(&boolValue) newMessage.SetIsOutOfDate(&boolValue)
case "meetingMessageType": case "meetingMessageType":
temp, err := models.ParseMeetingMessageType(*value) temp, err := models.ParseMeetingMessageType(*value)
if err != nil { if err != nil {
return nil, err return nil, err
} }
mType, ok := temp.(*models.MeetingMessageType) mType, ok := temp.(*models.MeetingMessageType)
if !ok { if !ok {
return nil, errors.New("failed to create meeting message type") return nil, errors.New("failed to create meeting message type")
} }
newMessage.SetMeetingMessageType(mType) newMessage.SetMeetingMessageType(mType)
} }
} }
} }
return newMessage, nil return newMessage, nil
} }

View File

@ -21,6 +21,7 @@ func (suite *SupportTestSuite) TestToMessage() {
bytes := mockconnector.GetMockMessageBytes("m365 mail support test") bytes := mockconnector.GetMockMessageBytes("m365 mail support test")
message, err := CreateMessageFromBytes(bytes) message, err := CreateMessageFromBytes(bytes)
require.NoError(suite.T(), err) require.NoError(suite.T(), err)
clone := ToMessage(message) clone := ToMessage(message)
suite.Equal(message.GetBccRecipients(), clone.GetBccRecipients()) suite.Equal(message.GetBccRecipients(), clone.GetBccRecipients())
suite.Equal(message.GetSubject(), clone.GetSubject()) suite.Equal(message.GetSubject(), clone.GetSubject())

View File

@ -33,11 +33,13 @@ func CreateStatus(
objects, success, folders int, objects, success, folders int,
err error, err error,
) *ConnectorOperationStatus { ) *ConnectorOperationStatus {
hasErrors := err != nil
var reason string var reason string
if err != nil { if err != nil {
reason = err.Error() reason = err.Error()
} }
hasErrors := err != nil
numErr := GetNumberOfErrors(err) numErr := GetNumberOfErrors(err)
status := ConnectorOperationStatus{ status := ConnectorOperationStatus{
lastOperation: op, lastOperation: op,
@ -48,6 +50,7 @@ func CreateStatus(
incomplete: hasErrors, incomplete: hasErrors,
incompleteReason: reason, incompleteReason: reason,
} }
if status.ObjectCount != status.errorCount+status.Successful { if status.ObjectCount != status.errorCount+status.Successful {
logger.Ctx(ctx).DPanicw( logger.Ctx(ctx).DPanicw(
"status object count does not match errors + successes", "status object count does not match errors + successes",
@ -55,6 +58,7 @@ func CreateStatus(
"successes", success, "successes", success,
"errors", numErr) "errors", numErr)
} }
return &status return &status
} }
@ -64,6 +68,8 @@ func (cos *ConnectorOperationStatus) String() string {
if cos.incomplete { if cos.incomplete {
message += " " + cos.incompleteReason message += " " + cos.incompleteReason
} }
message = message + "\n" message = message + "\n"
return message return message
} }

View File

@ -66,6 +66,7 @@ func (suite *GCStatusTestSuite) TestCreateStatus() {
func (suite *GCStatusTestSuite) TestCreateStatus_InvalidStatus() { func (suite *GCStatusTestSuite) TestCreateStatus_InvalidStatus() {
t := suite.T() t := suite.T()
params := statusParams{Backup, 9, 3, 13, errors.New("invalidcl")} params := statusParams{Backup, 9, 3, 13, errors.New("invalidcl")}
require.Panics(t, func() { require.Panics(t, func() {
CreateStatus( CreateStatus(
context.Background(), context.Background(),