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) 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 { if err != nil {
return metrics, err return metrics, err
} }

View File

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

View File

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

View File

@ -118,3 +118,11 @@ func (c Client) Get(
) (*http.Response, error) { ) (*http.Response, error) {
return c.Requester.Request(ctx, http.MethodGet, url, nil, headers) 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 // GetIDAndName looks up the group matching the given ID, and returns
// its canonical ID and the name. // 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) s, err := c.GetByID(ctx, groupID)
if err != nil { if err != nil {
return "", "", err return "", "", err

View File

@ -111,12 +111,16 @@ var uuidRE = regexp.MustCompile(uuidRETmpl)
// deadbeef-0000-0000-0000-000000000000,beefdead-0000-0000-0000-000000000000 // deadbeef-0000-0000-0000-000000000000,beefdead-0000-0000-0000-000000000000
var siteIDRE = regexp.MustCompile(`(.+,)?` + uuidRETmpl + "," + uuidRETmpl) 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 // 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; // canonical site id or a webURL. Assumes the webURL is complete and well formed;
// eg: https://10rqc2.sharepoint.com/sites/Example // 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 ( var (
resp models.Siteable resp models.Siteable
err error err error
@ -126,9 +130,11 @@ func (c Sites) GetByID(ctx context.Context, identifier string) (models.Siteable,
if siteIDRE.MatchString(identifier) { if siteIDRE.MatchString(identifier) {
options := &sites.SiteItemRequestBuilderGetRequestConfiguration{ options := &sites.SiteItemRequestBuilderGetRequestConfiguration{
QueryParameters: &sites.SiteItemRequestBuilderGetQueryParameters{ QueryParameters: &sites.SiteItemRequestBuilderGetQueryParameters{},
Expand: []string{"drive"}, }
},
if len(cc.Expand) > 0 {
options.QueryParameters.Expand = cc.Expand
} }
resp, err = c.Stable. 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 // don't construct a path with double leading slashes
path := strings.TrimPrefix(u.Path, "/") 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. resp, err = sites.
NewItemSitesSiteItemRequestBuilder(rawURL, c.Stable.Adapter()). 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 // 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 // its canonical ID and the webURL as the name. Accepts an ID or a
// WebURL as an ID. // WebURL as an ID.
func (c Sites) GetIDAndName(ctx context.Context, siteID string) (string, string, error) { func (c Sites) GetIDAndName(
s, err := c.GetByID(ctx, siteID) ctx context.Context,
siteID string,
cc CallConfig,
) (string, string, error) {
s, err := c.GetByID(ctx, siteID, cc)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }

View File

@ -232,7 +232,11 @@ func (suite *SitesIntgSuite) TestSites_GetByID() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() 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) expectedErr := test.expectErr(t, err)
if expectedErr { 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 // GetIDAndName looks up the user matching the given ID, and returns
// its canonical ID and the PrincipalName as the name. // 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) u, err := c.GetByID(ctx, userID)
if err != nil { if err != nil {
return "", "", err return "", "", err

View File

@ -14,6 +14,7 @@ import (
"github.com/alcionai/corso/src/pkg/account" "github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/services/m365/api"
) )
type SiteOwnerType string type SiteOwnerType string
@ -58,7 +59,11 @@ func SiteByID(
return nil, clues.Stack(err).WithClues(ctx) 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 { if err != nil {
return nil, clues.Stack(err) return nil, clues.Stack(err)
} }