Begin storing OneDrive file names in metadata (#2494)
## Description This starts to store the name of the OneDrive file/directory in the corso metadata file for the OneDrive file/directory. This data is not yet used anywhere ## Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No ## Type of change - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🧹 Tech Debt/Cleanup ## Issue(s) * #1535 ## Test Plan - [x] 💪 Manual - [ ] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
d7087d7461
commit
4565c9f33b
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/alcionai/corso/src/internal/connector/onedrive"
|
"github.com/alcionai/corso/src/internal/connector/onedrive"
|
||||||
"github.com/alcionai/corso/src/internal/tester"
|
"github.com/alcionai/corso/src/internal/tester"
|
||||||
"github.com/alcionai/corso/src/pkg/account"
|
"github.com/alcionai/corso/src/pkg/account"
|
||||||
|
"github.com/alcionai/corso/src/pkg/backup"
|
||||||
"github.com/alcionai/corso/src/pkg/control"
|
"github.com/alcionai/corso/src/pkg/control"
|
||||||
"github.com/alcionai/corso/src/pkg/path"
|
"github.com/alcionai/corso/src/pkg/path"
|
||||||
)
|
)
|
||||||
@ -83,10 +84,16 @@ var (
|
|||||||
[]byte("{}"),
|
[]byte("{}"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fileAData = []byte(strings.Repeat("a", 33))
|
||||||
|
fileBData = []byte(strings.Repeat("b", 65))
|
||||||
|
fileCData = []byte(strings.Repeat("c", 129))
|
||||||
|
fileDData = []byte(strings.Repeat("d", 257))
|
||||||
|
fileEData = []byte(strings.Repeat("e", 257))
|
||||||
|
|
||||||
fileAEmptyPerms = []itemInfo{
|
fileAEmptyPerms = []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt"+onedrive.DataFileSuffix,
|
"test-file.txt"+onedrive.DataFileSuffix,
|
||||||
[]byte(strings.Repeat("a", 33)),
|
fileAData,
|
||||||
),
|
),
|
||||||
fileEmptyPerms,
|
fileEmptyPerms,
|
||||||
}
|
}
|
||||||
@ -94,7 +101,7 @@ var (
|
|||||||
fileBEmptyPerms = []itemInfo{
|
fileBEmptyPerms = []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt"+onedrive.DataFileSuffix,
|
"test-file.txt"+onedrive.DataFileSuffix,
|
||||||
[]byte(strings.Repeat("b", 65)),
|
fileBData,
|
||||||
),
|
),
|
||||||
fileEmptyPerms,
|
fileEmptyPerms,
|
||||||
}
|
}
|
||||||
@ -102,7 +109,7 @@ var (
|
|||||||
fileCEmptyPerms = []itemInfo{
|
fileCEmptyPerms = []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt"+onedrive.DataFileSuffix,
|
"test-file.txt"+onedrive.DataFileSuffix,
|
||||||
[]byte(strings.Repeat("c", 129)),
|
fileCData,
|
||||||
),
|
),
|
||||||
fileEmptyPerms,
|
fileEmptyPerms,
|
||||||
}
|
}
|
||||||
@ -110,7 +117,7 @@ var (
|
|||||||
fileDEmptyPerms = []itemInfo{
|
fileDEmptyPerms = []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt"+onedrive.DataFileSuffix,
|
"test-file.txt"+onedrive.DataFileSuffix,
|
||||||
[]byte(strings.Repeat("d", 257)),
|
fileDData,
|
||||||
),
|
),
|
||||||
fileEmptyPerms,
|
fileEmptyPerms,
|
||||||
}
|
}
|
||||||
@ -118,7 +125,7 @@ var (
|
|||||||
fileEEmptyPerms = []itemInfo{
|
fileEEmptyPerms = []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt"+onedrive.DataFileSuffix,
|
"test-file.txt"+onedrive.DataFileSuffix,
|
||||||
[]byte(strings.Repeat("e", 257)),
|
fileEData,
|
||||||
),
|
),
|
||||||
fileEmptyPerms,
|
fileEmptyPerms,
|
||||||
}
|
}
|
||||||
@ -169,7 +176,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup() {
|
|||||||
items: withItems(
|
items: withItems(
|
||||||
onedriveFileWithMetadata(
|
onedriveFileWithMetadata(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("a", 33)),
|
fileAData,
|
||||||
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}),
|
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}),
|
||||||
),
|
),
|
||||||
[]itemInfo{onedriveItemWithData(
|
[]itemInfo{onedriveItemWithData(
|
||||||
@ -194,7 +201,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup() {
|
|||||||
category: path.FilesCategory,
|
category: path.FilesCategory,
|
||||||
items: onedriveFileWithMetadata(
|
items: onedriveFileWithMetadata(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("e", 66)),
|
fileEData,
|
||||||
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}),
|
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}),
|
||||||
),
|
),
|
||||||
auxItems: []itemInfo{
|
auxItems: []itemInfo{
|
||||||
@ -320,7 +327,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_Versio
|
|||||||
items: []itemInfo{
|
items: []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("a", 33)),
|
fileAData,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -335,7 +342,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_Versio
|
|||||||
items: []itemInfo{
|
items: []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("b", 65)),
|
fileBData,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -351,7 +358,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_Versio
|
|||||||
items: []itemInfo{
|
items: []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("c", 129)),
|
fileCData,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -368,7 +375,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_Versio
|
|||||||
items: []itemInfo{
|
items: []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("d", 257)),
|
fileDData,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -383,7 +390,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestRestoreAndBackup_Versio
|
|||||||
items: []itemInfo{
|
items: []itemInfo{
|
||||||
onedriveItemWithData(
|
onedriveItemWithData(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("e", 257)),
|
fileEData,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -435,13 +442,13 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsRestoreAndBa
|
|||||||
var (
|
var (
|
||||||
fileAWritePerms = onedriveFileWithMetadata(
|
fileAWritePerms = onedriveFileWithMetadata(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("a", 33)),
|
fileAData,
|
||||||
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}),
|
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}),
|
||||||
)
|
)
|
||||||
|
|
||||||
fileEReadPerms = onedriveFileWithMetadata(
|
fileEReadPerms = onedriveFileWithMetadata(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("e", 66)),
|
fileEData,
|
||||||
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}),
|
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"read"}),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -638,7 +645,7 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsBackupAndNoR
|
|||||||
category: path.FilesCategory,
|
category: path.FilesCategory,
|
||||||
items: onedriveFileWithMetadata(
|
items: onedriveFileWithMetadata(
|
||||||
"test-file.txt",
|
"test-file.txt",
|
||||||
[]byte(strings.Repeat("a", 33)),
|
fileAData,
|
||||||
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}),
|
getTestMetaJSON(suite.T(), suite.secondaryUser, []string{"write"}),
|
||||||
),
|
),
|
||||||
auxItems: []itemInfo{
|
auxItems: []itemInfo{
|
||||||
@ -668,3 +675,113 @@ func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsBackupAndNoR
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *GraphConnectorOneDriveIntegrationSuite) TestPermissionsRestoreAndNoBackup() {
|
||||||
|
ctx, flush := tester.NewContext()
|
||||||
|
defer flush()
|
||||||
|
|
||||||
|
t := suite.T()
|
||||||
|
|
||||||
|
driveID := mustGetDefaultDriveID(
|
||||||
|
t,
|
||||||
|
ctx,
|
||||||
|
suite.connector.Service,
|
||||||
|
suite.user,
|
||||||
|
)
|
||||||
|
|
||||||
|
test := restoreBackupInfoMultiVersion{
|
||||||
|
service: path.OneDriveService,
|
||||||
|
resource: Users,
|
||||||
|
backupVersion: backup.Version,
|
||||||
|
countMeta: false,
|
||||||
|
collectionsPrevious: []colInfo{
|
||||||
|
{
|
||||||
|
pathElements: []string{
|
||||||
|
"drives",
|
||||||
|
driveID,
|
||||||
|
"root:",
|
||||||
|
},
|
||||||
|
category: path.FilesCategory,
|
||||||
|
items: withItems(
|
||||||
|
onedriveFileWithMetadata(
|
||||||
|
"test-file.txt",
|
||||||
|
fileAData,
|
||||||
|
getTestMetaJSON(t, suite.secondaryUser, []string{"write"}),
|
||||||
|
),
|
||||||
|
[]itemInfo{onedriveItemWithData(
|
||||||
|
"b"+onedrive.DirMetaFileSuffix,
|
||||||
|
getTestMetaJSON(t, suite.secondaryUser, []string{"read"}),
|
||||||
|
)},
|
||||||
|
),
|
||||||
|
auxItems: []itemInfo{
|
||||||
|
onedriveItemWithData(
|
||||||
|
"test-file.txt"+onedrive.MetaFileSuffix,
|
||||||
|
getTestMetaJSON(t, suite.secondaryUser, []string{"write"}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathElements: []string{
|
||||||
|
"drives",
|
||||||
|
driveID,
|
||||||
|
"root:",
|
||||||
|
"b",
|
||||||
|
},
|
||||||
|
category: path.FilesCategory,
|
||||||
|
items: onedriveFileWithMetadata(
|
||||||
|
"test-file.txt",
|
||||||
|
fileEData,
|
||||||
|
getTestMetaJSON(t, suite.secondaryUser, []string{"read"}),
|
||||||
|
),
|
||||||
|
auxItems: []itemInfo{
|
||||||
|
onedriveItemWithData(
|
||||||
|
"test-file.txt"+onedrive.MetaFileSuffix,
|
||||||
|
getTestMetaJSON(t, suite.secondaryUser, []string{"read"}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
collectionsLatest: []colInfo{
|
||||||
|
{
|
||||||
|
pathElements: []string{
|
||||||
|
"drives",
|
||||||
|
driveID,
|
||||||
|
"root:",
|
||||||
|
},
|
||||||
|
category: path.FilesCategory,
|
||||||
|
items: withItems(
|
||||||
|
fileAEmptyPerms,
|
||||||
|
folderBEmptyPerms,
|
||||||
|
),
|
||||||
|
auxItems: []itemInfo{
|
||||||
|
fileEmptyPerms,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathElements: []string{
|
||||||
|
"drives",
|
||||||
|
driveID,
|
||||||
|
"root:",
|
||||||
|
"b",
|
||||||
|
},
|
||||||
|
category: path.FilesCategory,
|
||||||
|
items: fileEEmptyPerms,
|
||||||
|
auxItems: []itemInfo{
|
||||||
|
fileEmptyPerms,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
runRestoreBackupTestVersions(
|
||||||
|
t,
|
||||||
|
suite.acct,
|
||||||
|
test,
|
||||||
|
suite.connector.tenant,
|
||||||
|
[]string{suite.user},
|
||||||
|
control.Options{
|
||||||
|
RestorePermissions: true,
|
||||||
|
ToggleFeatures: control.Toggles{EnablePermissionsBackup: false},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@ -480,10 +480,7 @@ func runBackupAndCompare(
|
|||||||
ctx,
|
ctx,
|
||||||
backupSel,
|
backupSel,
|
||||||
nil,
|
nil,
|
||||||
control.Options{
|
config.opts,
|
||||||
RestorePermissions: true,
|
|
||||||
ToggleFeatures: control.Toggles{EnablePermissionsBackup: true},
|
|
||||||
},
|
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// No excludes yet because this isn't an incremental backup.
|
// No excludes yet because this isn't an incremental backup.
|
||||||
|
|||||||
@ -5,11 +5,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/alcionai/clues"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spatialcurrent/go-lazy/pkg/lazy"
|
"github.com/spatialcurrent/go-lazy/pkg/lazy"
|
||||||
@ -91,6 +91,7 @@ type itemMetaReaderFunc func(
|
|||||||
service graph.Servicer,
|
service graph.Servicer,
|
||||||
driveID string,
|
driveID string,
|
||||||
item models.DriveItemable,
|
item models.DriveItemable,
|
||||||
|
fetchPermissions bool,
|
||||||
) (io.ReadCloser, int, error)
|
) (io.ReadCloser, int, error)
|
||||||
|
|
||||||
// NewCollection creates a Collection
|
// NewCollection creates a Collection
|
||||||
@ -180,6 +181,7 @@ type UserPermission struct {
|
|||||||
// ItemMeta contains metadata about the Item. It gets stored in a
|
// ItemMeta contains metadata about the Item. It gets stored in a
|
||||||
// separate file in kopia
|
// separate file in kopia
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
|
FileName string `json:"filename,omitempty"`
|
||||||
Permissions []UserPermission `json:"permissions,omitempty"`
|
Permissions []UserPermission `json:"permissions,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,20 +294,16 @@ func (oc *Collection) populateItems(ctx context.Context) {
|
|||||||
|
|
||||||
if oc.source == OneDriveSource {
|
if oc.source == OneDriveSource {
|
||||||
// Fetch metadata for the file
|
// Fetch metadata for the file
|
||||||
if !oc.ctrl.ToggleFeatures.EnablePermissionsBackup {
|
itemMeta, itemMetaSize, err = oc.itemMetaReader(
|
||||||
// We are still writing the metadata file but with
|
ctx,
|
||||||
// empty permissions as we don't have a way to
|
oc.service,
|
||||||
// signify that the permissions was explicitly
|
oc.driveID,
|
||||||
// not added.
|
item,
|
||||||
itemMeta = io.NopCloser(strings.NewReader("{}"))
|
oc.ctrl.ToggleFeatures.EnablePermissionsBackup)
|
||||||
itemMetaSize = 2
|
|
||||||
} else {
|
|
||||||
itemMeta, itemMetaSize, err = oc.itemMetaReader(ctx, oc.service, oc.driveID, item)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errUpdater(*item.GetId(), errors.Wrap(err, "failed to get item permissions"))
|
errUpdater(itemID, clues.Wrap(err, "getting item metadata"))
|
||||||
return
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -197,6 +197,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
|
|||||||
_ graph.Servicer,
|
_ graph.Servicer,
|
||||||
_ string,
|
_ string,
|
||||||
_ models.DriveItemable,
|
_ models.DriveItemable,
|
||||||
|
_ bool,
|
||||||
) (io.ReadCloser, int, error) {
|
) (io.ReadCloser, int, error) {
|
||||||
metaJSON, err := json.Marshal(testItemMeta)
|
metaJSON, err := json.Marshal(testItemMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -331,6 +332,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionReadError() {
|
|||||||
_ graph.Servicer,
|
_ graph.Servicer,
|
||||||
_ string,
|
_ string,
|
||||||
_ models.DriveItemable,
|
_ models.DriveItemable,
|
||||||
|
_ bool,
|
||||||
) (io.ReadCloser, int, error) {
|
) (io.ReadCloser, int, error) {
|
||||||
return io.NopCloser(strings.NewReader(`{}`)), 2, nil
|
return io.NopCloser(strings.NewReader(`{}`)), 2, nil
|
||||||
}
|
}
|
||||||
@ -350,94 +352,6 @@ func (suite *CollectionUnitTestSuite) TestCollectionReadError() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *CollectionUnitTestSuite) TestCollectionDisablePermissionsBackup() {
|
|
||||||
table := []struct {
|
|
||||||
name string
|
|
||||||
source driveSource
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "oneDrive",
|
|
||||||
source: OneDriveSource,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range table {
|
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
|
||||||
ctx, flush := tester.NewContext()
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
var (
|
|
||||||
testItemID = "fakeItemID"
|
|
||||||
testItemName = "Fake Item"
|
|
||||||
testItemSize = int64(10)
|
|
||||||
collStatus = support.ConnectorOperationStatus{}
|
|
||||||
wg = sync.WaitGroup{}
|
|
||||||
)
|
|
||||||
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
folderPath, err := GetCanonicalPath("drive/driveID1/root:/folderPath", "a-tenant", "a-user", test.source)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
coll := NewCollection(
|
|
||||||
graph.HTTPClient(graph.NoTimeout()),
|
|
||||||
folderPath,
|
|
||||||
nil,
|
|
||||||
"fakeDriveID",
|
|
||||||
suite,
|
|
||||||
suite.testStatusUpdater(&wg, &collStatus),
|
|
||||||
test.source,
|
|
||||||
control.Options{ToggleFeatures: control.Toggles{}},
|
|
||||||
true)
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
mockItem := models.NewDriveItem()
|
|
||||||
mockItem.SetFile(models.NewFile())
|
|
||||||
mockItem.SetId(&testItemID)
|
|
||||||
mockItem.SetName(&testItemName)
|
|
||||||
mockItem.SetSize(&testItemSize)
|
|
||||||
mockItem.SetCreatedDateTime(&now)
|
|
||||||
mockItem.SetLastModifiedDateTime(&now)
|
|
||||||
coll.Add(mockItem)
|
|
||||||
|
|
||||||
coll.itemReader = func(
|
|
||||||
*http.Client,
|
|
||||||
models.DriveItemable,
|
|
||||||
) (details.ItemInfo, io.ReadCloser, error) {
|
|
||||||
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: "fakeName", Modified: time.Now()}},
|
|
||||||
io.NopCloser(strings.NewReader("Fake Data!")),
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
|
|
||||||
coll.itemMetaReader = func(_ context.Context,
|
|
||||||
_ graph.Servicer,
|
|
||||||
_ string,
|
|
||||||
_ models.DriveItemable,
|
|
||||||
) (io.ReadCloser, int, error) {
|
|
||||||
return io.NopCloser(strings.NewReader(`{"key": "value"}`)), 16, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
readItems := []data.Stream{}
|
|
||||||
for item := range coll.Items(ctx, fault.New(true)) {
|
|
||||||
readItems = append(readItems, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
// Expect no items
|
|
||||||
require.Equal(t, 1, collStatus.ObjectCount)
|
|
||||||
require.Equal(t, 1, collStatus.Successful)
|
|
||||||
|
|
||||||
for _, i := range readItems {
|
|
||||||
if strings.HasSuffix(i.UUID(), MetaFileSuffix) {
|
|
||||||
content, err := io.ReadAll(i.ToReader())
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, content, []byte("{}"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(meain): Remove this test once we start always backing up permissions
|
// TODO(meain): Remove this test once we start always backing up permissions
|
||||||
func (suite *CollectionUnitTestSuite) TestCollectionPermissionBackupLatestModTime() {
|
func (suite *CollectionUnitTestSuite) TestCollectionPermissionBackupLatestModTime() {
|
||||||
table := []struct {
|
table := []struct {
|
||||||
@ -502,6 +416,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionPermissionBackupLatestModTim
|
|||||||
_ graph.Servicer,
|
_ graph.Servicer,
|
||||||
_ string,
|
_ string,
|
||||||
_ models.DriveItemable,
|
_ models.DriveItemable,
|
||||||
|
_ bool,
|
||||||
) (io.ReadCloser, int, error) {
|
) (io.ReadCloser, int, error) {
|
||||||
return io.NopCloser(strings.NewReader(`{}`)), 16, nil
|
return io.NopCloser(strings.NewReader(`{}`)), 16, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alcionai/clues"
|
||||||
msdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
|
msdrives "github.com/microsoftgraph/msgraph-sdk-go/drives"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -61,18 +62,40 @@ func oneDriveItemMetaReader(
|
|||||||
service graph.Servicer,
|
service graph.Servicer,
|
||||||
driveID string,
|
driveID string,
|
||||||
item models.DriveItemable,
|
item models.DriveItemable,
|
||||||
|
fetchPermissions bool,
|
||||||
) (io.ReadCloser, int, error) {
|
) (io.ReadCloser, int, error) {
|
||||||
meta, err := oneDriveItemMetaInfo(ctx, service, driveID, item)
|
meta := Metadata{
|
||||||
|
FileName: *item.GetName(),
|
||||||
|
}
|
||||||
|
|
||||||
|
perms, err := oneDriveItemPermissionInfo(ctx, service, driveID, item, fetchPermissions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Keep this in an if-block because if it's not then we have a weird issue
|
||||||
|
// of having no value in error but golang thinking it's non nil because of
|
||||||
|
// the way interfaces work.
|
||||||
|
err = clues.Wrap(err, "fetching item permissions")
|
||||||
|
} else {
|
||||||
|
meta.Permissions = perms
|
||||||
|
}
|
||||||
|
|
||||||
|
metaJSON, serializeErr := json.Marshal(meta)
|
||||||
|
if serializeErr != nil {
|
||||||
|
serializeErr = clues.Wrap(serializeErr, "serializing item metadata")
|
||||||
|
|
||||||
|
// Need to check if err was already non-nil since it doesn't filter nil
|
||||||
|
// values out in calls to Stack().
|
||||||
|
if err != nil {
|
||||||
|
err = clues.Stack(err, serializeErr)
|
||||||
|
} else {
|
||||||
|
err = serializeErr
|
||||||
|
}
|
||||||
|
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
metaJSON, err := json.Marshal(meta)
|
r := io.NopCloser(bytes.NewReader(metaJSON))
|
||||||
if err != nil {
|
|
||||||
return nil, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return io.NopCloser(bytes.NewReader(metaJSON)), len(metaJSON), nil
|
return r, len(metaJSON), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// oneDriveItemReader will return a io.ReadCloser for the specified item
|
// oneDriveItemReader will return a io.ReadCloser for the specified item
|
||||||
@ -180,23 +203,32 @@ func oneDriveItemInfo(di models.DriveItemable, itemSize int64) *details.OneDrive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// oneDriveItemMetaInfo will fetch the meta information for a drive
|
// oneDriveItemPermissionInfo will fetch the permission information for a drive
|
||||||
// item. As of now, it only adds the permissions applicable for a
|
// item.
|
||||||
// onedrive item.
|
func oneDriveItemPermissionInfo(
|
||||||
func oneDriveItemMetaInfo(
|
ctx context.Context,
|
||||||
ctx context.Context, service graph.Servicer,
|
service graph.Servicer,
|
||||||
driveID string, di models.DriveItemable,
|
driveID string,
|
||||||
) (Metadata, error) {
|
di models.DriveItemable,
|
||||||
itemID := di.GetId()
|
fetchPermissions bool,
|
||||||
|
) ([]UserPermission, error) {
|
||||||
|
if !fetchPermissions {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
perm, err := service.Client().DrivesById(driveID).ItemsById(*itemID).Permissions().Get(ctx, nil)
|
perm, err := service.
|
||||||
|
Client().
|
||||||
|
DrivesById(driveID).
|
||||||
|
ItemsById(*di.GetId()).
|
||||||
|
Permissions().
|
||||||
|
Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Metadata{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
uperms := filterUserPermissions(perm.GetValue())
|
uperms := filterUserPermissions(perm.GetValue())
|
||||||
|
|
||||||
return Metadata{Permissions: uperms}, nil
|
return uperms, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterUserPermissions(perms []models.Permissionable) []UserPermission {
|
func filterUserPermissions(perms []models.Permissionable) []UserPermission {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user