move drive expand to config property (#4362)

the addition of the drive expand requires onedrive permissions in order to retrieve sites by ID.  This causes some users to violate customer contract by requiring unwanted permissions.  This change allows configuration of the getbyID call to optionally include the drive extend, which enables the backup process to return to the permission set as expected from v0.12

---

#### Does this PR need a docs update or release note?

- [x]  Yes, it's included

#### Type of change

- [x] 🌻 Feature

#### Issue(s)

* #4337

#### Test Plan

- [ ] 💪 Manual
- [ ] 💚 E2E
This commit is contained in:
Keepers 2023-09-25 13:18:16 -06:00 committed by GitHub
parent 732bac17a4
commit 01f61a44ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 16 deletions

View File

@ -290,7 +290,7 @@ func (sc *Collection) retrievePages(
return metrics, clues.New("beta service required").WithClues(ctx)
}
parent, err := as.GetByID(ctx, sc.fullPath.ProtectedResource())
parent, err := as.GetByID(ctx, sc.fullPath.ProtectedResource(), api.CallConfig{})
if err != nil {
return metrics, err
}

View File

@ -205,7 +205,11 @@ type resourceClient struct {
}
type getIDAndNamer interface {
GetIDAndName(ctx context.Context, owner string) (
GetIDAndName(
ctx context.Context,
owner string,
cc api.CallConfig,
) (
ownerID string,
ownerName string,
err error,
@ -254,7 +258,7 @@ func (r resourceClient) getOwnerIDAndNameFrom(
err error
)
id, name, err = r.getter.GetIDAndName(ctx, owner)
id, name, err = r.getter.GetIDAndName(ctx, owner, api.CallConfig{})
if err != nil {
if graph.IsErrUserNotFound(err) {
return "", "", clues.Stack(graph.ErrResourceOwnerNotFound, err)

View File

@ -1,6 +1,10 @@
package mock
import "context"
import (
"context"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type IDNameGetter struct {
ID, Name string
@ -10,6 +14,7 @@ type IDNameGetter struct {
func (ing IDNameGetter) GetIDAndName(
_ context.Context,
_ string,
_ api.CallConfig,
) (string, string, error) {
return ing.ID, ing.Name, ing.Err
}

View File

@ -118,3 +118,11 @@ func (c Client) Get(
) (*http.Response, error) {
return c.Requester.Request(ctx, http.MethodGet, url, nil, headers)
}
// ---------------------------------------------------------------------------
// per-call config
// ---------------------------------------------------------------------------
type CallConfig struct {
Expand []string
}

View File

@ -231,7 +231,11 @@ func IsTeam(ctx context.Context, mg models.Groupable) bool {
// GetIDAndName looks up the group matching the given ID, and returns
// its canonical ID and the name.
func (c Groups) GetIDAndName(ctx context.Context, groupID string) (string, string, error) {
func (c Groups) GetIDAndName(
ctx context.Context,
groupID string,
_ CallConfig, // not currently supported
) (string, string, error) {
s, err := c.GetByID(ctx, groupID)
if err != nil {
return "", "", err

View File

@ -111,12 +111,16 @@ var uuidRE = regexp.MustCompile(uuidRETmpl)
// deadbeef-0000-0000-0000-000000000000,beefdead-0000-0000-0000-000000000000
var siteIDRE = regexp.MustCompile(`(.+,)?` + uuidRETmpl + "," + uuidRETmpl)
const sitesWebURLGetTemplate = "https://graph.microsoft.com/v1.0/sites/%s:/%s?$expand=drive"
const sitesWebURLGetTemplate = "https://graph.microsoft.com/v1.0/sites/%s:/%s%s"
// GetByID looks up the site matching the given identifier. The identifier can be either a
// canonical site id or a webURL. Assumes the webURL is complete and well formed;
// eg: https://10rqc2.sharepoint.com/sites/Example
func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable, error) {
func (c Sites) GetByID(
ctx context.Context,
identifier string,
cc CallConfig,
) (models.Siteable, error) {
var (
resp models.Siteable
err error
@ -126,9 +130,11 @@ func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable,
if siteIDRE.MatchString(identifier) {
options := &sites.SiteItemRequestBuilderGetRequestConfiguration{
QueryParameters: &sites.SiteItemRequestBuilderGetQueryParameters{
Expand: []string{"drive"},
},
QueryParameters: &sites.SiteItemRequestBuilderGetQueryParameters{},
}
if len(cc.Expand) > 0 {
options.QueryParameters.Expand = cc.Expand
}
resp, err = c.Stable.
@ -167,7 +173,13 @@ func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable,
// don't construct a path with double leading slashes
path := strings.TrimPrefix(u.Path, "/")
rawURL := fmt.Sprintf(sitesWebURLGetTemplate, u.Host, path)
qp := ""
if len(cc.Expand) > 0 {
qp = "?expand=" + strings.Join(cc.Expand, ",")
}
rawURL := fmt.Sprintf(sitesWebURLGetTemplate, u.Host, path, qp)
resp, err = sites.
NewItemSitesSiteItemRequestBuilder(rawURL, c.Stable.Adapter()).
@ -190,8 +202,12 @@ func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable,
// GetIDAndName looks up the site matching the given ID, and returns
// its canonical ID and the webURL as the name. Accepts an ID or a
// WebURL as an ID.
func (c Sites) GetIDAndName(ctx context.Context, siteID string) (string, string, error) {
s, err := c.GetByID(ctx, siteID)
func (c Sites) GetIDAndName(
ctx context.Context,
siteID string,
cc CallConfig,
) (string, string, error) {
s, err := c.GetByID(ctx, siteID, cc)
if err != nil {
return "", "", err
}

View File

@ -232,7 +232,11 @@ func (suite *SitesIntgSuite) TestSites_GetByID() {
ctx, flush := tester.NewContext(t)
defer flush()
site, err := sitesAPI.GetByID(ctx, test.id)
cc := api.CallConfig{
Expand: []string{"drive"},
}
site, err := sitesAPI.GetByID(ctx, test.id, cc)
expectedErr := test.expectErr(t, err)
if expectedErr {

View File

@ -131,7 +131,11 @@ func (c Users) GetByID(ctx context.Context, identifier string) (models.Userable,
// GetIDAndName looks up the user matching the given ID, and returns
// its canonical ID and the PrincipalName as the name.
func (c Users) GetIDAndName(ctx context.Context, userID string) (string, string, error) {
func (c Users) GetIDAndName(
ctx context.Context,
userID string,
_ CallConfig, // not currently supported
) (string, string, error) {
u, err := c.GetByID(ctx, userID)
if err != nil {
return "", "", err

View File

@ -14,6 +14,7 @@ import (
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/services/m365/api"
)
type SiteOwnerType string
@ -58,7 +59,11 @@ func SiteByID(
return nil, clues.Stack(err).WithClues(ctx)
}
s, err := ac.Sites().GetByID(ctx, id)
cc := api.CallConfig{
Expand: []string{"drive"},
}
s, err := ac.Sites().GetByID(ctx, id, cc)
if err != nil {
return nil, clues.Stack(err)
}