Vaibhav Kamra 8fd867745f
Onedrive item reader (#582)
## Description

This contains the following changes:
- Support functions to enumerate a users drives and the files within it.
- `driveItemReader` method that that reads a drive item
- Integration tests for the above

## Type of change

Please check the type of change your PR introduces:
- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 🐹 Trivial/Minor

## Issue(s)
- #388 

## Test Plan

<!-- How will this be tested prior to merging.-->

- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
2022-08-18 23:38:23 +00:00

54 lines
1.6 KiB
Go

package onedrive
import (
"context"
"io"
"net/http"
"time"
"github.com/pkg/errors"
"github.com/alcionai/corso/internal/connector/graph"
"github.com/alcionai/corso/pkg/logger"
)
const (
// downloadUrlKey is used to find the download URL in a
// DriveItem response
downloadURLKey = "@microsoft.graph.downloadUrl"
)
// itemReader will return a io.ReadCloser for the specified item
// It crafts this by querying M365 for a download URL for the item
// and using a http client to initialize a reader
func driveItemReader(
ctx context.Context,
service graph.Service,
driveID, itemID string,
) (string, io.ReadCloser, error) {
logger.Ctx(ctx).Debugf("Reading Item %s at %s", itemID, time.Now())
item, err := service.Client().DrivesById(driveID).ItemsById(itemID).Get()
if err != nil {
return "", nil, errors.Wrapf(err, "failed to get item %s", itemID)
}
// Get the download URL - https://docs.microsoft.com/en-us/graph/api/driveitem-get-content
// These URLs are pre-authenticated and can be used to download the data using the standard
// http client
if _, found := item.GetAdditionalData()[downloadURLKey]; !found {
return "", nil, errors.Errorf("file does not have a download URL. ID: %s, %#v",
itemID, item.GetAdditionalData())
}
downloadURL := item.GetAdditionalData()[downloadURLKey].(*string)
// TODO: We should use the `msgraphgocore` http client which has the right
// middleware/options configured
resp, err := http.Get(*downloadURL)
if err != nil {
return "", nil, errors.Wrapf(err, "failed to download file from %s", *downloadURL)
}
return *item.GetName(), resp.Body, nil
}