enable restore path creation for sharepoint lists (#4922)

Enable restore path creation for sharepoint lists
Changes previously approved in: https://github.com/alcionai/corso/pull/4855

#### 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

#### Issue(s)
#4754 

#### Test Plan

<!-- How will this be tested prior to merging.-->
- [x] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Hitesh Pattanayak 2023-12-22 22:12:53 +05:30 committed by GitHub
parent d6e9a2112d
commit 98e8cac374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 101 additions and 30 deletions

View File

@ -142,7 +142,8 @@ func makeRestorePathsForEntry(
// * OneDrive/SharePoint (needs drive information)
switch true {
case ent.Exchange != nil ||
(ent.Groups != nil && ent.Groups.ItemType == details.GroupsChannelMessage):
(ent.Groups != nil && ent.Groups.ItemType == details.GroupsChannelMessage) ||
(ent.SharePoint != nil && ent.SharePoint.ItemType == details.SharePointList):
// TODO(ashmrtn): Eventually make Events have it's own function to handle
// setting the restore destination properly.
res.RestorePath, err = basicLocationPath(repoRef, locRef)

View File

@ -50,16 +50,19 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
driveID = "some-drive-id"
siteID = "some-site-id"
extraItemName = "some-item"
listName = "list1"
SharePointRootItemPath = testdata.SharePointRootPath.MustAppend(extraItemName, true)
SharePointListItemPath = testdata.SharePointListPath.MustAppend(listName, true)
GroupsRootItemPath = testdata.GroupsRootPath.MustAppend(extraItemName, true)
)
table := []struct {
name string
backupVersion int
input []*details.Entry
expectErr assert.ErrorAssertionFunc
expected []expectPaths
name string
backupVersion int
input []*details.Entry
expectErr assert.ErrorAssertionFunc
expected []expectPaths
isSharepointList bool
}{
{
name: "Groups List Errors v9",
@ -157,13 +160,13 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
},
},
{
name: "SharePoint List Errors",
name: "SharePoint List, item in root",
// No version bump for the change so we always have to check for this.
backupVersion: version.All8MigrateUserPNToID,
input: []*details.Entry{
{
RepoRef: SharePointRootItemPath.RR.String(),
LocationRef: SharePointRootItemPath.Loc.String(),
RepoRef: SharePointListItemPath.RR.String(),
LocationRef: SharePointListItemPath.Loc.String(),
ItemInfo: details.ItemInfo{
SharePoint: &details.SharePointInfo{
ItemType: details.SharePointList,
@ -171,7 +174,14 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
},
},
},
expectErr: assert.Error,
expected: []expectPaths{
{
storage: SharePointListItemPath.RR.String(),
restore: toRestore(SharePointListItemPath.RR),
},
},
expectErr: assert.NoError,
isSharepointList: true,
},
{
name: "SharePoint Page Errors",
@ -413,12 +423,23 @@ func (suite *RestorePathTransformerUnitSuite) TestGetPaths() {
for _, e := range test.expected {
tmp := path.RestorePaths{}
p, err := path.FromDataLayerPath(e.storage, true)
var p path.Path
var err error
if test.isSharepointList {
p, err = path.PrefixOrPathFromDataLayerPath(e.storage, true)
} else {
p, err = path.FromDataLayerPath(e.storage, true)
}
require.NoError(t, err, "parsing expected storage path", clues.ToCore(err))
tmp.StoragePath = p
p, err = path.FromDataLayerPath(e.restore, false)
if test.isSharepointList {
p, err = path.PrefixOrPathFromDataLayerPath(e.restore, false)
} else {
p, err = path.FromDataLayerPath(e.restore, false)
}
require.NoError(t, err, "parsing expected restore path", clues.ToCore(err))
if e.isRestorePrefix {

View File

@ -16,8 +16,16 @@ import (
// mustParsePath takes a string representing a resource path and returns a path
// instance. Panics if the path cannot be parsed. Useful for simple variable
// assignments.
func mustParsePath(ref string, isItem bool) path.Path {
p, err := path.FromDataLayerPath(ref, isItem)
func mustParsePath(ref string, isItem, isSharepointList bool) path.Path {
var p path.Path
var err error
if isSharepointList {
p, err = path.PrefixOrPathFromDataLayerPath(ref, isItem)
} else {
p, err = path.FromDataLayerPath(ref, isItem)
}
if err != nil {
panic(err)
}
@ -47,7 +55,7 @@ func locFromRepo(rr path.Path, isItem bool) *path.Builder {
if rr.Service() == path.GroupsService {
loc = loc.PopFront().PopFront().PopFront()
} else if rr.Service() == path.OneDriveService || rr.Category() == path.LibrariesCategory {
} else if rr.Service() == path.OneDriveService || rr.Category() == path.LibrariesCategory || rr.Category() == path.ListsCategory {
loc = loc.PopFront()
}
@ -117,9 +125,12 @@ func (p repoRefAndLocRef) locationAsRepoRef() path.Path {
return res
}
func mustPathRep(ref string, isItem bool) repoRefAndLocRef {
func mustPathRep(ref string, isItem, isSharepointList bool) repoRefAndLocRef {
var rr path.Path
var err error
res := repoRefAndLocRef{}
tmp := mustParsePath(ref, isItem)
tmp := mustParsePath(ref, isItem, isSharepointList)
// Now append stuff to the RepoRef elements so we have distinct LocationRef
// and RepoRef elements to simulate using IDs in the path instead of display
@ -133,12 +144,21 @@ func mustPathRep(ref string, isItem bool) repoRefAndLocRef {
rrPB = rrPB.Append(tmp.Item() + fileSuffix)
}
rr, err := rrPB.ToDataLayerPath(
tmp.Tenant(),
tmp.ProtectedResource(),
tmp.Service(),
tmp.Category(),
isItem)
if isSharepointList {
rr, err = rrPB.ToDataLayerSharePointListPath(
tmp.Tenant(),
tmp.ProtectedResource(),
tmp.Category(),
isItem)
} else {
rr, err = rrPB.ToDataLayerPath(
tmp.Tenant(),
tmp.ProtectedResource(),
tmp.Service(),
tmp.Category(),
isItem)
}
if err != nil {
panic(err)
}
@ -166,7 +186,7 @@ var (
Time3 = time.Date(2023, 9, 21, 10, 0, 0, 0, time.UTC)
Time4 = time.Date(2023, 10, 21, 10, 0, 0, 0, time.UTC)
ExchangeEmailInboxPath = mustPathRep("tenant-id/exchange/user-id/email/Inbox", false)
ExchangeEmailInboxPath = mustPathRep("tenant-id/exchange/user-id/email/Inbox", false, false)
ExchangeEmailBasePath = ExchangeEmailInboxPath.MustAppend("subfolder", false)
ExchangeEmailBasePath2 = ExchangeEmailInboxPath.MustAppend("othersubfolder/", false)
ExchangeEmailBasePath3 = ExchangeEmailBasePath2.MustAppend("subsubfolder", false)
@ -314,7 +334,7 @@ var (
},
}
ExchangeContactsRootPath = mustPathRep("tenant-id/exchange/user-id/contacts/contacts", false)
ExchangeContactsRootPath = mustPathRep("tenant-id/exchange/user-id/contacts/contacts", false, false)
ExchangeContactsBasePath = ExchangeContactsRootPath.MustAppend("contacts", false)
ExchangeContactsBasePath2 = ExchangeContactsRootPath.MustAppend("morecontacts", false)
ExchangeContactsItemPath1 = ExchangeContactsBasePath.MustAppend(ItemName1, true)
@ -403,8 +423,8 @@ var (
},
}
ExchangeEventsBasePath = mustPathRep("tenant-id/exchange/user-id/events/holidays", false)
ExchangeEventsBasePath2 = mustPathRep("tenant-id/exchange/user-id/events/moreholidays", false)
ExchangeEventsBasePath = mustPathRep("tenant-id/exchange/user-id/events/holidays", false, false)
ExchangeEventsBasePath2 = mustPathRep("tenant-id/exchange/user-id/events/moreholidays", false, false)
ExchangeEventsItemPath1 = ExchangeEventsBasePath.MustAppend(ItemName1, true)
ExchangeEventsItemPath2 = ExchangeEventsBasePath2.MustAppend(ItemName2, true)
@ -507,7 +527,7 @@ var (
},
}
OneDriveRootPath = mustPathRep("tenant-id/onedrive/user-id/files/drives/foo/root:", false)
OneDriveRootPath = mustPathRep("tenant-id/onedrive/user-id/files/drives/foo/root:", false, false)
OneDriveFolderPath = OneDriveRootPath.MustAppend("folder", false)
OneDriveBasePath1 = OneDriveFolderPath.MustAppend("a", false)
OneDriveBasePath2 = OneDriveFolderPath.MustAppend("b", false)
@ -732,10 +752,11 @@ var (
},
}
GroupsRootPath = mustPathRep("tenant-id/groups/group-id/libraries/sites/site-id/drives/foo/root:", false)
GroupsRootPath = mustPathRep("tenant-id/groups/group-id/libraries/sites/site-id/drives/foo/root:", false, false)
SharePointRootPath = mustPathRep("tenant-id/sharepoint/site-id/libraries/drives/foo/root:", false)
SharePointRootPath = mustPathRep("tenant-id/sharepoint/site-id/libraries/drives/foo/root:", false, false)
SharePointLibraryPath = SharePointRootPath.MustAppend("library", false)
SharePointListPath = mustPathRep("tenant-id/sharepoint/site-id/lists", false, true)
SharePointBasePath1 = SharePointLibraryPath.MustAppend("a", false)
SharePointBasePath2 = SharePointLibraryPath.MustAppend("b", false)

View File

@ -355,6 +355,34 @@ func (pb Builder) ToDataLayerSharePointPath(
return pb.ToDataLayerPath(tenant, site, SharePointService, category, isItem)
}
func (pb Builder) ToDataLayerSharePointListPath(
tenant, site string,
category CategoryType,
isItem bool,
) (Path, error) {
if err := ValidateServiceAndCategory(SharePointService, category); err != nil {
return nil, err
}
if err := verifyInputValues(tenant, site); err != nil {
return nil, err
}
prefixItems := []string{
tenant,
SharePointService.String(),
site,
category.String(),
}
return &dataLayerResourcePath{
Builder: *pb.withPrefix(prefixItems...),
service: SharePointService,
category: category,
hasItem: isItem,
}, nil
}
// ---------------------------------------------------------------------------
// Stringers and PII Concealer Compliance
// ---------------------------------------------------------------------------