GC: Item attachment contact support (#2465)
## Description The logic for sanitizing Contactable data for restoration of `ItemAttachable.Contact` types. Contact `Item.Attachment`s required the removal of: - `odata.Context` - `ETag` - `ParentFolder` Otherwise, the following error occurs on POST. ```bash UnableToDeserializePostBody were unable to deserialize ``` <!-- Insert PR description--> ## Does this PR need a docs update or release note? - [x] ⛔ No ## 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 #2426<issue> ## Test Plan - [x] ⚡ Unit test
This commit is contained in:
parent
d9d0158b6f
commit
b3a1de89bb
14
src/internal/common/ptr/pointer.go
Normal file
14
src/internal/common/ptr/pointer.go
Normal file
@ -0,0 +1,14 @@
|
||||
package ptr
|
||||
|
||||
// Val helper method for unwrapping strings
|
||||
// Microsoft Graph saves many variables as string pointers.
|
||||
// Function will safely check if the point is nil prior to
|
||||
// dereferencing the pointer. If the pointer is nil,
|
||||
// an empty string is returned.
|
||||
func Val(ptr *string) string {
|
||||
if ptr == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return *ptr
|
||||
}
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||
"github.com/alcionai/corso/src/internal/connector/support"
|
||||
"github.com/alcionai/corso/src/internal/connector/uploadsession"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
@ -63,19 +64,16 @@ func uploadAttachment(
|
||||
|
||||
attachment, err = support.ToItemAttachment(attachment)
|
||||
if err != nil {
|
||||
name := ""
|
||||
if prev.GetName() != nil {
|
||||
name = *prev.GetName()
|
||||
}
|
||||
name := ptr.Val(prev.GetName())
|
||||
msg := "item attachment restore not supported for this type. skipping upload."
|
||||
|
||||
// TODO: (rkeepers) Update to support PII protection
|
||||
msg := "item attachment restore not supported for this type. skipping upload."
|
||||
logger.Ctx(ctx).Infow(msg,
|
||||
"err", err,
|
||||
"attachment_name", name,
|
||||
"attachment_type", attachmentType,
|
||||
"internal_item_type", getItemAttachmentItemType(prev),
|
||||
"attachment_id", *prev.GetId(),
|
||||
"attachment_id", ptr.Val(prev.GetId()),
|
||||
)
|
||||
|
||||
return nil
|
||||
@ -129,9 +127,6 @@ func getItemAttachmentItemType(query models.Attachmentable) string {
|
||||
}
|
||||
|
||||
item := attachment.GetItem()
|
||||
if item.GetOdataType() == nil {
|
||||
return empty
|
||||
}
|
||||
|
||||
return *item.GetOdataType()
|
||||
return ptr.Val(item.GetOdataType())
|
||||
}
|
||||
|
||||
@ -230,6 +230,21 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
|
||||
return *folder.GetId()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test Mail: Item Attachment_Contact",
|
||||
bytes: mockconnector.GetMockMessageWithNestedItemAttachmentContact(t,
|
||||
mockconnector.GetMockContactBytes("Victor"),
|
||||
"Contact Item Attachment",
|
||||
),
|
||||
category: path.EmailCategory,
|
||||
destination: func(t *testing.T, ctx context.Context) string {
|
||||
folderName := "ItemMailAttachment_Contact " + common.FormatSimpleDateTime(now)
|
||||
folder, err := suite.ac.Mail().CreateMailFolder(ctx, userID, folderName)
|
||||
require.NoError(t, err)
|
||||
|
||||
return *folder.GetId()
|
||||
},
|
||||
},
|
||||
{ // Restore will upload the Message without uploading the attachment
|
||||
name: "Test Mail: Item Attachment_NestedEvent",
|
||||
bytes: mockconnector.GetMockMessageWithNestedItemAttachmentEvent("Nested Item Attachment"),
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
absser "github.com/microsoft/kiota-abstractions-go/serialization"
|
||||
js "github.com/microsoft/kiota-serialization-json-go"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
"github.com/pkg/errors"
|
||||
@ -706,8 +707,35 @@ func GetMockMessageWithNestedItemAttachmentMail(t *testing.T, nested []byte, sub
|
||||
iaNode.SetItem(nestedMessage)
|
||||
message.SetAttachments([]models.Attachmentable{iaNode})
|
||||
|
||||
return serialize(t, message)
|
||||
}
|
||||
|
||||
func GetMockMessageWithNestedItemAttachmentContact(t *testing.T, nested []byte, subject string) []byte {
|
||||
base := GetMockMessageBytes(subject)
|
||||
message, err := hydrateMessage(base)
|
||||
require.NoError(t, err)
|
||||
|
||||
parseNode, err := js.NewJsonParseNodeFactory().GetRootParseNode("application/json", nested)
|
||||
require.NoError(t, err)
|
||||
|
||||
anObject, err := parseNode.GetObjectValue(models.CreateContactFromDiscriminatorValue)
|
||||
require.NoError(t, err)
|
||||
|
||||
contact := anObject.(models.Contactable)
|
||||
internalName := "Nested Contact"
|
||||
iaNode := models.NewItemAttachment()
|
||||
attachmentSize := int32(len(nested))
|
||||
iaNode.SetSize(&attachmentSize)
|
||||
iaNode.SetName(&internalName)
|
||||
iaNode.SetItem(contact)
|
||||
message.SetAttachments([]models.Attachmentable{iaNode})
|
||||
|
||||
return serialize(t, message)
|
||||
}
|
||||
|
||||
func serialize(t *testing.T, item absser.Parsable) []byte {
|
||||
wtr := js.NewJsonSerializationWriter()
|
||||
err = wtr.WriteObjectValue("", message)
|
||||
err := wtr.WriteObjectValue("", item)
|
||||
require.NoError(t, err)
|
||||
|
||||
byteArray, err := wtr.GetSerializedContent()
|
||||
|
||||
@ -306,9 +306,10 @@ func cloneColumnDefinitionable(orig models.ColumnDefinitionable) models.ColumnDe
|
||||
//
|
||||
//nolint:lll
|
||||
const (
|
||||
itemAttachment = "#microsoft.graph.itemAttachment"
|
||||
eventItemType = "#microsoft.graph.event"
|
||||
mailItemType = "#microsoft.graph.message"
|
||||
itemAttachment = "#microsoft.graph.itemAttachment"
|
||||
eventItemType = "#microsoft.graph.event"
|
||||
mailItemType = "#microsoft.graph.message"
|
||||
contactItemType = "#microsoft.graph.contact"
|
||||
)
|
||||
|
||||
// ToItemAttachment transforms internal item, OutlookItemables, into
|
||||
@ -323,6 +324,13 @@ func ToItemAttachment(orig models.Attachmentable) (models.Attachmentable, error)
|
||||
itemType := item.GetOdataType()
|
||||
|
||||
switch *itemType {
|
||||
case contactItemType:
|
||||
contact := item.(models.Contactable)
|
||||
revised := sanitizeContact(contact)
|
||||
|
||||
transform.SetItem(revised)
|
||||
|
||||
return transform, nil
|
||||
case eventItemType:
|
||||
event := item.(models.Eventable)
|
||||
|
||||
@ -372,6 +380,15 @@ func ToItemAttachment(orig models.Attachmentable) (models.Attachmentable, error)
|
||||
// return attachments, nil
|
||||
// }
|
||||
|
||||
// sanitizeContact removes fields which prevent a Contact from
|
||||
// being uploaded as an attachment.
|
||||
func sanitizeContact(orig models.Contactable) models.Contactable {
|
||||
orig.SetParentFolderId(nil)
|
||||
orig.SetAdditionalData(nil)
|
||||
|
||||
return orig
|
||||
}
|
||||
|
||||
// sanitizeEvent transfers data into event object and
|
||||
// removes unique IDs from the M365 object
|
||||
func sanitizeEvent(orig models.Eventable) (models.Eventable, error) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user